IOTJS_Release_181221_630f029 accepted/tizen/unified/20181221.054506 submit/tizen/20181221.021259
authorHaesik Jun <haesik.jun@samsung.com>
Fri, 21 Dec 2018 02:05:04 +0000 (11:05 +0900)
committerHaesik Jun <haesik.jun@samsung.com>
Fri, 21 Dec 2018 02:05:04 +0000 (11:05 +0900)
Change-Id: I54fbaab303005111dfa699a641caa124daa93af7
Signed-off-by: Haesik Jun <haesik.jun@samsung.com>
797 files changed:
.gitignore
.travis.yml
CMakeLists.txt
README.md
appveyor.yml [new file with mode: 0644]
cmake/config/i686-windows.cmake [new file with mode: 0644]
cmake/config/noarch-linux.cmake [new file with mode: 0644]
cmake/config/x86_64-mock.cmake [new file with mode: 0644]
cmake/http-parser.cmake
cmake/iotjs.cmake
cmake/jerry.cmake
cmake/libtuv.cmake
cmake/mbedtls.cmake
config/nuttx/stm32f4dis/app/Makefile
config/nuttx/stm32f4dis/app/jerry_port.c
config/nuttx/stm32f4dis/iotjs-memstat.diff [deleted file]
config/nuttx/stm32f4dis/jerry-memstat.diff [deleted file]
config/nuttx/stm32f4dis/libtuv-memstat.diff [deleted file]
config/nuttx/stm32f4dis/nuttx-7.19.diff [deleted file]
config/tizen/filter.txt [new file with mode: 0644]
config/tizen/gbsbuild.sh
config/tizen/packaging/iotjs.spec
config/tizen/release.sh [new file with mode: 0755]
config/tizen/sample.gbs.conf
config/tizenrt/Makefile [new file with mode: 0644]
config/tizenrt/artik05x/configs/debug/defconfig [new file with mode: 0644]
config/tizenrt/artik05x/configs/defconfig [deleted file]
config/tizenrt/artik05x/configs/release/defconfig [new file with mode: 0644]
deps/http-parser/http_parser.c
deps/jerry/.gitignore
deps/jerry/.travis.yml
deps/jerry/CMakeLists.txt
deps/jerry/Doxyfile
deps/jerry/README.md
deps/jerry/appveyor.yml [new file with mode: 0644]
deps/jerry/cmake/toolchain_mcu_artik053.cmake
deps/jerry/docs/01.GETTING-STARTED.md
deps/jerry/docs/02.API-REFERENCE.md
deps/jerry/docs/03.API-EXAMPLE.md
deps/jerry/docs/05.PORT-API.md
deps/jerry/docs/06.REFERENCE-COUNTING.md
deps/jerry/docs/07.DEBUGGER.md
deps/jerry/docs/09.EXT-REFERENCE-ARG.md
deps/jerry/docs/10.EXT-REFERENCE-HANDLER.md
deps/jerry/docs/12.EXT-REFERENCE-MODULE.md
deps/jerry/docs/13.DEBUGGER-TRANSPORT.md [new file with mode: 0644]
deps/jerry/jerry-core/CMakeLists.txt
deps/jerry/jerry-core/api/jerry-debugger-transport.c [new file with mode: 0644]
deps/jerry/jerry-core/api/jerry-debugger.c
deps/jerry/jerry-core/api/jerry-snapshot.c
deps/jerry/jerry-core/api/jerry-snapshot.h
deps/jerry/jerry-core/api/jerry.c
deps/jerry/jerry-core/config.h
deps/jerry/jerry-core/debugger/debugger-sha1.c [deleted file]
deps/jerry/jerry-core/debugger/debugger-ws.c [deleted file]
deps/jerry/jerry-core/debugger/debugger-ws.h [deleted file]
deps/jerry/jerry-core/debugger/debugger.c
deps/jerry/jerry-core/debugger/debugger.h
deps/jerry/jerry-core/ecma/base/ecma-alloc.c
deps/jerry/jerry-core/ecma/base/ecma-alloc.h
deps/jerry/jerry-core/ecma/base/ecma-gc.c
deps/jerry/jerry-core/ecma/base/ecma-globals.h
deps/jerry/jerry-core/ecma/base/ecma-helpers-conversion.c
deps/jerry/jerry-core/ecma/base/ecma-helpers-errol.c
deps/jerry/jerry-core/ecma/base/ecma-helpers-external-pointers.c
deps/jerry/jerry-core/ecma/base/ecma-helpers-number.c
deps/jerry/jerry-core/ecma/base/ecma-helpers-string.c
deps/jerry/jerry-core/ecma/base/ecma-helpers-value.c
deps/jerry/jerry-core/ecma/base/ecma-helpers-values-collection.c
deps/jerry/jerry-core/ecma/base/ecma-helpers.c
deps/jerry/jerry-core/ecma/base/ecma-helpers.h
deps/jerry/jerry-core/ecma/base/ecma-init-finalize.c
deps/jerry/jerry-core/ecma/base/ecma-lcache.c
deps/jerry/jerry-core/ecma/base/ecma-lcache.h
deps/jerry/jerry-core/ecma/base/ecma-literal-storage.c
deps/jerry/jerry-core/ecma/base/ecma-property-hashmap.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-arraybuffer.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-boolean.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-date-prototype.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-date.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-error-prototype.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-function.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-global.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-json.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-sort.c [new file with mode: 0644]
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-helpers.h
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-json.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-map-prototype.c [new file with mode: 0644]
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-map-prototype.inc.h [new file with mode: 0644]
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-map.c [new file with mode: 0644]
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-map.inc.h [new file with mode: 0644]
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-math.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-number-prototype.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-object-prototype.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-object.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-promise.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-regexp-prototype.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-regexp.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-string-prototype.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtins.c
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtins.h
deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float32array-prototype.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float32array.c
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float32array.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float64array-prototype.c
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float64array-prototype.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float64array.c
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-float64array.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int16array-prototype.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int16array.c
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int16array.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int32array-prototype.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int32array.c
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int32array.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int8array-prototype.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int8array.c
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-int8array.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-helpers.c [new file with mode: 0644]
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-helpers.h [new file with mode: 0644]
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype-template.inc.h [new file with mode: 0644]
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.c
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-template.inc.h [new file with mode: 0644]
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray.c
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint16array-prototype.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint16array.c
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint16array.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint32array-prototype.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint32array.c
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint32array.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint8array-prototype.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint8array.c
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint8array.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint8clampedarray-prototype.inc.h
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint8clampedarray.c
deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-uint8clampedarray.inc.h
deps/jerry/jerry-core/ecma/operations/ecma-array-object.c
deps/jerry/jerry-core/ecma/operations/ecma-array-object.h
deps/jerry/jerry-core/ecma/operations/ecma-arraybuffer-object.c
deps/jerry/jerry-core/ecma/operations/ecma-arraybuffer-object.h
deps/jerry/jerry-core/ecma/operations/ecma-boolean-object.c
deps/jerry/jerry-core/ecma/operations/ecma-conversion.c
deps/jerry/jerry-core/ecma/operations/ecma-eval.c
deps/jerry/jerry-core/ecma/operations/ecma-eval.h
deps/jerry/jerry-core/ecma/operations/ecma-exceptions.c
deps/jerry/jerry-core/ecma/operations/ecma-exceptions.h
deps/jerry/jerry-core/ecma/operations/ecma-function-object.c
deps/jerry/jerry-core/ecma/operations/ecma-function-object.h
deps/jerry/jerry-core/ecma/operations/ecma-get-put-value.c
deps/jerry/jerry-core/ecma/operations/ecma-jobqueue.c
deps/jerry/jerry-core/ecma/operations/ecma-lex-env.c
deps/jerry/jerry-core/ecma/operations/ecma-lex-env.h
deps/jerry/jerry-core/ecma/operations/ecma-map-object.c [new file with mode: 0644]
deps/jerry/jerry-core/ecma/operations/ecma-map-object.h [new file with mode: 0644]
deps/jerry/jerry-core/ecma/operations/ecma-number-object.c
deps/jerry/jerry-core/ecma/operations/ecma-objects-arguments.c
deps/jerry/jerry-core/ecma/operations/ecma-objects-general.c
deps/jerry/jerry-core/ecma/operations/ecma-objects.c
deps/jerry/jerry-core/ecma/operations/ecma-objects.h
deps/jerry/jerry-core/ecma/operations/ecma-promise-object.c
deps/jerry/jerry-core/ecma/operations/ecma-promise-object.h
deps/jerry/jerry-core/ecma/operations/ecma-reference.c
deps/jerry/jerry-core/ecma/operations/ecma-reference.h
deps/jerry/jerry-core/ecma/operations/ecma-regexp-object.c
deps/jerry/jerry-core/ecma/operations/ecma-regexp-object.h
deps/jerry/jerry-core/ecma/operations/ecma-string-object.c
deps/jerry/jerry-core/ecma/operations/ecma-try-catch-macro.h
deps/jerry/jerry-core/ecma/operations/ecma-typedarray-object.c
deps/jerry/jerry-core/include/jerry-api.h [deleted file]
deps/jerry/jerry-core/include/jerry-port.h [deleted file]
deps/jerry/jerry-core/include/jerryscript-compiler.h [new file with mode: 0644]
deps/jerry/jerry-core/include/jerryscript-core.h
deps/jerry/jerry-core/include/jerryscript-debugger-transport.h [new file with mode: 0644]
deps/jerry/jerry-core/include/jerryscript-debugger.h
deps/jerry/jerry-core/include/jerryscript-port.h
deps/jerry/jerry-core/include/jerryscript-snapshot.h
deps/jerry/jerry-core/jcontext/jcontext.c
deps/jerry/jerry-core/jcontext/jcontext.h
deps/jerry/jerry-core/jmem/jmem-allocator-internal.h
deps/jerry/jerry-core/jmem/jmem-allocator.c
deps/jerry/jerry-core/jmem/jmem-heap.c
deps/jerry/jerry-core/jmem/jmem-poolman.c
deps/jerry/jerry-core/jmem/jmem.h
deps/jerry/jerry-core/jrt/jrt-fatals.c
deps/jerry/jerry-core/jrt/jrt.h
deps/jerry/jerry-core/lit/lit-char-helpers.c
deps/jerry/jerry-core/lit/lit-char-helpers.h
deps/jerry/jerry-core/lit/lit-globals.h
deps/jerry/jerry-core/lit/lit-magic-strings.c
deps/jerry/jerry-core/lit/lit-magic-strings.h
deps/jerry/jerry-core/lit/lit-magic-strings.inc.h
deps/jerry/jerry-core/lit/lit-magic-strings.ini
deps/jerry/jerry-core/lit/lit-strings.c
deps/jerry/jerry-core/lit/lit-strings.h
deps/jerry/jerry-core/parser/js/byte-code.c
deps/jerry/jerry-core/parser/js/byte-code.h
deps/jerry/jerry-core/parser/js/common.h
deps/jerry/jerry-core/parser/js/js-lexer.c
deps/jerry/jerry-core/parser/js/js-lexer.h
deps/jerry/jerry-core/parser/js/js-parser-expr.c
deps/jerry/jerry-core/parser/js/js-parser-internal.h
deps/jerry/jerry-core/parser/js/js-parser-limits.h
deps/jerry/jerry-core/parser/js/js-parser-scanner.c
deps/jerry/jerry-core/parser/js/js-parser-statm.c
deps/jerry/jerry-core/parser/js/js-parser-util.c
deps/jerry/jerry-core/parser/js/js-parser.c
deps/jerry/jerry-core/parser/js/js-parser.h
deps/jerry/jerry-core/parser/regexp/re-bytecode.c
deps/jerry/jerry-core/parser/regexp/re-bytecode.h
deps/jerry/jerry-core/parser/regexp/re-compiler.c
deps/jerry/jerry-core/parser/regexp/re-parser.c
deps/jerry/jerry-core/profiles/README.md
deps/jerry/jerry-core/vm/opcodes-ecma-relational-equality.c
deps/jerry/jerry-core/vm/opcodes.c
deps/jerry/jerry-core/vm/opcodes.h
deps/jerry/jerry-core/vm/vm-defines.h
deps/jerry/jerry-core/vm/vm-stack.c
deps/jerry/jerry-core/vm/vm-stack.h
deps/jerry/jerry-core/vm/vm-utils.c
deps/jerry/jerry-core/vm/vm.c
deps/jerry/jerry-core/vm/vm.h
deps/jerry/jerry-debugger/README.md [new file with mode: 0644]
deps/jerry/jerry-debugger/jerry-client-ws-html.py [deleted file]
deps/jerry/jerry-debugger/jerry-client-ws.html [deleted file]
deps/jerry/jerry-debugger/jerry-client-ws.py [deleted file]
deps/jerry/jerry-debugger/jerry_client.py [new file with mode: 0755]
deps/jerry/jerry-debugger/jerry_client_ws.py [new file with mode: 0644]
deps/jerry/jerry-ext/CMakeLists.txt
deps/jerry/jerry-ext/arg/arg-transform-functions.c
deps/jerry/jerry-ext/arg/arg.c
deps/jerry/jerry-ext/common/jext-common.h [new file with mode: 0644]
deps/jerry/jerry-ext/debugger/debugger-common.c [new file with mode: 0644]
deps/jerry/jerry-ext/debugger/debugger-sha1.c [new file with mode: 0644]
deps/jerry/jerry-ext/debugger/debugger-sha1.h [new file with mode: 0644]
deps/jerry/jerry-ext/debugger/debugger-tcp.c [new file with mode: 0644]
deps/jerry/jerry-ext/debugger/debugger-ws.c [new file with mode: 0644]
deps/jerry/jerry-ext/handler/handler-assert.c
deps/jerry/jerry-ext/handler/handler-gc.c
deps/jerry/jerry-ext/handler/handler-print.c
deps/jerry/jerry-ext/include/jerryscript-ext/arg.impl.h
deps/jerry/jerry-ext/include/jerryscript-ext/debugger.h [new file with mode: 0644]
deps/jerry/jerry-ext/include/jerryscript-ext/handler.h
deps/jerry/jerry-ext/include/jerryscript-ext/module.h
deps/jerry/jerry-ext/module/module.c
deps/jerry/jerry-libc/CMakeLists.txt [deleted file]
deps/jerry/jerry-libc/arch/arm-v7.h [deleted file]
deps/jerry/jerry-libc/arch/x86-32.h [deleted file]
deps/jerry/jerry-libc/arch/x86-64.h [deleted file]
deps/jerry/jerry-libc/include/assert.h [deleted file]
deps/jerry/jerry-libc/include/setjmp.h [deleted file]
deps/jerry/jerry-libc/include/stdio.h [deleted file]
deps/jerry/jerry-libc/include/stdlib.h [deleted file]
deps/jerry/jerry-libc/include/string.h [deleted file]
deps/jerry/jerry-libc/include/sys/time.h [deleted file]
deps/jerry/jerry-libc/jerry-libc-defs.h [deleted file]
deps/jerry/jerry-libc/jerry-libc-init.c [deleted file]
deps/jerry/jerry-libc/jerry-libc-printf.c [deleted file]
deps/jerry/jerry-libc/jerry-libc.c [deleted file]
deps/jerry/jerry-libc/target/posix/jerry-asm.S [deleted file]
deps/jerry/jerry-libc/target/posix/jerry-libc-target.c [deleted file]
deps/jerry/jerry-libm/CMakeLists.txt
deps/jerry/jerry-main/CMakeLists.txt
deps/jerry/jerry-main/benchmarking.c
deps/jerry/jerry-main/cli.c
deps/jerry/jerry-main/main-unix-snapshot.c
deps/jerry/jerry-main/main-unix-test.c
deps/jerry/jerry-main/main-unix.c
deps/jerry/jerry-port/default/CMakeLists.txt
deps/jerry/jerry-port/default/default-date.c
deps/jerry/jerry-port/default/default-debugger.c
deps/jerry/jerry-port/default/default-external-context.c
deps/jerry/jerry-port/default/default-fatal.c
deps/jerry/jerry-port/default/default-io.c
deps/jerry/jerry-port/default/defaultx-handler.c
deps/jerry/jerry-port/default/include/jerryscript-port-default.h
deps/jerry/sonar-project.properties [new file with mode: 0644]
deps/jerry/targets/curie_bsp/jerry_app/quark/main.c
deps/jerry/targets/curie_bsp/source/curie-bsp-port.c
deps/jerry/targets/esp8266/Makefile.esp8266
deps/jerry/targets/esp8266/Makefile.travis
deps/jerry/targets/esp8266/user/jerry_extapi.c
deps/jerry/targets/esp8266/user/jerry_port.c
deps/jerry/targets/esp8266/user/jerry_run.c
deps/jerry/targets/mbed/Makefile.mbed [deleted file]
deps/jerry/targets/mbed/Makefile.travis [deleted file]
deps/jerry/targets/mbed/js/blink.js [deleted file]
deps/jerry/targets/mbed/js/main.js [deleted file]
deps/jerry/targets/mbed/module.json [deleted file]
deps/jerry/targets/mbed/readme.md [deleted file]
deps/jerry/targets/mbed/source/jerry_extapi.cpp [deleted file]
deps/jerry/targets/mbed/source/jerry_extapi.h [deleted file]
deps/jerry/targets/mbed/source/jerry_run.cpp [deleted file]
deps/jerry/targets/mbed/source/jerry_run.h [deleted file]
deps/jerry/targets/mbed/source/main.cpp [deleted file]
deps/jerry/targets/mbed/source/makejerry.cmake [deleted file]
deps/jerry/targets/mbed/source/native_mbed.cpp [deleted file]
deps/jerry/targets/mbed/source/native_mbed.h [deleted file]
deps/jerry/targets/mbed/source/port/jerry_port.c [deleted file]
deps/jerry/targets/mbedos5/Makefile.travis
deps/jerry/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/setInterval-js.cpp
deps/jerry/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-drivers/source/setTimeout-js.cpp
deps/jerry/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/source/launcher.cpp
deps/jerry/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-launcher/source/setup.cpp
deps/jerry/targets/mbedos5/jerryscript-mbed/jerryscript-mbed-library-registry/source/wrap_tools.cpp
deps/jerry/targets/mbedos5/source/jerry_port_mbed.c
deps/jerry/targets/mbedos5/template-mbedignore.txt
deps/jerry/targets/mbedos5/tools/generate_pins.py
deps/jerry/targets/nuttx-stm32f4/Makefile.travis
deps/jerry/targets/nuttx-stm32f4/README.md
deps/jerry/targets/nuttx-stm32f4/jerry_main.c
deps/jerry/targets/openwrt/readme.md
deps/jerry/targets/particle/Makefile.particle
deps/jerry/targets/particle/source/main.cpp
deps/jerry/targets/riot-stm32f4/Makefile
deps/jerry/targets/riot-stm32f4/Makefile.riot
deps/jerry/targets/riot-stm32f4/Makefile.travis
deps/jerry/targets/riot-stm32f4/source/main-riotos.c
deps/jerry/targets/tizenrt-artik053/Makefile.tizenrt
deps/jerry/targets/tizenrt-artik053/README.md
deps/jerry/targets/tizenrt-artik053/apps/jerryscript/Makefile
deps/jerry/targets/tizenrt-artik053/apps/jerryscript/jerry_main.c
deps/jerry/targets/tizenrt-artik053/configs/jerryscript/Make.defs
deps/jerry/targets/zephyr/CMakeLists.txt
deps/jerry/targets/zephyr/Makefile.travis
deps/jerry/targets/zephyr/Makefile.zephyr
deps/jerry/targets/zephyr/prj.conf
deps/jerry/targets/zephyr/src/jerry-port.c
deps/jerry/targets/zephyr/src/main-zephyr.c
deps/jerry/tests/debugger/do_backtrace.cmd
deps/jerry/tests/debugger/do_backtrace.expected
deps/jerry/tests/debugger/do_break.expected
deps/jerry/tests/debugger/do_delete.expected
deps/jerry/tests/debugger/do_delete_all.expected
deps/jerry/tests/debugger/do_eval_at.cmd [new file with mode: 0644]
deps/jerry/tests/debugger/do_eval_at.expected [new file with mode: 0644]
deps/jerry/tests/debugger/do_eval_at.js [new file with mode: 0644]
deps/jerry/tests/debugger/do_help.expected
deps/jerry/tests/debugger/do_pending_breakpoints.expected
deps/jerry/tests/debugger/do_print.cmd [new file with mode: 0644]
deps/jerry/tests/debugger/do_print.expected [new file with mode: 0644]
deps/jerry/tests/debugger/do_print.js [new file with mode: 0644]
deps/jerry/tests/debugger/do_restart.cmd [new file with mode: 0644]
deps/jerry/tests/debugger/do_restart.expected [new file with mode: 0644]
deps/jerry/tests/debugger/do_restart.js [new file with mode: 0644]
deps/jerry/tests/debugger/do_scopes.cmd [new file with mode: 0644]
deps/jerry/tests/debugger/do_scopes.expected [new file with mode: 0644]
deps/jerry/tests/debugger/do_scopes.js [new file with mode: 0644]
deps/jerry/tests/debugger/do_variables.cmd [new file with mode: 0644]
deps/jerry/tests/debugger/do_variables.expected [new file with mode: 0644]
deps/jerry/tests/debugger/do_variables.js [new file with mode: 0644]
deps/jerry/tests/jerry-test-suite/11/11.08/11.08.06/11.08.06-008.js [new file with mode: 0644]
deps/jerry/tests/jerry/N.compact-profile-error.js [deleted file]
deps/jerry/tests/jerry/arithmetics-2.js
deps/jerry/tests/jerry/arithmetics-bignums.js
deps/jerry/tests/jerry/date-getters.js
deps/jerry/tests/jerry/date-setters.js
deps/jerry/tests/jerry/equality.js
deps/jerry/tests/jerry/es2015/array-prototype-find.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-bound.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-builtin-array.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-builtin-typedarray.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-core-1.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-core-10.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-core-11.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-core-12.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-core-13.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-core-14.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-core-15.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-core-2.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-core-3.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-core-4.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-core-5.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-core-6.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-core-7.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-core-8.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-core-9.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-early-semantics.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-mixins-1.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class-inheritance-mixins-2.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/class.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/function-param-init.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/map.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/object-computed-prescanner.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/object-computed.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/object-initializer.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/regression-test-issue-2414.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/regression-test-issue-2435.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/regression-test-issue-2465.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/regression-test-issue-2468.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/regression-test-issue-2486.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/regression-test-issue-2487.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/regression-test-issue-2488.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/regression-test-issue-2489-original.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/regression-test-issue-2490.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/regression-test-issue-2528.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/regression-test-issue-2587.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/regression-test-issue-2602.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/regression-test-issue-2603.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/typedArray-fill.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/typedArray-find.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/typedArray-join.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/typedArray-set-with-typedArray.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/typedArray-sort.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/typedArray-subarray.js [new file with mode: 0644]
deps/jerry/tests/jerry/es2015/typedArray-tostring.js [new file with mode: 0644]
deps/jerry/tests/jerry/es5.1/object-literal-fails.js [new file with mode: 0644]
deps/jerry/tests/jerry/fail/object-get-data.js [deleted file]
deps/jerry/tests/jerry/fail/object-get-get.js [deleted file]
deps/jerry/tests/jerry/fail/object-several-prop-names-strict.js [deleted file]
deps/jerry/tests/jerry/fail/regression-test-issue-2344.js [new file with mode: 0644]
deps/jerry/tests/jerry/fail/regression-test-issue-2489.js [new file with mode: 0644]
deps/jerry/tests/jerry/fail/regression-test-issue-2544.js [new file with mode: 0644]
deps/jerry/tests/jerry/function-expr-named.js [new file with mode: 0644]
deps/jerry/tests/jerry/math-pow.js
deps/jerry/tests/jerry/object-get-own-property-names.js
deps/jerry/tests/jerry/object-literal-3.js [deleted file]
deps/jerry/tests/jerry/object-literal-prescanner.js [new file with mode: 0644]
deps/jerry/tests/jerry/parser-oom2.js [new file with mode: 0644]
deps/jerry/tests/jerry/regression-test-issue-1821.js [new file with mode: 0644]
deps/jerry/tests/jerry/regression-test-issue-1833.js [deleted file]
deps/jerry/tests/jerry/regression-test-issue-2230.js [new file with mode: 0644]
deps/jerry/tests/jerry/regression-test-issue-2237.js [new file with mode: 0644]
deps/jerry/tests/jerry/regression-test-issue-2384.js [new file with mode: 0644]
deps/jerry/tests/jerry/regression-test-issue-2386.js [new file with mode: 0644]
deps/jerry/tests/jerry/regression-test-issue-2398.js [new file with mode: 0644]
deps/jerry/tests/jerry/regression-test-issue-2400.js [new file with mode: 0644]
deps/jerry/tests/jerry/regression-test-issue-2409.js [new file with mode: 0644]
deps/jerry/tests/jerry/regression-test-issue-2451.js [new file with mode: 0644]
deps/jerry/tests/jerry/regression-test-issue-2452.js [new file with mode: 0644]
deps/jerry/tests/jerry/regression-test-issue-2453.js [new file with mode: 0644]
deps/jerry/tests/jerry/regression-test-issue-2478.js [new file with mode: 0644]
deps/jerry/tests/jerry/regression-test-issue-2494.js [new file with mode: 0644]
deps/jerry/tests/jerry/regression-test-issue-2614.js [new file with mode: 0644]
deps/jerry/tests/jerry/unusual.js [new file with mode: 0644]
deps/jerry/tests/jerry/windows-line-ending.js [new file with mode: 0644]
deps/jerry/tests/unit-core/CMakeLists.txt
deps/jerry/tests/unit-core/test-abort.c
deps/jerry/tests/unit-core/test-api-errortype.c
deps/jerry/tests/unit-core/test-api-property.c [new file with mode: 0644]
deps/jerry/tests/unit-core/test-api-set-and-clear-error-flag.c
deps/jerry/tests/unit-core/test-api-strings.c [new file with mode: 0644]
deps/jerry/tests/unit-core/test-api-value-type.c
deps/jerry/tests/unit-core/test-api.c
deps/jerry/tests/unit-core/test-arraybuffer.c
deps/jerry/tests/unit-core/test-backtrace.c
deps/jerry/tests/unit-core/test-common.h
deps/jerry/tests/unit-core/test-exec-stop.c
deps/jerry/tests/unit-core/test-mem-stats.c
deps/jerry/tests/unit-core/test-objects-foreach.c
deps/jerry/tests/unit-core/test-promise.c
deps/jerry/tests/unit-core/test-regexp.c [new file with mode: 0644]
deps/jerry/tests/unit-core/test-snapshot.c
deps/jerry/tests/unit-core/test-typedarray.c
deps/jerry/tests/unit-doc/CMakeLists.txt
deps/jerry/tests/unit-ext/CMakeLists.txt
deps/jerry/tests/unit-ext/module/CMakeLists.txt
deps/jerry/tests/unit-ext/module/jerry-module-test.c
deps/jerry/tests/unit-ext/test-common.h
deps/jerry/tests/unit-ext/test-ext-arg.c
deps/jerry/tests/unit-ext/test-ext-autorelease.c
deps/jerry/tests/unit-ext/test-ext-module-empty.c
deps/jerry/tests/unit-libm/CMakeLists.txt
deps/jerry/tools/build.py
deps/jerry/tools/check-cppcheck.sh
deps/jerry/tools/check-doxygen.sh
deps/jerry/tools/check-license.py
deps/jerry/tools/check-magic-strings.sh
deps/jerry/tools/check-sonarqube.sh [new file with mode: 0755]
deps/jerry/tools/check-vera.sh
deps/jerry/tools/cppcheck/suppressions-list
deps/jerry/tools/gen-magic-strings.py
deps/jerry/tools/generator.sh [deleted file]
deps/jerry/tools/make-log-perf-compare.sh [deleted file]
deps/jerry/tools/pylint/pylintrc
deps/jerry/tools/run-tests.py
deps/jerry/tools/runners/run-debugger-test.sh
deps/jerry/tools/runners/run-stability-test.sh [deleted file]
deps/jerry/tools/runners/run-test-suite-test262.sh
deps/jerry/tools/runners/run-test-suite.sh
deps/jerry/tools/runners/run-tests-remote.sh [deleted file]
deps/jerry/tools/runners/run-unittests-remote.sh [deleted file]
deps/jerry/tools/runners/run-unittests.sh
deps/jerry/tools/settings.py
deps/jerry/tools/sort-fails.sh [deleted file]
deps/jerry/tools/update-webpage.sh
deps/libtuv/CMakeLists.txt
deps/libtuv/Makefile
deps/libtuv/cmake/config/config_i686-windows.cmake [new file with mode: 0644]
deps/libtuv/cmake/libtuv.cmake
deps/libtuv/cmake/option/option_i686-windows.cmake [new file with mode: 0644]
deps/libtuv/cmake/option/option_mips-openwrt.cmake [changed mode: 0755->0644]
deps/libtuv/cmake/option/option_unix_common.cmake
deps/libtuv/cmake/option/option_windows_common.cmake [new file with mode: 0644]
deps/libtuv/include/uv-nuttx.h
deps/libtuv/include/uv.h
deps/libtuv/src/unix/core.c
deps/libtuv/src/unix/fs.c
deps/libtuv/src/unix/getaddrinfo.c
deps/libtuv/src/unix/linux-core.c
deps/libtuv/src/unix/loop.c
deps/libtuv/src/unix/process.c
deps/libtuv/src/unix/stream.c
deps/libtuv/src/unix/thread.c
deps/libtuv/src/unix/udp.c
deps/libtuv/src/uv-common.c
deps/libtuv/src/uv-common.h
deps/libtuv/src/win/async.c [new file with mode: 0644]
deps/libtuv/src/win/atomicops-inl.h [new file with mode: 0644]
deps/libtuv/src/win/core.c [new file with mode: 0644]
deps/libtuv/src/win/detect-wakeup.c [new file with mode: 0644]
deps/libtuv/src/win/dl.c [new file with mode: 0644]
deps/libtuv/src/win/error.c [new file with mode: 0644]
deps/libtuv/src/win/fs-event.c [new file with mode: 0644]
deps/libtuv/src/win/fs.c [new file with mode: 0644]
deps/libtuv/src/win/getaddrinfo.c [new file with mode: 0644]
deps/libtuv/src/win/getnameinfo.c [new file with mode: 0644]
deps/libtuv/src/win/handle-inl.h [new file with mode: 0644]
deps/libtuv/src/win/handle.c [new file with mode: 0644]
deps/libtuv/src/win/internal.h [new file with mode: 0644]
deps/libtuv/src/win/loop-watcher.c [new file with mode: 0644]
deps/libtuv/src/win/pipe.c [new file with mode: 0644]
deps/libtuv/src/win/poll.c [new file with mode: 0644]
deps/libtuv/src/win/process-stdio.c [new file with mode: 0644]
deps/libtuv/src/win/process.c [new file with mode: 0644]
deps/libtuv/src/win/req-inl.h [new file with mode: 0644]
deps/libtuv/src/win/req.c [new file with mode: 0644]
deps/libtuv/src/win/signal.c [new file with mode: 0644]
deps/libtuv/src/win/snprintf.c [new file with mode: 0644]
deps/libtuv/src/win/stream-inl.h [new file with mode: 0644]
deps/libtuv/src/win/stream.c [new file with mode: 0644]
deps/libtuv/src/win/tcp.c [new file with mode: 0644]
deps/libtuv/src/win/thread.c [new file with mode: 0644]
deps/libtuv/src/win/timer.c [new file with mode: 0644]
deps/libtuv/src/win/tty.c [new file with mode: 0644]
deps/libtuv/src/win/udp.c [new file with mode: 0644]
deps/libtuv/src/win/util.c [new file with mode: 0644]
deps/libtuv/src/win/winapi.c [new file with mode: 0644]
deps/libtuv/src/win/winapi.h [new file with mode: 0644]
deps/libtuv/src/win/winsock.c [new file with mode: 0644]
deps/libtuv/src/win/winsock.h [new file with mode: 0644]
deps/libtuv/test/echo_server.c
deps/libtuv/test/runner.h
deps/libtuv/test/runner_linux.c
deps/libtuv/test/runner_list.h
deps/libtuv/test/test_ipc.c [new file with mode: 0644]
deps/libtuv/test/test_pipe_bind_error.c [new file with mode: 0644]
deps/libtuv/test/test_pipe_close_stdout_read_stdin.c [new file with mode: 0644]
deps/libtuv/test/test_pipe_connect_error.c [new file with mode: 0644]
deps/libtuv/test/test_pipe_connect_multiple.c [new file with mode: 0644]
deps/libtuv/test/test_pipe_connect_prepare.c [new file with mode: 0644]
deps/libtuv/test/test_pipe_getsockname.c [new file with mode: 0644]
deps/libtuv/test/test_pipe_pending_instances.c [new file with mode: 0644]
deps/libtuv/test/test_pipe_sendmsg.c [new file with mode: 0644]
deps/libtuv/test/test_pipe_server_close.c [new file with mode: 0644]
deps/libtuv/test/test_pipe_set_non_blocking.c [new file with mode: 0644]
deps/libtuv/test/test_signal.c [new file with mode: 0644]
deps/libtuv/test/test_spawn.c [new file with mode: 0644]
docs/Getting-Started.md
docs/api/IoT.js-API-Buffer.md
docs/api/IoT.js-API-Crypto.md [new file with mode: 0644]
docs/api/IoT.js-API-File-System.md
docs/api/IoT.js-API-GPIO.md
docs/api/IoT.js-API-HTTP-Signature.md [new file with mode: 0644]
docs/api/IoT.js-API-HTTP.md
docs/api/IoT.js-API-HTTPS.md
docs/api/IoT.js-API-MQTT.md
docs/api/IoT.js-API-Stream.md
docs/api/IoT.js-API-TLS.md
docs/api/IoT.js-API-UART.md
docs/api/IoT.js-API-WebSocket.md [new file with mode: 0644]
docs/build/Build-Script.md
docs/build/Build-for-ARTIK053-TizenRT.md
docs/build/Build-for-ARTIK10-Tizen.md [deleted file]
docs/build/Build-for-RPi3-Tizen.md
docs/build/Build-for-STM32F4-NuttX.md
docs/build/Build-for-Windows.md [new file with mode: 0644]
docs/contributing/Community-Guidelines.md
docs/devs/API-Document-Guidelines.md
docs/devs/Coding-Style-Guidelines.md
docs/devs/Inside-IoT.js.md
docs/devs/Optimization-Tips.md
docs/devs/Test-Guidelines.md
docs/devs/Use-JerryScript-Debugger.md
packaging/iotjs.spec
samples/bridge_sample/README.md [deleted file]
samples/bridge_sample/js/bridge_sample.js [deleted file]
samples/bridge_sample/module.cmake [deleted file]
samples/bridge_sample/modules.json [deleted file]
samples/bridge_sample/src/iotjs_bridge_sample.c [deleted file]
samples/bridge_sample/test.js [deleted file]
samples/fur-elise/play.js [deleted file]
samples/gpio-blinkedled/gpio_led.js [deleted file]
samples/gpio-blinkedled/systemio_pin.js [deleted file]
samples/http-gpio-panel/favicon.ico [deleted file]
samples/http-gpio-panel/index.html [deleted file]
samples/http-gpio-panel/server.js [deleted file]
samples/http-hello/client_get.js [deleted file]
samples/http-hello/client_post.js [deleted file]
samples/http-hello/server.js [deleted file]
samples/i2c/i2c_ht16k33.js [deleted file]
samples/light-fade/light-fade.js [deleted file]
samples/net-hello/client.js [deleted file]
samples/net-hello/server.js [deleted file]
samples/tizen-bridge-native/tizen_bridge_native.c [deleted file]
samples/tizen-bridge-native/tizen_bridge_native.js [deleted file]
samples/uart-iotjs-console/console.js [deleted file]
samples/udp-chat/chat.js [deleted file]
src/iotjs.c
src/iotjs_binding.c
src/iotjs_binding.h
src/iotjs_binding_helper.c
src/iotjs_binding_helper.h
src/iotjs_compatibility.h [new file with mode: 0644]
src/iotjs_def.h
src/iotjs_env.c
src/iotjs_env.h
src/iotjs_handlewrap.c [deleted file]
src/iotjs_handlewrap.h [deleted file]
src/iotjs_magic_strings.h
src/iotjs_reqwrap.c [deleted file]
src/iotjs_reqwrap.h [deleted file]
src/iotjs_string.c
src/iotjs_string_ext.c
src/iotjs_util.h
src/iotjs_uv_handle.c [new file with mode: 0644]
src/iotjs_uv_handle.h [new file with mode: 0644]
src/iotjs_uv_request.c [new file with mode: 0644]
src/iotjs_uv_request.h [new file with mode: 0644]
src/js/ble_hci_socket_hci.js
src/js/ble_hci_socket_hci_status.js
src/js/buffer.js
src/js/crypto.js [new file with mode: 0644]
src/js/dgram.js
src/js/dns.js
src/js/fs.js
src/js/http.js
src/js/http_client.js
src/js/http_common.js
src/js/http_incoming.js
src/js/http_outgoing.js
src/js/http_server.js
src/js/http_signature.js [new file with mode: 0644]
src/js/https.js
src/js/iotjs.js
src/js/module.js
src/js/mqtt.js
src/js/net.js
src/js/stream_readable.js
src/js/stream_writable.js
src/js/timers.js
src/js/tizen.js
src/js/tls.js
src/js/util.js
src/js/websocket.js [new file with mode: 0644]
src/modules.json
src/modules/iotjs_module_adc.c
src/modules/iotjs_module_adc.h
src/modules/iotjs_module_blehcisocket.c
src/modules/iotjs_module_blehcisocket.h
src/modules/iotjs_module_bridge.c
src/modules/iotjs_module_buffer.c
src/modules/iotjs_module_buffer.h
src/modules/iotjs_module_constants.c
src/modules/iotjs_module_crypto.c [new file with mode: 0644]
src/modules/iotjs_module_crypto.h [new file with mode: 0644]
src/modules/iotjs_module_dns.c
src/modules/iotjs_module_dns.h [deleted file]
src/modules/iotjs_module_fs.c
src/modules/iotjs_module_gpio.c
src/modules/iotjs_module_gpio.h
src/modules/iotjs_module_http_parser.c
src/modules/iotjs_module_i2c.c
src/modules/iotjs_module_i2c.h
src/modules/iotjs_module_mqtt.c
src/modules/iotjs_module_mqtt.h
src/modules/iotjs_module_periph_common.c
src/modules/iotjs_module_periph_common.h
src/modules/iotjs_module_process.c
src/modules/iotjs_module_pwm.c
src/modules/iotjs_module_pwm.h
src/modules/iotjs_module_spi.c
src/modules/iotjs_module_spi.h
src/modules/iotjs_module_tcp.c
src/modules/iotjs_module_tcp.h
src/modules/iotjs_module_timer.c
src/modules/iotjs_module_timer.h [deleted file]
src/modules/iotjs_module_tls.c
src/modules/iotjs_module_uart.c
src/modules/iotjs_module_uart.h
src/modules/iotjs_module_udp.c
src/modules/iotjs_module_udp.h [deleted file]
src/modules/iotjs_module_websocket.c [new file with mode: 0644]
src/modules/iotjs_module_websocket.h [new file with mode: 0644]
src/modules/linux/iotjs_module_blehcisocket-linux.c
src/modules/linux/iotjs_module_gpio-linux.c
src/modules/linux/iotjs_module_pwm-linux.c
src/modules/linux/iotjs_module_uart-linux.c
src/modules/mock/iotjs_module_gpio-mock.c [new file with mode: 0644]
src/modules/mock/iotjs_module_i2c-mock.c [new file with mode: 0644]
src/modules/nuttx/iotjs_module_gpio-nuttx.c
src/modules/nuttx/iotjs_module_uart-nuttx.c
src/modules/tizen/iotjs_module_gpio-tizen.c
src/modules/tizen/iotjs_module_tizen-tizen.c
src/modules/tizen/iotjs_module_uart-tizen.c
src/modules/tizenrt/iotjs_module_gpio-tizenrt.c
src/modules/tizenrt/iotjs_module_uart-tizenrt.c
src/platform/linux/iotjs_systemio-linux.c
src/platform/tizen/iotjs_tizen_service_app.c
src/platform/tizenrt/iotjs_main_tizenrt.c
test/dynamicmodule/CMakeLists.txt
test/node/common.js
test/node/parallel/test-net-bind-twice.js
test/profiles/host-linux.profile
test/profiles/mock-linux.profile [new file with mode: 0644]
test/profiles/nuttx.profile
test/profiles/rpi2-linux.profile
test/profiles/tizen-jerry.profile [new file with mode: 0644]
test/profiles/tizen.profile
test/profiles/tizenrt.profile
test/resources/crypto_public.pem [new file with mode: 0644]
test/resources/http_signature_key.key [new file with mode: 0644]
test/resources/my_ca.crt [new file with mode: 0644]
test/resources/my_ca.key [new file with mode: 0644]
test/resources/my_ca.srl [new file with mode: 0644]
test/resources/my_crt.crt [new file with mode: 0644]
test/resources/my_crt.pem [deleted file]
test/resources/my_csr.csr [new file with mode: 0644]
test/resources/my_key.key [new file with mode: 0644]
test/resources/my_key.pem [deleted file]
test/run_fail/test-issue-1570.js [new file with mode: 0644]
test/run_pass/issue/issue-1463.js [new file with mode: 0644]
test/run_pass/test_buffer_from.js [new file with mode: 0644]
test/run_pass/test_buffer_from_arraybuffer.js [new file with mode: 0644]
test/run_pass/test_buffer_inmutability_creation.js [new file with mode: 0644]
test/run_pass/test_crypto.js [new file with mode: 0644]
test/run_pass/test_crypto_tls.js [new file with mode: 0644]
test/run_pass/test_dns_lookup.js
test/run_pass/test_fs_read_stream.js [new file with mode: 0644]
test/run_pass/test_fs_stream_pipe.js [new file with mode: 0644]
test/run_pass/test_fs_write_stream.js [new file with mode: 0644]
test/run_pass/test_gpio_api.js [new file with mode: 0644]
test/run_pass/test_gpio_direction.js [new file with mode: 0644]
test/run_pass/test_http_signature.js [new file with mode: 0644]
test/run_pass/test_i2c_api.js [new file with mode: 0644]
test/run_pass/test_module_dynamicload.js
test/run_pass/test_mqtt.js [new file with mode: 0644]
test/run_pass/test_mqtt_frags.js [new file with mode: 0644]
test/run_pass/test_net_headers.js
test/run_pass/test_net_http_methods.js [new file with mode: 0644]
test/run_pass/test_net_http_modified_req_resp.js [new file with mode: 0644]
test/run_pass/test_net_http_modified_request.js [new file with mode: 0644]
test/run_pass/test_net_http_modified_response.js [new file with mode: 0644]
test/run_pass/test_net_http_outgoing_buffer.js [new file with mode: 0644]
test/run_pass/test_net_http_request_http_version.js [new file with mode: 0644]
test/run_pass/test_net_https_modified_req_resp.js [new file with mode: 0644]
test/run_pass/test_net_https_server.js
test/run_pass/test_process_chdir.js
test/run_pass/test_stream_pipe.js [new file with mode: 0644]
test/run_pass/test_tls.js [deleted file]
test/run_pass/test_tls_1.js [new file with mode: 0644]
test/run_pass/test_tls_2.js [new file with mode: 0644]
test/run_pass/test_tls_3.js [new file with mode: 0644]
test/run_pass/test_tls_4.js [new file with mode: 0644]
test/run_pass/test_tls_ca.js [new file with mode: 0644]
test/run_pass/test_tls_stream_duplex.js [new file with mode: 0644]
test/run_pass/test_websocket.js [new file with mode: 0644]
test/run_pass/test_websocket_server.js [new file with mode: 0644]
test/run_pass/test_websocket_server_secure.js [new file with mode: 0644]
test/testsets-es2015.json [deleted file]
test/testsets-external-modules.json [deleted file]
test/testsets-host-darwin.json [deleted file]
test/testsets-host-linux.json [deleted file]
test/testsets-minimal.json [deleted file]
test/testsets.json
test/tools/iotjs_build_info.js [new file with mode: 0644]
tools/apt-get-install-deps.sh
tools/build.py
tools/check_sonarqube.sh
tools/check_tidy.py
tools/common_js/logger.js [deleted file]
tools/common_js/module/console.js [deleted file]
tools/common_js/option_parser.js [deleted file]
tools/common_js/util.js [deleted file]
tools/common_py/path.py
tools/common_py/system/executor.py
tools/common_py/system/platform.py
tools/iotjs_build_info.js [deleted file]
tools/js2c.py
tools/testrunner.py
tools/travis_script.py

index 97cf8e679233634601d2e5828b0b1b3ae93b7203..673f9eb340ddbbdb5aa5117884fb2c03b4c9df9b 100644 (file)
@@ -7,6 +7,7 @@
 /src/iotjs_string_ext.inl.h
 /src/iotjs_module_inl.h
 /test/tmp/*
+/test/dynamicmodule/build/*
 eslint.log
 
 # IDE related files
index 2916ac0117008531b97e6c1832f25051f26f15c6..3733d74bc71c0be315060729e17ec497c7a409f3 100644 (file)
@@ -2,64 +2,81 @@ language: c
 
 os: linux
 dist: trusty
-sudo: required
+sudo: false
 
 services:
   - docker
 
 before_install:
-  - if [[ "$RUN_DOCKER" == "yes" ]]; then docker pull iotjs/ubuntu:0.6; fi
-  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then tools/brew-install-deps.sh; fi
-  - if [[ "$OPTS" == "misc" ]]; then tools/apt-get-install-deps.sh; fi
-
-install:
-  pip install --user jsonmerge
+  - if [[ "$RUN_DOCKER" == "yes" ]]; then docker pull iotjs/ubuntu:0.9; fi
 
 script:
   tools/travis_script.py
 
-env:
-  global:
-    - secure: "lUGzoKK/Yn4/OmpqLQALrIgfY9mQWE51deUawPrCO87UQ2GknfQ4BvwY3UT5QY0XnztPBP1+vRQ2qxbiAU7VWicp280sXDnh0FeuZD14FcE9l0FczraL12reoLu+gY5HWFfbkZncmcBsZkxDEYxhkM14FJU8fxyqGQW2ypJNz+gUGP+8r40Re5J3WjcddCQNe5IG8U+M9B4YeDHhN2QspLdN5pkgn56XtdGa3+qbecO2NpjJG5ltM9j1tTuo/Dg22DxrIFVfeFSFKUj4nfMrgPo5LevRsC/lfaBSCsj751eqrxRcQRh2hkpiIJ7mEBs2LL1EH9O6Mbj+eRh8BvIYqTB85VPNFc43sLWk14apcSVBrxJE5j3kP9sAsOD9Y5JynnkeuxYyISrkywwoX2uxsmCzIfGbwsv5VLToQzrqWlGYrHOAmVXNi8561dLfsWwxxFUjdqkZr1Kgc8UfnBEcBUtSiKCHS86/YUUbBJGkEkjDUS0GiqhFY4bXLQCR7EX4qDX3m6p7Mnh4NVUolpnSmyeYE/MjmqQ+7PJsPLL3EcIYmJ7dtW3mZ3yE2NyaFD0Pym9+TiuCCXRtrNVK1M3Kya64KNv+HbhjT/fTCgXLSeyDmJOKVAqugRlDo3b1KGR1LI0AfegzSA6mEC4e9JLjYiSnHPMUahzgLt8oU0hNFRY="
-  matrix:
-    - OPTS="host-linux" RUN_DOCKER=yes
-    - OPTS="rpi2" RUN_DOCKER=yes
-    - OPTS="stm32f4dis" RUN_DOCKER=yes
-    - OPTS="artik053" RUN_DOCKER=yes
-    - OPTS="tizen" RUN_DOCKER=yes
-    - OPTS="es2015" RUN_DOCKER=yes
-    - OPTS="external-modules" RUN_DOCKER=yes
-    - OPTS="no-snapshot" RUN_DOCKER=yes
-    - OPTS="misc" RUN_DOCKER=yes
-
 matrix:
   include:
-    - os: osx
-      env: OPTS="host-darwin"
-      install: pip2 install --user jsonmerge
-    - compiler: gcc-4.9
-      before_install: tools/apt-get-install-travis-i686.sh
-      addons:
-        apt:
-          sources:
-            - ubuntu-toolchain-r-test
-          packages:
-            - gcc-4.9
-            - gcc-4.9-multilib
-      env: OPTS="asan" ASAN_OPTIONS=detect_stack_use_after_return=1:check_initialization_order=true:strict_init_order=true
-    - compiler: gcc-4.9
-      before_install: tools/apt-get-install-travis-i686.sh
+    - env:
+      - JOBNAME="Linux/x86-64 Build & Correctness Tests"
+      - OPTS="host-linux"
+      - RUN_DOCKER=yes
+    - env:
+      - JOBNAME="Mock Linux Build & Correctness Tests"
+      - OPTS="mock-linux"
+      - RUN_DOCKER=yes
+    - env:
+      - JOBNAME="Raspberry Pi 2 Build Test"
+      - OPTS="rpi2"
+      - RUN_DOCKER=yes
+    - env:
+      - JOBNAME="STM32f4 Discovery with Nuttx Build Test"
+      - OPTS="stm32f4dis"
+      - RUN_DOCKER=yes
+    - env:
+      - JOBNAME="Artik053 with TizenRT Build Test"
+      - OPTS="artik053"
+      - RUN_DOCKER=yes
+    - env:
+      - JOBNAME="Tizen Build Test"
+      - OPTS="tizen"
+      - RUN_DOCKER=yes
+    - env:
+      - JOBNAME="ECMAScript 2015 features Build & Correctness Tests"
+      - OPTS="es2015"
+      - RUN_DOCKER=yes
+    - env:
+      - JOBNAME="External modules Build & Correctness Tests"
+      - OPTS="external-modules"
+      - RUN_DOCKER=yes
+    - env:
+      - JOBNAME="Linux/x86-64 without snapshot Build & Correctness Tests"
+      - OPTS="no-snapshot"
+      - RUN_DOCKER=yes
+    - env:
+      - JOBNAME="Misc checks (e.g. style checker)"
+      - OPTS="misc"
       addons:
         apt:
-          sources:
-            - ubuntu-toolchain-r-test
-          packages:
-            - gcc-4.9
-            - gcc-4.9-multilib
-      env: OPTS="ubsan" UBSAN_OPTIONS=print_stacktrace=1
-    - os: linux
+          packages: [valgrind, clang-format-3.9]
+    - env:
+      - JOBNAME="OSX/x86-64 Build & Correctness Tests"
+      - OPTS="host-darwin"
+      os: osx
+      install: tools/brew-install-deps.sh
+    - env:
+      - JOBNAME="ASAN Tests"
+      - OPTS="asan"
+      - RUN_DOCKER=yes
+    - env:
+      - JOBNAME="UBSAN Tests"
+      - OPTS="ubsan"
+      - RUN_DOCKER=yes
+    - env:
+      - JOBNAME="Coverity Scan"
+      - OPTS="coverity"
+      # Declaration of the encrypted COVERITY_SCAN_TOKEN, created via the
+      # "travis encrypt" command using the project repo's public key.
+      - secure: "lUGzoKK/Yn4/OmpqLQALrIgfY9mQWE51deUawPrCO87UQ2GknfQ4BvwY3UT5QY0XnztPBP1+vRQ2qxbiAU7VWicp280sXDnh0FeuZD14FcE9l0FczraL12reoLu+gY5HWFfbkZncmcBsZkxDEYxhkM14FJU8fxyqGQW2ypJNz+gUGP+8r40Re5J3WjcddCQNe5IG8U+M9B4YeDHhN2QspLdN5pkgn56XtdGa3+qbecO2NpjJG5ltM9j1tTuo/Dg22DxrIFVfeFSFKUj4nfMrgPo5LevRsC/lfaBSCsj751eqrxRcQRh2hkpiIJ7mEBs2LL1EH9O6Mbj+eRh8BvIYqTB85VPNFc43sLWk14apcSVBrxJE5j3kP9sAsOD9Y5JynnkeuxYyISrkywwoX2uxsmCzIfGbwsv5VLToQzrqWlGYrHOAmVXNi8561dLfsWwxxFUjdqkZr1Kgc8UfnBEcBUtSiKCHS86/YUUbBJGkEkjDUS0GiqhFY4bXLQCR7EX4qDX3m6p7Mnh4NVUolpnSmyeYE/MjmqQ+7PJsPLL3EcIYmJ7dtW3mZ3yE2NyaFD0Pym9+TiuCCXRtrNVK1M3Kya64KNv+HbhjT/fTCgXLSeyDmJOKVAqugRlDo3b1KGR1LI0AfegzSA6mEC4e9JLjYiSnHPMUahzgLt8oU0hNFRY="
       before_install:
-        - tools/apt-get-install-deps.sh
         - echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
       addons:
         coverity_scan:
@@ -69,8 +86,8 @@ matrix:
           notification_email: duddlf.choi@samsung.com
           build_command: "tools/travis_script.py"
           branch_pattern: master
-      env: OPTS="coverity"
-    - os: linux
+    - env:
+      - JOBNAME="SonarQube"
       addons:
         sonarcloud:
           organization: "samsung-iotjs"
@@ -80,5 +97,4 @@ matrix:
       cache:
         directories:
           - '$HOME/.sonar/cache'
-      env: OPTS="sonarqube"
   fast_finish: true
index bc9c4cf03667e5c32b80df8e0c339ddbf8b42a02..c8321e06ef92cdf77d1fa56847f800b58cd218f2 100644 (file)
@@ -20,16 +20,10 @@ project(IOTJS C)
 set(IOTJS_VERSION_MAJOR 1)
 set(IOTJS_VERSION_MINOR 0)
 
-# Do a few default checks
-if(NOT DEFINED PLATFORM_DESCRIPTOR)
-  message(FATAL_ERROR "No PLATFORM_DESCRIPTOR specified (format: <arch>-<os>)")
-endif()
-
-string(REPLACE "-" ";" PLATFORM_ARGS ${PLATFORM_DESCRIPTOR})
 if(NOT DEFINED TARGET_OS)
-  list(GET PLATFORM_ARGS 1 TARGET_OS)
+  string(TOLOWER ${CMAKE_SYSTEM_NAME} TARGET_OS)
   message(
-    "TARGET_OS not specified, using '${TARGET_OS}' from PLATFORM_DESCRIPTOR")
+    "TARGET_OS not specified, using '${TARGET_OS}' from CMAKE_SYSTEM_NAME")
 endif()
 
 if(NOT CMAKE_BUILD_TYPE)
@@ -68,12 +62,24 @@ macro(iotjs_add_link_flags)
   iotjs_add_flags(IOTJS_LINKER_FLAGS ${ARGV})
 endmacro()
 
+macro(build_lib_name LIB_VAR NAME)
+  set(${LIB_VAR}
+      ${CMAKE_STATIC_LIBRARY_PREFIX}${NAME}${CMAKE_STATIC_LIBRARY_SUFFIX})
+endmacro()
+
+if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
+  set(USING_MSVC 1)
+  set(CONFIG_TYPE $<$<CONFIG:Debug>:Debug>$<$<CONFIG:Release>:Release>)
+  # disable warning C4820: 'x' bytes padding added after construct 'membername'
+  iotjs_add_compile_flags(-wd4820)
+endif()
+
 CHECK_C_COMPILER_FLAG(-no-pie HAS_NO_PIE)
 
 # Add buildtype-related flags
 if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
   iotjs_add_compile_flags(-DDEBUG -DENABLE_DEBUG_LOG)
-  if(HAS_NO_PIE)
+  if(HAS_NO_PIE AND NOT "${TARGET_OS}" STREQUAL "darwin")
     iotjs_add_link_flags(-no-pie)
   endif()
 endif()
@@ -90,7 +96,10 @@ endif()
 if("${TARGET_ARCH}" STREQUAL "arm")
   iotjs_add_compile_flags(-D__arm__ -mthumb -fno-short-enums -mlittle-endian)
 elseif("${TARGET_ARCH}" STREQUAL "i686")
-  iotjs_add_compile_flags(-D__i686__ -D__x86__ -march=i686 -m32)
+  iotjs_add_compile_flags(-D__i686__ -D__x86__)
+  if(NOT USING_MSVC)
+    iotjs_add_compile_flags(-march=i686 -m32)
+  endif()
 elseif("${TARGET_ARCH}" STREQUAL "x86_64")
   iotjs_add_compile_flags(-D__x86_64__)
 elseif("${TARGET_ARCH}" STREQUAL "mips")
@@ -130,19 +139,24 @@ endif()
 if("${TARGET_OS}" STREQUAL "darwin")
   iotjs_add_compile_flags(-D__DARWIN__ -fno-builtin)
 elseif("${TARGET_OS}" STREQUAL "linux")
-  iotjs_add_compile_flags(-D__LINUX__ -fno-builtin -rdynamic)
-  iotjs_add_link_flags(-pthread)
+  iotjs_add_compile_flags(-D__LINUX__ -fno-builtin)
+  iotjs_add_link_flags(-pthread -rdynamic)
   iotjs_add_flags(EXTERNAL_LIBS m rt)
 elseif("${TARGET_OS}" STREQUAL "nuttx")
   iotjs_add_compile_flags(-D__NUTTX__ -Os -fno-strict-aliasing)
   iotjs_add_compile_flags(-fno-strength-reduce -fomit-frame-pointer)
 elseif("${TARGET_OS}" STREQUAL "tizen")
-  iotjs_add_compile_flags(-D__TIZEN__ -fno-builtin -rdynamic)
-  iotjs_add_link_flags(-pthread)
+  iotjs_add_compile_flags(-D__TIZEN__ -fno-builtin)
+  iotjs_add_link_flags(-pthread -rdynamic)
   iotjs_add_flags(EXTERNAL_LIBS m rt)
 elseif("${TARGET_OS}" STREQUAL "tizenrt")
   iotjs_add_compile_flags(-D__TIZENRT__ -Os -fno-strict-aliasing)
   iotjs_add_compile_flags(-fno-strength-reduce -fomit-frame-pointer)
+elseif("${TARGET_OS}" STREQUAL "windows")
+  message("Windows support is experimental!")
+  if(NOT EXPERIMENTAL)
+    message(FATAL_ERROR "Missing --experimental build option for Windows!")
+  endif()
 elseif("${TARGET_OS}" STREQUAL "openwrt")
   message("OpenWrt support is experimental!")
   if(NOT EXPERIMENTAL)
@@ -171,6 +185,10 @@ set(ARCHIVE_DIR ${CMAKE_BINARY_DIR}/lib)
 
 include(ExternalProject)
 
+if(NOT ${EXTERNAL_LIBC_INTERFACE} STREQUAL "")
+  iotjs_add_compile_flags(-isystem ${EXTERNAL_LIBC_INTERFACE})
+endif()
+
 # Include external projects
 include(cmake/jerry.cmake)
 include(cmake/http-parser.cmake)
index fcde96fcdb577e3191e776cf1efdf03c4a78c8c5..a3d0c6f56f11b67ae08ef6dff308971406b16569 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,7 +1,8 @@
 # IoT.js: Platform for Internet of Things with JavaScript
 [![License](https://img.shields.io/badge/licence-Apache%202.0-brightgreen.svg?style=flat)](LICENSE)
 [![Build Status](https://travis-ci.org/Samsung/iotjs.svg?branch=master)](https://travis-ci.org/Samsung/iotjs)
-[![Coverity Scan Build Status](https://img.shields.io/coverity/scan/12140.svg)](https://scan.coverity.com/projects/samsung-iotjs)
+[![Coverity Scan Build Status](https://scan.coverity.com/projects/12140/badge.svg)](https://scan.coverity.com/projects/samsung-iotjs)
+[![SonarCloud Status](https://sonarcloud.io/api/project_badges/measure?project=samsung.iot.js&metric=alert_status)](https://sonarcloud.io/dashboard?id=samsung.iot.js)
 [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FSamsung%2Fiotjs.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FSamsung%2Fiotjs?ref=badge_shield)
 [![IRC Channel](https://img.shields.io/badge/chat-on%20freenode-brightgreen.svg)](https://kiwiirc.com/client/irc.freenode.net/#iotjs)
 
@@ -11,11 +12,11 @@ Memory usage and Binary footprint are measured at [here](https://samsung.github.
 
 The following table shows the latest results on the devices:
 
-|      Artik053         | [![Remote Testrunner](https://firebasestorage.googleapis.com/v0/b/remote-testrunner.appspot.com/o/status%2Fiotjs%2Fartik053.svg?alt=media&token=1)](https://samsung.github.io/iotjs-test-results/?view=artik053)  |
+|      Artik053         | [![Remote Testrunner](https://firebasestorage.googleapis.com/v0/b/jsremote-testrunner.appspot.com/o/status%2Fiotjs%2Fartik053.svg?alt=media&token=1)](https://samsung.github.io/iotjs-test-results/?view=artik053)  |
 |        :---:          |                                             :---:                                                                                                |
-| **Artik530**    | [![Remote Testrunner](https://firebasestorage.googleapis.com/v0/b/remote-testrunner.appspot.com/o/status%2Fiotjs%2Fartik530.svg?alt=media&token=1)](https://samsung.github.io/iotjs-test-results/?view=artik530)          |
-| **Raspberry Pi 2**    | [![Remote Testrunner](https://firebasestorage.googleapis.com/v0/b/remote-testrunner.appspot.com/o/status%2Fiotjs%2Frpi2.svg?alt=media&token=1)](https://samsung.github.io/iotjs-test-results/?view=rpi2)          |
-| **STM32F4-Discovery** | [![Remote Testrunner](https://firebasestorage.googleapis.com/v0/b/remote-testrunner.appspot.com/o/status%2Fiotjs%2Fstm32f4dis.svg?alt=media&token=1)](https://samsung.github.io/iotjs-test-results/?view=stm32f4dis)   |
+| **Artik530**    | [![Remote Testrunner](https://firebasestorage.googleapis.com/v0/b/jsremote-testrunner.appspot.com/o/status%2Fiotjs%2Fartik530.svg?alt=media&token=1)](https://samsung.github.io/iotjs-test-results/?view=artik530)          |
+| **Raspberry Pi 2**    | [![Remote Testrunner](https://firebasestorage.googleapis.com/v0/b/jsremote-testrunner.appspot.com/o/status%2Fiotjs%2Frpi2.svg?alt=media&token=1)](https://samsung.github.io/iotjs-test-results/?view=rpi2)          |
+| **STM32F4-Discovery** | [![Remote Testrunner](https://firebasestorage.googleapis.com/v0/b/jsremote-testrunner.appspot.com/o/status%2Fiotjs%2Fstm32f4dis.svg?alt=media&token=1)](https://samsung.github.io/iotjs-test-results/?view=stm32f4dis)   |
 
 
 IRC channel: #iotjs on [freenode](https://freenode.net)
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644 (file)
index 0000000..930f787
--- /dev/null
@@ -0,0 +1,30 @@
+version: 1.0.{build}
+pull_requests:
+  do_not_increment_build_number: true
+branches:
+  except:
+  - coverity_scan
+  - gh_pages
+skip_tags: true
+image:
+  - Visual Studio 2017
+configuration:
+  - Debug
+  - Release
+platform:
+  - Win32
+init:
+  - cmd: |
+      cmake -version
+before_build:
+  - cmd: |
+      tools\build.py --experimental --buildtype=debug
+
+artifacts:
+  - path: build\i686-windows\debug\bin\$(configuration)\
+    name: IoTjsbinary
+
+build:
+  project: build\i686-windows\debug\IOTJS.sln
+  parallel: true
+  verbosity: minimal
diff --git a/cmake/config/i686-windows.cmake b/cmake/config/i686-windows.cmake
new file mode 100644 (file)
index 0000000..a7cea9d
--- /dev/null
@@ -0,0 +1,19 @@
+# Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors
+#
+# 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 Windows)
+set(CMAKE_SYSTEM_PROCESSOR i686)
+
+set(CMAKE_C_COMPILER CL.exe)
+set(CMAKE_C_COMPILER_WORKS TRUE)
diff --git a/cmake/config/noarch-linux.cmake b/cmake/config/noarch-linux.cmake
new file mode 100644 (file)
index 0000000..a856848
--- /dev/null
@@ -0,0 +1,15 @@
+# Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set(CMAKE_SYSTEM_NAME Linux)
diff --git a/cmake/config/x86_64-mock.cmake b/cmake/config/x86_64-mock.cmake
new file mode 100644 (file)
index 0000000..0a0a88e
--- /dev/null
@@ -0,0 +1,16 @@
+# Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+#
+# 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 MockLinux)
+set(CMAKE_SYSTEM_PROCESSOR x86_64)
index 3ba07f9573432ff58196638acaf56d79daa35831..83f25798a06526e471a049779dbc28a50b8dcae9 100644 (file)
@@ -18,6 +18,8 @@ if("${TARGET_OS}" MATCHES "NUTTX|TIZENRT")
   set(HTTPPARSER_NUTTX_ARG -DNUTTX_HOME=${TARGET_SYSTEMROOT})
 endif()
 
+build_lib_name(HTTPPARSER_NAME httpparser)
+
 set(DEPS_HTTPPARSER deps/http-parser)
 set(DEPS_HTTPPARSER_SRC ${ROOT_DIR}/${DEPS_HTTPPARSER}/)
 ExternalProject_Add(http-parser
@@ -26,8 +28,8 @@ ExternalProject_Add(http-parser
   BUILD_IN_SOURCE 0
   BINARY_DIR ${DEPS_HTTPPARSER}
   INSTALL_COMMAND
-    ${CMAKE_COMMAND} -E copy
-    ${CMAKE_BINARY_DIR}/${DEPS_HTTPPARSER}/libhttpparser.a
+    ${CMAKE_COMMAND} -E copy_directory
+    ${CMAKE_BINARY_DIR}/${DEPS_HTTPPARSER}/${CONFIG_TYPE}/
     ${CMAKE_BINARY_DIR}/lib/
   CMAKE_ARGS
     -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
@@ -40,8 +42,8 @@ ExternalProject_Add(http-parser
 add_library(libhttp-parser STATIC IMPORTED)
 add_dependencies(libhttp-parser http-parser)
 set_property(TARGET libhttp-parser PROPERTY
-  IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/libhttpparser.a)
+  IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/${HTTPPARSER_NAME})
 set_property(DIRECTORY APPEND PROPERTY
-  ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/lib/libhttpparser.a)
+  ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/lib/${HTTPPARSER_NAME})
 
 set(HTTPPARSER_INCLUDE_DIR ${DEPS_HTTPPARSER_SRC})
index 4a7b5b34beec19f3a1297acaf6867bad52fd5c99..3885f01c3134fd938bf2e5b023b1cf7dd0857ae1 100644 (file)
@@ -345,8 +345,11 @@ foreach(module ${IOTJS_MODULES})
 endforeach()
 
 # Common compile flags
-iotjs_add_compile_flags(-Wall -Wextra -Werror -Wno-unused-parameter)
-iotjs_add_compile_flags(-Wsign-conversion -std=gnu99)
+iotjs_add_compile_flags(-Wall)
+if(NOT USING_MSVC)
+  iotjs_add_compile_flags(-Wextra -Werror -Wno-unused-parameter)
+  iotjs_add_compile_flags(-Wsign-conversion -std=gnu99)
+endif()
 
 if(ENABLE_SNAPSHOT)
   set(JS2C_SNAPSHOT_ARG --snapshot-tool=${JERRY_HOST_SNAPSHOT})
@@ -359,15 +362,21 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
   set(JS2C_RUN_MODE "debug")
 endif()
 
+if(USING_MSVC)
+  set(JS2C_PREPROCESS_ARGS /EP /d1PP)
+else()
+  set(JS2C_PREPROCESS_ARGS -E -dD)
+endif()
+
+string (REPLACE ";" "," IOTJS_JS_MODULES_STR "${IOTJS_JS_MODULES}")
 add_custom_command(
   OUTPUT ${IOTJS_SOURCE_DIR}/iotjs_js.c ${IOTJS_SOURCE_DIR}/iotjs_js.h
-  COMMAND ${CMAKE_C_COMPILER} -E -dD ${IOTJS_MODULE_DEFINES}
+  COMMAND ${CMAKE_C_COMPILER} ${JS2C_PREPROCESS_ARGS} ${IOTJS_MODULE_DEFINES}
             ${IOTJS_SOURCE_DIR}/iotjs_magic_strings.h
-          | grep IOTJS_MAGIC_STRING
           > ${IOTJS_SOURCE_DIR}/iotjs_magic_strings.in
   COMMAND python ${ROOT_DIR}/tools/js2c.py
   ARGS --buildtype=${JS2C_RUN_MODE}
-       --modules '${IOTJS_JS_MODULES}'
+       --modules "${IOTJS_JS_MODULES_STR}"
        ${JS2C_SNAPSHOT_ARG}
   COMMAND ${CMAKE_COMMAND} -E remove
             -f ${IOTJS_SOURCE_DIR}/iotjs_magic_strings.in
@@ -422,6 +431,7 @@ set(IOTJS_INCLUDE_DIRS
   ${MODULES_INCLUDE_DIR}
   ${PLATFORM_OS_DIR}
   ${JERRY_PORT_DIR}/include
+  ${JERRY_EXT_DIR}/include
   ${JERRY_INCLUDE_DIR}
   ${HTTPPARSER_INCLUDE_DIR}
   ${MBEDTLS_INCLUDE_DIR}
@@ -431,6 +441,8 @@ set(IOTJS_INCLUDE_DIRS
 if(NOT BUILD_LIB_ONLY)
   if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
     iotjs_add_link_flags("-Xlinker -map -Xlinker iotjs.map")
+  elseif(USING_MSVC)
+    iotjs_add_link_flags("/MAP:iotjs.map")
   else()
     iotjs_add_link_flags("-Xlinker -Map -Xlinker iotjs.map")
   endif()
@@ -454,13 +466,15 @@ message(STATUS "JERRY_DEBUGGER           ${FEATURE_DEBUGGER}")
 message(STATUS "JERRY_HEAP_SIZE_KB       ${MEM_HEAP_SIZE_KB}")
 message(STATUS "JERRY_MEM_STATS          ${FEATURE_MEM_STATS}")
 message(STATUS "JERRY_PROFILE            ${FEATURE_PROFILE}")
-message(STATUS "PLATFORM_DESCRIPTOR      ${PLATFORM_DESCRIPTOR}")
 message(STATUS "TARGET_ARCH              ${TARGET_ARCH}")
 message(STATUS "TARGET_BOARD             ${TARGET_BOARD}")
 message(STATUS "TARGET_OS                ${TARGET_OS}")
 message(STATUS "TARGET_SYSTEMROOT        ${TARGET_SYSTEMROOT}")
 
 iotjs_add_compile_flags(${IOTJS_MODULE_DEFINES})
+if(FEATURE_DEBUGGER)
+  iotjs_add_compile_flags("-DJERRY_DEBUGGER")
+endif()
 
 # Configure the libiotjs.a
 set(TARGET_STATIC_IOTJS libiotjs)
@@ -488,6 +502,13 @@ endif()
 
 install(TARGETS ${TARGET_STATIC_IOTJS} DESTINATION ${LIB_INSTALL_DIR})
 
+# Install headers
+if("${INCLUDE_INSTALL_DIR}" STREQUAL "")
+  set(INCLUDE_INSTALL_DIR "include/iotjs")
+endif()
+file(GLOB IOTJS_HEADERS include/*.h)
+install(FILES ${IOTJS_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR})
+
 # Configure the libiotjs.so
 if (NOT BUILD_LIB_ONLY AND CREATE_SHARED_LIB)
   set(TARGET_SHARED_IOTJS shared_iotjs)
@@ -506,6 +527,7 @@ if (NOT BUILD_LIB_ONLY AND CREATE_SHARED_LIB)
     ${MBEDTLS_LIBS}
     -Wl,--no-whole-archive
     ${EXTERNAL_LIBS})
+  install(TARGETS ${TARGET_SHARED_IOTJS} DESTINATION ${LIB_INSTALL_DIR})
 endif()
 
 # Configure the iotjs executable
index 598036a1390c0eb94572446c8b0a0093f7d75204..c6dc778222089163a46312fdf4df31851a5ab853 100644 (file)
@@ -21,18 +21,29 @@ ExternalProject_Add(hostjerry
   SOURCE_DIR ${ROOT_DIR}/deps/jerry/
   BUILD_IN_SOURCE 0
   BINARY_DIR ${DEPS_HOST_JERRY}
-  INSTALL_COMMAND ""
   CMAKE_ARGS
     -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
+    -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/${DEPS_HOST_JERRY}
     -DENABLE_ALL_IN_ONE=ON
     -DENABLE_LTO=${ENABLE_LTO}
-    -DJERRY_LIBC=OFF
     -DJERRY_CMDLINE=OFF
     -DJERRY_CMDLINE_SNAPSHOT=ON
-    -DJERRY_EXT=OFF
+    -DJERRY_EXT=ON
+    -DFEATURE_LOGGING=ON
     -DFEATURE_SNAPSHOT_SAVE=${ENABLE_SNAPSHOT}
     -DFEATURE_PROFILE=${FEATURE_PROFILE}
     ${EXTRA_JERRY_CMAKE_PARAMS}
+
+    # The snapshot tool does not require the system allocator
+    # turn it off by default.
+    #
+    # Additionally this is required if one compiles on a
+    # 64bit system to a 32bit system with system allocator
+    # enabled. This is beacuse on 64bit the system allocator
+    # should not be used as it returns 64bit pointers which
+    # can not be represented correctly in the JerryScript engine
+    # currently.
+    -DFEATURE_SYSTEM_ALLOCATOR=OFF
 )
 set(JERRY_HOST_SNAPSHOT
     ${CMAKE_BINARY_DIR}/${DEPS_HOST_JERRY}/bin/jerry-snapshot)
@@ -49,7 +60,7 @@ macro(add_cmake_arg TARGET_ARG KEY)
 endmacro(add_cmake_arg)
 
 # Target libjerry
-set(JERRY_LIBS jerry-core jerry-port-default)
+set(JERRY_LIBS jerry-core jerry-port-default jerry-ext)
 set(DEPS_LIB_JERRY_ARGS)
 
 # Configure the MinSizeRel as the default build type
@@ -61,24 +72,23 @@ else()
 endif()
 
 
-# use system libc/libm on Unix like targets
+# use system libm on Unix like targets
 if("${TARGET_OS}" MATCHES "TIZENRT|NUTTX")
   list(APPEND JERRY_LIBS jerry-libm)
   list(APPEND DEPS_LIB_JERRY_ARGS
-    -DJERRY_LIBC=OFF
     -DJERRY_LIBM=ON
-    -DEXTERNAL_LIBC_INTERFACE=${EXTERNAL_LIBC_INTERFACE}
     -DEXTERNAL_CMAKE_SYSTEM_PROCESSOR=${EXTERNAL_CMAKE_SYSTEM_PROCESSOR}
   )
 elseif("${TARGET_OS}" MATCHES "LINUX|TIZEN|DARWIN|OPENWRT")
   list(APPEND JERRY_LIBS m)
   list(APPEND DEPS_LIB_JERRY_ARGS
-    -DJERRY_LIBC=OFF
+    -DJERRY_LIBM=OFF)
+elseif("${TARGET_OS}" MATCHES "WINDOWS")
+  list(APPEND DEPS_LIB_JERRY_ARGS
     -DJERRY_LIBM=OFF)
 else()
-  list(APPEND JERRY_LIBS jerry-libm jerry-libc)
+  list(APPEND JERRY_LIBS jerry-libm)
   list(APPEND DEPS_LIB_JERRY_ARGS
-    -DEXTERNAL_LIBC_INTERFACE=${EXTERNAL_LIBC_INTERFACE}
     -DEXTERNAL_CMAKE_SYSTEM_PROCESSOR=${EXTERNAL_CMAKE_SYSTEM_PROCESSOR}
   )
 endif()
@@ -89,7 +99,7 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
 endif()
 
 # NuttX is not using the default port implementation of JerryScript
-if("${TARGET_OS}" MATCHES "NUTTX")
+if("${TARGET_OS}" MATCHES "NUTTX|TIZENRT")
   list(APPEND DEPS_LIB_JERRY_ARGS -DJERRY_PORT_DEFAULT=OFF)
 else()
   list(APPEND DEPS_LIB_JERRY_ARGS -DJERRY_PORT_DEFAULT=ON)
@@ -103,6 +113,11 @@ add_cmake_arg(DEPS_LIB_JERRY_ARGS MEM_HEAP_SIZE_KB)
 add_cmake_arg(DEPS_LIB_JERRY_ARGS JERRY_HEAP_SECTION_ATTR)
 
 separate_arguments(EXTRA_JERRY_CMAKE_PARAMS)
+
+build_lib_name(JERRY_CORE_NAME jerry-core)
+build_lib_name(JERRY_LIBM_NAME jerry-libm)
+build_lib_name(JERRY_EXT_NAME jerry-ext)
+
 set(DEPS_LIB_JERRY deps/jerry)
 set(DEPS_LIB_JERRY_SRC ${ROOT_DIR}/${DEPS_LIB_JERRY})
 ExternalProject_Add(libjerry
@@ -112,7 +127,7 @@ ExternalProject_Add(libjerry
   BINARY_DIR ${DEPS_LIB_JERRY}
   INSTALL_COMMAND
     ${CMAKE_COMMAND} -E copy_directory
-    ${CMAKE_BINARY_DIR}/${DEPS_LIB_JERRY}/lib/
+    ${CMAKE_BINARY_DIR}/${DEPS_LIB_JERRY}/lib/${CONFIG_TYPE}
     ${CMAKE_BINARY_DIR}/lib/
   CMAKE_ARGS
     -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
@@ -123,6 +138,7 @@ ExternalProject_Add(libjerry
     -DFEATURE_SNAPSHOT_EXEC=${ENABLE_SNAPSHOT}
     -DFEATURE_SNAPSHOT_SAVE=OFF
     -DFEATURE_PROFILE=${FEATURE_PROFILE}
+    -DFEATURE_LOGGING=ON
     -DFEATURE_LINE_INFO=${FEATURE_JS_BACKTRACE}
     -DFEATURE_VM_EXEC_STOP=ON
     -DENABLE_LTO=${ENABLE_LTO}
@@ -132,42 +148,45 @@ ExternalProject_Add(libjerry
 
 set_property(DIRECTORY APPEND PROPERTY
   ADDITIONAL_MAKE_CLEAN_FILES
-    ${CMAKE_BINARY_DIR}/lib/libjerry-core.a
-    ${CMAKE_BINARY_DIR}/lib/libjerry-libm.a
-    ${CMAKE_BINARY_DIR}/lib/libjerry-libc.a
+    ${CMAKE_BINARY_DIR}/lib/${JERRY_CORE_NAME}
+    ${CMAKE_BINARY_DIR}/lib/${JERRY_LIBM_NAME}
+    ${CMAKE_BINARY_DIR}/lib/${JERRY_EXT_NAME}
 )
 
 # define external jerry-core target
 add_library(jerry-core STATIC IMPORTED)
 add_dependencies(jerry-core libjerry)
 set_property(TARGET jerry-core PROPERTY
-  IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/libjerry-core.a)
-
-# define external jerry-libc target
-add_library(jerry-libc STATIC IMPORTED)
-add_dependencies(jerry-libc libjerry)
-set_property(TARGET jerry-libc PROPERTY
-  IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/libjerry-libc.a)
+  IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/${JERRY_CORE_NAME})
 
 # define external jerry-libm target
 add_library(jerry-libm STATIC IMPORTED)
 add_dependencies(jerry-libm libjerry)
 set_property(TARGET jerry-libm PROPERTY
-  IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/libjerry-libm.a)
+  IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/${JERRY_LIBM_NAME})
+
+# define external jerry-ext target
+add_library(jerry-ext STATIC IMPORTED)
+add_dependencies(jerry-ext libjerry)
+set_property(TARGET jerry-ext PROPERTY
+  IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/${JERRY_EXT_NAME})
 
-if(NOT "${TARGET_OS}" MATCHES "NUTTX")
+if(NOT "${TARGET_OS}" MATCHES "NUTTX|TIZENRT")
+  build_lib_name(JERRY_PORT_NAME jerry-port)
+  build_lib_name(JERRY_PORT_DEFAULT_NAME jerry-port-default)
   set_property(DIRECTORY APPEND PROPERTY
     ADDITIONAL_MAKE_CLEAN_FILES
-      ${CMAKE_BINARY_DIR}/lib/libjerry-port.a
+      ${CMAKE_BINARY_DIR}/lib/${JERRY_PORT_NAME}
   )
 
   # define external jerry-port-default target
   add_library(jerry-port-default STATIC IMPORTED)
   add_dependencies(jerry-port-default libjerry)
   set_property(TARGET jerry-port-default PROPERTY
-    IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/libjerry-port-default.a)
+    IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/${JERRY_PORT_DEFAULT_NAME})
 
   set(JERRY_PORT_DIR ${DEPS_LIB_JERRY_SRC}/jerry-port/default)
 endif()
 
 set(JERRY_INCLUDE_DIR ${DEPS_LIB_JERRY_SRC}/jerry-core/include)
+set(JERRY_EXT_DIR ${DEPS_LIB_JERRY_SRC}/jerry-ext)
index 40eb22a94d5c68fe00cbb15c7dd8ea78ae182e29..1c4ab4c9f3abe6164c6a95898ea983af7bd29a34 100644 (file)
@@ -18,6 +18,12 @@ cmake_minimum_required(VERSION 2.8)
 set(DEPS_TUV deps/libtuv)
 set(DEPS_TUV_SRC ${ROOT_DIR}/${DEPS_TUV})
 
+build_lib_name(LIBTUV_NAME tuv)
+if("${TARGET_OS}" STREQUAL "MOCK")
+  string(TOLOWER ${TARGET_ARCH}-linux PLATFORM_DESCRIPTOR)
+else()
+  string(TOLOWER ${TARGET_ARCH}-${TARGET_OS} PLATFORM_DESCRIPTOR)
+endif()
 set(DEPS_TUV_TOOLCHAIN
   ${DEPS_TUV_SRC}/cmake/config/config_${PLATFORM_DESCRIPTOR}.cmake)
 message(STATUS "libtuv toolchain file: ${DEPS_TUV_TOOLCHAIN}")
@@ -27,8 +33,8 @@ ExternalProject_Add(libtuv
   BUILD_IN_SOURCE 0
   BINARY_DIR ${DEPS_TUV}
   INSTALL_COMMAND
-    ${CMAKE_COMMAND} -E copy
-    ${CMAKE_BINARY_DIR}/${DEPS_TUV}/lib/libtuv.a
+    ${CMAKE_COMMAND} -E copy_directory
+    ${CMAKE_BINARY_DIR}/${DEPS_TUV}/lib/${CONFIG_TYPE}/
     ${CMAKE_BINARY_DIR}/lib/
   CMAKE_ARGS
     -DCMAKE_TOOLCHAIN_FILE=${DEPS_TUV_TOOLCHAIN}
@@ -44,12 +50,21 @@ ExternalProject_Add(libtuv
 add_library(tuv STATIC IMPORTED)
 add_dependencies(tuv libtuv)
 set_property(TARGET tuv PROPERTY
-  IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/libtuv.a)
+  IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/${LIBTUV_NAME})
 set_property(DIRECTORY APPEND PROPERTY
-  ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/lib/libtuv.a)
+  ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/lib/${LIBTUV_NAME})
 set(TUV_INCLUDE_DIR ${DEPS_TUV_SRC}/include)
 set(TUV_LIBS tuv)
 
-if("${TARGET_OS}" STREQUAL "LINUX")
+if("${TARGET_OS}" STREQUAL "MOCK" OR
+   "${TARGET_OS}" STREQUAL "LINUX")
   list(APPEND TUV_LIBS pthread)
+elseif("${TARGET_OS}" STREQUAL "WINDOWS")
+  list(APPEND TUV_LIBS
+        ws2_32.lib
+        UserEnv.lib
+        advapi32.lib
+        iphlpapi.lib
+        psapi.lib
+        shell32.lib)
 endif()
index 212f6e0641a88c14f26798b7600316fb4e63f5a0..0a8e841e8901d6b6c202b202a9a0cc019c9f2618 100644 (file)
 
 cmake_minimum_required(VERSION 2.8)
 
-set(DEPS_MBEDTLS deps/mbedtls)
-set(DEPS_MBEDTLS_SRC ${ROOT_DIR}/${DEPS_MBEDTLS})
-set(DEPS_MBEDTLS_BUILD_DIR ${CMAKE_BINARY_DIR}/${DEPS_MBEDTLS}/library)
 set(MODULE_NAME "tls")
-set(MODULE_BINARY_DIR ${DEPS_MBEDTLS_BUILD_DIR})
 
-if("${TARGET_OS}" STREQUAL "TIZEN")
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-cpp")
-endif()
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-conversion")
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${ROOT_DIR}/config/mbedtls")
-set(CMAKE_C_FLAGS
-    "${CMAKE_C_FLAGS} -DMBEDTLS_CONFIG_FILE='<config-for-iotjs.h>'")
+if ("${TARGET_OS}" STREQUAL "TIZENRT")
+  set(MBEDTLS_LIBS "")
+  set(MBEDTLS_INCLUDE_DIR ${TARGET_SYSTEMROOT}/../external/include)
+else()
+  set(DEPS_MBEDTLS deps/mbedtls)
+  set(DEPS_MBEDTLS_SRC ${ROOT_DIR}/${DEPS_MBEDTLS})
+  set(DEPS_MBEDTLS_BUILD_DIR
+      ${CMAKE_BINARY_DIR}/${DEPS_MBEDTLS}/library/${CONFIG_TYPE})
+  set(MODULE_BINARY_DIR ${DEPS_MBEDTLS_BUILD_DIR})
+
+  if("${TARGET_OS}" STREQUAL "TIZEN")
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-cpp")
+  endif()
+
+  if(USING_MSVC)
+    set(CONFIG_DELIMITER "")
+  else()
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-sign-conversion")
+    set(CONFIG_DELIMITER "'")
+  endif()
 
-# FIXME:
-#       Remove this workaround when the related bug is fixed in
-#       mbedtls. https://github.com/ARMmbed/mbedtls/issues/1550
-set(CMAKE_C_FLAGS_BCK "${CMAKE_C_FLAGS}")
-string(REPLACE "-fsanitize=address" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
+  set(MBED_CONFIG "${CONFIG_DELIMITER}<config-for-iotjs.h>${CONFIG_DELIMITER}")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${ROOT_DIR}/config/mbedtls")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMBEDTLS_CONFIG_FILE=${MBED_CONFIG}")
 
-ExternalProject_Add(mbedtls
-  PREFIX ${DEPS_MBEDTLS}
-  SOURCE_DIR ${DEPS_MBEDTLS_SRC}
-  BUILD_IN_SOURCE 0
-  BINARY_DIR ${DEPS_MBEDTLS}
-  INSTALL_COMMAND
-    COMMAND ${CMAKE_COMMAND} -E copy
-      ${DEPS_MBEDTLS_BUILD_DIR}/libmbedx509.a ${ARCHIVE_DIR}
-    COMMAND ${CMAKE_COMMAND} -E copy
-      ${DEPS_MBEDTLS_BUILD_DIR}/libmbedtls.a ${ARCHIVE_DIR}
-    COMMAND ${CMAKE_COMMAND} -E copy
-      ${DEPS_MBEDTLS_BUILD_DIR}/libmbedcrypto.a ${ARCHIVE_DIR}
-  CMAKE_ARGS
-    -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
-    -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-    -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
-    -DENABLE_PROGRAMS=OFF
-    -DENABLE_TESTING=OFF
-)
+  # FIXME:
+  #       Remove this workaround when the related bug is fixed in
+  #       mbedtls. https://github.com/ARMmbed/mbedtls/issues/1550
+  set(CMAKE_C_FLAGS_BCK "${CMAKE_C_FLAGS}")
+  string(REPLACE "-fsanitize=address" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
 
-# define external mbedtls target
-add_library(libmbedtls STATIC IMPORTED)
-add_dependencies(libmbedtls mbedtls)
-set_property(TARGET libmbedtls PROPERTY
-  IMPORTED_LOCATION ${ARCHIVE_DIR}/libmbedtls.a)
+  build_lib_name(MBED_X509_NAME mbedx509)
+  build_lib_name(MBED_TLS_NAME mbedtls)
+  build_lib_name(MBED_CRYPTO_NAME mbedcrypto)
+  ExternalProject_Add(mbedtls
+    PREFIX ${DEPS_MBEDTLS}
+    SOURCE_DIR ${DEPS_MBEDTLS_SRC}
+    BUILD_IN_SOURCE 0
+    BINARY_DIR ${DEPS_MBEDTLS}
+    INSTALL_COMMAND
+      COMMAND ${CMAKE_COMMAND} -E copy
+        ${DEPS_MBEDTLS_BUILD_DIR}/${MBED_X509_NAME} ${ARCHIVE_DIR}
+      COMMAND ${CMAKE_COMMAND} -E copy
+        ${DEPS_MBEDTLS_BUILD_DIR}/${MBED_TLS_NAME} ${ARCHIVE_DIR}
+      COMMAND ${CMAKE_COMMAND} -E copy
+        ${DEPS_MBEDTLS_BUILD_DIR}/${MBED_CRYPTO_NAME} ${ARCHIVE_DIR}
+    CMAKE_ARGS
+      -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
+      -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
+      -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
+      -DENABLE_PROGRAMS=OFF
+      -DENABLE_TESTING=OFF
+  )
 
-# define external mbedx509 target
-add_library(libmbedx509 STATIC IMPORTED)
-add_dependencies(libmbedx509 mbedx509)
-set_property(TARGET libmbedx509 PROPERTY
-  IMPORTED_LOCATION ${ARCHIVE_DIR}/libmbedx509.a)
+  # define external mbedtls target
+  add_library(libmbedtls STATIC IMPORTED)
+  add_dependencies(libmbedtls mbedtls)
+  set_property(TARGET libmbedtls PROPERTY
+    IMPORTED_LOCATION ${ARCHIVE_DIR}/${MBED_TLS_NAME})
 
-# define external libmbedcrypto target
-add_library(libmbedcrypto STATIC IMPORTED)
-add_dependencies(libmbedcrypto mbedcrypto)
-set_property(TARGET libmbedcrypto PROPERTY
-  IMPORTED_LOCATION ${ARCHIVE_DIR}/libmbedcrypto.a)
+  # define external mbedx509 target
+  add_library(libmbedx509 STATIC IMPORTED)
+  add_dependencies(libmbedx509 mbedx509)
+  set_property(TARGET libmbedx509 PROPERTY
+    IMPORTED_LOCATION ${ARCHIVE_DIR}/${MBED_X509_NAME})
 
-set_property(DIRECTORY APPEND PROPERTY
-  ADDITIONAL_MAKE_CLEAN_FILES
-  ${ARCHIVE_DIR}/libmbedx509.a
-  ${ARCHIVE_DIR}/libmbedtls.a
-  ${ARCHIVE_DIR}/libmbedcrypto.a
-)
+  # define external libmbedcrypto target
+  add_library(libmbedcrypto STATIC IMPORTED)
+  add_dependencies(libmbedcrypto mbedcrypto)
+  set_property(TARGET libmbedcrypto PROPERTY
+    IMPORTED_LOCATION ${ARCHIVE_DIR}/${MBED_CRYPTO_NAME})
 
-set(MBEDTLS_LIBS libmbedtls libmbedx509 libmbedcrypto)
-set(MBEDTLS_INCLUDE_DIR ${DEPS_MBEDTLS}/include)
+  set_property(DIRECTORY APPEND PROPERTY
+    ADDITIONAL_MAKE_CLEAN_FILES
+    ${ARCHIVE_DIR}/${MBED_X509_NAME}
+    ${ARCHIVE_DIR}/${MBED_TLS_NAME}
+    ${ARCHIVE_DIR}/${MBED_CRYPTO_NAME}
+  )
 
-# FIXME:
-#       Remove this workaround when the related bug is fixed in
-#       mbedtls. https://github.com/ARMmbed/mbedtls/issues/1550
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_BCK}")
+  set(MBEDTLS_LIBS libmbedtls libmbedx509 libmbedcrypto)
+  set(MBEDTLS_INCLUDE_DIR ${DEPS_MBEDTLS}/include)
+
+  # FIXME:
+  #       Remove this workaround when the related bug is fixed in
+  #       mbedtls. https://github.com/ARMmbed/mbedtls/issues/1550
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_BCK}")
+endif()
index cda803a3205e415e0760f3c1b36baa081996a917..575c96f85cd22f72695052f5717c39c447b303e6 100644 (file)
@@ -68,7 +68,7 @@ HEAPSIZE = $(CONFIG_IOTJS_HEAPSIZE)
 ASRCS = setjmp.S
 CSRCS = jerry_port.c
 MAINSRC = iotjs_main.c
-LIBS = libhttpparser.a libiotjs.a libjerry-core.a libtuv.a libjerry-libm.a
+LIBS = libhttpparser.a libiotjs.a libjerry-core.a libtuv.a libjerry-libm.a libjerry-ext.a
 
 AOBJS = $(ASRCS:.S=$(OBJEXT))
 COBJS = $(CSRCS:.c=$(OBJEXT))
@@ -88,12 +88,12 @@ ifneq ($(CONFIG_BUILD_KERNEL),y)
 endif
 
 ifeq ($(CONFIG_WINDOWS_NATIVE),y)
-  BIN = ..\..\libapps$(LIBEXT)
+  BIN = $(APPDIR)\libapps$(LIBEXT)
 else
 ifeq ($(WINTOOL),y)
-  BIN = ..\\..\\libapps$(LIBEXT)
+  BIN = $(APPDIR)\\libapps$(LIBEXT)
 else
-  BIN = ../../libapps$(LIBEXT)
+  BIN = $(APPDIR)/libapps$(LIBEXT)
 endif
 endif
 
index 886f749bbd6e43e3883d16881f27275c029dc5f2..ec5e23acc0e1c087ce138a44c8026890aa01d04f 100644 (file)
@@ -38,17 +38,14 @@ void jerry_port_log(jerry_log_level_t level, /**< log level */
 } /* jerry_port_log */
 
 /**
- * Dummy function to get the time zone.
- *
- * @return true
+ * Dummy function to get local time zone adjustment, in milliseconds,
+ * for the given timestamp.
  */
-bool jerry_port_get_time_zone(jerry_time_zone_t *tz_p) {
-  /* We live in UTC. */
-  tz_p->offset = 0;
-  tz_p->daylight_saving_time = 0;
-
-  return true;
-} /* jerry_port_get_time_zone */
+double jerry_port_get_local_time_zone_adjustment(double unix_ms, bool is_utc) {
+  (void)unix_ms;
+  (void)is_utc;
+  return 0.0;
+} /* jerry_port_get_local_time_zone_adjustment */
 
 /**
  * Dummy function to get the current time.
diff --git a/config/nuttx/stm32f4dis/iotjs-memstat.diff b/config/nuttx/stm32f4dis/iotjs-memstat.diff
deleted file mode 100644 (file)
index cfd9c37..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-diff --git a/src/iotjs_util.c b/src/iotjs_util.c
-index 62ca214..dd6a978 100644
---- a/src/iotjs_util.c
-+++ b/src/iotjs_util.c
-@@ -58,8 +58,18 @@ iotjs_string_t iotjs_file_read(const char* path) {
- }
-
-
-+#define SIZEOF_MM_ALLOCNODE 8
-+extern void jmem_heap_stat_alloc(size_t size);
-+extern void jmem_heap_stat_free(size_t size);
-+
-+
- char* iotjs_buffer_allocate(size_t size) {
-   char* buffer = (char*)(calloc(size, sizeof(char)));
-+
-+  size_t new_size;
-+  memcpy(&new_size, (buffer - SIZEOF_MM_ALLOCNODE), sizeof(size_t));
-+  jmem_heap_stat_alloc(new_size - SIZEOF_MM_ALLOCNODE);
-+
-   IOTJS_ASSERT(buffer != NULL);
-   return buffer;
- }
-@@ -67,11 +77,26 @@ char* iotjs_buffer_allocate(size_t size) {
-
- char* iotjs_buffer_reallocate(char* buffer, size_t size) {
-   IOTJS_ASSERT(buffer != NULL);
--  return (char*)(realloc(buffer, size));
-+
-+  size_t old_size;
-+  memcpy(&old_size, (buffer - SIZEOF_MM_ALLOCNODE), sizeof(size_t));
-+  jmem_heap_stat_free(old_size - SIZEOF_MM_ALLOCNODE);
-+
-+  char* ptr = (char*)(realloc(buffer, size));
-+
-+  size_t new_size;
-+  memcpy(&new_size, (ptr - SIZEOF_MM_ALLOCNODE), sizeof(size_t));
-+  jmem_heap_stat_alloc(new_size - SIZEOF_MM_ALLOCNODE);
-+
-+  return ptr;
- }
-
-
- void iotjs_buffer_release(char* buffer) {
-+  size_t size;
-+  memcpy(&size, (buffer - SIZEOF_MM_ALLOCNODE), sizeof(size_t));
-+  jmem_heap_stat_free(size - SIZEOF_MM_ALLOCNODE);
-+
-   IOTJS_ASSERT(buffer != NULL);
-   free(buffer);
- }
diff --git a/config/nuttx/stm32f4dis/jerry-memstat.diff b/config/nuttx/stm32f4dis/jerry-memstat.diff
deleted file mode 100644 (file)
index e7d791a..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-diff --git a/jerry-core/api/jerry.c b/jerry-core/api/jerry.c
-index 1032881..88db6a3 100644
---- a/jerry-core/api/jerry.c
-+++ b/jerry-core/api/jerry.c
-@@ -149,7 +149,7 @@ jerry_init (jerry_init_flag_t flags) /**< combination of Jerry flags */
-   }
-
-   /* Zero out all members. */
--  memset (&JERRY_CONTEXT (JERRY_CONTEXT_FIRST_MEMBER), 0, sizeof (jerry_context_t));
-+  // memset (&JERRY_CONTEXT (JERRY_CONTEXT_FIRST_MEMBER), 0, sizeof (jerry_context_t));
-
-   JERRY_CONTEXT (jerry_init_flags) = flags;
-
-diff --git a/jerry-core/jmem/jmem-heap.c b/jerry-core/jmem/jmem-heap.c
-index f15ba90..8154880 100644
---- a/jerry-core/jmem/jmem-heap.c
-+++ b/jerry-core/jmem/jmem-heap.c
-@@ -113,8 +113,8 @@ JERRY_STATIC_ASSERT (sizeof (jmem_heap_t) <= JMEM_HEAP_SIZE,
-
- #ifdef JMEM_STATS
- static void jmem_heap_stat_init (void);
--static void jmem_heap_stat_alloc (size_t num);
--static void jmem_heap_stat_free (size_t num);
-+void jmem_heap_stat_alloc (size_t num);
-+void jmem_heap_stat_free (size_t num);
-
- #ifndef JERRY_SYSTEM_ALLOCATOR
- static void jmem_heap_stat_skip (void);
-@@ -580,7 +580,7 @@ jmem_heap_stats_print (void)
- {
-   jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
-
--  JERRY_DEBUG_MSG ("Heap stats:\n"
-+  printf ("Heap stats:\n"
-                    "  Heap size = %zu bytes\n"
-                    "  Allocated = %zu bytes\n"
-                    "  Peak allocated = %zu bytes\n"
-@@ -632,7 +632,7 @@ jmem_heap_stat_init (void)
- /**
-  * Account allocation
-  */
--static void
-+void
- jmem_heap_stat_alloc (size_t size) /**< Size of allocated block */
- {
-   const size_t aligned_size = (size + JMEM_ALIGNMENT - 1) / JMEM_ALIGNMENT * JMEM_ALIGNMENT;
-@@ -658,7 +658,7 @@ jmem_heap_stat_alloc (size_t size) /**< Size of allocated block */
- /**
-  * Account freeing
-  */
--static void
-+void
- jmem_heap_stat_free (size_t size) /**< Size of freed block */
- {
-   const size_t aligned_size = (size + JMEM_ALIGNMENT - 1) / JMEM_ALIGNMENT * JMEM_ALIGNMENT;
diff --git a/config/nuttx/stm32f4dis/libtuv-memstat.diff b/config/nuttx/stm32f4dis/libtuv-memstat.diff
deleted file mode 100644 (file)
index 1988712..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-diff --git a/src/unix/fs.c b/src/unix/fs.c
-index 4281246..cc0d694 100644
---- a/src/unix/fs.c
-+++ b/src/unix/fs.c
-@@ -98,7 +98,7 @@
-     if (cb == NULL) {                                                         \
-       req->path = path;                                                       \
-     } else {                                                                  \
--      req->path = strdup(path);                                               \
-+      req->path = uv__strdup(path);                                           \
-       if (req->path == NULL) {                                                \
-         uv__req_unregister(loop, req);                                        \
-         return -ENOMEM;                                                       \
-diff --git a/src/uv-common.c b/src/uv-common.c
-index 813e499..04a7f18 100644
---- a/src/uv-common.c
-+++ b/src/uv-common.c
-@@ -67,7 +67,6 @@ static uv__allocator_t uv__allocator = {
-   free,
- };
-
--#if defined(__APPLE__)
- char* uv__strdup(const char* s) {
-   size_t len = strlen(s) + 1;
-   char* m = uv__malloc(len);
-@@ -75,13 +74,29 @@ char* uv__strdup(const char* s) {
-     return NULL;
-   return memcpy(m, s, len);
- }
--#endif
-+
-+#define SIZEOF_MM_ALLOCNODE 8
-+extern void jmem_heap_stat_alloc (size_t size);
-+extern void jmem_heap_stat_free (size_t size);
-
- void* uv__malloc(size_t size) {
--  return uv__allocator.local_malloc(size);
-+  char* ptr = (char*)uv__allocator.local_malloc(size);
-+
-+  size_t new_size;
-+  memcpy(&new_size, (ptr - SIZEOF_MM_ALLOCNODE), sizeof(size_t));
-+  jmem_heap_stat_alloc(new_size - SIZEOF_MM_ALLOCNODE);
-+
-+  return (void*)ptr;
- }
-
- void uv__free(void* ptr) {
-+  if (ptr == NULL)
-+    return;
-+
-+  size_t size;
-+  memcpy(&size, (char*)ptr - SIZEOF_MM_ALLOCNODE, sizeof(size_t));
-+  jmem_heap_stat_free(size);
-+
-   int saved_errno;
-
-   /* Libuv expects that free() does not clobber errno.  The system allocator
-@@ -93,11 +108,31 @@ void uv__free(void* ptr) {
- }
-
- void* uv__calloc(size_t count, size_t size) {
--  return uv__allocator.local_calloc(count, size);
-+  char* ptr = (char*)uv__allocator.local_calloc(count, size);
-+
-+  size_t new_size;
-+  memcpy(&new_size, (ptr - SIZEOF_MM_ALLOCNODE), sizeof(size_t));
-+  jmem_heap_stat_alloc(new_size - SIZEOF_MM_ALLOCNODE);
-+
-+  return (void*)ptr;
- }
-
- void* uv__realloc(void* ptr, size_t size) {
--  return uv__allocator.local_realloc(ptr, size);
-+  if (ptr != NULL) {
-+    size_t old_size;
-+    memcpy(&old_size, (char*)ptr - SIZEOF_MM_ALLOCNODE, sizeof(size_t));
-+    jmem_heap_stat_free(old_size - SIZEOF_MM_ALLOCNODE);
-+
-+    char* new_ptr = (char*)uv__allocator.local_realloc(ptr, size);
-+
-+    size_t new_size;
-+    memcpy(&new_size, (new_ptr - SIZEOF_MM_ALLOCNODE), sizeof(size_t));
-+    jmem_heap_stat_alloc(new_size - SIZEOF_MM_ALLOCNODE);
-+
-+    return (void*)new_ptr;
-+  }
-+
-+  return uv__malloc(size);
- }
-
- uv_buf_t uv_buf_init(char* base, unsigned int len) {
-diff --git a/src/uv-common.h b/src/uv-common.h
-index 069b5af..a24de69 100644
---- a/src/uv-common.h
-+++ b/src/uv-common.h
-@@ -239,9 +239,7 @@ void uv__fs_scandir_cleanup(uv_fs_t* req);
-
- /* Allocator prototypes */
- void *uv__calloc(size_t count, size_t size);
--#if defined(__APPLE__)
- char *uv__strdup(const char* s);
--#endif
- void* uv__malloc(size_t size);
- void uv__free(void* ptr);
- void* uv__realloc(void* ptr, size_t size);
diff --git a/config/nuttx/stm32f4dis/nuttx-7.19.diff b/config/nuttx/stm32f4dis/nuttx-7.19.diff
deleted file mode 100644 (file)
index ec5a290..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-diff --git a/net/socket/getsockname.c b/net/socket/getsockname.c
-index 7bf87c2..79fb7d7 100644
---- a/net/socket/getsockname.c
-+++ b/net/socket/getsockname.c
-@@ -151,10 +151,29 @@ int ipv4_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
-    * a single network device and only the network device knows the IP address.
-    */
-
-+  if (lipaddr == 0)
-+    {
-+#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_UDP)
-+       outaddr->sin_family = AF_INET;
-+       outaddr->sin_addr.s_addr = 0;
-+       *addrlen = sizeof(struct sockaddr_in);
-+#endif
-+
-+      return OK;
-+    }
-+
-   net_lock();
-
- #ifdef CONFIG_NETDEV_MULTINIC
--  /* Find the device matching the IPv4 address in the connection structure */
-+  /* Find the device matching the IPv4 address in the connection structure.
-+   * NOTE: listening sockets have no ripaddr.  Work around is to use the
-+   * lipaddr when ripaddr is not available.
-+   */
-+
-+  if (ripaddr == 0)
-+    {
-+      ripaddr = lipaddr;
-+    }
-
-   dev = netdev_findby_ipv4addr(lipaddr, ripaddr);
- #else
-@@ -274,10 +293,29 @@ int ipv6_getsockname(FAR struct socket *psock, FAR struct sockaddr *addr,
-    * a single network device and only the network device knows the IP address.
-    */
-
-+  if (net_ipv6addr_cmp(lipaddr, g_ipv6_allzeroaddr))
-+    {
-+#if defined(NET_TCP_HAVE_STACK) || defined(NET_UDP_HAVE_STACK)
-+      outaddr->sin6_family = AF_INET6;
-+      memcpy(outaddr->sin6_addr.in6_u.u6_addr8, g_ipv6_allzeroaddr, 16);
-+      *addrlen = sizeof(struct sockaddr_in6);
-+#endif
-+
-+      return OK;
-+    }
-+
-   net_lock();
-
- #ifdef CONFIG_NETDEV_MULTINIC
--  /* Find the device matching the IPv6 address in the connection structure */
-+  /* Find the device matching the IPv6 address in the connection structure.
-+   * NOTE: listening sockets have no ripaddr.  Work around is to use the
-+   * lipaddr when ripaddr is not available.
-+   */
-+
-+  if (net_ipv6addr_cmp(ripaddr, g_ipv6_allzeroaddr))
-+    {
-+      ripaddr = lipaddr;
-+    }
-
-   dev = netdev_findby_ipv6addr(*lipaddr, *ripaddr);
- #else
-diff --git a/net/socket/listen.c b/net/socket/listen.c
-index 0d91ccb..4409a0e 100644
---- a/net/socket/listen.c
-+++ b/net/socket/listen.c
-@@ -142,7 +142,12 @@ int psock_listen(FAR struct socket *psock, int backlog)
-        * accept() is called and enables poll()/select() logic.
-        */
-
--      tcp_listen(conn);
-+      errcode = tcp_listen(conn);
-+      if (errcode < 0)
-+        {
-+          errcode = -errcode;
-+          goto errout;
-+        }
-     }
- #endif /* CONFIG_NET_TCP */
-
diff --git a/config/tizen/filter.txt b/config/tizen/filter.txt
new file mode 100644 (file)
index 0000000..c9fdf90
--- /dev/null
@@ -0,0 +1,2 @@
+P /.git
+- .git
index 965f110e668b1d4c279187ca1bd41ad3ed7c133e..2232793afce8cfb838e407af1b86403676c6c2e1 100755 (executable)
@@ -81,7 +81,7 @@ then
   echo "========================================================"
   echo "1. GBS Build is successful."
   echo "2. You can find rpm packages in below folder"
-  echo "   GBS-ROOT/local/repos/tizen_unified_rreview2/armv7l/RPMS"
+  echo "   ~/GBS-ROOT/local/repos/tizen50m2/armv7l/RPMS"
 else
   echo "GBS Build failed!"
   ret=1
index 0be3a5580780ca75da8f10f407b6960a1ec9a844..1a535e2b73d87d59e7106196dcb6a521eac35e22 100644 (file)
@@ -10,7 +10,6 @@ Source1:    %{name}.pc.in
 Source1001: %{name}.manifest
 ExclusiveArch: %arm %ix86 x86_64
 
-
 BuildRequires: python
 BuildRequires: cmake
 BuildRequires: glibc-static
@@ -40,6 +39,7 @@ Platform for Internet of Things with JavaScript
 # Initialize the variables
 %{!?build_mode: %define build_mode release}
 %{!?external_build_options: %define external_build_options %{nil}}
+
 %package service
 Summary: Development files for %{name}
 Group: Network & Connectivity/Service
@@ -63,12 +63,13 @@ chmod g-w %_sourcedir/*
 cat LICENSE
 cp %{SOURCE1001} .
 
-
 %build
 V=1 VERBOSE=1 ./tools/build.py \
   --clean \
   --buildtype=%{build_mode} \
   --profile=test/profiles/tizen.profile \
+  --jerry-profile $PWD/test/profiles/tizen-jerry.profile \
+  --js-backtrace ON \
   --target-arch=noarch \
   --target-os=tizen \
 %ifarch %{arm}
@@ -82,13 +83,13 @@ V=1 VERBOSE=1 ./tools/build.py \
   --external-lib=appcore-agent \
   --external-lib=pthread \
   --external-lib=curl \
+  --external-lib=glib-2.0 \
   --external-include-dir=/usr/include/dlog/ \
   --external-include-dir=/usr/include/appcore-agent/ \
   --external-include-dir=/usr/include/appfw/ \
   --compile-flag="%(pkg-config --cflags glib-2.0)" \
   --compile-flag=-D__TIZEN__ \
   --compile-flag=-DENABLE_DEBUG_LOG \
-  --jerry-cmake-param=-DENABLE_STATIC_LINK=OFF \
   --create-shared-lib \
   --no-init-submodule \
   --no-parallel-build \
diff --git a/config/tizen/release.sh b/config/tizen/release.sh
new file mode 100755 (executable)
index 0000000..13b770f
--- /dev/null
@@ -0,0 +1,70 @@
+#!/bin/bash
+ROOT=`pwd`
+
+# Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+#
+# 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.
+
+echo "******************************************************************"
+echo "*                       Tizen release script                     *"
+echo "******************************************************************"
+
+repo=$1
+
+if [ "$repo" == "../iotjs_tizen" -o "$repo" == "../iotjs_tizen/" ]; then
+    echo "Syncing with: tizen iotjs"
+else
+    echo "Usage: $0 [ ../iotjs_tizen ]"
+    exit 0
+fi
+
+if [ ! -d ../iotjs_tizen ]; then
+    # echo "cloning..."
+    echo "Error: $repo not exist"
+    exit 0
+fi
+
+cd ..
+echo copy from $OLDPWD to ../iotjs_tizen_org
+cp -ra $OLDPWD iotjs_tizen_org
+cd iotjs_tizen_org
+
+echo -e "\n(1) Now, cloning submodules. "
+git submodule init
+
+echo -e "\n(2) Update submodules... "
+git submodule update
+
+echo -e "\n(3) Modify version... "
+hash=`git log | head -1 | cut -f2 -d' ' | cut -c 1-7`
+today=`date +%y%m%d`
+sed -i "s/\(IOTJS_VERSION \".*\"\)/\1 \"$today\_$hash\"/g" src/iotjs_def.h
+
+echo -e "\n(4) Patch for tizen.org... "
+patch -p1 < config/tizen/iotjs_tizen.patch
+cp -ra config/tizen/packaging .
+
+merge_filter="merge config/tizen/filter.txt"
+rsync -av --delete --delete-excluded --filter="$merge_filter" . $repo
+
+cd $repo
+
+git add -A
+echo "======================================="
+echo git commit -m "IOTJS_Release_$today""_$hash"
+echo "======================================="
+msg="IOTJS_Release_$today""_$hash"
+git commit -m "$msg"
+cd $ROOT
+
+rm -rf ../iotjs_tizen_org
index 961c3812dc14c7a671c9ec84fd340ba18ab59eba..dd198bfe2a75154455c088a59295f574cc4b2b5d 100644 (file)
@@ -1,78 +1,70 @@
 [general]
-profile = profile.tizen_unified_preview2
-#profile = profile.tizen_4.0_unified
-#profile = profile.tizen_unified
+#profile = profile.tizen40m3
+#profile = profile.tizen50
+#profile = profile.tizen50m1
+profile = profile.tizen50m2
+
 upstream_branch = ${upstreamversion}
 upstream_tag = ${upstreamversion}
 packaging_dir = config/tizen/packaging
 
-[profile.tizen_unified_preview2]
-obs = obs.spin
-repos = repo.tizen_local, repo.tizen_4.0_base_arm_20171222.1, repo.tizen_4.0_unified_20180118.1
 
-[profile.tizen_4.0_unified]
+[profile.tizen50m2]
 obs = obs.spin
-repos = repo.public_4.0_base_arm, repo.tizen_4.0_unified
+repos = repo.tizen50m2_base, repo.tizen50m2_standard
 
-[profile.tizen_unified]
-obs = obs.spin
-repos = repo.tizen_base_arm, repo.tizen_unified
+[repo.tizen50m2_base]
+url = http://download.tizen.org/releases/milestone/tizen/base/tizen-base_20180928.1/repos/standard/packages/
 
-[profile.tizen_artik10]
-obs = obs.spin
-repos = repo.public_3.0_base_arm, repo.public_3_arm
+[repo.tizen50m2_standard]
+url = http://download.tizen.org/releases/milestone/tizen/unified/tizen-unified_20181024.1/repos/standard/packages/
 
-[obs.spin]
-url = http://168.219.209.58:81
 
-[obs.tizen]
-url = https://api.tizen.org
-user = obs_viewer
-passwdx = QlpoOTFBWSZTWRP5nYMAAB6fgCAAeUA9mr+QBvzF4CAAVGAZDTRoDI0YBlCKeptQBoA0aGZIAottAkltEPOK7BAFXE9mTUzocPMzQRkPoPpNwEZx3rRQhxkXmGHS6wCjHskyVCP4u5IpwoSAn8zsGA==
 
+[profile.tizen50m1]
+obs = obs.spin
+repos = repo.tizen50m1_base, repo.tizen50m1_standard
 
-[repo.public_3_arm] 
-url = http://download.tizen.org/releases/milestone/tizen/3.0.m2/common_artik/tizen-common-artik_20170111.3/repos/arm-wayland/packages/
-user =
-passwdx = 
+[repo.tizen50m1_base]
+url = http://download.tizen.org/releases/milestone/tizen/base/tizen-base_20180518.1/repos/standard/packages/
 
-[repo.public_3.0_base_arm]
-url = http://download.tizen.org/snapshots/tizen/base/latest/repos/arm/packages/armv7l/
-user = 
-passwdx = 
+[repo.tizen50m1_standard]
+url = http://download.tizen.org/releases/milestone/tizen/unified/tizen-unified_20180528.1/repos/standard/packages/
 
 
-[repo.tizen_unified]
-url = http://download.tizen.org/snapshots/tizen/unified/latest/repos/standard/packages/
-user =
-passwdx =
+# for platform developer
+[profile.tizen50]
+obs = obs.spin
+repos = repo.tizen_local, repo.tizen50_base, repo.tizen50_standard
 
-[repo.tizen_base_arm]
+[repo.tizen50_base]
 url = http://download.tizen.org/snapshots/tizen/base/latest/repos/standard/packages/
-user =
-passwdx =
+
+[repo.tizen50_standard]
+url = http://download.tizen.org/snapshots/tizen/unified/latest/repos/standard/packages/
 
 
-[repo.tizen_4.0_unified]
-url = http://download.tizen.org/snapshots/tizen/4.0-unified/latest/repos/standard/packages/
-user =
-passwdx =
 
-[repo.public_4.0_base_arm]
-url = http://download.tizen.org/snapshots/tizen/4.0-base/latest/repos/arm/packages/
-user = 
-passwdx =
+[profile.tizen40m3]
+obs = obs.spin
+repos = repo.tizen40m3_base, repo.tizen40m3_standard
+
+[repo.tizen40m3_base]
+url = http://download.tizen.org/releases/milestone/tizen/4.0-base/tizen-4.0-base_20180817.1/repos/arm/packages
 
+[repo.tizen40m3_standard]
+url = http://download.tizen.org/releases/milestone/tizen/4.0-unified/tizen-4.0-unified_20180821.6/repos/standard/packages/
 
-[repo.tizen_4.0_base_arm_20171222.1]
-url = http://download.tizen.org/releases/previews/iot/preview2/tizen-4.0-base_20171222.1/repos/arm/packages/
-user =
-passwdx =
 
-[repo.tizen_4.0_unified_20180118.1]
-url = http://download.tizen.org/releases/previews/iot/preview2/tizen-4.0-unified_20180118.1/repos/standard/packages/
-user =
-passwdx =
 
 [repo.tizen_local]
-url = ~/GBS-ROOT/local/repos/tizen_unified_preview2/
+url = ~/GBS-ROOT/local/repos/tizen50/
+
+[obs.spin]
+url = http://168.219.209.58:81
+
+[obs.tizen]
+url = https://api.tizen.org
+user = obs_viewer
+passwdx = QlpoOTFBWSZTWRP5nYMAAB6fgCAAeUA9mr+QBvzF4CAAVGAZDTRoDI0YBlCKeptQBoA0aGZIAottAkltEPOK7BAFXE9mTUzocPMzQRkPoPpNwEZx3rRQhxkXmGHS6wCjHskyVCP4u5IpwoSAn8zsGA==
+
diff --git a/config/tizenrt/Makefile b/config/tizenrt/Makefile
new file mode 100644 (file)
index 0000000..14b919d
--- /dev/null
@@ -0,0 +1,58 @@
+###########################################################################
+#
+# Copyright 2018 Samsung Electronics All Rights Reserved.
+#
+# 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 $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+
+IOTJS_ROOT_DIR ?= $(TOPDIR)/$(EXTDIR)/iotjs
+IOTJS_BUILD_OPTION ?=
+ifeq ($(CONFIG_DEBUG),y)
+  IOTJS_BUILDTYPE = debug
+else
+  IOTJS_BUILDTYPE = release
+endif
+IOTJS_OS ?= tizenrt
+IOTJS_ARCH ?= arm
+IOTJS_BUILDCONFIG ?= ${IOTJS_ARCH}-${IOTJS_OS}
+IOTJS_LIB_DIR ?= $(IOTJS_ROOT_DIR)/build/${IOTJS_BUILDCONFIG}/$(IOTJS_BUILDTYPE)/lib
+IOTJS_ROOT_DIR ?= .
+IOTJS_PROFILE_FILE ?= ${IOTJS_ROOT_DIR}/test/profiles/tizenrt.profile
+
+all: build
+.PHONY: depend clean distclean
+
+${TOPDIR}/include/sys/uio.h:
+       @mkdir -p ${@D}
+       @echo "#include <uio.h>" > $@
+
+build: $(IOTJS_ROOT_DIR)/tools/build.py ${IOTJS_PROFILE_FILE} ${TOPDIR}/include/sys/uio.h
+       $(Q) python $< \
+       --target-arch=$(CONFIG_ARCH) \
+       --target-os=${IOTJS_OS} \
+       --sysroot=$(TOPDIR) --target-board=$(CONFIG_ARCH_BOARD) --jerry-heaplimit=$(CONFIG_IOTJS_JERRY_HEAP) \
+       --buildtype=$(IOTJS_BUILDTYPE) --no-init-submodule $(IOTJS_BUILD_OPTION) \
+       --profile ${IOTJS_PROFILE_FILE}
+       $(Q) cp $(IOTJS_LIB_DIR)/*.a $(IOTJS_ROOT_DIR)
+
+depend:
+
+clean:
+       $(Q) $(call DELDIR, $(IOTJS_ROOT_DIR)/build)
+       $(Q) $(call DELFILE, $(IOTJS_ROOT_DIR)/*.a)
+
+distclean:
diff --git a/config/tizenrt/artik05x/configs/debug/defconfig b/config/tizenrt/artik05x/configs/debug/defconfig
new file mode 100644 (file)
index 0000000..a9e801c
--- /dev/null
@@ -0,0 +1,1308 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# TinyAra Configuration
+#
+
+#
+# Build Setup
+#
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_DEFAULT_SMALL is not set
+CONFIG_HOST_LINUX=y
+# CONFIG_HOST_OSX is not set
+# CONFIG_HOST_WINDOWS is not set
+# CONFIG_HOST_OTHER is not set
+# CONFIG_WINDOWS_NATIVE is not set
+
+#
+# Build Configuration
+#
+CONFIG_APPS_DIR="../apps"
+CONFIG_FRAMEWORK_DIR="../framework"
+CONFIG_TOOLS_DIR="../tools"
+CONFIG_BUILD_FLAT=y
+# CONFIG_BUILD_PROTECTED is not set
+# CONFIG_BUILD_2PASS is not set
+
+#
+# Binary Output Formats
+#
+# CONFIG_INTELHEX_BINARY is not set
+# CONFIG_MOTOROLA_SREC is not set
+CONFIG_RAW_BINARY=y
+# CONFIG_UBOOT_UIMAGE is not set
+# CONFIG_DOWNLOAD_IMAGE is not set
+# CONFIG_SMARTFS_IMAGE is not set
+
+#
+# Customize Header Files
+#
+# CONFIG_ARCH_STDINT_H is not set
+# CONFIG_ARCH_STDBOOL_H is not set
+# CONFIG_ARCH_MATH_H is not set
+# CONFIG_ARCH_FLOAT_H is not set
+# CONFIG_ARCH_STDARG_H is not set
+CONFIG_ARCH_HAVE_CUSTOMOPT=y
+# CONFIG_DEBUG_NOOPT is not set
+# CONFIG_DEBUG_CUSTOMOPT is not set
+CONFIG_DEBUG_FULLOPT=y
+
+#
+# Hardware Configuration
+#
+
+#
+# Chip Selection
+#
+CONFIG_ARCH_ARM=y
+CONFIG_ARCH="arm"
+# CONFIG_ARCH_CHIP_LM is not set
+CONFIG_ARCH_CHIP_S5J=y
+# CONFIG_ARCH_CHIP_BCM4390X is not set
+CONFIG_ARCH_CHIP="s5j"
+
+#
+# ARM Options
+#
+# CONFIG_ARCH_CORTEXM3 is not set
+# CONFIG_ARCH_CORTEXM4 is not set
+CONFIG_ARCH_CORTEXR4=y
+CONFIG_ARCH_FAMILY="armv7-r"
+# CONFIG_ARCH_HAVE_FPU is not set
+CONFIG_ARMV7M_MPU=y
+CONFIG_ARMV7M_MPU_NREGIONS=12
+
+#
+# Exception stack options
+#
+CONFIG_ARCH_HAVE_DABORTSTACK=y
+CONFIG_ARCH_DABORTSTACK=0
+
+#
+# ARMv7-R Configuration Options
+#
+CONFIG_ARMV7R_HAVE_GICv2=y
+CONFIG_ARMV7R_MEMINIT=y
+CONFIG_ARMV7R_ICACHE=y
+CONFIG_ARMV7R_DCACHE=y
+# CONFIG_ARMV7R_DCACHE_WRITETHROUGH is not set
+# CONFIG_ARMV7R_HAVE_L2CC is not set
+# CONFIG_ARMV7R_HAVE_L2CC_PL310 is not set
+# CONFIG_ARMV7R_TOOLCHAIN_BUILDROOT is not set
+# CONFIG_ARMV7R_TOOLCHAIN_CODESOURCERYL is not set
+CONFIG_ARMV7R_TOOLCHAIN_GNU_EABIL=y
+# CONFIG_ARMV7R_TOOLCHAIN_GNU_OABI is not set
+# CONFIG_ARMV7R_HAVE_DECODEFIQ is not set
+
+#
+# S5J Configuration Options
+#
+CONFIG_ARCH_CHIP_S5JT200=y
+CONFIG_S5J_S5JT200=y
+
+#
+# S5J Peripheral Support
+#
+CONFIG_S5J_HAVE_ADC=y
+CONFIG_S5J_HAVE_DMA=y
+CONFIG_S5J_HAVE_I2C=y
+CONFIG_S5J_HAVE_I2S=y
+CONFIG_S5J_HAVE_MCT=y
+CONFIG_S5J_HAVE_PWM0=y
+CONFIG_S5J_HAVE_PWM1=y
+CONFIG_S5J_HAVE_PWM2=y
+CONFIG_S5J_HAVE_PWM3=y
+CONFIG_S5J_HAVE_PWM4=y
+CONFIG_S5J_HAVE_PWM5=y
+CONFIG_S5J_HAVE_RTC=y
+CONFIG_S5J_HAVE_SFLASH=y
+CONFIG_S5J_HAVE_SPI=y
+CONFIG_S5J_HAVE_SSS=y
+CONFIG_S5J_HAVE_UART0=y
+CONFIG_S5J_HAVE_UART1=y
+CONFIG_S5J_HAVE_UART2=y
+CONFIG_S5J_HAVE_UART3=y
+CONFIG_S5J_HAVE_UART4=y
+CONFIG_S5J_HAVE_WATCHDOG=y
+CONFIG_S5J_ADC=y
+# CONFIG_S5J_DMA is not set
+CONFIG_S5J_I2C=y
+# CONFIG_S5J_I2S is not set
+CONFIG_S5J_MCT=y
+CONFIG_S5J_TIMER0=y
+# CONFIG_S5J_TIMER1 is not set
+# CONFIG_S5J_TIMER2 is not set
+# CONFIG_S5J_TIMER3 is not set
+# CONFIG_S5J_UART_FLOWCONTROL is not set
+CONFIG_S5J_UART0=y
+CONFIG_S5J_UART1=y
+CONFIG_S5J_UART2=y
+CONFIG_S5J_UART3=y
+CONFIG_S5J_UART4=y
+CONFIG_S5J_PWM=y
+CONFIG_S5J_PWM0=y
+CONFIG_S5J_PWM1=y
+CONFIG_S5J_PWM2=y
+CONFIG_S5J_PWM3=y
+CONFIG_S5J_PWM4=y
+CONFIG_S5J_PWM5=y
+# CONFIG_S5J_SSS is not set
+CONFIG_S5J_SPI=y
+# CONFIG_S5J_WATCHDOG is not set
+CONFIG_S5J_SFLASH=y
+# CONFIG_S5J_SENSOR_PPD42NS is not set
+
+#
+# Architecture Options
+#
+# CONFIG_ARCH_NOINTC is not set
+# CONFIG_ARCH_VECNOTIRQ is not set
+# CONFIG_ARCH_DMA is not set
+# CONFIG_ARCH_HAVE_IRQPRIO is not set
+# CONFIG_ARCH_L2CACHE is not set
+# CONFIG_ARCH_HAVE_COHERENT_DCACHE is not set
+# CONFIG_ARCH_HAVE_ADDRENV is not set
+# CONFIG_ARCH_NEED_ADDRENV_MAPPING is not set
+CONFIG_ARCH_HAVE_VFORK=y
+# CONFIG_ARCH_HAVE_MMU is not set
+CONFIG_ARCH_HAVE_MPU=y
+# CONFIG_ARCH_NAND_HWECC is not set
+# CONFIG_ARCH_HAVE_EXTCLK is not set
+# CONFIG_ARCH_HAVE_POWEROFF is not set
+CONFIG_ARCH_HAVE_RESET=y
+CONFIG_ARCH_USE_MPU=y
+CONFIG_ARCH_STACKDUMP=y
+# CONFIG_DEBUG_DISPLAY_SYMBOL is not set
+# CONFIG_ENDIAN_BIG is not set
+# CONFIG_ARCH_IDLE_CUSTOM is not set
+CONFIG_ARCH_CUSTOM_PMINIT=y
+# CONFIG_ARCH_HAVE_RAMFUNCS is not set
+# CONFIG_ARCH_HAVE_RAMVECTORS is not set
+
+#
+# Board Settings
+#
+CONFIG_BOARD_LOOPSPERMSEC=29100
+# CONFIG_ARCH_CALIBRATION is not set
+
+#
+# Interrupt options
+#
+CONFIG_ARCH_HAVE_INTERRUPTSTACK=y
+CONFIG_ARCH_INTERRUPTSTACK=0
+# CONFIG_ARCH_HAVE_HIPRI_INTERRUPT is not set
+
+#
+# Boot options
+#
+# CONFIG_BOOT_RUNFROMEXTSRAM is not set
+CONFIG_BOOT_RUNFROMFLASH=y
+# CONFIG_BOOT_RUNFROMISRAM is not set
+# CONFIG_BOOT_RUNFROMSDRAM is not set
+# CONFIG_BOOT_COPYTORAM is not set
+
+#
+# Boot Memory Configuration
+#
+CONFIG_RAM_START=0x02023800
+CONFIG_RAM_SIZE=968704
+# CONFIG_DDR is not set
+# CONFIG_ARCH_HAVE_SDRAM is not set
+
+#
+# Board Selection
+#
+CONFIG_ARCH_BOARD_ARTIK053=y
+# CONFIG_ARCH_BOARD_ARTIK053S is not set
+# CONFIG_ARCH_BOARD_ARTIK055S is not set
+# CONFIG_ARCH_BOARD_SIDK_S5JT200 is not set
+CONFIG_ARCH_BOARD_ARTIK05X_FAMILY=y
+CONFIG_ARCH_BOARD="artik05x"
+
+#
+# Common Board Options
+#
+# CONFIG_BOARD_CRASHDUMP is not set
+# CONFIG_BOARD_ASSERT_AUTORESET is not set
+CONFIG_LIB_BOARDCTL=y
+CONFIG_BOARDCTL_RESET=y
+# CONFIG_BOARDCTL_UNIQUEID is not set
+# CONFIG_BOARD_FOTA_SUPPORT is not set
+
+#
+# Board-Specific Options
+#
+CONFIG_ARTIK05X_BOOT_FAILURE_DETECTION=y
+CONFIG_ARTIK05X_BOOT_COUNTS_ADDR=0x80090810
+CONFIG_ARTIK05X_FLASH_CAPACITY=8388608
+CONFIG_ARTIK05X_FLASH_PAGE_SIZE=4096
+CONFIG_ARTIK05X_FLASH_PART=y
+CONFIG_ARTIK05X_FLASH_MINOR=0
+CONFIG_ARTIK05X_FLASH_PART_LIST="16,48,192,32,512,2400,1536,1536,1000,400,8,512,"
+CONFIG_ARTIK05X_FLASH_PART_TYPE="none,ftl,none,none,none,none,none,ftl,smartfs,romfs,config,none,"
+CONFIG_ARTIK05X_FLASH_PART_NAME="bl1,sssro,bl2,sssfw,wlanfw,os,factory,ota,user,rom,nvram,sssrw,"
+CONFIG_ARTIK05X_AUTOMOUNT=y
+CONFIG_ARTIK05X_AUTOMOUNT_USERFS=y
+CONFIG_ARTIK05X_AUTOMOUNT_USERFS_DEVNAME="/dev/smart0p8"
+CONFIG_ARTIK05X_AUTOMOUNT_USERFS_MOUNTPOINT="/mnt"
+# CONFIG_ARTIK05X_AUTOMOUNT_SSSRW is not set
+CONFIG_ARTIK05X_AUTOMOUNT_ROMFS=y
+CONFIG_ARTIK05X_AUTOMOUNT_ROMFS_DEVNAME="/dev/mtdblock9"
+CONFIG_ARTIK05X_AUTOMOUNT_ROMFS_MOUNTPOINT="/rom"
+
+#
+# Kernel Features
+#
+CONFIG_DISABLE_OS_API=y
+# CONFIG_DISABLE_POSIX_TIMERS is not set
+# CONFIG_DISABLE_PTHREAD is not set
+# CONFIG_DISABLE_SIGNALS is not set
+# CONFIG_DISABLE_MQUEUE is not set
+# CONFIG_DISABLE_ENVIRON is not set
+
+#
+# Clocks and Timers
+#
+CONFIG_ARCH_HAVE_TICKLESS=y
+# CONFIG_SCHED_TICKLESS is not set
+CONFIG_USEC_PER_TICK=9979
+CONFIG_SYSTEM_TIME64=y
+CONFIG_CLOCK_MONOTONIC=y
+# CONFIG_JULIAN_TIME is not set
+CONFIG_MAX_WDOGPARMS=4
+CONFIG_PREALLOC_WDOGS=32
+CONFIG_WDOG_INTRESERVE=4
+CONFIG_PREALLOC_TIMERS=8
+
+#
+# Tasks and Scheduling
+#
+CONFIG_INIT_ENTRYPOINT=y
+CONFIG_RR_INTERVAL=100
+CONFIG_TASK_NAME_SIZE=31
+CONFIG_MAX_TASKS=32
+CONFIG_SCHED_HAVE_PARENT=y
+# CONFIG_SCHED_CHILD_STATUS is not set
+CONFIG_SCHED_WAITPID=y
+
+#
+# Pthread Options
+#
+CONFIG_PTHREAD_MUTEX_TYPES=y
+# CONFIG_PTHREAD_MUTEX_ROBUST is not set
+CONFIG_PTHREAD_MUTEX_UNSAFE=y
+# CONFIG_PTHREAD_MUTEX_BOTH is not set
+CONFIG_NPTHREAD_KEYS=4
+CONFIG_NPTHREAD_DESTRUCTOR_ITERATIONS=4
+# CONFIG_PTHREAD_CLEANUP is not set
+# CONFIG_CANCELLATION_POINTS is not set
+
+#
+# Performance Monitoring
+#
+# CONFIG_SCHED_CPULOAD is not set
+
+#
+# Latency optimization
+#
+# CONFIG_SCHED_YIELD_OPTIMIZATION is not set
+
+#
+# Files and I/O
+#
+CONFIG_DEV_CONSOLE=y
+# CONFIG_FDCLONE_DISABLE is not set
+# CONFIG_FDCLONE_STDIO is not set
+# CONFIG_SDCLONE_DISABLE is not set
+CONFIG_NFILE_DESCRIPTORS=16
+CONFIG_NFILE_STREAMS=16
+CONFIG_NAME_MAX=32
+CONFIG_PRIORITY_INHERITANCE=y
+CONFIG_SEM_PREALLOCHOLDERS=16
+CONFIG_SEM_NNESTPRIO=16
+
+#
+# RTOS hooks
+#
+CONFIG_BOARD_INITIALIZE=y
+# CONFIG_BOARD_INITTHREAD is not set
+# CONFIG_SCHED_STARTHOOK is not set
+CONFIG_SCHED_ATEXIT=y
+CONFIG_SCHED_ONEXIT=y
+
+#
+# Signal Numbers
+#
+CONFIG_SIG_SIGUSR1=1
+CONFIG_SIG_SIGUSR2=2
+CONFIG_SIG_SIGALARM=3
+CONFIG_SIG_SIGCHLD=4
+CONFIG_SIG_SIGCONDTIMEDOUT=16
+CONFIG_SIG_SIGWORK=17
+
+#
+# POSIX Message Queue Options
+#
+CONFIG_PREALLOC_MQ_MSGS=4
+CONFIG_MQ_MAXMSGSIZE=600
+
+#
+# Work Queue Support
+#
+CONFIG_SCHED_WORKQUEUE=y
+CONFIG_SCHED_WORKQUEUE_SORTING=y
+CONFIG_SCHED_HPWORK=y
+CONFIG_SCHED_HPWORKPRIORITY=224
+CONFIG_SCHED_HPWORKPERIOD=50000
+CONFIG_SCHED_HPWORKSTACKSIZE=2048
+CONFIG_SCHED_LPWORK=y
+CONFIG_SCHED_LPNTHREADS=1
+CONFIG_SCHED_LPWORKPRIORITY=176
+CONFIG_SCHED_LPWORKPRIOMAX=176
+CONFIG_SCHED_LPWORKPERIOD=50000
+CONFIG_SCHED_LPWORKSTACKSIZE=2048
+
+#
+# Stack size information
+#
+CONFIG_IDLETHREAD_STACKSIZE=1024
+CONFIG_USERMAIN_STACKSIZE=2048
+# CONFIG_MPU_STACKGAURD is not set
+CONFIG_PTHREAD_STACK_MIN=256
+CONFIG_PTHREAD_STACK_DEFAULT=2048
+
+#
+# Device Drivers
+#
+# CONFIG_DISABLE_POLL is not set
+CONFIG_DEV_NULL=y
+CONFIG_DEV_ZERO=y
+# CONFIG_DRVR_WRITEBUFFER is not set
+# CONFIG_DRVR_READAHEAD is not set
+# CONFIG_CAN is not set
+# CONFIG_ARCH_HAVE_PWM_PULSECOUNT is not set
+# CONFIG_ARCH_HAVE_PWM_MULTICHAN is not set
+CONFIG_PWM=y
+# CONFIG_ARCH_HAVE_I2CRESET is not set
+CONFIG_I2C=y
+CONFIG_I2C_SLAVE=y
+CONFIG_I2C_USERIO=y
+CONFIG_I2C_TRANSFER=y
+CONFIG_I2C_POLLED=y
+# CONFIG_I2C_TRACE is not set
+# CONFIG_I2C_WRITEREAD is not set
+CONFIG_SPI=y
+# CONFIG_SPI_OWNBUS is not set
+CONFIG_SPI_EXCHANGE=y
+# CONFIG_SPI_CMDDATA is not set
+# CONFIG_SPI_BITBANG is not set
+CONFIG_GPIO=y
+# CONFIG_I2S is not set
+# CONFIG_AUDIO_DEVICES is not set
+CONFIG_BCH=y
+CONFIG_RTC=y
+CONFIG_RTC_DATETIME=y
+# CONFIG_RTC_ALARM is not set
+CONFIG_RTC_DRIVER=y
+# CONFIG_RTC_IOCTL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_DEVPATH="/dev/watchdog0"
+# CONFIG_TIMER is not set
+CONFIG_ANALOG=y
+CONFIG_ADC=y
+CONFIG_ADC_FIFOSIZE=8
+# CONFIG_DAC is not set
+CONFIG_NETDEVICES=y
+
+#
+# General Ethernet MAC Driver Options
+#
+CONFIG_NETDEV_TELNET=y
+CONFIG_NETDEV_MULTINIC=y
+# CONFIG_NET_DUMPPACKET is not set
+
+#
+# External Ethernet MAC Device Support
+#
+# CONFIG_NET_DM90x0 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ENCX24J600 is not set
+# CONFIG_NET_E1000 is not set
+# CONFIG_NET_SLIP is not set
+# CONFIG_NET_VNET is not set
+# CONFIG_PIPES is not set
+CONFIG_POWER=y
+# CONFIG_BATTERY_CHARGER is not set
+# CONFIG_BATTERY_GAUGE is not set
+CONFIG_SERIAL=y
+# CONFIG_DEV_LOWCONSOLE is not set
+# CONFIG_16550_UART is not set
+# CONFIG_ARCH_HAVE_UART is not set
+CONFIG_ARCH_HAVE_UART0=y
+CONFIG_ARCH_HAVE_UART1=y
+CONFIG_ARCH_HAVE_UART2=y
+CONFIG_ARCH_HAVE_UART3=y
+CONFIG_ARCH_HAVE_UART4=y
+# CONFIG_ARCH_HAVE_UART5 is not set
+# CONFIG_ARCH_HAVE_UART6 is not set
+# CONFIG_ARCH_HAVE_UART7 is not set
+# CONFIG_ARCH_HAVE_UART8 is not set
+# CONFIG_ARCH_HAVE_SCI0 is not set
+# CONFIG_ARCH_HAVE_SCI1 is not set
+# CONFIG_ARCH_HAVE_USART0 is not set
+# CONFIG_ARCH_HAVE_USART1 is not set
+# CONFIG_ARCH_HAVE_USART2 is not set
+# CONFIG_ARCH_HAVE_USART3 is not set
+# CONFIG_ARCH_HAVE_USART4 is not set
+# CONFIG_ARCH_HAVE_USART5 is not set
+# CONFIG_ARCH_HAVE_USART6 is not set
+# CONFIG_ARCH_HAVE_USART7 is not set
+# CONFIG_ARCH_HAVE_USART8 is not set
+# CONFIG_ARCH_HAVE_OTHER_UART is not set
+
+#
+# USART Configuration
+#
+CONFIG_MCU_SERIAL=y
+CONFIG_STANDARD_SERIAL=y
+CONFIG_SERIAL_NPOLLWAITERS=2
+# CONFIG_SERIAL_IFLOWCONTROL is not set
+# CONFIG_SERIAL_OFLOWCONTROL is not set
+# CONFIG_SERIAL_TIOCSERGSTRUCT is not set
+CONFIG_ARCH_HAVE_SERIAL_TERMIOS=y
+CONFIG_SERIAL_TERMIOS=y
+# CONFIG_UART0_SERIAL_CONSOLE is not set
+# CONFIG_UART1_SERIAL_CONSOLE is not set
+# CONFIG_UART2_SERIAL_CONSOLE is not set
+# CONFIG_UART3_SERIAL_CONSOLE is not set
+CONFIG_UART4_SERIAL_CONSOLE=y
+# CONFIG_OTHER_SERIAL_CONSOLE is not set
+# CONFIG_NO_SERIAL_CONSOLE is not set
+
+#
+# UART0 Configuration
+#
+CONFIG_UART0_RXBUFSIZE=64
+CONFIG_UART0_TXBUFSIZE=64
+CONFIG_UART0_BAUD=115200
+CONFIG_UART0_BITS=8
+CONFIG_UART0_PARITY=0
+CONFIG_UART0_2STOP=0
+# CONFIG_UART0_IFLOWCONTROL is not set
+# CONFIG_UART0_OFLOWCONTROL is not set
+
+#
+# UART1 Configuration
+#
+CONFIG_UART1_RXBUFSIZE=256
+CONFIG_UART1_TXBUFSIZE=256
+CONFIG_UART1_BAUD=115200
+CONFIG_UART1_BITS=8
+CONFIG_UART1_PARITY=0
+CONFIG_UART1_2STOP=0
+# CONFIG_UART1_IFLOWCONTROL is not set
+# CONFIG_UART1_OFLOWCONTROL is not set
+
+#
+# UART2 Configuration
+#
+CONFIG_UART2_RXBUFSIZE=256
+CONFIG_UART2_TXBUFSIZE=256
+CONFIG_UART2_BAUD=115200
+CONFIG_UART2_BITS=8
+CONFIG_UART2_PARITY=0
+CONFIG_UART2_2STOP=0
+# CONFIG_UART2_IFLOWCONTROL is not set
+# CONFIG_UART2_OFLOWCONTROL is not set
+
+#
+# UART3 Configuration
+#
+CONFIG_UART3_RXBUFSIZE=256
+CONFIG_UART3_TXBUFSIZE=256
+CONFIG_UART3_BAUD=115200
+CONFIG_UART3_BITS=8
+CONFIG_UART3_PARITY=0
+CONFIG_UART3_2STOP=0
+# CONFIG_UART3_IFLOWCONTROL is not set
+# CONFIG_UART3_OFLOWCONTROL is not set
+
+#
+# UART4 Configuration
+#
+CONFIG_UART4_RXBUFSIZE=256
+CONFIG_UART4_TXBUFSIZE=256
+CONFIG_UART4_BAUD=115200
+CONFIG_UART4_BITS=8
+CONFIG_UART4_PARITY=0
+CONFIG_UART4_2STOP=0
+# CONFIG_UART4_IFLOWCONTROL is not set
+# CONFIG_UART4_OFLOWCONTROL is not set
+# CONFIG_SENSOR is not set
+# CONFIG_USBDEV is not set
+# CONFIG_FOTA_DRIVER is not set
+
+#
+# System Logging
+#
+# CONFIG_RAMLOG is not set
+# CONFIG_SYSLOG_CONSOLE is not set
+
+#
+# T-trace
+#
+# CONFIG_TTRACE is not set
+
+#
+# Wireless Device Options
+#
+CONFIG_DRIVERS_WIRELESS=y
+CONFIG_SCSC_WLAN=y
+# CONFIG_SLSI_RX_PERFORMANCE_TEST is not set
+CONFIG_SCSC_TX_FLOW_CONTROL=y
+CONFIG_SCSC_ENABLE_PORT_CONTROL=y
+# CONFIG_SCSC_WLAN_STA_ONLY is not set
+# CONFIG_SCSC_WLAN_BLOCK_IPV6 is not set
+# CONFIG_SCSC_WLAN_UDP_FLOWCONTROL is not set
+# CONFIG_SCSC_WLAN_AUTO_RECOVERY is not set
+CONFIG_SCSC_WLAN_POWER_SAVE=y
+CONFIG_SCSC_WLAN_MAX_INTERFACES=1
+CONFIG_SCSC_CORE=y
+CONFIG_SCSC_PLATFORM=y
+# CONFIG_SCSC_WLANLITE is not set
+# CONFIG_SCSC_DISABLE_WLAN_RESET is not set
+
+#
+# Networking Support
+#
+CONFIG_ARCH_HAVE_NET=y
+# CONFIG_ARCH_HAVE_PHY is not set
+CONFIG_NET=y
+CONFIG_NET_LWIP=y
+
+#
+# LwIP options
+#
+CONFIG_NET_IPv4=y
+CONFIG_NET_IP_DEFAULT_TTL=255
+# CONFIG_NET_IP_FORWARD is not set
+CONFIG_NET_IP_OPTIONS_ALLOWED=y
+CONFIG_NET_IP_FRAG=y
+CONFIG_NET_IP_REASSEMBLY=y
+CONFIG_NET_IPV4_REASS_MAX_PBUFS=20
+CONFIG_NET_IPV4_REASS_MAXAGE=5
+CONFIG_NET_IPv6=y
+CONFIG_NET_IPv6_NUM_ADDRESSES=3
+# CONFIG_NET_IPv6_FORWARD is not set
+# CONFIG_NET_IPv6_FRAG is not set
+CONFIG_NET_IPv6_REASS=y
+CONFIG_NET_IPV6_REASS_MAXAGE=60
+CONFIG_NET_IPv6_SEND_ROUTER_SOLICIT=y
+CONFIG_NET_IPv6_AUTOCONFIG=y
+CONFIG_NET_IPv6_DUP_DETECT_ATTEMPTS=1
+# CONFIG_NET_IPv6_PMTU_FOR_MULTICAST is not set
+
+#
+# Socket support
+#
+CONFIG_NET_SOCKET=y
+CONFIG_NSOCKET_DESCRIPTORS=20
+CONFIG_NET_TCP_KEEPALIVE=y
+CONFIG_NET_RAW=y
+# CONFIG_NET_SOCKET_OPTION_BROADCAST is not set
+# CONFIG_NET_RANDOMIZE_INITIAL_LOCAL_PORTS is not set
+# CONFIG_NET_SO_SNDTIMEO is not set
+CONFIG_NET_SO_RCVTIMEO=y
+# CONFIG_NET_SO_RCVBUF is not set
+CONFIG_NET_SO_REUSE=y
+# CONFIG_NET_SO_REUSE_RXTOALL is not set
+CONFIG_NET_ARP=y
+CONFIG_NET_ARP_TABLESIZE=10
+CONFIG_NET_ARP_QUEUEING=y
+CONFIG_NET_ETHARP_TRUST_IP_MAC=y
+CONFIG_NET_ETH_PAD_SIZE=0
+# CONFIG_NET_ARP_STATIC_ENTRIES is not set
+CONFIG_NET_IPv6_ND=y
+CONFIG_NET_IPv6_ND_QUEUEING=y
+CONFIG_NET_IPv6_ND_QUEUE=20
+CONFIG_NET_IPv6_ND_NUM_NEIGHBORS=10
+CONFIG_NET_IPv6_ND_NUM_DESTINATIONS=10
+CONFIG_NET_IPv6_ND_NUM_PREFIXES=5
+CONFIG_NET_IPv6_ND_NUM_ROUTERS=3
+CONFIG_NET_IPv6_ND_MAX_MULTICAST_SOLICIT=3
+CONFIG_NET_IPv6_ND_MAX_UNICAST_SOLICIT=3
+CONFIG_NET_IPv6_ND_MAX_SOLICIT_INTERVAL=4000
+CONFIG_NET_IPv6_ND_REACHABLE_TIME=30000
+CONFIG_NET_IPv6_ND_RETRANS_TIMER=1000
+CONFIG_NET_IPv6_ND_DELAY_FIRST_PROBE_TIME=5000
+CONFIG_NET_IPv6_ND_ALLOW_RA_UPDATES=y
+CONFIG_NET_IPv6_ND_TCP_REACHABILITY_HINTS=y
+CONFIG_NET_IPv6_ND_RDNSS_MAX_DNS_SERVERS=0
+CONFIG_NET_UDP=y
+# CONFIG_NET_NETBUF_RECVINFO is not set
+CONFIG_NET_UDP_TTL=255
+# CONFIG_NET_UDPLITE is not set
+CONFIG_NET_TCP=y
+CONFIG_NET_TCP_TTL=255
+CONFIG_NET_TCP_WND=58400
+CONFIG_NET_TCP_MAXRTX=12
+CONFIG_NET_TCP_SYNMAXRTX=6
+CONFIG_NET_TCP_QUEUE_OOSEQ=y
+CONFIG_NET_TCP_MSS=1460
+CONFIG_NET_TCP_CALCULATE_EFF_SEND_MSS=y
+CONFIG_NET_TCP_SND_BUF=29200
+CONFIG_NET_TCP_SND_QUEUELEN=80
+# CONFIG_NET_TCP_LISTEN_BACKLOG is not set
+CONFIG_NET_TCP_OVERSIZE=536
+# CONFIG_NET_TCP_TIMESTAMPS is not set
+CONFIG_NET_TCP_WND_UPDATE_THRESHOLD=536
+CONFIG_NET_ICMP=y
+CONFIG_NET_ICMP_TTL=255
+# CONFIG_NET_BROADCAST_PING is not set
+# CONFIG_NET_MULTICAST_PING4 is not set
+CONFIG_NET_IPv6_ICMP=y
+CONFIG_NET_IPv6_ICMP_DATASIZE=8
+CONFIG_NET_IPv6_ICMP_HL=255
+# CONFIG_NET_MULTICAST_PING6 is not set
+CONFIG_NET_LWIP_IGMP=y
+CONFIG_NET_LWIP_MEMP_NUM_IGMP_GROUP=8
+CONFIG_NET_IPv6_MLD=y
+CONFIG_NET_IPv6_MLD_GROUP=4
+# CONFIG_NET_IPv6_DHCP is not set
+
+#
+# LWIP Mailbox Configurations
+#
+CONFIG_NET_TCPIP_MBOX_SIZE=64
+CONFIG_NET_DEFAULT_ACCEPTMBOX_SIZE=64
+CONFIG_NET_DEFAULT_RAW_RECVMBOX_SIZE=64
+CONFIG_NET_DEFAULT_TCP_RECVMBOX_SIZE=54
+CONFIG_NET_DEFAULT_UDP_RECVMBOX_SIZE=64
+
+#
+# Memory Configurations
+#
+CONFIG_NET_MEM_ALIGNMENT=4
+# CONFIG_NET_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is not set
+# CONFIG_NET_MEM_LIBC_MALLOC is not set
+CONFIG_NET_MEMP_MEM_MALLOC=y
+# CONFIG_NET_MEM_USE_POOLS is not set
+CONFIG_NET_MEM_SIZE=153600
+
+#
+# LWIP Task Configurations
+#
+# CONFIG_NET_TCPIP_CORE_LOCKING is not set
+# CONFIG_NET_TCPIP_CORE_LOCKING_INPUT is not set
+CONFIG_NET_TCPIP_THREAD_NAME="LWIP_TCP/IP"
+CONFIG_NET_TCPIP_THREAD_PRIO=110
+CONFIG_NET_TCPIP_THREAD_STACKSIZE=4096
+CONFIG_NET_COMPAT_MUTEX=y
+CONFIG_NET_SYS_LIGHTWEIGHT_PROT=y
+CONFIG_NET_DEFAULT_THREAD_NAME="lwIP"
+CONFIG_NET_DEFAULT_THREAD_PRIO=1
+CONFIG_NET_DEFAULT_THREAD_STACKSIZE=0
+
+#
+# Debug Options for Network
+#
+# CONFIG_NET_LWIP_ASSERT is not set
+# CONFIG_NET_LWIP_ERROR is not set
+# CONFIG_NET_LWIP_DEBUG is not set
+
+#
+# Enable Statistics
+#
+CONFIG_NET_STATS=y
+CONFIG_NET_STATS_DISPLAY=y
+CONFIG_NET_LINK_STATS=y
+CONFIG_NET_ETHARP_STATS=y
+CONFIG_NET_IP_STATS=y
+# CONFIG_NET_IPFRAG_STATS is not set
+# CONFIG_NET_ICMP_STATS is not set
+CONFIG_NET_UDP_STATS=y
+CONFIG_NET_TCP_STATS=y
+CONFIG_NET_MEM_STATS=y
+CONFIG_NET_SYS_STATS=y
+# CONFIG_NET_IPv6_STATS is not set
+# CONFIG_NET_IPv6_ICMP_STATS is not set
+# CONFIG_NET_IPv6_MLD_STATS is not set
+# CONFIG_NET_IPv6_ND_STATS is not set
+# CONFIG_NET_LWIP_VLAN is not set
+CONFIG_NET_LWIP_LOOPBACK_INTERFACE=y
+# CONFIG_NET_LWIP_SLIP_INTERFACE is not set
+# CONFIG_NET_LWIP_PPP_SUPPORT is not set
+# CONFIG_NET_LWIP_SNMP is not set
+
+#
+# Interface Name
+#
+CONFIG_NET_ETH_IFNAME="en"
+CONFIG_NET_LOOP_IFNAME="lo"
+CONFIG_NET_STA_IFNAME="wl"
+CONFIG_NET_SOFTAP_IFNAME="sa"
+CONFIG_NET_LWIP_NETDB=y
+CONFIG_NET_DNS_TABLE_SIZE=4
+CONFIG_NET_DNS_MAX_NAME_LENGTH=256
+CONFIG_NET_DNS_MAX_SERVERS=2
+# CONFIG_NET_DNS_DOES_NAME_CHECK is not set
+CONFIG_NET_DNS_SECURE=0
+# CONFIG_NET_DNS_LOCAL_HOSTLIST is not set
+
+#
+# Driver buffer configuration
+#
+CONFIG_NET_MULTIBUFFER=y
+CONFIG_NET_ETH_MTU=590
+CONFIG_NET_GUARDSIZE=2
+
+#
+# Data link support
+#
+# CONFIG_NET_MULTILINK is not set
+CONFIG_NET_ETHERNET=y
+
+#
+# Network Device Operations
+#
+# CONFIG_NETDEV_PHY_IOCTL is not set
+
+#
+# Protocols
+#
+CONFIG_NETUTILS_DHCPD=y
+CONFIG_NETUTILS_DHCPD_IGNOREBROADCAST=y
+CONFIG_NETUTILS_DHCPD_INTERFACE="wl1"
+CONFIG_NETUTILS_DHCPD_LEASETIME=864000
+CONFIG_NETUTILS_DHCPD_MINLEASETIME=86400
+CONFIG_NETUTILS_DHCPD_MAXLEASETIME=2592000
+CONFIG_NETUTILS_DHCPD_MAXLEASES=6
+CONFIG_NETUTILS_DHCPD_STARTIP=0xc0a82f02
+CONFIG_NETUTILS_DHCPD_ROUTERIP=0xc0a82f01
+CONFIG_NETUTILS_DHCPD_NETMASK=0xffffff00
+CONFIG_NETUTILS_DHCPD_DNSIP=0x08080808
+CONFIG_NETUTILS_DHCPD_OFFERTIME=3600
+CONFIG_NETUTILS_DHCPD_DECLINETIME=3600
+# CONFIG_NETUTILS_XMLRPC is not set
+# CONFIG_NETUTILS_NTPCLIENT is not set
+# CONFIG_NETUTILS_WEBSERVER is not set
+# CONFIG_NETUTILS_FTPC is not set
+# CONFIG_NETUTILS_MDNS is not set
+# CONFIG_NETUTILS_FTPD is not set
+CONFIG_NETUTILS_DHCPC=y
+# CONFIG_NETUTILS_WEBSOCKET is not set
+# CONFIG_NETUTILS_LIBCOAP is not set
+# CONFIG_NETUTILS_TFTPC is not set
+# CONFIG_NETUTILS_TELNETD is not set
+# CONFIG_NETUTILS_SMTP is not set
+# CONFIG_NETUTILS_MQTT is not set
+CONFIG_NET_SECURITY_TLS=y
+CONFIG_TLS_MPI_MAX_SIZE=512
+
+#
+# Wireless
+#
+CONFIG_WIFI_MANAGER=y
+CONFIG_SELECT_WPA_SUPPLICANT=y
+# CONFIG_SELECT_PROPIETARY_SUPPLICANT is not set
+# CONFIG_SELECT_NO_DRIVER is not set
+CONFIG_SELECT_SCSC_WLAN=y
+# CONFIG_SELECT_PROPIETARY_WLAN is not set
+CONFIG_NETUTILS_WIFI=y
+CONFIG_SLSI_WIFI_DEFAULT_WLAN_COUNTRY_CODE="00"
+CONFIG_SLSI_WIFI_DEFAULT_WLAN_TX_POWER=30
+# CONFIG_SLSI_WIFI_FILESYSTEM_SUPPORT is not set
+
+#
+# wpa_supplicant
+#
+CONFIG_WPA_SUPPLICANT=y
+CONFIG_WPA_SUPPLICANT_PRIORITY=100
+CONFIG_WPA_SUPPLICANT_STACKSIZE=16384
+CONFIG_WPA_SUPPLICANT_ENTRYPOINT="wpa_supplicant_main"
+CONFIG_CTRL_IFACE=y
+CONFIG_CTRL_IFACE_FIFO=y
+CONFIG_WPA_CTRL_FIFO_DEV_REQ="/dev/wpa_ctrl_req"
+CONFIG_WPA_CTRL_FIFO_DEV_CFM="/dev/wpa_ctrl_cfm"
+CONFIG_WPA_CTRL_FIFO_DEV_GLOBAL_REQ="/dev/wpa_ctrl_global_req"
+CONFIG_WPA_CTRL_FIFO_DEV_GLOBAL_CFM="/dev/wpa_ctrl_global_cfm"
+CONFIG_WPA_MONITOR_FIFO_DEV="/dev/wpa_monitor"
+CONFIG_WPA_CTRL_FIFO_MK_MODE=666
+CONFIG_ELOOP_POLL=y
+# CONFIG_WPA_SUPPLICANT_CMD is not set
+CONFIG_DRIVER_T20=y
+# CONFIG_ENABLE_EAP_FOR_SUPPLICANT is not set
+CONFIG_WIFIMGR_SOFTAP_IFNAME="wl1"
+CONFIG_WIFIMGR_STA_IFNAME="wl1"
+# CONFIG_WIFIMGR_DISABLE_AUTO_GET_IP is not set
+# CONFIG_DISABLE_EXTERNAL_AUTOCONNECT is not set
+
+#
+# Network utilities
+#
+CONFIG_NETUTILS_NETLIB=y
+CONFIG_NET_NETMON=y
+
+#
+# Audio Support
+#
+# CONFIG_AUDIO is not set
+
+#
+# Media Support
+#
+
+#
+# File Systems
+#
+# CONFIG_DISABLE_MOUNTPOINT is not set
+# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set
+CONFIG_FS_READABLE=y
+CONFIG_FS_WRITABLE=y
+# CONFIG_FS_AIO is not set
+# CONFIG_FS_NAMED_SEMAPHORES is not set
+CONFIG_FS_MQUEUE_MPATH="/var/mqueue"
+CONFIG_FS_SMARTFS=y
+
+#
+# SMARTFS options
+#
+CONFIG_SMARTFS_ERASEDSTATE=0xff
+CONFIG_SMARTFS_MAXNAMLEN=32
+# CONFIG_SMARTFS_MULTI_ROOT_DIRS is not set
+CONFIG_SMARTFS_ALIGNED_ACCESS=y
+# CONFIG_SMARTFS_BAD_SECTOR is not set
+# CONFIG_SMARTFS_DYNAMIC_HEADER is not set
+# CONFIG_SMARTFS_JOURNALING is not set
+# CONFIG_SMARTFS_SECTOR_RECOVERY is not set
+CONFIG_FS_PROCFS=y
+# CONFIG_FS_AUTOMOUNT_PROCFS is not set
+
+#
+# Exclude individual procfs entries
+#
+# CONFIG_FS_PROCFS_EXCLUDE_PROCESS is not set
+# CONFIG_FS_PROCFS_EXCLUDE_UPTIME is not set
+# CONFIG_FS_PROCFS_EXCLUDE_VERSION is not set
+# CONFIG_FS_PROCFS_EXCLUDE_MTD is not set
+# CONFIG_FS_PROCFS_EXCLUDE_PARTITIONS is not set
+# CONFIG_FS_PROCFS_EXCLUDE_SMARTFS is not set
+# CONFIG_FS_PROCFS_EXCLUDE_POWER is not set
+CONFIG_FS_ROMFS=y
+# CONFIG_FS_TMPFS is not set
+
+#
+# Block Driver Configurations
+#
+CONFIG_RAMDISK=y
+
+#
+# MTD Configuration
+#
+CONFIG_MTD=y
+CONFIG_MTD_PARTITION=y
+CONFIG_MTD_PARTITION_NAMES=y
+CONFIG_MTD_PROGMEM=y
+CONFIG_MTD_FTL=y
+
+#
+# MTD_FTL Configurations
+#
+CONFIG_MTD_CONFIG=y
+
+#
+# MTD Configurations
+#
+# CONFIG_MTD_CONFIG_RAM_CONSOLIDATE is not set
+CONFIG_MTD_CONFIG_ERASEDVALUE=0xff
+# CONFIG_MTD_BYTE_WRITE is not set
+
+#
+# MTD Device Drivers
+#
+# CONFIG_MTD_M25P is not set
+# CONFIG_RAMMTD is not set
+CONFIG_MTD_SMART=y
+
+#
+# SMART Device options
+#
+CONFIG_MTD_SMART_SECTOR_SIZE=512
+# CONFIG_MTD_SMART_WEAR_LEVEL is not set
+# CONFIG_MTD_SMART_ENABLE_CRC is not set
+# CONFIG_MTD_SMART_SECTOR_ERASE_DEBUG is not set
+# CONFIG_MTD_SMART_ALLOC_DEBUG is not set
+# CONFIG_MTD_W25 is not set
+
+#
+# System Logging
+#
+# CONFIG_SYSLOG is not set
+# CONFIG_SYSLOG_TIMESTAMP is not set
+
+#
+# Database
+#
+# CONFIG_ARASTORAGE is not set
+
+#
+# Memory Management
+#
+# CONFIG_REALLOC_DISABLE_NEIGHBOR_EXTENSION is not set
+# CONFIG_MM_SMALL is not set
+CONFIG_MM_REGIONS=1
+# CONFIG_GRAN is not set
+
+#
+# Power Management
+#
+CONFIG_PM=y
+# CONFIG_DEBUG_PM is not set
+# CONFIG_PM_TEST is not set
+CONFIG_PM_DEVNAME_LEN=32
+# CONFIG_PM_METRICS is not set
+CONFIG_PM_SLICEMS=100
+CONFIG_PM_NDOMAINS=1
+CONFIG_PM_MEMORY=2
+CONFIG_PM_COEFN=1
+CONFIG_PM_COEF1=1
+CONFIG_PM_COEF2=1
+CONFIG_PM_COEF3=1
+CONFIG_PM_COEF4=1
+CONFIG_PM_COEF5=1
+CONFIG_PM_IDLEENTER_THRESH=1
+CONFIG_PM_IDLEEXIT_THRESH=2
+CONFIG_PM_IDLEENTER_COUNT=30
+CONFIG_PM_STANDBYENTER_THRESH=1
+CONFIG_PM_STANDBYEXIT_THRESH=2
+CONFIG_PM_STANDBYENTER_COUNT=50
+CONFIG_PM_SLEEPENTER_THRESH=1
+CONFIG_PM_SLEEPEXIT_THRESH=2
+CONFIG_PM_SLEEPENTER_COUNT=70
+
+#
+# Debug Options
+#
+CONFIG_DEBUG=y
+CONFIG_DEBUG_ERROR=y
+# CONFIG_DEBUG_WARN is not set
+CONFIG_DEBUG_VERBOSE=y
+
+#
+# Subsystem Debug Options
+#
+# CONFIG_DEBUG_LIB is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_IOTBUS is not set
+# CONFIG_DEBUG_MM is not set
+CONFIG_DEBUG_NET=y
+# CONFIG_DEBUG_NET_ERROR is not set
+# CONFIG_DEBUG_NET_INFO is not set
+# CONFIG_DEBUG_SCHED is not set
+# CONFIG_DEBUG_TASH is not set
+CONFIG_DEBUG_WLAN=y
+
+#
+# SLSI WLAN FW Debug Options
+#
+# CONFIG_SCSC_ENABLE_FWFAULT_LOG is not set
+
+#
+# SLSI WLAN Driver Debug Options
+#
+CONFIG_DEBUG_WLAN_DRIVER_ERROR=y
+# CONFIG_DEBUG_WLAN_DRIVER_DEBUG is not set
+# CONFIG_DEBUG_WLAN_DRIVER_MORE is not set
+# CONFIG_DEBUG_WLAN_DRIVER_INFO is not set
+
+#
+# SLSI WPA Supplicant Debug Options
+#
+CONFIG_DEBUG_WLAN_SUPPLICANT_ERROR=y
+# CONFIG_DEBUG_WLAN_SUPPLICANT_DEBUG is not set
+# CONFIG_DEBUG_WLAN_SUPPLICANT_MORE is not set
+# CONFIG_DEBUG_WLAN_SUPPLICANT_INFO is not set
+
+#
+# SLSI Wi-Fi API Debug Options
+#
+CONFIG_DEBUG_WLAN_API_ERROR=y
+# CONFIG_DEBUG_WLAN_API_DEBUG is not set
+# CONFIG_DEBUG_WLAN_API_INFO is not set
+
+#
+# OS Function Debug Options
+#
+# CONFIG_ARCH_HAVE_HEAPCHECK is not set
+CONFIG_DEBUG_MM_HEAPINFO=y
+# CONFIG_DEBUG_IRQ is not set
+
+#
+# Driver Debug Options
+#
+# CONFIG_DEBUG_I2S is not set
+# CONFIG_DEBUG_PWM is not set
+# CONFIG_DEBUG_RTC is not set
+# CONFIG_DEBUG_SPI is not set
+# CONFIG_DEBUG_WATCHDOG is not set
+
+#
+# System Debug Options
+#
+# CONFIG_DEBUG_SYSTEM is not set
+
+#
+# Stack Debug Options
+#
+CONFIG_ARCH_HAVE_STACKCHECK=y
+CONFIG_STACK_COLORATION=y
+
+#
+# Build Debug Options
+#
+CONFIG_DEBUG_SYMBOLS=y
+# CONFIG_FRAME_POINTER is not set
+
+#
+# Logger Module
+#
+CONFIG_LOGM=y
+# CONFIG_PRINTF2LOGM is not set
+CONFIG_SYSLOG2LOGM=y
+# CONFIG_LOGM_TIMESTAMP is not set
+CONFIG_LOGM_BUFFER_SIZE=10240
+CONFIG_LOGM_PRINT_INTERVAL=1000
+CONFIG_LOGM_TASK_PRIORITY=110
+CONFIG_LOGM_TASK_STACKSIZE=2048
+# CONFIG_LOGM_TEST is not set
+
+#
+# Built-in Libraries
+#
+
+#
+# Standard C Library Options
+#
+CONFIG_STDIO_BUFFER_SIZE=64
+CONFIG_STDIO_LINEBUFFER=y
+CONFIG_NUNGET_CHARS=2
+CONFIG_LIB_HOMEDIR="/"
+CONFIG_LIBM=y
+# CONFIG_NOPRINTF_FIELDWIDTH is not set
+CONFIG_LIBC_FLOATINGPOINT=y
+CONFIG_LIBC_FLOATPRECISION=6
+CONFIG_LIBC_SCANSET=y
+# CONFIG_NOPRINTF_LONGLONG_TO_ASCII is not set
+CONFIG_LIBC_IOCTL_VARIADIC=y
+# CONFIG_LIBC_WCHAR is not set
+# CONFIG_LIBC_LOCALE is not set
+CONFIG_LIB_RAND_ORDER=1
+# CONFIG_EOL_IS_CR is not set
+# CONFIG_EOL_IS_LF is not set
+# CONFIG_EOL_IS_BOTH_CRLF is not set
+CONFIG_EOL_IS_EITHER_CRLF=y
+CONFIG_LIBC_STRERROR=y
+# CONFIG_LIBC_STRERROR_SHORT is not set
+# CONFIG_LIBC_PERROR_STDOUT is not set
+CONFIG_LIBC_TMPDIR="/tmp"
+CONFIG_LIBC_MAX_TMPFILE=32
+CONFIG_ARCH_LOWPUTC=y
+# CONFIG_LIBC_LOCALTIME is not set
+# CONFIG_TIME_EXTENDED is not set
+CONFIG_LIB_SENDFILE_BUFSIZE=512
+CONFIG_ARCH_OPTIMIZED_FUNCTIONS=y
+# CONFIG_ARCH_MEMCPY is not set
+CONFIG_MEMCPY_VIK=y
+# CONFIG_MEMCPY_PRE_INC_PTRS is not set
+CONFIG_MEMCPY_INDEXED_COPY=y
+# CONFIG_MEMCPY_64BIT is not set
+# CONFIG_ARCH_MEMCMP is not set
+# CONFIG_ARCH_MEMMOVE is not set
+# CONFIG_ARCH_MEMSET is not set
+# CONFIG_MEMSET_OPTSPEED is not set
+# CONFIG_ARCH_STRCHR is not set
+# CONFIG_ARCH_STRCMP is not set
+# CONFIG_ARCH_STRCPY is not set
+# CONFIG_ARCH_STRNCPY is not set
+# CONFIG_ARCH_STRLEN is not set
+# CONFIG_ARCH_STRNLEN is not set
+# CONFIG_ARCH_BZERO is not set
+
+#
+# Non-standard Library Support
+#
+
+#
+# Basic CXX Support
+#
+# CONFIG_C99_BOOL8 is not set
+# CONFIG_HAVE_CXX is not set
+
+#
+# External Libraries
+#
+# CONFIG_AVS_DEVICE_SDK is not set
+# CONFIG_AWS_SDK is not set
+# CONFIG_NETUTILS_CODECS is not set
+
+#
+# CURL Options
+#
+# CONFIG_ENABLE_CURL is not set
+# CONFIG_ERROR_REPORT is not set
+# CONFIG_ENABLE_IOTIVITY is not set
+CONFIG_NETUTILS_JSON=y
+# CONFIG_LIBTUV is not set
+# CONFIG_LWM2M_WAKAAMA is not set
+# CONFIG_STRESS_TOOL is not set
+# CONFIG_VOICE_SOFTWARE_EPD is not set
+
+#
+# Application Configuration
+#
+
+#
+# Application entry point list
+#
+# CONFIG_ENTRY_MANUAL is not set
+# CONFIG_ENTRY_HELLO is not set
+CONFIG_ENTRY_IOTJS_STARTUP=y
+CONFIG_USER_ENTRYPOINT="iotjs_startup_main"
+CONFIG_BUILTIN_APPS=y
+
+#
+# Examples
+#
+# CONFIG_EXAMPLES_AVS_TEST is not set
+# CONFIG_EXAMPLES_AWS is not set
+# CONFIG_EXAMPLES_CURLTEST is not set
+# CONFIG_EXAMPLES_DNSCLIENT_TEST is not set
+# CONFIG_EXAMPLES_DTLS_CLIENT is not set
+# CONFIG_EXAMPLES_DTLS_SERVER is not set
+# CONFIG_EXAMPLES_EEPROM_TEST is not set
+# CONFIG_EXAMPLES_EVENTLOOP is not set
+# CONFIG_EXAMPLES_FOTA_SAMPLE is not set
+# CONFIG_FILESYSTEM_HELPER_ENABLE is not set
+CONFIG_EXAMPLES_HELLO=y
+# CONFIG_EXAMPLES_HELLOXX is not set
+# CONFIG_EXAMPLES_IOTBUS_TEST is not set
+CONFIG_EXAMPLES_IOTJS_STARTUP=y
+CONFIG_EXAMPLES_IOTJS_STARTUP_JS_FILE="/rom/example/index.js"
+# CONFIG_EXAMPLES_IOTJS_STARTUP_WIFI is not set
+# CONFIG_EXAMPLES_KERNEL_SAMPLE is not set
+# CONFIG_EXAMPLES_LIBTUV is not set
+# CONFIG_EXAMPLES_NETTEST is not set
+# CONFIG_EXAMPLES_PROC_TEST is not set
+# CONFIG_EXAMPLES_SELECT_TEST is not set
+# CONFIG_EXAMPLES_SENSORBOARD is not set
+# CONFIG_EXAMPLES_SETJMP_TEST is not set
+CONFIG_EXAMPLES_SLSIWIFI=y
+CONFIG_EXAMPLES_SLSIWIFI_PRIORITY=50
+CONFIG_EXAMPLES_SLSIWIFI_STACKSIZE=2048
+# CONFIG_EXAMPLES_SMART is not set
+# CONFIG_EXAMPLES_SMART_TEST is not set
+# CONFIG_EXAMPLES_SPEECH_DETECTOR_TEST is not set
+# CONFIG_EXAMPLES_ST_THINGS is not set
+# CONFIG_EXAMPLES_TESTCASE is not set
+# CONFIG_EXAMPLES_TLS_BENCHMARK is not set
+# CONFIG_EXAMPLES_TLS_CLIENT is not set
+# CONFIG_EXAMPLES_TLS_SELFTEST is not set
+# CONFIG_EXAMPLES_TLS_SERVER is not set
+# CONFIG_EXAMPLES_WIFIMANAGER_TEST is not set
+
+#
+# Platform-specific Support
+#
+# CONFIG_PLATFORM_CONFIGDATA is not set
+
+#
+# Shell
+#
+CONFIG_TASH=y
+CONFIG_TASH_MAX_COMMANDS=132
+# CONFIG_TASH_USLEEP is not set
+CONFIG_TASH_COMMAND_INTERFACE=y
+CONFIG_TASH_CMDTASK_STACKSIZE=4096
+CONFIG_TASH_CMDTASK_PRIORITY=100
+# CONFIG_TASH_SCRIPT is not set
+
+#
+# System Libraries and Add-Ons
+#
+# CONFIG_SYSTEM_CLE is not set
+# CONFIG_SYSTEM_CUTERM is not set
+# CONFIG_SYSTEM_FLASH_ERASEALL is not set
+# CONFIG_SYSTEM_FOTA_HAL is not set
+# CONFIG_SYSTEM_I2CTOOL is not set
+# CONFIG_SYSTEM_INIFILE is not set
+CONFIG_SYSTEM_PREAPP_INIT=y
+CONFIG_SYSTEM_PREAPP_STACKSIZE=2048
+# CONFIG_SYSTEM_INSTALL is not set
+CONFIG_SYSTEM_IPERF=y
+# CONFIG_SYSTEM_NETDB is not set
+CONFIG_SYSTEM_RAMTEST=y
+CONFIG_SYSTEM_RAMTEST_PRIORITY=100
+CONFIG_SYSTEM_RAMTEST_STACKSIZE=1024
+CONFIG_SYSTEM_READLINE=y
+CONFIG_READLINE_ECHO=y
+CONFIG_SYSTEM_INFORMATION=y
+CONFIG_KERNEL_CMDS=y
+CONFIG_FS_CMDS=y
+CONFIG_FSCMD_BUFFER_LEN=64
+CONFIG_NET_CMDS=y
+CONFIG_NET_PING_CMD=y
+CONFIG_NET_PING_CMD_ICOUNT=5
+CONFIG_ENABLE_DATE_CMD=y
+CONFIG_ENABLE_ENV_GET_CMD=y
+CONFIG_ENABLE_ENV_SET_CMD=y
+CONFIG_ENABLE_ENV_UNSET_CMD=y
+CONFIG_ENABLE_FREE_CMD=y
+CONFIG_ENABLE_HEAPINFO_CMD=y
+# CONFIG_HEAPINFO_USER_GROUP is not set
+# CONFIG_ENABLE_IRQINFO_CMD is not set
+CONFIG_ENABLE_KILL_CMD=y
+CONFIG_ENABLE_KILLALL_CMD=y
+CONFIG_ENABLE_PS_CMD=y
+CONFIG_ENABLE_STACKMONITOR_CMD=y
+CONFIG_STACKMONITOR_PRIORITY=100
+CONFIG_STACKMONITOR_INTERVAL=5
+CONFIG_ENABLE_UPTIME_CMD=y
+# CONFIG_SYSTEM_VI is not set
+
+#
+# Runtime Environment
+#
+CONFIG_ENABLE_IOTJS=y
+CONFIG_IOTJS_PRIORITY=100
+CONFIG_IOTJS_STACKSIZE=32768
+CONFIG_IOTJS_JERRY_HEAP=128
+
+#
+# Device Management
+#
+# CONFIG_DM is not set
+
+#
+# Task manager
+#
+# CONFIG_TASK_MANAGER is not set
+
+#
+# Event Loop Framework
+#
+# CONFIG_EVENTLOOP is not set
+
+#
+# Things Management
+#
+# CONFIG_ST_THINGS is not set
+
+#
+# IoTBus Framework
+#
+CONFIG_IOTBUS=y
+CONFIG_IOTBUS_GPIO=y
+CONFIG_IOTBUS_I2C=y
+CONFIG_IOTBUS_PWM=y
+CONFIG_IOTBUS_SPI=y
+CONFIG_IOTBUS_UART=y
diff --git a/config/tizenrt/artik05x/configs/defconfig b/config/tizenrt/artik05x/configs/defconfig
deleted file mode 100644 (file)
index fa7e477..0000000
+++ /dev/null
@@ -1,1202 +0,0 @@
-#
-# Automatically generated file; DO NOT EDIT.
-# TinyAra Configuration
-#
-
-#
-# Build Setup
-#
-# CONFIG_EXPERIMENTAL is not set
-# CONFIG_DEFAULT_SMALL is not set
-CONFIG_HOST_LINUX=y
-# CONFIG_HOST_OSX is not set
-# CONFIG_HOST_WINDOWS is not set
-# CONFIG_HOST_OTHER is not set
-# CONFIG_WINDOWS_NATIVE is not set
-
-#
-# Build Configuration
-#
-CONFIG_APPS_DIR="../apps"
-CONFIG_FRAMEWORK_DIR="../framework"
-CONFIG_TOOLS_DIR="../tools"
-CONFIG_BUILD_FLAT=y
-# CONFIG_BUILD_PROTECTED is not set
-# CONFIG_BUILD_2PASS is not set
-
-#
-# Binary Output Formats
-#
-# CONFIG_INTELHEX_BINARY is not set
-# CONFIG_MOTOROLA_SREC is not set
-CONFIG_RAW_BINARY=y
-CONFIG_SAMSUNG_NS2=y
-# CONFIG_UBOOT_UIMAGE is not set
-# CONFIG_DOWNLOAD_IMAGE is not set
-# CONFIG_SMARTFS_IMAGE is not set
-
-#
-# Customize Header Files
-#
-# CONFIG_ARCH_STDINT_H is not set
-# CONFIG_ARCH_STDBOOL_H is not set
-# CONFIG_ARCH_MATH_H is not set
-# CONFIG_ARCH_FLOAT_H is not set
-# CONFIG_ARCH_STDARG_H is not set
-
-#
-# Debug Options
-#
-CONFIG_DEBUG=y
-CONFIG_DEBUG_ERROR=y
-# CONFIG_DEBUG_WARN is not set
-CONFIG_DEBUG_VERBOSE=y
-
-#
-# Subsystem Debug Options
-#
-# CONFIG_DEBUG_FS is not set
-# CONFIG_DEBUG_LIB is not set
-# CONFIG_DEBUG_MM is not set
-CONFIG_DEBUG_NET=y
-# CONFIG_DEBUG_NET_ERROR is not set
-# CONFIG_DEBUG_NET_INFO is not set
-# CONFIG_DEBUG_SCHED is not set
-CONFIG_DEBUG_WLAN=y
-
-#
-# SLSI WLAN FW Debug Options
-#
-# CONFIG_SCSC_ENABLE_FWFAULT_LOG is not set
-
-#
-# SLSI WLAN Driver Debug Options
-#
-CONFIG_DEBUG_WLAN_DRIVER_ERROR=y
-# CONFIG_DEBUG_WLAN_DRIVER_DEBUG is not set
-# CONFIG_DEBUG_WLAN_DRIVER_MORE is not set
-# CONFIG_DEBUG_WLAN_DRIVER_VERBOSE is not set
-
-#
-# SLSI WPA Supplicant Debug Options
-#
-CONFIG_DEBUG_WLAN_SUPPLICANT_ERROR=y
-# CONFIG_DEBUG_WLAN_SUPPLICANT_DEBUG is not set
-# CONFIG_DEBUG_WLAN_SUPPLICANT_MORE is not set
-# CONFIG_DEBUG_WLAN_SUPPLICANT_VERBOSE is not set
-
-#
-# SLSI Wi-Fi API Debug Options
-#
-CONFIG_DEBUG_WLAN_API_ERROR=y
-# CONFIG_DEBUG_WLAN_API_DEBUG is not set
-# CONFIG_DEBUG_WLAN_API_VERBOSE is not set
-
-#
-# OS Function Debug Options
-#
-# CONFIG_ARCH_HAVE_HEAPCHECK is not set
-CONFIG_DEBUG_MM_HEAPINFO=y
-# CONFIG_DEBUG_IRQ is not set
-
-#
-# Driver Debug Options
-#
-# CONFIG_DEBUG_PWM is not set
-# CONFIG_DEBUG_RTC is not set
-# CONFIG_DEBUG_SPI is not set
-# CONFIG_DEBUG_WATCHDOG is not set
-# CONFIG_DEBUG_TTRACE is not set
-
-#
-# Stack Debug Options
-#
-CONFIG_ARCH_HAVE_STACKCHECK=y
-CONFIG_STACK_COLORATION=y
-
-#
-# Build Debug Options
-#
-CONFIG_DEBUG_SYMBOLS=y
-# CONFIG_FRAME_POINTER is not set
-CONFIG_ARCH_HAVE_CUSTOMOPT=y
-# CONFIG_DEBUG_NOOPT is not set
-# CONFIG_DEBUG_CUSTOMOPT is not set
-CONFIG_DEBUG_FULLOPT=y
-
-#
-# Chip Selection
-#
-CONFIG_ARCH_ARM=y
-CONFIG_ARCH="arm"
-
-#
-# ARM Options
-#
-CONFIG_ARCH_CHIP_S5J=y
-# CONFIG_ARCH_CORTEXM3 is not set
-# CONFIG_ARCH_CORTEXM4 is not set
-CONFIG_ARCH_CORTEXR4=y
-CONFIG_ARCH_FAMILY="armv7-r"
-CONFIG_ARCH_CHIP="s5j"
-# CONFIG_ARCH_HAVE_FPU is not set
-CONFIG_ARMV7M_MPU=y
-CONFIG_ARMV7M_MPU_NREGIONS=12
-
-#
-# Exception stack options
-#
-CONFIG_ARCH_HAVE_DABORTSTACK=y
-CONFIG_ARCH_DABORTSTACK=0
-
-#
-# ARMv7-R Configuration Options
-#
-CONFIG_ARMV7R_HAVE_GICv2=y
-CONFIG_ARMV7R_MEMINIT=y
-CONFIG_ARMV7R_ICACHE=y
-CONFIG_ARMV7R_DCACHE=y
-# CONFIG_ARMV7R_DCACHE_WRITETHROUGH is not set
-# CONFIG_ARMV7R_HAVE_L2CC is not set
-# CONFIG_ARMV7R_HAVE_L2CC_PL310 is not set
-# CONFIG_ARMV7R_TOOLCHAIN_BUILDROOT is not set
-# CONFIG_ARMV7R_TOOLCHAIN_CODESOURCERYL is not set
-CONFIG_ARMV7R_TOOLCHAIN_GNU_EABIL=y
-# CONFIG_ARMV7R_TOOLCHAIN_GNU_OABI is not set
-# CONFIG_ARMV7R_HAVE_DECODEFIQ is not set
-# CONFIG_BOOT_RESULT is not set
-
-#
-# S5J Configuration Options
-#
-CONFIG_ARCH_CHIP_S5JT200=y
-CONFIG_S5J_S5JT200=y
-
-#
-# S5J Peripheral Support
-#
-CONFIG_S5J_HAVE_ADC=y
-CONFIG_S5J_HAVE_I2C=y
-CONFIG_S5J_HAVE_MCT=y
-CONFIG_S5J_HAVE_PWM0=y
-CONFIG_S5J_HAVE_PWM1=y
-CONFIG_S5J_HAVE_PWM2=y
-CONFIG_S5J_HAVE_PWM3=y
-CONFIG_S5J_HAVE_PWM4=y
-CONFIG_S5J_HAVE_PWM5=y
-CONFIG_S5J_HAVE_PWR=y
-CONFIG_S5J_HAVE_RTC=y
-CONFIG_S5J_HAVE_SFLASH=y
-CONFIG_S5J_HAVE_SPI=y
-CONFIG_S5J_HAVE_SSS=y
-CONFIG_S5J_HAVE_UART0=y
-CONFIG_S5J_HAVE_UART1=y
-CONFIG_S5J_HAVE_UART2=y
-CONFIG_S5J_HAVE_UART3=y
-CONFIG_S5J_HAVE_UART4=y
-CONFIG_S5J_HAVE_WATCHDOG=y
-CONFIG_S5J_ADC=y
-CONFIG_S5J_I2C=y
-# CONFIG_S5J_MCT is not set
-# CONFIG_S5J_TIMER0 is not set
-# CONFIG_S5J_TIMER1 is not set
-# CONFIG_S5J_TIMER2 is not set
-# CONFIG_S5J_TIMER3 is not set
-# CONFIG_S5J_UART_FLOWCONTROL is not set
-CONFIG_S5J_UART0=y
-CONFIG_S5J_UART1=y
-CONFIG_S5J_UART2=y
-# CONFIG_S5J_UART2_FLOWCONTROL is not set
-CONFIG_S5J_UART3=y
-# CONFIG_S5J_UART3_FLOWCONTROL is not set
-CONFIG_S5J_UART4=y
-CONFIG_S5J_PWM=y
-CONFIG_S5J_PWM0=y
-CONFIG_S5J_PWM1=y
-CONFIG_S5J_PWM2=y
-CONFIG_S5J_PWM3=y
-CONFIG_S5J_PWM4=y
-CONFIG_S5J_PWM5=y
-CONFIG_S5J_SSS=y
-CONFIG_S5J_SPI=y
-# CONFIG_S5J_WATCHDOG is not set
-CONFIG_S5J_SFLASH=y
-CONFIG_S5J_PWR=y
-
-#
-# PMU Configuration
-#
-CONFIG_S5J_PWR_DSTOP=y
-# CONFIG_S5J_PWR_SLEEP is not set
-
-#
-# Architecture Options
-#
-# CONFIG_ARCH_NOINTC is not set
-# CONFIG_ARCH_VECNOTIRQ is not set
-# CONFIG_ARCH_DMA is not set
-# CONFIG_ARCH_HAVE_IRQPRIO is not set
-# CONFIG_ARCH_L2CACHE is not set
-# CONFIG_ARCH_HAVE_COHERENT_DCACHE is not set
-# CONFIG_ARCH_HAVE_ADDRENV is not set
-# CONFIG_ARCH_NEED_ADDRENV_MAPPING is not set
-CONFIG_ARCH_HAVE_VFORK=y
-# CONFIG_ARCH_HAVE_MMU is not set
-CONFIG_ARCH_HAVE_MPU=y
-# CONFIG_ARCH_NAND_HWECC is not set
-# CONFIG_ARCH_HAVE_EXTCLK is not set
-# CONFIG_ARCH_HAVE_POWEROFF is not set
-CONFIG_ARCH_HAVE_RESET=y
-CONFIG_ARCH_USE_MPU=y
-CONFIG_ARCH_STACKDUMP=y
-# CONFIG_ENDIAN_BIG is not set
-# CONFIG_ARCH_IDLE_CUSTOM is not set
-CONFIG_ARCH_CUSTOM_PMINIT=y
-# CONFIG_ARCH_HAVE_RAMFUNCS is not set
-# CONFIG_ARCH_HAVE_RAMVECTORS is not set
-
-#
-# Board Settings
-#
-CONFIG_BOARD_LOOPSPERMSEC=29100
-# CONFIG_ARCH_CALIBRATION is not set
-
-#
-# Interrupt options
-#
-CONFIG_ARCH_HAVE_INTERRUPTSTACK=y
-CONFIG_ARCH_INTERRUPTSTACK=0
-# CONFIG_ARCH_HAVE_HIPRI_INTERRUPT is not set
-
-#
-# Boot options
-#
-# CONFIG_BOOT_RUNFROMEXTSRAM is not set
-CONFIG_BOOT_RUNFROMFLASH=y
-# CONFIG_BOOT_RUNFROMISRAM is not set
-# CONFIG_BOOT_RUNFROMSDRAM is not set
-# CONFIG_BOOT_COPYTORAM is not set
-
-#
-# Boot Memory Configuration
-#
-CONFIG_RAM_START=0x02023800
-CONFIG_RAM_SIZE=804864
-# CONFIG_ARCH_HAVE_SDRAM is not set
-
-#
-# Board Selection
-#
-CONFIG_ARCH_BOARD_ARTIK053=y
-# CONFIG_ARCH_BOARD_SIDK_S5JT200 is not set
-CONFIG_ARCH_BOARD="artik053"
-
-#
-# Common Board Options
-#
-# CONFIG_BOARD_CRASHDUMP is not set
-CONFIG_LIB_BOARDCTL=y
-CONFIG_BOARDCTL_RESET=y
-# CONFIG_BOARDCTL_UNIQUEID is not set
-# CONFIG_BOARD_COREDUMP_FLASH is not set
-# CONFIG_BOARD_FOTA_SUPPORT is not set
-# CONFIG_BOARD_RAMDUMP_FLASH is not set
-# CONFIG_BOARD_RAMDUMP_UART is not set
-
-#
-# Board-Specific Options
-#
-CONFIG_ARTIK053_BOOT_FAILURE_DETECTION=y
-CONFIG_ARTIK053_BOOT_COUNTS_ADDR=0x80090810
-CONFIG_ARTIK053_FLASH_CAPACITY=8388608
-CONFIG_ARTIK053_FLASH_PAGE_SIZE=4096
-CONFIG_ARTIK053_FLASH_PART=y
-CONFIG_ARTIK053_FLASH_MINOR=0
-CONFIG_ARTIK053_FLASH_PART_LIST="16,48,192,32,512,2400,1536,1536,1000,400,8,512,"
-CONFIG_ARTIK053_FLASH_PART_TYPE="none,ftl,none,none,none,none,none,ftl,smartfs,romfs,config,none,"
-CONFIG_ARTIK053_FLASH_PART_NAME="bl1,sssro,bl2,sssfw,wlanfw,os,factory,ota,user,rom,nvram,sssrw,"
-CONFIG_ARTIK053_AUTOMOUNT=y
-CONFIG_ARTIK053_AUTOMOUNT_USERFS=y
-CONFIG_ARTIK053_AUTOMOUNT_USERFS_DEVNAME="/dev/smart0p8"
-CONFIG_ARTIK053_AUTOMOUNT_USERFS_MOUNTPOINT="/mnt"
-
-#
-# RTOS Features
-#
-CONFIG_DISABLE_OS_API=y
-# CONFIG_DISABLE_POSIX_TIMERS is not set
-# CONFIG_DISABLE_PTHREAD is not set
-# CONFIG_DISABLE_SIGNALS is not set
-# CONFIG_DISABLE_MQUEUE is not set
-# CONFIG_DISABLE_ENVIRON is not set
-
-#
-# Clocks and Timers
-#
-CONFIG_ARCH_HAVE_TICKLESS=y
-# CONFIG_SCHED_TICKLESS is not set
-CONFIG_USEC_PER_TICK=9979
-CONFIG_SYSTEM_TIME64=y
-CONFIG_CLOCK_MONOTONIC=y
-# CONFIG_JULIAN_TIME is not set
-CONFIG_MAX_WDOGPARMS=4
-CONFIG_PREALLOC_WDOGS=32
-CONFIG_WDOG_INTRESERVE=4
-CONFIG_PREALLOC_TIMERS=8
-
-#
-# Tasks and Scheduling
-#
-CONFIG_INIT_ENTRYPOINT=y
-CONFIG_RR_INTERVAL=100
-CONFIG_TASK_NAME_SIZE=31
-CONFIG_MAX_TASKS=32
-CONFIG_SCHED_HAVE_PARENT=y
-# CONFIG_SCHED_CHILD_STATUS is not set
-CONFIG_SCHED_WAITPID=y
-
-#
-# Pthread Options
-#
-CONFIG_PTHREAD_MUTEX_TYPES=y
-# CONFIG_PTHREAD_MUTEX_ROBUST is not set
-CONFIG_PTHREAD_MUTEX_UNSAFE=y
-# CONFIG_PTHREAD_MUTEX_BOTH is not set
-CONFIG_NPTHREAD_KEYS=4
-# CONFIG_PTHREAD_CLEANUP is not set
-# CONFIG_CANCELLATION_POINTS is not set
-
-#
-# Performance Monitoring
-#
-# CONFIG_SCHED_CPULOAD is not set
-# CONFIG_SCHED_INSTRUMENTATION is not set
-
-#
-# Latency optimization
-#
-# CONFIG_SCHED_YIELD_OPTIMIZATION is not set
-
-#
-# Files and I/O
-#
-CONFIG_DEV_CONSOLE=y
-# CONFIG_FDCLONE_DISABLE is not set
-# CONFIG_FDCLONE_STDIO is not set
-# CONFIG_SDCLONE_DISABLE is not set
-CONFIG_NFILE_DESCRIPTORS=16
-CONFIG_NFILE_STREAMS=16
-CONFIG_NAME_MAX=32
-CONFIG_PRIORITY_INHERITANCE=y
-CONFIG_SEM_PREALLOCHOLDERS=16
-CONFIG_SEM_NNESTPRIO=16
-
-#
-# RTOS hooks
-#
-CONFIG_BOARD_INITIALIZE=y
-# CONFIG_BOARD_INITTHREAD is not set
-# CONFIG_SCHED_STARTHOOK is not set
-CONFIG_SCHED_ATEXIT=y
-CONFIG_SCHED_ONEXIT=y
-CONFIG_SCHED_ONEXIT_MAX=1
-
-#
-# Signal Numbers
-#
-CONFIG_SIG_SIGUSR1=1
-CONFIG_SIG_SIGUSR2=2
-CONFIG_SIG_SIGALARM=3
-CONFIG_SIG_SIGCHLD=4
-CONFIG_SIG_SIGCONDTIMEDOUT=16
-CONFIG_SIG_SIGWORK=17
-
-#
-# POSIX Message Queue Options
-#
-CONFIG_PREALLOC_MQ_MSGS=4
-CONFIG_MQ_MAXMSGSIZE=600
-
-#
-# Work Queue Support
-#
-CONFIG_SCHED_WORKQUEUE=y
-CONFIG_SCHED_WORKQUEUE_SORTING=y
-CONFIG_SCHED_HPWORK=y
-CONFIG_SCHED_HPWORKPRIORITY=224
-CONFIG_SCHED_HPWORKPERIOD=50000
-CONFIG_SCHED_HPWORKSTACKSIZE=2048
-CONFIG_SCHED_LPWORK=y
-CONFIG_SCHED_LPNTHREADS=1
-CONFIG_SCHED_LPWORKPRIORITY=176
-CONFIG_SCHED_LPWORKPRIOMAX=176
-CONFIG_SCHED_LPWORKPERIOD=50000
-CONFIG_SCHED_LPWORKSTACKSIZE=2048
-
-#
-# Stack size information
-#
-CONFIG_IDLETHREAD_STACKSIZE=1024
-CONFIG_USERMAIN_STACKSIZE=2048
-# CONFIG_MPU_STACKGAURD is not set
-CONFIG_PTHREAD_STACK_MIN=256
-CONFIG_PTHREAD_STACK_DEFAULT=2048
-
-#
-# System Call
-#
-# CONFIG_LIB_SYSCALL is not set
-
-#
-# Device Drivers
-#
-# CONFIG_DISABLE_POLL is not set
-CONFIG_DEV_NULL=y
-CONFIG_DEV_ZERO=y
-
-#
-# Buffering
-#
-# CONFIG_DRVR_WRITEBUFFER is not set
-# CONFIG_DRVR_READAHEAD is not set
-# CONFIG_CAN is not set
-# CONFIG_ARCH_HAVE_PWM_PULSECOUNT is not set
-# CONFIG_ARCH_HAVE_PWM_MULTICHAN is not set
-CONFIG_PWM=y
-# CONFIG_ARCH_HAVE_I2CRESET is not set
-CONFIG_I2C=y
-CONFIG_I2C_SLAVE=y
-CONFIG_I2C_USERIO=y
-CONFIG_I2C_TRANSFER=y
-CONFIG_I2C_POLLED=y
-# CONFIG_I2C_TRACE is not set
-# CONFIG_I2C_WRITEREAD is not set
-CONFIG_SPI=y
-# CONFIG_SPI_OWNBUS is not set
-CONFIG_SPI_EXCHANGE=y
-# CONFIG_SPI_CMDDATA is not set
-# CONFIG_SPI_BITBANG is not set
-CONFIG_GPIO=y
-CONFIG_I2S=y
-# CONFIG_BCH is not set
-CONFIG_RTC=y
-CONFIG_RTC_DATETIME=y
-# CONFIG_RTC_ALARM is not set
-CONFIG_RTC_DRIVER=y
-# CONFIG_RTC_IOCTL is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_DEVPATH="/dev/watchdog0"
-# CONFIG_TIMER is not set
-CONFIG_ANALOG=y
-CONFIG_ADC=y
-CONFIG_ADC_FIFOSIZE=8
-# CONFIG_DAC is not set
-# CONFIG_AUDIO_DEVICES is not set
-# CONFIG_LCD is not set
-CONFIG_NETDEVICES=y
-
-#
-# General Ethernet MAC Driver Options
-#
-CONFIG_NETDEV_TELNET=y
-CONFIG_NETDEV_MULTINIC=y
-# CONFIG_NET_DUMPPACKET is not set
-
-#
-# External Ethernet MAC Device Support
-#
-# CONFIG_NET_DM90x0 is not set
-# CONFIG_ENC28J60 is not set
-# CONFIG_ENCX24J600 is not set
-# CONFIG_NET_E1000 is not set
-# CONFIG_NET_SLIP is not set
-# CONFIG_NET_VNET is not set
-# CONFIG_PIPES is not set
-CONFIG_POWER=y
-# CONFIG_BATTERY_CHARGER is not set
-# CONFIG_BATTERY_GAUGE is not set
-# CONFIG_SERCOMM_CONSOLE is not set
-CONFIG_SERIAL=y
-# CONFIG_DEV_LOWCONSOLE is not set
-# CONFIG_16550_UART is not set
-# CONFIG_ARCH_HAVE_UART is not set
-CONFIG_ARCH_HAVE_UART0=y
-CONFIG_ARCH_HAVE_UART1=y
-CONFIG_ARCH_HAVE_UART2=y
-CONFIG_ARCH_HAVE_UART3=y
-CONFIG_ARCH_HAVE_UART4=y
-# CONFIG_ARCH_HAVE_UART5 is not set
-# CONFIG_ARCH_HAVE_UART6 is not set
-# CONFIG_ARCH_HAVE_UART7 is not set
-# CONFIG_ARCH_HAVE_UART8 is not set
-# CONFIG_ARCH_HAVE_SCI0 is not set
-# CONFIG_ARCH_HAVE_SCI1 is not set
-# CONFIG_ARCH_HAVE_USART0 is not set
-# CONFIG_ARCH_HAVE_USART1 is not set
-# CONFIG_ARCH_HAVE_USART2 is not set
-# CONFIG_ARCH_HAVE_USART3 is not set
-# CONFIG_ARCH_HAVE_USART4 is not set
-# CONFIG_ARCH_HAVE_USART5 is not set
-# CONFIG_ARCH_HAVE_USART6 is not set
-# CONFIG_ARCH_HAVE_USART7 is not set
-# CONFIG_ARCH_HAVE_USART8 is not set
-# CONFIG_ARCH_HAVE_OTHER_UART is not set
-
-#
-# USART Configuration
-#
-CONFIG_MCU_SERIAL=y
-CONFIG_STANDARD_SERIAL=y
-CONFIG_SERIAL_NPOLLWAITERS=2
-# CONFIG_SERIAL_IFLOWCONTROL is not set
-# CONFIG_SERIAL_OFLOWCONTROL is not set
-# CONFIG_SERIAL_TIOCSERGSTRUCT is not set
-CONFIG_ARCH_HAVE_SERIAL_TERMIOS=y
-CONFIG_SERIAL_TERMIOS=y
-# CONFIG_UART0_SERIAL_CONSOLE is not set
-# CONFIG_UART1_SERIAL_CONSOLE is not set
-# CONFIG_UART2_SERIAL_CONSOLE is not set
-# CONFIG_UART3_SERIAL_CONSOLE is not set
-CONFIG_UART4_SERIAL_CONSOLE=y
-# CONFIG_OTHER_SERIAL_CONSOLE is not set
-# CONFIG_NO_SERIAL_CONSOLE is not set
-
-#
-# UART0 Configuration
-#
-CONFIG_UART0_RXBUFSIZE=64
-CONFIG_UART0_TXBUFSIZE=64
-CONFIG_UART0_BAUD=115200
-CONFIG_UART0_BITS=8
-CONFIG_UART0_PARITY=0
-CONFIG_UART0_2STOP=0
-# CONFIG_UART0_IFLOWCONTROL is not set
-# CONFIG_UART0_OFLOWCONTROL is not set
-
-#
-# UART1 Configuration
-#
-CONFIG_UART1_RXBUFSIZE=256
-CONFIG_UART1_TXBUFSIZE=256
-CONFIG_UART1_BAUD=115200
-CONFIG_UART1_BITS=8
-CONFIG_UART1_PARITY=0
-CONFIG_UART1_2STOP=0
-# CONFIG_UART1_IFLOWCONTROL is not set
-# CONFIG_UART1_OFLOWCONTROL is not set
-
-#
-# UART2 Configuration
-#
-CONFIG_UART2_RXBUFSIZE=256
-CONFIG_UART2_TXBUFSIZE=256
-CONFIG_UART2_BAUD=115200
-CONFIG_UART2_BITS=8
-CONFIG_UART2_PARITY=0
-CONFIG_UART2_2STOP=0
-# CONFIG_UART2_IFLOWCONTROL is not set
-# CONFIG_UART2_OFLOWCONTROL is not set
-
-#
-# UART3 Configuration
-#
-CONFIG_UART3_RXBUFSIZE=256
-CONFIG_UART3_TXBUFSIZE=256
-CONFIG_UART3_BAUD=115200
-CONFIG_UART3_BITS=8
-CONFIG_UART3_PARITY=0
-CONFIG_UART3_2STOP=0
-# CONFIG_UART3_IFLOWCONTROL is not set
-# CONFIG_UART3_OFLOWCONTROL is not set
-
-#
-# UART4 Configuration
-#
-CONFIG_UART4_RXBUFSIZE=256
-CONFIG_UART4_TXBUFSIZE=256
-CONFIG_UART4_BAUD=115200
-CONFIG_UART4_BITS=8
-CONFIG_UART4_PARITY=0
-CONFIG_UART4_2STOP=0
-# CONFIG_UART4_IFLOWCONTROL is not set
-# CONFIG_UART4_OFLOWCONTROL is not set
-# CONFIG_USBDEV is not set
-# CONFIG_FOTA_DRIVER is not set
-
-#
-# System Logging
-#
-# CONFIG_RAMLOG is not set
-# CONFIG_SYSLOG_CONSOLE is not set
-
-#
-# T-trace
-#
-# CONFIG_TTRACE is not set
-
-#
-# Wireless Device Options
-#
-CONFIG_DRIVERS_WIRELESS=y
-CONFIG_SCSC_WLAN=y
-# CONFIG_SLSI_RX_PERFORMANCE_TEST is not set
-CONFIG_SCSC_TX_FLOW_CONTROL=y
-CONFIG_SCSC_ENABLE_PORT_CONTROL=y
-# CONFIG_SCSC_WLAN_STA_ONLY is not set
-# CONFIG_SCSC_WLAN_BLOCK_IPV6 is not set
-# CONFIG_SCSC_WLAN_UDP_FLOWCONTROL is not set
-# CONFIG_SCSC_WLAN_AUTO_RECOVERY is not set
-CONFIG_SCSC_WLAN_POWER_SAVE=y
-CONFIG_SCSC_WLAN_MAX_INTERFACES=1
-CONFIG_SCSC_CORE=y
-CONFIG_SCSC_PLATFORM=y
-# CONFIG_SCSC_WLANLITE is not set
-# CONFIG_SCSC_DISABLE_WLAN_RESET is not set
-
-#
-# Networking Support
-#
-CONFIG_ARCH_HAVE_NET=y
-# CONFIG_ARCH_HAVE_PHY is not set
-CONFIG_NET=y
-CONFIG_NET_LWIP=y
-
-#
-# LwIP options
-#
-CONFIG_NET_IPv4=y
-CONFIG_NET_IP_DEFAULT_TTL=255
-# CONFIG_NET_IP_FORWARD is not set
-CONFIG_NET_IP_OPTIONS_ALLOWED=y
-CONFIG_NET_IP_FRAG=y
-CONFIG_NET_IP_REASSEMBLY=y
-CONFIG_NET_IPV4_REASS_MAX_PBUFS=20
-CONFIG_NET_IPV4_REASS_MAXAGE=5
-
-#
-# Socket support
-#
-CONFIG_NET_SOCKET=y
-CONFIG_NSOCKET_DESCRIPTORS=8
-CONFIG_NET_TCP_KEEPALIVE=y
-CONFIG_NET_RAW=y
-# CONFIG_NET_SOCKET_OPTION_BROADCAST is not set
-# CONFIG_NET_RANDOMIZE_INITIAL_LOCAL_PORTS is not set
-# CONFIG_NET_SO_SNDTIMEO is not set
-CONFIG_NET_SO_RCVTIMEO=y
-# CONFIG_NET_SO_RCVBUF is not set
-CONFIG_NET_SO_REUSE=y
-# CONFIG_NET_SO_REUSE_RXTOALL is not set
-CONFIG_NET_ARP=y
-CONFIG_NET_ARP_TABLESIZE=10
-CONFIG_NET_ARP_QUEUEING=y
-CONFIG_NET_ETHARP_TRUST_IP_MAC=y
-CONFIG_NET_ETH_PAD_SIZE=0
-# CONFIG_NET_ARP_STATIC_ENTRIES is not set
-CONFIG_NET_UDP=y
-# CONFIG_NET_NETBUF_RECVINFO is not set
-CONFIG_NET_UDP_TTL=255
-# CONFIG_NET_UDPLITE is not set
-CONFIG_NET_TCP=y
-CONFIG_NET_TCP_TTL=255
-CONFIG_NET_TCP_WND=58400
-CONFIG_NET_TCP_MAXRTX=12
-CONFIG_NET_TCP_SYNMAXRTX=6
-CONFIG_NET_TCP_QUEUE_OOSEQ=y
-CONFIG_NET_TCP_MSS=1460
-CONFIG_NET_TCP_CALCULATE_EFF_SEND_MSS=y
-CONFIG_NET_TCP_SND_BUF=29200
-CONFIG_NET_TCP_SND_QUEUELEN=80
-# CONFIG_NET_TCP_LISTEN_BACKLOG is not set
-CONFIG_NET_TCP_OVERSIZE=536
-# CONFIG_NET_TCP_TIMESTAMPS is not set
-CONFIG_NET_TCP_WND_UPDATE_THREASHOLD=536
-CONFIG_NET_ICMP=y
-CONFIG_NET_ICMP_TTL=255
-# CONFIG_NET_BROADCAST_PING is not set
-# CONFIG_NET_MULTICAST_PING is not set
-CONFIG_NET_LWIP_IGMP=y
-CONFIG_NET_LWIP_MEMP_NUM_IGMP_GROUP=8
-
-#
-# LWIP Mailbox Configurations
-#
-CONFIG_NET_TCPIP_MBOX_SIZE=64
-CONFIG_NET_DEFAULT_ACCEPTMBOX_SIZE=64
-CONFIG_NET_DEFAULT_RAW_RECVMBOX_SIZE=64
-CONFIG_NET_DEFAULT_TCP_RECVMBOX_SIZE=54
-CONFIG_NET_DEFAULT_UDP_RECVMBOX_SIZE=64
-
-#
-# Memory Configurations
-#
-CONFIG_NET_MEM_ALIGNMENT=4
-# CONFIG_NET_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is not set
-# CONFIG_NET_MEM_LIBC_MALLOC is not set
-CONFIG_NET_MEMP_MEM_MALLOC=y
-# CONFIG_NET_MEM_USE_POOLS is not set
-CONFIG_NET_MEM_SIZE=153600
-
-#
-# LWIP Task Configurations
-#
-# CONFIG_NET_TCPIP_CORE_LOCKING is not set
-# CONFIG_NET_TCPIP_CORE_LOCKING_INPUT is not set
-CONFIG_NET_TCPIP_THREAD_NAME="LWIP_TCP/IP"
-CONFIG_NET_TCPIP_THREAD_PRIO=110
-CONFIG_NET_TCPIP_THREAD_STACKSIZE=4096
-CONFIG_NET_COMPAT_MUTEX=y
-CONFIG_NET_SYS_LIGHTWEIGHT_PROT=y
-CONFIG_NET_DEFAULT_THREAD_NAME="lwIP"
-CONFIG_NET_DEFAULT_THREAD_PRIO=1
-CONFIG_NET_DEFAULT_THREAD_STACKSIZE=0
-
-#
-# Debug Options for Network
-#
-# CONFIG_NET_LWIP_DEBUG is not set
-
-#
-# Enable Statistics
-#
-CONFIG_NET_STATS=y
-CONFIG_NET_STATS_DISPLAY=y
-CONFIG_NET_LINK_STATS=y
-CONFIG_NET_ETHARP_STATS=y
-CONFIG_NET_IP_STATS=y
-# CONFIG_NET_IPFRAG_STATS is not set
-# CONFIG_NET_ICMP_STATS is not set
-CONFIG_NET_UDP_STATS=y
-CONFIG_NET_TCP_STATS=y
-CONFIG_NET_MEM_STATS=y
-CONFIG_NET_SYS_STATS=y
-# CONFIG_NET_LWIP_VLAN is not set
-CONFIG_NET_LWIP_LOOPBACK_INTERFACE=y
-# CONFIG_NET_LWIP_SLIP_INTERFACE is not set
-# CONFIG_NET_LWIP_PPP_SUPPORT is not set
-# CONFIG_NET_LWIP_SNMP is not set
-CONFIG_NET_SECURITY_TLS=y
-# CONFIG_TLS_WITH_SSS is not set
-
-#
-# Driver buffer configuration
-#
-CONFIG_NET_MULTIBUFFER=y
-CONFIG_NET_ETH_MTU=1500
-CONFIG_NET_GUARDSIZE=2
-
-#
-# Data link support
-#
-# CONFIG_NET_MULTILINK is not set
-CONFIG_NET_ETHERNET=y
-
-#
-# Network Device Operations
-#
-# CONFIG_NETDEV_PHY_IOCTL is not set
-
-#
-# Routing Table Configuration
-#
-# CONFIG_NET_ROUTE is not set
-
-#
-# File Systems
-#
-
-#
-# File system configuration
-#
-# CONFIG_DISABLE_MOUNTPOINT is not set
-# CONFIG_FS_AUTOMOUNTER is not set
-# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set
-CONFIG_FS_READABLE=y
-CONFIG_FS_WRITABLE=y
-# CONFIG_FS_AIO is not set
-# CONFIG_FS_NAMED_SEMAPHORES is not set
-CONFIG_FS_MQUEUE_MPATH="/var/mqueue"
-CONFIG_FS_SMARTFS=y
-
-#
-# SMARTFS options
-#
-CONFIG_SMARTFS_ERASEDSTATE=0xff
-CONFIG_SMARTFS_MAXNAMLEN=32
-# CONFIG_SMARTFS_MULTI_ROOT_DIRS is not set
-CONFIG_SMARTFS_ALIGNED_ACCESS=y
-# CONFIG_SMARTFS_BAD_SECTOR is not set
-# CONFIG_SMARTFS_DYNAMIC_HEADER is not set
-# CONFIG_SMARTFS_JOURNALING is not set
-# CONFIG_SMARTFS_SECTOR_RECOVERY is not set
-CONFIG_FS_PROCFS=y
-
-#
-# Exclude individual procfs entries
-#
-# CONFIG_FS_PROCFS_EXCLUDE_PROCESS is not set
-# CONFIG_FS_PROCFS_EXCLUDE_UPTIME is not set
-# CONFIG_FS_PROCFS_EXCLUDE_VERSION is not set
-# CONFIG_FS_PROCFS_EXCLUDE_MTD is not set
-# CONFIG_FS_PROCFS_EXCLUDE_PARTITIONS is not set
-# CONFIG_FS_PROCFS_EXCLUDE_SMARTFS is not set
-# CONFIG_FS_PROCFS_EXCLUDE_POWER is not set
-CONFIG_FS_ROMFS=y
-
-#
-# Block Driver Configurations
-#
-CONFIG_RAMDISK=y
-
-#
-# MTD Configuration
-#
-CONFIG_MTD=y
-CONFIG_MTD_PARTITION=y
-CONFIG_MTD_PARTITION_NAMES=y
-CONFIG_MTD_PROGMEM=y
-CONFIG_MTD_FTL=y
-
-#
-# MTD_FTL Configurations
-#
-CONFIG_MTD_CONFIG=y
-
-#
-# MTD Configurations
-#
-# CONFIG_MTD_CONFIG_RAM_CONSOLIDATE is not set
-CONFIG_MTD_CONFIG_ERASEDVALUE=0xff
-# CONFIG_MTD_BYTE_WRITE is not set
-
-#
-# MTD Device Drivers
-#
-# CONFIG_MTD_M25P is not set
-# CONFIG_RAMMTD is not set
-CONFIG_MTD_SMART=y
-
-#
-# SMART Device options
-#
-CONFIG_MTD_SMART_SECTOR_SIZE=4096
-# CONFIG_MTD_SMART_WEAR_LEVEL is not set
-# CONFIG_MTD_SMART_ENABLE_CRC is not set
-# CONFIG_MTD_SMART_SECTOR_ERASE_DEBUG is not set
-# CONFIG_MTD_SMART_ALLOC_DEBUG is not set
-
-#
-# System Logging
-#
-# CONFIG_SYSLOG is not set
-# CONFIG_SYSLOG_TIMESTAMP is not set
-
-#
-# Arastorage
-#
-
-#
-# AraStorage database configuration
-#
-# CONFIG_ARASTORAGE is not set
-
-#
-# Memory Management
-#
-# CONFIG_DISABLE_REALLOC_NEIGHBOR_EXTENTION is not set
-# CONFIG_MM_SMALL is not set
-CONFIG_MM_REGIONS=1
-# CONFIG_ARCH_HAVE_HEAP2 is not set
-# CONFIG_GRAN is not set
-
-#
-# Power Management
-#
-CONFIG_PM=y
-# CONFIG_DEBUG_PM is not set
-# CONFIG_PM_TEST is not set
-CONFIG_PM_DEVNAME_LEN=32
-# CONFIG_PM_METRICS is not set
-CONFIG_PM_SLICEMS=100
-CONFIG_PM_NDOMAINS=1
-CONFIG_PM_MEMORY=2
-CONFIG_PM_COEFN=1
-CONFIG_PM_COEF1=1
-CONFIG_PM_COEF2=1
-CONFIG_PM_COEF3=1
-CONFIG_PM_COEF4=1
-CONFIG_PM_COEF5=1
-CONFIG_PM_IDLEENTER_THRESH=1
-CONFIG_PM_IDLEEXIT_THRESH=2
-CONFIG_PM_IDLEENTER_COUNT=30
-CONFIG_PM_STANDBYENTER_THRESH=1
-CONFIG_PM_STANDBYEXIT_THRESH=2
-CONFIG_PM_STANDBYENTER_COUNT=50
-CONFIG_PM_SLEEPENTER_THRESH=1
-CONFIG_PM_SLEEPEXIT_THRESH=2
-CONFIG_PM_SLEEPENTER_COUNT=70
-
-#
-# Logger Module
-#
-CONFIG_LOGM=y
-# CONFIG_PRINTF2LOGM is not set
-CONFIG_SYSLOG2LOGM=y
-# CONFIG_LOGM_TIMESTAMP is not set
-CONFIG_LOGM_BUFFER_SIZE=10240
-CONFIG_LOGM_PRINT_INTERVAL=1000
-CONFIG_LOGM_TASK_PRIORITY=110
-CONFIG_LOGM_TASK_STACKSIZE=2048
-# CONFIG_LOGM_TEST is not set
-
-#
-# Library Routines
-#
-
-#
-# Standard C Library Options
-#
-CONFIG_STDIO_BUFFER_SIZE=64
-CONFIG_STDIO_LINEBUFFER=y
-CONFIG_NUNGET_CHARS=2
-CONFIG_LIB_HOMEDIR="/"
-CONFIG_LIBM=y
-# CONFIG_NOPRINTF_FIELDWIDTH is not set
-CONFIG_LIBC_FLOATINGPOINT=y
-CONFIG_LIBC_IOCTL_VARIADIC=y
-CONFIG_LIB_RAND_ORDER=1
-# CONFIG_EOL_IS_CR is not set
-# CONFIG_EOL_IS_LF is not set
-# CONFIG_EOL_IS_BOTH_CRLF is not set
-CONFIG_EOL_IS_EITHER_CRLF=y
-CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=1024
-CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048
-CONFIG_LIBC_STRERROR=y
-# CONFIG_LIBC_STRERROR_SHORT is not set
-# CONFIG_LIBC_PERROR_STDOUT is not set
-CONFIG_LIBC_TMPDIR="/tmp"
-CONFIG_LIBC_MAX_TMPFILE=32
-CONFIG_ARCH_LOWPUTC=y
-# CONFIG_LIBC_LOCALTIME is not set
-# CONFIG_TIME_EXTENDED is not set
-CONFIG_LIB_SENDFILE_BUFSIZE=512
-# CONFIG_ARCH_ROMGETC is not set
-CONFIG_ARCH_OPTIMIZED_FUNCTIONS=y
-# CONFIG_ARCH_MEMCPY is not set
-CONFIG_MEMCPY_VIK=y
-# CONFIG_MEMCPY_PRE_INC_PTRS is not set
-CONFIG_MEMCPY_INDEXED_COPY=y
-# CONFIG_MEMCPY_64BIT is not set
-# CONFIG_ARCH_MEMCMP is not set
-# CONFIG_ARCH_MEMMOVE is not set
-# CONFIG_ARCH_MEMSET is not set
-# CONFIG_MEMSET_OPTSPEED is not set
-# CONFIG_ARCH_STRCHR is not set
-# CONFIG_ARCH_STRCMP is not set
-# CONFIG_ARCH_STRCPY is not set
-# CONFIG_ARCH_STRNCPY is not set
-# CONFIG_ARCH_STRLEN is not set
-# CONFIG_ARCH_STRNLEN is not set
-# CONFIG_ARCH_BZERO is not set
-CONFIG_LIBC_NETDB=y
-# CONFIG_NETDB_HOSTFILE is not set
-CONFIG_NETDB_DNSCLIENT=y
-CONFIG_NETDB_DNSCLIENT_ENTRIES=8
-CONFIG_NETDB_DNSCLIENT_NAMESIZE=32
-CONFIG_NETDB_DNSCLIENT_LIFESEC=3600
-CONFIG_NETDB_DNSCLIENT_MAXRESPONSE=512
-# CONFIG_NETDB_RESOLVCONF is not set
-CONFIG_NETDB_DNSSERVER_BY_DHCP=y
-# CONFIG_NETDB_DNSSERVER_IPv4 is not set
-
-#
-# Non-standard Library Support
-#
-
-#
-# Basic CXX Support
-#
-# CONFIG_C99_BOOL8 is not set
-# CONFIG_HAVE_CXX is not set
-
-#
-# External Functions
-#
-CONFIG_DM=y
-# CONFIG_LWM2M_WAKAAMA is not set
-CONFIG_DM_WIFI=y
-CONFIG_DM_AP_SSID="TizenRT1"
-CONFIG_DM_AP_PASS="tizenrt_tdc2017"
-CONFIG_DM_AP_SECURITY="wpa2_aes"
-
-#
-# IOTIVITY Config Parameters
-#
-# CONFIG_ENABLE_IOTIVITY is not set
-# CONFIG_LIBTUV is not set
-# CONFIG_AWS_SDK is not set
-
-#
-# Application Configuration
-#
-# CONFIG_ENTRY_MANUAL is not set
-
-#
-# Application entry point list
-#
-# CONFIG_ENTRY_HELLO is not set
-# CONFIG_ENTRY_IPERF is not set
-# CONFIG_ENTRY_WIFI_TEST is not set
-CONFIG_ENTRY_IOTJS=y
-CONFIG_USER_ENTRYPOINT="iotjs_main"
-CONFIG_BUILTIN_APPS=y
-
-#
-# Examples
-#
-# CONFIG_EXAMPLES_ARTIK_DEMO is not set
-# CONFIG_EXAMPLES_AWS is not set
-# CONFIG_EXAMPLES_DNSCLIENT_TEST is not set
-# CONFIG_EXAMPLES_DTLS_CLIENT is not set
-# CONFIG_EXAMPLES_DTLS_SERVER is not set
-# CONFIG_EXAMPLES_EEPROM_TEST is not set
-# CONFIG_EXAMPLES_FOTA_SAMPLE is not set
-CONFIG_EXAMPLES_HELLO=y
-# CONFIG_EXAMPLES_HELLO_TASH is not set
-# CONFIG_EXAMPLES_HELLOXX is not set
-# CONFIG_EXAMPLES_IOTBUS_TEST is not set
-CONFIG_EXAMPLES_IPERF=y
-# CONFIG_EXAMPLES_KERNEL_SAMPLE is not set
-# CONFIG_EXAMPLES_LIBTUV is not set
-# CONFIG_EXAMPLES_MTDPART is not set
-# CONFIG_EXAMPLES_NETTEST is not set
-# CONFIG_EXAMPLES_PROC_TEST is not set
-# CONFIG_EXAMPLES_SELECT_TEST is not set
-# CONFIG_EXAMPLES_SENSORBOARD is not set
-CONFIG_EXAMPLES_SLSIWIFI=y
-CONFIG_EXAMPLES_SLSIWIFI_PRIORITY=50
-CONFIG_EXAMPLES_SLSIWIFI_STACKSIZE=2048
-# CONFIG_EXAMPLES_SMART is not set
-# CONFIG_EXAMPLES_SMART_TEST is not set
-# CONFIG_EXAMPLES_SYSIO_TEST is not set
-# CONFIG_EXAMPLES_TESTCASE is not set
-# CONFIG_EXAMPLES_TLS_CLIENT is not set
-# CONFIG_EXAMPLES_TLS_SELFTEST is not set
-# CONFIG_EXAMPLES_TLS_SERVER is not set
-# CONFIG_EXAMPLES_WAKAAMA_CLIENT is not set
-CONFIG_EXAMPLES_WIFI_TEST=y
-# CONFIG_EXAMPLES_WORKQUEUE is not set
-
-#
-# Network Utilities
-#
-# CONFIG_NETUTILS_CODECS is not set
-CONFIG_NETUTILS_DHCPC=y
-CONFIG_NETUTILS_DHCPD=y
-CONFIG_NETUTILS_DHCPD_IGNOREBROADCAST=y
-CONFIG_NETUTILS_DHCPD_INTERFACE="wl1"
-CONFIG_NETUTILS_DHCPD_LEASETIME=864000
-CONFIG_NETUTILS_DHCPD_MINLEASETIME=86400
-CONFIG_NETUTILS_DHCPD_MAXLEASETIME=2592000
-CONFIG_NETUTILS_DHCPD_MAXLEASES=6
-CONFIG_NETUTILS_DHCPD_STARTIP=0xc0a82f02
-CONFIG_NETUTILS_DHCPD_ROUTERIP=0xc0a82f01
-CONFIG_NETUTILS_DHCPD_NETMASK=0xffffff00
-CONFIG_NETUTILS_DHCPD_DNSIP=0x08080808
-CONFIG_NETUTILS_DHCPD_OFFERTIME=3600
-CONFIG_NETUTILS_DHCPD_DECLINETIME=3600
-# CONFIG_NETUTILS_ERCOAP is not set
-# CONFIG_NETUTILS_FTPC is not set
-CONFIG_NETUTILS_FTPD=y
-CONFIG_NETUTILS_JSON=y
-# CONFIG_NETUTILS_MDNS is not set
-# CONFIG_NETUTILS_MQTT is not set
-CONFIG_NETUTILS_NETLIB=y
-# CONFIG_NETUTILS_NTPCLIENT is not set
-# CONFIG_NETUTILS_SMTP is not set
-# CONFIG_NETUTILS_TELNETD is not set
-# CONFIG_NETUTILS_TFTPC is not set
-# CONFIG_NETUTILS_WEBCLIENT is not set
-# CONFIG_NETUTILS_WEBSERVER is not set
-# CONFIG_NETUTILS_WEBSOCKET is not set
-CONFIG_NETUTILS_WIFI=y
-CONFIG_SLSI_WIFI_DEFAULT_WLAN_COUNTRY_CODE="00"
-CONFIG_SLSI_WIFI_DEFAULT_WLAN_TX_POWER=30
-# CONFIG_SLSI_WIFI_FILESYSTEM_SUPPORT is not set
-# CONFIG_NETUTILS_XMLRPC is not set
-
-#
-# Platform-specific Support
-#
-# CONFIG_PLATFORM_CONFIGDATA is not set
-
-#
-# Shell
-#
-CONFIG_TASH=y
-CONFIG_TASH_MAX_COMMANDS=132
-# CONFIG_DEBUG_TASH is not set
-CONFIG_TASH_TELNET_INTERFACE=y
-CONFIG_TASH_CMDTASK_STACKSIZE=4096
-CONFIG_TASH_CMDTASK_PRIORITY=100
-
-#
-# System Libraries and Add-Ons
-#
-# CONFIG_SYSTEM_CLE is not set
-# CONFIG_SYSTEM_CUTERM is not set
-# CONFIG_SYSTEM_FOTA_HAL is not set
-# CONFIG_SYSTEM_I2CTOOL is not set
-# CONFIG_SYSTEM_INIFILE is not set
-CONFIG_SYSTEM_PREAPP_INIT=y
-CONFIG_SYSTEM_PREAPP_STACKSIZE=2048
-# CONFIG_SYSTEM_INSTALL is not set
-CONFIG_SYSTEM_IOTJS=y
-CONFIG_IOTJS_PRIORITY=100
-CONFIG_IOTJS_STACKSIZE=65536
-# CONFIG_SYSTEM_NETDB is not set
-# CONFIG_SYSTEM_POWEROFF is not set
-CONFIG_SYSTEM_RAMTEST=y
-# CONFIG_SYSTEM_RAMTRON is not set
-CONFIG_SYSTEM_READLINE=y
-CONFIG_READLINE_ECHO=y
-CONFIG_SYSTEM_INFORMATION=y
-CONFIG_KERNEL_CMDS=y
-CONFIG_FS_CMDS=y
-CONFIG_FSCMD_BUFFER_LEN=64
-CONFIG_NET_CMDS=y
-CONFIG_ENABLE_DATE=y
-CONFIG_ENABLE_ENV_GET=y
-CONFIG_ENABLE_ENV_SET=y
-CONFIG_ENABLE_ENV_UNSET=y
-CONFIG_ENABLE_FREE=y
-CONFIG_ENABLE_HEAPINFO=y
-CONFIG_ENABLE_KILL=y
-CONFIG_ENABLE_KILLALL=y
-CONFIG_ENABLE_PS=y
-CONFIG_ENABLE_STACKMONITOR=y
-CONFIG_STACKMONITOR_PRIORITY=100
-CONFIG_STACKMONITOR_INTERVAL=5
-CONFIG_ENABLE_UPTIME=y
-CONFIG_SYSTEM_VI=y
-CONFIG_SYSTEM_VI_COLS=64
-CONFIG_SYSTEM_VI_ROWS=16
-CONFIG_SYSTEM_VI_DEBUGLEVEL=0
-
-#
-# wpa_supplicant
-#
-CONFIG_WPA_SUPPLICANT=y
-CONFIG_WPA_SUPPLICANT_PRIORITY=100
-CONFIG_WPA_SUPPLICANT_STACKSIZE=16384
-CONFIG_WPA_SUPPLICANT_ENTRYPOINT="wpa_supplicant_main"
-CONFIG_CTRL_IFACE=y
-CONFIG_CTRL_IFACE_FIFO=y
-CONFIG_WPA_CTRL_FIFO_DEV_REQ="/dev/wpa_ctrl_req"
-CONFIG_WPA_CTRL_FIFO_DEV_CFM="/dev/wpa_ctrl_cfm"
-CONFIG_WPA_CTRL_FIFO_DEV_GLOBAL_REQ="/dev/wpa_ctrl_global_req"
-CONFIG_WPA_CTRL_FIFO_DEV_GLOBAL_CFM="/dev/wpa_ctrl_global_cfm"
-CONFIG_WPA_MONITOR_FIFO_DEV="/dev/wpa_monitor"
-CONFIG_WPA_CTRL_FIFO_MK_MODE=666
-CONFIG_ELOOP_POLL=y
-# CONFIG_WPA_SUPPLICANT_CMD is not set
diff --git a/config/tizenrt/artik05x/configs/release/defconfig b/config/tizenrt/artik05x/configs/release/defconfig
new file mode 100644 (file)
index 0000000..2e6189f
--- /dev/null
@@ -0,0 +1,1308 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# TinyAra Configuration
+#
+
+#
+# Build Setup
+#
+# CONFIG_EXPERIMENTAL is not set
+# CONFIG_DEFAULT_SMALL is not set
+CONFIG_HOST_LINUX=y
+# CONFIG_HOST_OSX is not set
+# CONFIG_HOST_WINDOWS is not set
+# CONFIG_HOST_OTHER is not set
+# CONFIG_WINDOWS_NATIVE is not set
+
+#
+# Build Configuration
+#
+CONFIG_APPS_DIR="../apps"
+CONFIG_FRAMEWORK_DIR="../framework"
+CONFIG_TOOLS_DIR="../tools"
+CONFIG_BUILD_FLAT=y
+# CONFIG_BUILD_PROTECTED is not set
+# CONFIG_BUILD_2PASS is not set
+
+#
+# Binary Output Formats
+#
+# CONFIG_INTELHEX_BINARY is not set
+# CONFIG_MOTOROLA_SREC is not set
+CONFIG_RAW_BINARY=y
+# CONFIG_UBOOT_UIMAGE is not set
+# CONFIG_DOWNLOAD_IMAGE is not set
+# CONFIG_SMARTFS_IMAGE is not set
+
+#
+# Customize Header Files
+#
+# CONFIG_ARCH_STDINT_H is not set
+# CONFIG_ARCH_STDBOOL_H is not set
+# CONFIG_ARCH_MATH_H is not set
+# CONFIG_ARCH_FLOAT_H is not set
+# CONFIG_ARCH_STDARG_H is not set
+CONFIG_ARCH_HAVE_CUSTOMOPT=y
+# CONFIG_DEBUG_NOOPT is not set
+# CONFIG_DEBUG_CUSTOMOPT is not set
+# CONFIG_DEBUG_FULLOPT is not set
+
+#
+# Hardware Configuration
+#
+
+#
+# Chip Selection
+#
+CONFIG_ARCH_ARM=y
+CONFIG_ARCH="arm"
+# CONFIG_ARCH_CHIP_LM is not set
+CONFIG_ARCH_CHIP_S5J=y
+# CONFIG_ARCH_CHIP_BCM4390X is not set
+CONFIG_ARCH_CHIP="s5j"
+
+#
+# ARM Options
+#
+# CONFIG_ARCH_CORTEXM3 is not set
+# CONFIG_ARCH_CORTEXM4 is not set
+CONFIG_ARCH_CORTEXR4=y
+CONFIG_ARCH_FAMILY="armv7-r"
+# CONFIG_ARCH_HAVE_FPU is not set
+CONFIG_ARMV7M_MPU=y
+CONFIG_ARMV7M_MPU_NREGIONS=12
+
+#
+# Exception stack options
+#
+CONFIG_ARCH_HAVE_DABORTSTACK=y
+CONFIG_ARCH_DABORTSTACK=0
+
+#
+# ARMv7-R Configuration Options
+#
+CONFIG_ARMV7R_HAVE_GICv2=y
+CONFIG_ARMV7R_MEMINIT=y
+CONFIG_ARMV7R_ICACHE=y
+CONFIG_ARMV7R_DCACHE=y
+# CONFIG_ARMV7R_DCACHE_WRITETHROUGH is not set
+# CONFIG_ARMV7R_HAVE_L2CC is not set
+# CONFIG_ARMV7R_HAVE_L2CC_PL310 is not set
+# CONFIG_ARMV7R_TOOLCHAIN_BUILDROOT is not set
+# CONFIG_ARMV7R_TOOLCHAIN_CODESOURCERYL is not set
+CONFIG_ARMV7R_TOOLCHAIN_GNU_EABIL=y
+# CONFIG_ARMV7R_TOOLCHAIN_GNU_OABI is not set
+# CONFIG_ARMV7R_HAVE_DECODEFIQ is not set
+
+#
+# S5J Configuration Options
+#
+CONFIG_ARCH_CHIP_S5JT200=y
+CONFIG_S5J_S5JT200=y
+
+#
+# S5J Peripheral Support
+#
+CONFIG_S5J_HAVE_ADC=y
+CONFIG_S5J_HAVE_DMA=y
+CONFIG_S5J_HAVE_I2C=y
+CONFIG_S5J_HAVE_I2S=y
+CONFIG_S5J_HAVE_MCT=y
+CONFIG_S5J_HAVE_PWM0=y
+CONFIG_S5J_HAVE_PWM1=y
+CONFIG_S5J_HAVE_PWM2=y
+CONFIG_S5J_HAVE_PWM3=y
+CONFIG_S5J_HAVE_PWM4=y
+CONFIG_S5J_HAVE_PWM5=y
+CONFIG_S5J_HAVE_RTC=y
+CONFIG_S5J_HAVE_SFLASH=y
+CONFIG_S5J_HAVE_SPI=y
+CONFIG_S5J_HAVE_SSS=y
+CONFIG_S5J_HAVE_UART0=y
+CONFIG_S5J_HAVE_UART1=y
+CONFIG_S5J_HAVE_UART2=y
+CONFIG_S5J_HAVE_UART3=y
+CONFIG_S5J_HAVE_UART4=y
+CONFIG_S5J_HAVE_WATCHDOG=y
+CONFIG_S5J_ADC=y
+# CONFIG_S5J_DMA is not set
+CONFIG_S5J_I2C=y
+# CONFIG_S5J_I2S is not set
+CONFIG_S5J_MCT=y
+CONFIG_S5J_TIMER0=y
+# CONFIG_S5J_TIMER1 is not set
+# CONFIG_S5J_TIMER2 is not set
+# CONFIG_S5J_TIMER3 is not set
+# CONFIG_S5J_UART_FLOWCONTROL is not set
+CONFIG_S5J_UART0=y
+CONFIG_S5J_UART1=y
+CONFIG_S5J_UART2=y
+CONFIG_S5J_UART3=y
+CONFIG_S5J_UART4=y
+CONFIG_S5J_PWM=y
+CONFIG_S5J_PWM0=y
+CONFIG_S5J_PWM1=y
+CONFIG_S5J_PWM2=y
+CONFIG_S5J_PWM3=y
+CONFIG_S5J_PWM4=y
+CONFIG_S5J_PWM5=y
+# CONFIG_S5J_SSS is not set
+CONFIG_S5J_SPI=y
+# CONFIG_S5J_WATCHDOG is not set
+CONFIG_S5J_SFLASH=y
+# CONFIG_S5J_SENSOR_PPD42NS is not set
+
+#
+# Architecture Options
+#
+# CONFIG_ARCH_NOINTC is not set
+# CONFIG_ARCH_VECNOTIRQ is not set
+# CONFIG_ARCH_DMA is not set
+# CONFIG_ARCH_HAVE_IRQPRIO is not set
+# CONFIG_ARCH_L2CACHE is not set
+# CONFIG_ARCH_HAVE_COHERENT_DCACHE is not set
+# CONFIG_ARCH_HAVE_ADDRENV is not set
+# CONFIG_ARCH_NEED_ADDRENV_MAPPING is not set
+CONFIG_ARCH_HAVE_VFORK=y
+# CONFIG_ARCH_HAVE_MMU is not set
+CONFIG_ARCH_HAVE_MPU=y
+# CONFIG_ARCH_NAND_HWECC is not set
+# CONFIG_ARCH_HAVE_EXTCLK is not set
+# CONFIG_ARCH_HAVE_POWEROFF is not set
+CONFIG_ARCH_HAVE_RESET=y
+CONFIG_ARCH_USE_MPU=y
+CONFIG_ARCH_STACKDUMP=y
+# CONFIG_DEBUG_DISPLAY_SYMBOL is not set
+# CONFIG_ENDIAN_BIG is not set
+# CONFIG_ARCH_IDLE_CUSTOM is not set
+CONFIG_ARCH_CUSTOM_PMINIT=y
+# CONFIG_ARCH_HAVE_RAMFUNCS is not set
+# CONFIG_ARCH_HAVE_RAMVECTORS is not set
+
+#
+# Board Settings
+#
+CONFIG_BOARD_LOOPSPERMSEC=29100
+# CONFIG_ARCH_CALIBRATION is not set
+
+#
+# Interrupt options
+#
+CONFIG_ARCH_HAVE_INTERRUPTSTACK=y
+CONFIG_ARCH_INTERRUPTSTACK=0
+# CONFIG_ARCH_HAVE_HIPRI_INTERRUPT is not set
+
+#
+# Boot options
+#
+# CONFIG_BOOT_RUNFROMEXTSRAM is not set
+CONFIG_BOOT_RUNFROMFLASH=y
+# CONFIG_BOOT_RUNFROMISRAM is not set
+# CONFIG_BOOT_RUNFROMSDRAM is not set
+# CONFIG_BOOT_COPYTORAM is not set
+
+#
+# Boot Memory Configuration
+#
+CONFIG_RAM_START=0x02023800
+CONFIG_RAM_SIZE=968704
+# CONFIG_DDR is not set
+# CONFIG_ARCH_HAVE_SDRAM is not set
+
+#
+# Board Selection
+#
+CONFIG_ARCH_BOARD_ARTIK053=y
+# CONFIG_ARCH_BOARD_ARTIK053S is not set
+# CONFIG_ARCH_BOARD_ARTIK055S is not set
+# CONFIG_ARCH_BOARD_SIDK_S5JT200 is not set
+CONFIG_ARCH_BOARD_ARTIK05X_FAMILY=y
+CONFIG_ARCH_BOARD="artik05x"
+
+#
+# Common Board Options
+#
+# CONFIG_BOARD_CRASHDUMP is not set
+# CONFIG_BOARD_ASSERT_AUTORESET is not set
+CONFIG_LIB_BOARDCTL=y
+CONFIG_BOARDCTL_RESET=y
+# CONFIG_BOARDCTL_UNIQUEID is not set
+# CONFIG_BOARD_FOTA_SUPPORT is not set
+
+#
+# Board-Specific Options
+#
+CONFIG_ARTIK05X_BOOT_FAILURE_DETECTION=y
+CONFIG_ARTIK05X_BOOT_COUNTS_ADDR=0x80090810
+CONFIG_ARTIK05X_FLASH_CAPACITY=8388608
+CONFIG_ARTIK05X_FLASH_PAGE_SIZE=4096
+CONFIG_ARTIK05X_FLASH_PART=y
+CONFIG_ARTIK05X_FLASH_MINOR=0
+CONFIG_ARTIK05X_FLASH_PART_LIST="16,48,192,32,512,2400,1536,1536,1000,400,8,512,"
+CONFIG_ARTIK05X_FLASH_PART_TYPE="none,ftl,none,none,none,none,none,ftl,smartfs,romfs,config,none,"
+CONFIG_ARTIK05X_FLASH_PART_NAME="bl1,sssro,bl2,sssfw,wlanfw,os,factory,ota,user,rom,nvram,sssrw,"
+CONFIG_ARTIK05X_AUTOMOUNT=y
+CONFIG_ARTIK05X_AUTOMOUNT_USERFS=y
+CONFIG_ARTIK05X_AUTOMOUNT_USERFS_DEVNAME="/dev/smart0p8"
+CONFIG_ARTIK05X_AUTOMOUNT_USERFS_MOUNTPOINT="/mnt"
+# CONFIG_ARTIK05X_AUTOMOUNT_SSSRW is not set
+CONFIG_ARTIK05X_AUTOMOUNT_ROMFS=y
+CONFIG_ARTIK05X_AUTOMOUNT_ROMFS_DEVNAME="/dev/mtdblock9"
+CONFIG_ARTIK05X_AUTOMOUNT_ROMFS_MOUNTPOINT="/rom"
+
+#
+# Kernel Features
+#
+CONFIG_DISABLE_OS_API=y
+# CONFIG_DISABLE_POSIX_TIMERS is not set
+# CONFIG_DISABLE_PTHREAD is not set
+# CONFIG_DISABLE_SIGNALS is not set
+# CONFIG_DISABLE_MQUEUE is not set
+# CONFIG_DISABLE_ENVIRON is not set
+
+#
+# Clocks and Timers
+#
+CONFIG_ARCH_HAVE_TICKLESS=y
+# CONFIG_SCHED_TICKLESS is not set
+CONFIG_USEC_PER_TICK=9979
+CONFIG_SYSTEM_TIME64=y
+CONFIG_CLOCK_MONOTONIC=y
+# CONFIG_JULIAN_TIME is not set
+CONFIG_MAX_WDOGPARMS=4
+CONFIG_PREALLOC_WDOGS=32
+CONFIG_WDOG_INTRESERVE=4
+CONFIG_PREALLOC_TIMERS=8
+
+#
+# Tasks and Scheduling
+#
+CONFIG_INIT_ENTRYPOINT=y
+CONFIG_RR_INTERVAL=100
+CONFIG_TASK_NAME_SIZE=31
+CONFIG_MAX_TASKS=32
+CONFIG_SCHED_HAVE_PARENT=y
+# CONFIG_SCHED_CHILD_STATUS is not set
+CONFIG_SCHED_WAITPID=y
+
+#
+# Pthread Options
+#
+CONFIG_PTHREAD_MUTEX_TYPES=y
+# CONFIG_PTHREAD_MUTEX_ROBUST is not set
+CONFIG_PTHREAD_MUTEX_UNSAFE=y
+# CONFIG_PTHREAD_MUTEX_BOTH is not set
+CONFIG_NPTHREAD_KEYS=4
+CONFIG_NPTHREAD_DESTRUCTOR_ITERATIONS=4
+# CONFIG_PTHREAD_CLEANUP is not set
+# CONFIG_CANCELLATION_POINTS is not set
+
+#
+# Performance Monitoring
+#
+# CONFIG_SCHED_CPULOAD is not set
+
+#
+# Latency optimization
+#
+# CONFIG_SCHED_YIELD_OPTIMIZATION is not set
+
+#
+# Files and I/O
+#
+CONFIG_DEV_CONSOLE=y
+# CONFIG_FDCLONE_DISABLE is not set
+# CONFIG_FDCLONE_STDIO is not set
+# CONFIG_SDCLONE_DISABLE is not set
+CONFIG_NFILE_DESCRIPTORS=16
+CONFIG_NFILE_STREAMS=16
+CONFIG_NAME_MAX=32
+CONFIG_PRIORITY_INHERITANCE=y
+CONFIG_SEM_PREALLOCHOLDERS=16
+CONFIG_SEM_NNESTPRIO=16
+
+#
+# RTOS hooks
+#
+CONFIG_BOARD_INITIALIZE=y
+# CONFIG_BOARD_INITTHREAD is not set
+# CONFIG_SCHED_STARTHOOK is not set
+CONFIG_SCHED_ATEXIT=y
+CONFIG_SCHED_ONEXIT=y
+
+#
+# Signal Numbers
+#
+CONFIG_SIG_SIGUSR1=1
+CONFIG_SIG_SIGUSR2=2
+CONFIG_SIG_SIGALARM=3
+CONFIG_SIG_SIGCHLD=4
+CONFIG_SIG_SIGCONDTIMEDOUT=16
+CONFIG_SIG_SIGWORK=17
+
+#
+# POSIX Message Queue Options
+#
+CONFIG_PREALLOC_MQ_MSGS=4
+CONFIG_MQ_MAXMSGSIZE=600
+
+#
+# Work Queue Support
+#
+CONFIG_SCHED_WORKQUEUE=y
+CONFIG_SCHED_WORKQUEUE_SORTING=y
+CONFIG_SCHED_HPWORK=y
+CONFIG_SCHED_HPWORKPRIORITY=224
+CONFIG_SCHED_HPWORKPERIOD=50000
+CONFIG_SCHED_HPWORKSTACKSIZE=2048
+CONFIG_SCHED_LPWORK=y
+CONFIG_SCHED_LPNTHREADS=1
+CONFIG_SCHED_LPWORKPRIORITY=176
+CONFIG_SCHED_LPWORKPRIOMAX=176
+CONFIG_SCHED_LPWORKPERIOD=50000
+CONFIG_SCHED_LPWORKSTACKSIZE=2048
+
+#
+# Stack size information
+#
+CONFIG_IDLETHREAD_STACKSIZE=1024
+CONFIG_USERMAIN_STACKSIZE=2048
+# CONFIG_MPU_STACKGAURD is not set
+CONFIG_PTHREAD_STACK_MIN=256
+CONFIG_PTHREAD_STACK_DEFAULT=2048
+
+#
+# Device Drivers
+#
+# CONFIG_DISABLE_POLL is not set
+CONFIG_DEV_NULL=y
+CONFIG_DEV_ZERO=y
+# CONFIG_DRVR_WRITEBUFFER is not set
+# CONFIG_DRVR_READAHEAD is not set
+# CONFIG_CAN is not set
+# CONFIG_ARCH_HAVE_PWM_PULSECOUNT is not set
+# CONFIG_ARCH_HAVE_PWM_MULTICHAN is not set
+CONFIG_PWM=y
+# CONFIG_ARCH_HAVE_I2CRESET is not set
+CONFIG_I2C=y
+CONFIG_I2C_SLAVE=y
+CONFIG_I2C_USERIO=y
+CONFIG_I2C_TRANSFER=y
+CONFIG_I2C_POLLED=y
+# CONFIG_I2C_TRACE is not set
+# CONFIG_I2C_WRITEREAD is not set
+CONFIG_SPI=y
+# CONFIG_SPI_OWNBUS is not set
+CONFIG_SPI_EXCHANGE=y
+# CONFIG_SPI_CMDDATA is not set
+# CONFIG_SPI_BITBANG is not set
+CONFIG_GPIO=y
+# CONFIG_I2S is not set
+# CONFIG_AUDIO_DEVICES is not set
+CONFIG_BCH=y
+CONFIG_RTC=y
+CONFIG_RTC_DATETIME=y
+# CONFIG_RTC_ALARM is not set
+CONFIG_RTC_DRIVER=y
+# CONFIG_RTC_IOCTL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_DEVPATH="/dev/watchdog0"
+# CONFIG_TIMER is not set
+CONFIG_ANALOG=y
+CONFIG_ADC=y
+CONFIG_ADC_FIFOSIZE=8
+# CONFIG_DAC is not set
+CONFIG_NETDEVICES=y
+
+#
+# General Ethernet MAC Driver Options
+#
+CONFIG_NETDEV_TELNET=y
+CONFIG_NETDEV_MULTINIC=y
+# CONFIG_NET_DUMPPACKET is not set
+
+#
+# External Ethernet MAC Device Support
+#
+# CONFIG_NET_DM90x0 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_ENCX24J600 is not set
+# CONFIG_NET_E1000 is not set
+# CONFIG_NET_SLIP is not set
+# CONFIG_NET_VNET is not set
+# CONFIG_PIPES is not set
+CONFIG_POWER=y
+# CONFIG_BATTERY_CHARGER is not set
+# CONFIG_BATTERY_GAUGE is not set
+CONFIG_SERIAL=y
+# CONFIG_DEV_LOWCONSOLE is not set
+# CONFIG_16550_UART is not set
+# CONFIG_ARCH_HAVE_UART is not set
+CONFIG_ARCH_HAVE_UART0=y
+CONFIG_ARCH_HAVE_UART1=y
+CONFIG_ARCH_HAVE_UART2=y
+CONFIG_ARCH_HAVE_UART3=y
+CONFIG_ARCH_HAVE_UART4=y
+# CONFIG_ARCH_HAVE_UART5 is not set
+# CONFIG_ARCH_HAVE_UART6 is not set
+# CONFIG_ARCH_HAVE_UART7 is not set
+# CONFIG_ARCH_HAVE_UART8 is not set
+# CONFIG_ARCH_HAVE_SCI0 is not set
+# CONFIG_ARCH_HAVE_SCI1 is not set
+# CONFIG_ARCH_HAVE_USART0 is not set
+# CONFIG_ARCH_HAVE_USART1 is not set
+# CONFIG_ARCH_HAVE_USART2 is not set
+# CONFIG_ARCH_HAVE_USART3 is not set
+# CONFIG_ARCH_HAVE_USART4 is not set
+# CONFIG_ARCH_HAVE_USART5 is not set
+# CONFIG_ARCH_HAVE_USART6 is not set
+# CONFIG_ARCH_HAVE_USART7 is not set
+# CONFIG_ARCH_HAVE_USART8 is not set
+# CONFIG_ARCH_HAVE_OTHER_UART is not set
+
+#
+# USART Configuration
+#
+CONFIG_MCU_SERIAL=y
+CONFIG_STANDARD_SERIAL=y
+CONFIG_SERIAL_NPOLLWAITERS=2
+# CONFIG_SERIAL_IFLOWCONTROL is not set
+# CONFIG_SERIAL_OFLOWCONTROL is not set
+# CONFIG_SERIAL_TIOCSERGSTRUCT is not set
+CONFIG_ARCH_HAVE_SERIAL_TERMIOS=y
+CONFIG_SERIAL_TERMIOS=y
+# CONFIG_UART0_SERIAL_CONSOLE is not set
+# CONFIG_UART1_SERIAL_CONSOLE is not set
+# CONFIG_UART2_SERIAL_CONSOLE is not set
+# CONFIG_UART3_SERIAL_CONSOLE is not set
+CONFIG_UART4_SERIAL_CONSOLE=y
+# CONFIG_OTHER_SERIAL_CONSOLE is not set
+# CONFIG_NO_SERIAL_CONSOLE is not set
+
+#
+# UART0 Configuration
+#
+CONFIG_UART0_RXBUFSIZE=64
+CONFIG_UART0_TXBUFSIZE=64
+CONFIG_UART0_BAUD=115200
+CONFIG_UART0_BITS=8
+CONFIG_UART0_PARITY=0
+CONFIG_UART0_2STOP=0
+# CONFIG_UART0_IFLOWCONTROL is not set
+# CONFIG_UART0_OFLOWCONTROL is not set
+
+#
+# UART1 Configuration
+#
+CONFIG_UART1_RXBUFSIZE=256
+CONFIG_UART1_TXBUFSIZE=256
+CONFIG_UART1_BAUD=115200
+CONFIG_UART1_BITS=8
+CONFIG_UART1_PARITY=0
+CONFIG_UART1_2STOP=0
+# CONFIG_UART1_IFLOWCONTROL is not set
+# CONFIG_UART1_OFLOWCONTROL is not set
+
+#
+# UART2 Configuration
+#
+CONFIG_UART2_RXBUFSIZE=256
+CONFIG_UART2_TXBUFSIZE=256
+CONFIG_UART2_BAUD=115200
+CONFIG_UART2_BITS=8
+CONFIG_UART2_PARITY=0
+CONFIG_UART2_2STOP=0
+# CONFIG_UART2_IFLOWCONTROL is not set
+# CONFIG_UART2_OFLOWCONTROL is not set
+
+#
+# UART3 Configuration
+#
+CONFIG_UART3_RXBUFSIZE=256
+CONFIG_UART3_TXBUFSIZE=256
+CONFIG_UART3_BAUD=115200
+CONFIG_UART3_BITS=8
+CONFIG_UART3_PARITY=0
+CONFIG_UART3_2STOP=0
+# CONFIG_UART3_IFLOWCONTROL is not set
+# CONFIG_UART3_OFLOWCONTROL is not set
+
+#
+# UART4 Configuration
+#
+CONFIG_UART4_RXBUFSIZE=256
+CONFIG_UART4_TXBUFSIZE=256
+CONFIG_UART4_BAUD=115200
+CONFIG_UART4_BITS=8
+CONFIG_UART4_PARITY=0
+CONFIG_UART4_2STOP=0
+# CONFIG_UART4_IFLOWCONTROL is not set
+# CONFIG_UART4_OFLOWCONTROL is not set
+# CONFIG_SENSOR is not set
+# CONFIG_USBDEV is not set
+# CONFIG_FOTA_DRIVER is not set
+
+#
+# System Logging
+#
+# CONFIG_RAMLOG is not set
+# CONFIG_SYSLOG_CONSOLE is not set
+
+#
+# T-trace
+#
+# CONFIG_TTRACE is not set
+
+#
+# Wireless Device Options
+#
+CONFIG_DRIVERS_WIRELESS=y
+CONFIG_SCSC_WLAN=y
+# CONFIG_SLSI_RX_PERFORMANCE_TEST is not set
+CONFIG_SCSC_TX_FLOW_CONTROL=y
+CONFIG_SCSC_ENABLE_PORT_CONTROL=y
+# CONFIG_SCSC_WLAN_STA_ONLY is not set
+# CONFIG_SCSC_WLAN_BLOCK_IPV6 is not set
+# CONFIG_SCSC_WLAN_UDP_FLOWCONTROL is not set
+# CONFIG_SCSC_WLAN_AUTO_RECOVERY is not set
+CONFIG_SCSC_WLAN_POWER_SAVE=y
+CONFIG_SCSC_WLAN_MAX_INTERFACES=1
+CONFIG_SCSC_CORE=y
+CONFIG_SCSC_PLATFORM=y
+# CONFIG_SCSC_WLANLITE is not set
+# CONFIG_SCSC_DISABLE_WLAN_RESET is not set
+
+#
+# Networking Support
+#
+CONFIG_ARCH_HAVE_NET=y
+# CONFIG_ARCH_HAVE_PHY is not set
+CONFIG_NET=y
+CONFIG_NET_LWIP=y
+
+#
+# LwIP options
+#
+CONFIG_NET_IPv4=y
+CONFIG_NET_IP_DEFAULT_TTL=255
+# CONFIG_NET_IP_FORWARD is not set
+CONFIG_NET_IP_OPTIONS_ALLOWED=y
+CONFIG_NET_IP_FRAG=y
+CONFIG_NET_IP_REASSEMBLY=y
+CONFIG_NET_IPV4_REASS_MAX_PBUFS=20
+CONFIG_NET_IPV4_REASS_MAXAGE=5
+CONFIG_NET_IPv6=y
+CONFIG_NET_IPv6_NUM_ADDRESSES=3
+# CONFIG_NET_IPv6_FORWARD is not set
+# CONFIG_NET_IPv6_FRAG is not set
+CONFIG_NET_IPv6_REASS=y
+CONFIG_NET_IPV6_REASS_MAXAGE=60
+CONFIG_NET_IPv6_SEND_ROUTER_SOLICIT=y
+CONFIG_NET_IPv6_AUTOCONFIG=y
+CONFIG_NET_IPv6_DUP_DETECT_ATTEMPTS=1
+# CONFIG_NET_IPv6_PMTU_FOR_MULTICAST is not set
+
+#
+# Socket support
+#
+CONFIG_NET_SOCKET=y
+CONFIG_NSOCKET_DESCRIPTORS=20
+CONFIG_NET_TCP_KEEPALIVE=y
+CONFIG_NET_RAW=y
+# CONFIG_NET_SOCKET_OPTION_BROADCAST is not set
+# CONFIG_NET_RANDOMIZE_INITIAL_LOCAL_PORTS is not set
+# CONFIG_NET_SO_SNDTIMEO is not set
+CONFIG_NET_SO_RCVTIMEO=y
+# CONFIG_NET_SO_RCVBUF is not set
+CONFIG_NET_SO_REUSE=y
+# CONFIG_NET_SO_REUSE_RXTOALL is not set
+CONFIG_NET_ARP=y
+CONFIG_NET_ARP_TABLESIZE=10
+CONFIG_NET_ARP_QUEUEING=y
+CONFIG_NET_ETHARP_TRUST_IP_MAC=y
+CONFIG_NET_ETH_PAD_SIZE=0
+# CONFIG_NET_ARP_STATIC_ENTRIES is not set
+CONFIG_NET_IPv6_ND=y
+CONFIG_NET_IPv6_ND_QUEUEING=y
+CONFIG_NET_IPv6_ND_QUEUE=20
+CONFIG_NET_IPv6_ND_NUM_NEIGHBORS=10
+CONFIG_NET_IPv6_ND_NUM_DESTINATIONS=10
+CONFIG_NET_IPv6_ND_NUM_PREFIXES=5
+CONFIG_NET_IPv6_ND_NUM_ROUTERS=3
+CONFIG_NET_IPv6_ND_MAX_MULTICAST_SOLICIT=3
+CONFIG_NET_IPv6_ND_MAX_UNICAST_SOLICIT=3
+CONFIG_NET_IPv6_ND_MAX_SOLICIT_INTERVAL=4000
+CONFIG_NET_IPv6_ND_REACHABLE_TIME=30000
+CONFIG_NET_IPv6_ND_RETRANS_TIMER=1000
+CONFIG_NET_IPv6_ND_DELAY_FIRST_PROBE_TIME=5000
+CONFIG_NET_IPv6_ND_ALLOW_RA_UPDATES=y
+CONFIG_NET_IPv6_ND_TCP_REACHABILITY_HINTS=y
+CONFIG_NET_IPv6_ND_RDNSS_MAX_DNS_SERVERS=0
+CONFIG_NET_UDP=y
+# CONFIG_NET_NETBUF_RECVINFO is not set
+CONFIG_NET_UDP_TTL=255
+# CONFIG_NET_UDPLITE is not set
+CONFIG_NET_TCP=y
+CONFIG_NET_TCP_TTL=255
+CONFIG_NET_TCP_WND=58400
+CONFIG_NET_TCP_MAXRTX=12
+CONFIG_NET_TCP_SYNMAXRTX=6
+CONFIG_NET_TCP_QUEUE_OOSEQ=y
+CONFIG_NET_TCP_MSS=1460
+CONFIG_NET_TCP_CALCULATE_EFF_SEND_MSS=y
+CONFIG_NET_TCP_SND_BUF=29200
+CONFIG_NET_TCP_SND_QUEUELEN=80
+# CONFIG_NET_TCP_LISTEN_BACKLOG is not set
+CONFIG_NET_TCP_OVERSIZE=536
+# CONFIG_NET_TCP_TIMESTAMPS is not set
+CONFIG_NET_TCP_WND_UPDATE_THRESHOLD=536
+CONFIG_NET_ICMP=y
+CONFIG_NET_ICMP_TTL=255
+# CONFIG_NET_BROADCAST_PING is not set
+# CONFIG_NET_MULTICAST_PING4 is not set
+CONFIG_NET_IPv6_ICMP=y
+CONFIG_NET_IPv6_ICMP_DATASIZE=8
+CONFIG_NET_IPv6_ICMP_HL=255
+# CONFIG_NET_MULTICAST_PING6 is not set
+CONFIG_NET_LWIP_IGMP=y
+CONFIG_NET_LWIP_MEMP_NUM_IGMP_GROUP=8
+CONFIG_NET_IPv6_MLD=y
+CONFIG_NET_IPv6_MLD_GROUP=4
+# CONFIG_NET_IPv6_DHCP is not set
+
+#
+# LWIP Mailbox Configurations
+#
+CONFIG_NET_TCPIP_MBOX_SIZE=64
+CONFIG_NET_DEFAULT_ACCEPTMBOX_SIZE=64
+CONFIG_NET_DEFAULT_RAW_RECVMBOX_SIZE=64
+CONFIG_NET_DEFAULT_TCP_RECVMBOX_SIZE=54
+CONFIG_NET_DEFAULT_UDP_RECVMBOX_SIZE=64
+
+#
+# Memory Configurations
+#
+CONFIG_NET_MEM_ALIGNMENT=4
+# CONFIG_NET_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is not set
+# CONFIG_NET_MEM_LIBC_MALLOC is not set
+CONFIG_NET_MEMP_MEM_MALLOC=y
+# CONFIG_NET_MEM_USE_POOLS is not set
+CONFIG_NET_MEM_SIZE=153600
+
+#
+# LWIP Task Configurations
+#
+# CONFIG_NET_TCPIP_CORE_LOCKING is not set
+# CONFIG_NET_TCPIP_CORE_LOCKING_INPUT is not set
+CONFIG_NET_TCPIP_THREAD_NAME="LWIP_TCP/IP"
+CONFIG_NET_TCPIP_THREAD_PRIO=110
+CONFIG_NET_TCPIP_THREAD_STACKSIZE=4096
+CONFIG_NET_COMPAT_MUTEX=y
+CONFIG_NET_SYS_LIGHTWEIGHT_PROT=y
+CONFIG_NET_DEFAULT_THREAD_NAME="lwIP"
+CONFIG_NET_DEFAULT_THREAD_PRIO=1
+CONFIG_NET_DEFAULT_THREAD_STACKSIZE=0
+
+#
+# Debug Options for Network
+#
+# CONFIG_NET_LWIP_ASSERT is not set
+# CONFIG_NET_LWIP_ERROR is not set
+# CONFIG_NET_LWIP_DEBUG is not set
+
+#
+# Enable Statistics
+#
+CONFIG_NET_STATS=y
+CONFIG_NET_STATS_DISPLAY=y
+CONFIG_NET_LINK_STATS=y
+CONFIG_NET_ETHARP_STATS=y
+CONFIG_NET_IP_STATS=y
+# CONFIG_NET_IPFRAG_STATS is not set
+# CONFIG_NET_ICMP_STATS is not set
+CONFIG_NET_UDP_STATS=y
+CONFIG_NET_TCP_STATS=y
+CONFIG_NET_MEM_STATS=y
+CONFIG_NET_SYS_STATS=y
+# CONFIG_NET_IPv6_STATS is not set
+# CONFIG_NET_IPv6_ICMP_STATS is not set
+# CONFIG_NET_IPv6_MLD_STATS is not set
+# CONFIG_NET_IPv6_ND_STATS is not set
+# CONFIG_NET_LWIP_VLAN is not set
+CONFIG_NET_LWIP_LOOPBACK_INTERFACE=y
+# CONFIG_NET_LWIP_SLIP_INTERFACE is not set
+# CONFIG_NET_LWIP_PPP_SUPPORT is not set
+# CONFIG_NET_LWIP_SNMP is not set
+
+#
+# Interface Name
+#
+CONFIG_NET_ETH_IFNAME="en"
+CONFIG_NET_LOOP_IFNAME="lo"
+CONFIG_NET_STA_IFNAME="wl"
+CONFIG_NET_SOFTAP_IFNAME="sa"
+CONFIG_NET_LWIP_NETDB=y
+CONFIG_NET_DNS_TABLE_SIZE=4
+CONFIG_NET_DNS_MAX_NAME_LENGTH=256
+CONFIG_NET_DNS_MAX_SERVERS=2
+# CONFIG_NET_DNS_DOES_NAME_CHECK is not set
+CONFIG_NET_DNS_SECURE=0
+# CONFIG_NET_DNS_LOCAL_HOSTLIST is not set
+
+#
+# Driver buffer configuration
+#
+CONFIG_NET_MULTIBUFFER=y
+CONFIG_NET_ETH_MTU=590
+CONFIG_NET_GUARDSIZE=2
+
+#
+# Data link support
+#
+# CONFIG_NET_MULTILINK is not set
+CONFIG_NET_ETHERNET=y
+
+#
+# Network Device Operations
+#
+# CONFIG_NETDEV_PHY_IOCTL is not set
+
+#
+# Protocols
+#
+CONFIG_NETUTILS_DHCPD=y
+CONFIG_NETUTILS_DHCPD_IGNOREBROADCAST=y
+CONFIG_NETUTILS_DHCPD_INTERFACE="wl1"
+CONFIG_NETUTILS_DHCPD_LEASETIME=864000
+CONFIG_NETUTILS_DHCPD_MINLEASETIME=86400
+CONFIG_NETUTILS_DHCPD_MAXLEASETIME=2592000
+CONFIG_NETUTILS_DHCPD_MAXLEASES=6
+CONFIG_NETUTILS_DHCPD_STARTIP=0xc0a82f02
+CONFIG_NETUTILS_DHCPD_ROUTERIP=0xc0a82f01
+CONFIG_NETUTILS_DHCPD_NETMASK=0xffffff00
+CONFIG_NETUTILS_DHCPD_DNSIP=0x08080808
+CONFIG_NETUTILS_DHCPD_OFFERTIME=3600
+CONFIG_NETUTILS_DHCPD_DECLINETIME=3600
+# CONFIG_NETUTILS_XMLRPC is not set
+# CONFIG_NETUTILS_NTPCLIENT is not set
+# CONFIG_NETUTILS_WEBSERVER is not set
+# CONFIG_NETUTILS_FTPC is not set
+# CONFIG_NETUTILS_MDNS is not set
+# CONFIG_NETUTILS_FTPD is not set
+CONFIG_NETUTILS_DHCPC=y
+# CONFIG_NETUTILS_WEBSOCKET is not set
+# CONFIG_NETUTILS_LIBCOAP is not set
+# CONFIG_NETUTILS_TFTPC is not set
+# CONFIG_NETUTILS_TELNETD is not set
+# CONFIG_NETUTILS_SMTP is not set
+# CONFIG_NETUTILS_MQTT is not set
+CONFIG_NET_SECURITY_TLS=y
+CONFIG_TLS_MPI_MAX_SIZE=512
+
+#
+# Wireless
+#
+CONFIG_WIFI_MANAGER=y
+CONFIG_SELECT_WPA_SUPPLICANT=y
+# CONFIG_SELECT_PROPIETARY_SUPPLICANT is not set
+# CONFIG_SELECT_NO_DRIVER is not set
+CONFIG_SELECT_SCSC_WLAN=y
+# CONFIG_SELECT_PROPIETARY_WLAN is not set
+CONFIG_NETUTILS_WIFI=y
+CONFIG_SLSI_WIFI_DEFAULT_WLAN_COUNTRY_CODE="00"
+CONFIG_SLSI_WIFI_DEFAULT_WLAN_TX_POWER=30
+# CONFIG_SLSI_WIFI_FILESYSTEM_SUPPORT is not set
+
+#
+# wpa_supplicant
+#
+CONFIG_WPA_SUPPLICANT=y
+CONFIG_WPA_SUPPLICANT_PRIORITY=100
+CONFIG_WPA_SUPPLICANT_STACKSIZE=16384
+CONFIG_WPA_SUPPLICANT_ENTRYPOINT="wpa_supplicant_main"
+CONFIG_CTRL_IFACE=y
+CONFIG_CTRL_IFACE_FIFO=y
+CONFIG_WPA_CTRL_FIFO_DEV_REQ="/dev/wpa_ctrl_req"
+CONFIG_WPA_CTRL_FIFO_DEV_CFM="/dev/wpa_ctrl_cfm"
+CONFIG_WPA_CTRL_FIFO_DEV_GLOBAL_REQ="/dev/wpa_ctrl_global_req"
+CONFIG_WPA_CTRL_FIFO_DEV_GLOBAL_CFM="/dev/wpa_ctrl_global_cfm"
+CONFIG_WPA_MONITOR_FIFO_DEV="/dev/wpa_monitor"
+CONFIG_WPA_CTRL_FIFO_MK_MODE=666
+CONFIG_ELOOP_POLL=y
+# CONFIG_WPA_SUPPLICANT_CMD is not set
+CONFIG_DRIVER_T20=y
+# CONFIG_ENABLE_EAP_FOR_SUPPLICANT is not set
+CONFIG_WIFIMGR_SOFTAP_IFNAME="wl1"
+CONFIG_WIFIMGR_STA_IFNAME="wl1"
+# CONFIG_WIFIMGR_DISABLE_AUTO_GET_IP is not set
+# CONFIG_DISABLE_EXTERNAL_AUTOCONNECT is not set
+
+#
+# Network utilities
+#
+CONFIG_NETUTILS_NETLIB=y
+CONFIG_NET_NETMON=y
+
+#
+# Audio Support
+#
+# CONFIG_AUDIO is not set
+
+#
+# Media Support
+#
+
+#
+# File Systems
+#
+# CONFIG_DISABLE_MOUNTPOINT is not set
+# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set
+CONFIG_FS_READABLE=y
+CONFIG_FS_WRITABLE=y
+# CONFIG_FS_AIO is not set
+# CONFIG_FS_NAMED_SEMAPHORES is not set
+CONFIG_FS_MQUEUE_MPATH="/var/mqueue"
+CONFIG_FS_SMARTFS=y
+
+#
+# SMARTFS options
+#
+CONFIG_SMARTFS_ERASEDSTATE=0xff
+CONFIG_SMARTFS_MAXNAMLEN=32
+# CONFIG_SMARTFS_MULTI_ROOT_DIRS is not set
+CONFIG_SMARTFS_ALIGNED_ACCESS=y
+# CONFIG_SMARTFS_BAD_SECTOR is not set
+# CONFIG_SMARTFS_DYNAMIC_HEADER is not set
+# CONFIG_SMARTFS_JOURNALING is not set
+# CONFIG_SMARTFS_SECTOR_RECOVERY is not set
+CONFIG_FS_PROCFS=y
+# CONFIG_FS_AUTOMOUNT_PROCFS is not set
+
+#
+# Exclude individual procfs entries
+#
+# CONFIG_FS_PROCFS_EXCLUDE_PROCESS is not set
+# CONFIG_FS_PROCFS_EXCLUDE_UPTIME is not set
+# CONFIG_FS_PROCFS_EXCLUDE_VERSION is not set
+# CONFIG_FS_PROCFS_EXCLUDE_MTD is not set
+# CONFIG_FS_PROCFS_EXCLUDE_PARTITIONS is not set
+# CONFIG_FS_PROCFS_EXCLUDE_SMARTFS is not set
+# CONFIG_FS_PROCFS_EXCLUDE_POWER is not set
+CONFIG_FS_ROMFS=y
+# CONFIG_FS_TMPFS is not set
+
+#
+# Block Driver Configurations
+#
+CONFIG_RAMDISK=y
+
+#
+# MTD Configuration
+#
+CONFIG_MTD=y
+CONFIG_MTD_PARTITION=y
+CONFIG_MTD_PARTITION_NAMES=y
+CONFIG_MTD_PROGMEM=y
+CONFIG_MTD_FTL=y
+
+#
+# MTD_FTL Configurations
+#
+CONFIG_MTD_CONFIG=y
+
+#
+# MTD Configurations
+#
+# CONFIG_MTD_CONFIG_RAM_CONSOLIDATE is not set
+CONFIG_MTD_CONFIG_ERASEDVALUE=0xff
+# CONFIG_MTD_BYTE_WRITE is not set
+
+#
+# MTD Device Drivers
+#
+# CONFIG_MTD_M25P is not set
+# CONFIG_RAMMTD is not set
+CONFIG_MTD_SMART=y
+
+#
+# SMART Device options
+#
+CONFIG_MTD_SMART_SECTOR_SIZE=512
+# CONFIG_MTD_SMART_WEAR_LEVEL is not set
+# CONFIG_MTD_SMART_ENABLE_CRC is not set
+# CONFIG_MTD_SMART_SECTOR_ERASE_DEBUG is not set
+# CONFIG_MTD_SMART_ALLOC_DEBUG is not set
+# CONFIG_MTD_W25 is not set
+
+#
+# System Logging
+#
+# CONFIG_SYSLOG is not set
+# CONFIG_SYSLOG_TIMESTAMP is not set
+
+#
+# Database
+#
+# CONFIG_ARASTORAGE is not set
+
+#
+# Memory Management
+#
+# CONFIG_REALLOC_DISABLE_NEIGHBOR_EXTENSION is not set
+# CONFIG_MM_SMALL is not set
+CONFIG_MM_REGIONS=1
+# CONFIG_GRAN is not set
+
+#
+# Power Management
+#
+CONFIG_PM=y
+# CONFIG_DEBUG_PM is not set
+# CONFIG_PM_TEST is not set
+CONFIG_PM_DEVNAME_LEN=32
+# CONFIG_PM_METRICS is not set
+CONFIG_PM_SLICEMS=100
+CONFIG_PM_NDOMAINS=1
+CONFIG_PM_MEMORY=2
+CONFIG_PM_COEFN=1
+CONFIG_PM_COEF1=1
+CONFIG_PM_COEF2=1
+CONFIG_PM_COEF3=1
+CONFIG_PM_COEF4=1
+CONFIG_PM_COEF5=1
+CONFIG_PM_IDLEENTER_THRESH=1
+CONFIG_PM_IDLEEXIT_THRESH=2
+CONFIG_PM_IDLEENTER_COUNT=30
+CONFIG_PM_STANDBYENTER_THRESH=1
+CONFIG_PM_STANDBYEXIT_THRESH=2
+CONFIG_PM_STANDBYENTER_COUNT=50
+CONFIG_PM_SLEEPENTER_THRESH=1
+CONFIG_PM_SLEEPEXIT_THRESH=2
+CONFIG_PM_SLEEPENTER_COUNT=70
+
+#
+# Debug Options
+#
+# CONFIG_DEBUG is not set
+# CONFIG_DEBUG_ERROR is not set
+# CONFIG_DEBUG_WARN is not set
+# CONFIG_DEBUG_VERBOSE is not set
+
+#
+# Subsystem Debug Options
+#
+# CONFIG_DEBUG_LIB is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_IOTBUS is not set
+# CONFIG_DEBUG_MM is not set
+# CONFIG_DEBUG_NET is not set
+# CONFIG_DEBUG_NET_ERROR is not set
+# CONFIG_DEBUG_NET_INFO is not set
+# CONFIG_DEBUG_SCHED is not set
+# CONFIG_DEBUG_TASH is not set
+# CONFIG_DEBUG_WLAN is not set
+
+#
+# SLSI WLAN FW Debug Options
+#
+# CONFIG_SCSC_ENABLE_FWFAULT_LOG is not set
+
+#
+# SLSI WLAN Driver Debug Options
+#
+# CONFIG_DEBUG_WLAN_DRIVER_ERROR is not set
+# CONFIG_DEBUG_WLAN_DRIVER_DEBUG is not set
+# CONFIG_DEBUG_WLAN_DRIVER_MORE is not set
+# CONFIG_DEBUG_WLAN_DRIVER_INFO is not set
+
+#
+# SLSI WPA Supplicant Debug Options
+#
+# CONFIG_DEBUG_WLAN_SUPPLICANT_ERROR is not set
+# CONFIG_DEBUG_WLAN_SUPPLICANT_DEBUG is not set
+# CONFIG_DEBUG_WLAN_SUPPLICANT_MORE is not set
+# CONFIG_DEBUG_WLAN_SUPPLICANT_INFO is not set
+
+#
+# SLSI Wi-Fi API Debug Options
+#
+# CONFIG_DEBUG_WLAN_API_ERROR is not set
+# CONFIG_DEBUG_WLAN_API_DEBUG is not set
+# CONFIG_DEBUG_WLAN_API_INFO is not set
+
+#
+# OS Function Debug Options
+#
+# CONFIG_ARCH_HAVE_HEAPCHECK is not set
+# CONFIG_DEBUG_MM_HEAPINFO is not set
+# CONFIG_DEBUG_IRQ is not set
+
+#
+# Driver Debug Options
+#
+# CONFIG_DEBUG_I2S is not set
+# CONFIG_DEBUG_PWM is not set
+# CONFIG_DEBUG_RTC is not set
+# CONFIG_DEBUG_SPI is not set
+# CONFIG_DEBUG_WATCHDOG is not set
+
+#
+# System Debug Options
+#
+# CONFIG_DEBUG_SYSTEM is not set
+
+#
+# Stack Debug Options
+#
+CONFIG_ARCH_HAVE_STACKCHECK=y
+CONFIG_STACK_COLORATION=y
+
+#
+# Build Debug Options
+#
+# CONFIG_DEBUG_SYMBOLS is not set
+# CONFIG_FRAME_POINTER is not set
+
+#
+# Logger Module
+#
+CONFIG_LOGM=y
+# CONFIG_PRINTF2LOGM is not set
+CONFIG_SYSLOG2LOGM=y
+# CONFIG_LOGM_TIMESTAMP is not set
+CONFIG_LOGM_BUFFER_SIZE=10240
+CONFIG_LOGM_PRINT_INTERVAL=1000
+CONFIG_LOGM_TASK_PRIORITY=110
+CONFIG_LOGM_TASK_STACKSIZE=2048
+# CONFIG_LOGM_TEST is not set
+
+#
+# Built-in Libraries
+#
+
+#
+# Standard C Library Options
+#
+CONFIG_STDIO_BUFFER_SIZE=64
+CONFIG_STDIO_LINEBUFFER=y
+CONFIG_NUNGET_CHARS=2
+CONFIG_LIB_HOMEDIR="/"
+CONFIG_LIBM=y
+# CONFIG_NOPRINTF_FIELDWIDTH is not set
+CONFIG_LIBC_FLOATINGPOINT=y
+CONFIG_LIBC_FLOATPRECISION=6
+CONFIG_LIBC_SCANSET=y
+# CONFIG_NOPRINTF_LONGLONG_TO_ASCII is not set
+CONFIG_LIBC_IOCTL_VARIADIC=y
+# CONFIG_LIBC_WCHAR is not set
+# CONFIG_LIBC_LOCALE is not set
+CONFIG_LIB_RAND_ORDER=1
+# CONFIG_EOL_IS_CR is not set
+# CONFIG_EOL_IS_LF is not set
+# CONFIG_EOL_IS_BOTH_CRLF is not set
+CONFIG_EOL_IS_EITHER_CRLF=y
+CONFIG_LIBC_STRERROR=y
+# CONFIG_LIBC_STRERROR_SHORT is not set
+# CONFIG_LIBC_PERROR_STDOUT is not set
+CONFIG_LIBC_TMPDIR="/tmp"
+CONFIG_LIBC_MAX_TMPFILE=32
+CONFIG_ARCH_LOWPUTC=y
+# CONFIG_LIBC_LOCALTIME is not set
+# CONFIG_TIME_EXTENDED is not set
+CONFIG_LIB_SENDFILE_BUFSIZE=512
+CONFIG_ARCH_OPTIMIZED_FUNCTIONS=y
+# CONFIG_ARCH_MEMCPY is not set
+CONFIG_MEMCPY_VIK=y
+# CONFIG_MEMCPY_PRE_INC_PTRS is not set
+CONFIG_MEMCPY_INDEXED_COPY=y
+# CONFIG_MEMCPY_64BIT is not set
+# CONFIG_ARCH_MEMCMP is not set
+# CONFIG_ARCH_MEMMOVE is not set
+# CONFIG_ARCH_MEMSET is not set
+# CONFIG_MEMSET_OPTSPEED is not set
+# CONFIG_ARCH_STRCHR is not set
+# CONFIG_ARCH_STRCMP is not set
+# CONFIG_ARCH_STRCPY is not set
+# CONFIG_ARCH_STRNCPY is not set
+# CONFIG_ARCH_STRLEN is not set
+# CONFIG_ARCH_STRNLEN is not set
+# CONFIG_ARCH_BZERO is not set
+
+#
+# Non-standard Library Support
+#
+
+#
+# Basic CXX Support
+#
+# CONFIG_C99_BOOL8 is not set
+# CONFIG_HAVE_CXX is not set
+
+#
+# External Libraries
+#
+# CONFIG_AVS_DEVICE_SDK is not set
+# CONFIG_AWS_SDK is not set
+# CONFIG_NETUTILS_CODECS is not set
+
+#
+# CURL Options
+#
+# CONFIG_ENABLE_CURL is not set
+# CONFIG_ERROR_REPORT is not set
+# CONFIG_ENABLE_IOTIVITY is not set
+CONFIG_NETUTILS_JSON=y
+# CONFIG_LIBTUV is not set
+# CONFIG_LWM2M_WAKAAMA is not set
+# CONFIG_STRESS_TOOL is not set
+# CONFIG_VOICE_SOFTWARE_EPD is not set
+
+#
+# Application Configuration
+#
+
+#
+# Application entry point list
+#
+# CONFIG_ENTRY_MANUAL is not set
+# CONFIG_ENTRY_HELLO is not set
+CONFIG_ENTRY_IOTJS_STARTUP=y
+CONFIG_USER_ENTRYPOINT="iotjs_startup_main"
+CONFIG_BUILTIN_APPS=y
+
+#
+# Examples
+#
+# CONFIG_EXAMPLES_AVS_TEST is not set
+# CONFIG_EXAMPLES_AWS is not set
+# CONFIG_EXAMPLES_CURLTEST is not set
+# CONFIG_EXAMPLES_DNSCLIENT_TEST is not set
+# CONFIG_EXAMPLES_DTLS_CLIENT is not set
+# CONFIG_EXAMPLES_DTLS_SERVER is not set
+# CONFIG_EXAMPLES_EEPROM_TEST is not set
+# CONFIG_EXAMPLES_EVENTLOOP is not set
+# CONFIG_EXAMPLES_FOTA_SAMPLE is not set
+# CONFIG_FILESYSTEM_HELPER_ENABLE is not set
+CONFIG_EXAMPLES_HELLO=y
+# CONFIG_EXAMPLES_HELLOXX is not set
+# CONFIG_EXAMPLES_IOTBUS_TEST is not set
+CONFIG_EXAMPLES_IOTJS_STARTUP=y
+CONFIG_EXAMPLES_IOTJS_STARTUP_JS_FILE="/rom/example/index.js"
+# CONFIG_EXAMPLES_IOTJS_STARTUP_WIFI is not set
+# CONFIG_EXAMPLES_KERNEL_SAMPLE is not set
+# CONFIG_EXAMPLES_LIBTUV is not set
+# CONFIG_EXAMPLES_NETTEST is not set
+# CONFIG_EXAMPLES_PROC_TEST is not set
+# CONFIG_EXAMPLES_SELECT_TEST is not set
+# CONFIG_EXAMPLES_SENSORBOARD is not set
+# CONFIG_EXAMPLES_SETJMP_TEST is not set
+CONFIG_EXAMPLES_SLSIWIFI=y
+CONFIG_EXAMPLES_SLSIWIFI_PRIORITY=50
+CONFIG_EXAMPLES_SLSIWIFI_STACKSIZE=2048
+# CONFIG_EXAMPLES_SMART is not set
+# CONFIG_EXAMPLES_SMART_TEST is not set
+# CONFIG_EXAMPLES_SPEECH_DETECTOR_TEST is not set
+# CONFIG_EXAMPLES_ST_THINGS is not set
+# CONFIG_EXAMPLES_TESTCASE is not set
+# CONFIG_EXAMPLES_TLS_BENCHMARK is not set
+# CONFIG_EXAMPLES_TLS_CLIENT is not set
+# CONFIG_EXAMPLES_TLS_SELFTEST is not set
+# CONFIG_EXAMPLES_TLS_SERVER is not set
+# CONFIG_EXAMPLES_WIFIMANAGER_TEST is not set
+
+#
+# Platform-specific Support
+#
+# CONFIG_PLATFORM_CONFIGDATA is not set
+
+#
+# Shell
+#
+CONFIG_TASH=y
+CONFIG_TASH_MAX_COMMANDS=132
+# CONFIG_TASH_USLEEP is not set
+CONFIG_TASH_COMMAND_INTERFACE=y
+CONFIG_TASH_CMDTASK_STACKSIZE=4096
+CONFIG_TASH_CMDTASK_PRIORITY=100
+# CONFIG_TASH_SCRIPT is not set
+
+#
+# System Libraries and Add-Ons
+#
+# CONFIG_SYSTEM_CLE is not set
+# CONFIG_SYSTEM_CUTERM is not set
+# CONFIG_SYSTEM_FLASH_ERASEALL is not set
+# CONFIG_SYSTEM_FOTA_HAL is not set
+# CONFIG_SYSTEM_I2CTOOL is not set
+# CONFIG_SYSTEM_INIFILE is not set
+CONFIG_SYSTEM_PREAPP_INIT=y
+CONFIG_SYSTEM_PREAPP_STACKSIZE=2048
+# CONFIG_SYSTEM_INSTALL is not set
+CONFIG_SYSTEM_IPERF=y
+# CONFIG_SYSTEM_NETDB is not set
+CONFIG_SYSTEM_RAMTEST=y
+CONFIG_SYSTEM_RAMTEST_PRIORITY=100
+CONFIG_SYSTEM_RAMTEST_STACKSIZE=1024
+CONFIG_SYSTEM_READLINE=y
+CONFIG_READLINE_ECHO=y
+CONFIG_SYSTEM_INFORMATION=y
+CONFIG_KERNEL_CMDS=y
+CONFIG_FS_CMDS=y
+CONFIG_FSCMD_BUFFER_LEN=64
+CONFIG_NET_CMDS=y
+CONFIG_NET_PING_CMD=y
+CONFIG_NET_PING_CMD_ICOUNT=5
+CONFIG_ENABLE_DATE_CMD=y
+CONFIG_ENABLE_ENV_GET_CMD=y
+CONFIG_ENABLE_ENV_SET_CMD=y
+CONFIG_ENABLE_ENV_UNSET_CMD=y
+CONFIG_ENABLE_FREE_CMD=y
+CONFIG_ENABLE_HEAPINFO_CMD=y
+# CONFIG_HEAPINFO_USER_GROUP is not set
+# CONFIG_ENABLE_IRQINFO_CMD is not set
+CONFIG_ENABLE_KILL_CMD=y
+CONFIG_ENABLE_KILLALL_CMD=y
+CONFIG_ENABLE_PS_CMD=y
+CONFIG_ENABLE_STACKMONITOR_CMD=y
+CONFIG_STACKMONITOR_PRIORITY=100
+CONFIG_STACKMONITOR_INTERVAL=5
+CONFIG_ENABLE_UPTIME_CMD=y
+# CONFIG_SYSTEM_VI is not set
+
+#
+# Runtime Environment
+#
+CONFIG_ENABLE_IOTJS=y
+CONFIG_IOTJS_PRIORITY=100
+CONFIG_IOTJS_STACKSIZE=32768
+CONFIG_IOTJS_JERRY_HEAP=128
+
+#
+# Device Management
+#
+# CONFIG_DM is not set
+
+#
+# Task manager
+#
+# CONFIG_TASK_MANAGER is not set
+
+#
+# Event Loop Framework
+#
+# CONFIG_EVENTLOOP is not set
+
+#
+# Things Management
+#
+# CONFIG_ST_THINGS is not set
+
+#
+# IoTBus Framework
+#
+CONFIG_IOTBUS=y
+CONFIG_IOTBUS_GPIO=y
+CONFIG_IOTBUS_I2C=y
+CONFIG_IOTBUS_PWM=y
+CONFIG_IOTBUS_SPI=y
+CONFIG_IOTBUS_UART=y
index 9233391dbda4ba35b65525728f742b85cee4ae23..0c77d621c3679aa06be97bd915f97a8f2b44c2ca 100644 (file)
@@ -123,7 +123,7 @@ do {                                                                 \
     FOR##_mark = NULL;                                               \
   }                                                                  \
 } while (0)
-  
+
 /* Run the data callback FOR and consume the current byte */
 #define CALLBACK_DATA(FOR)                                           \
     CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1)
@@ -171,7 +171,7 @@ do {                                                                 \
 #define CLOSE "close"
 
 
-static const char *method_strings[] =
+static const char * const method_strings[] =
   {
 #define XX(num, name, string) #string,
   HTTP_METHOD_MAP(XX)
@@ -461,7 +461,7 @@ do {                                                                 \
 static struct {
   const char *name;
   const char *description;
-} http_strerror_tab[] = {
+} const http_strerror_tab[] = {
   HTTP_ERRNO_MAP(HTTP_STRERROR_GEN)
 };
 #undef HTTP_STRERROR_GEN
index 6517d250c697c579a55226fce794b76975ce8595..3bb753c2a3ea2eea11d7e39e7f8b7436b485d15d 100644 (file)
@@ -29,10 +29,6 @@ ID
 
 # targets
 jerry-targetjs.h
-targets/mbed/libjerry
-targets/mbed/build
-targets/mbed/yotta_modules
-targets/mbed/yotta_targets
 .output
 targets/esp8266/output.map
 targets/esp8266/libs
@@ -42,4 +38,4 @@ docs/doxygen
 
 # Tests
 tests/test262/
-tests/unit-doc/*.c
+.vs
index 337941105cf9ad61077f882b607e64f150e7e8c9..8b0b27d867d4ca317b80d9ee58161ce9094c64b0 100644 (file)
@@ -1,19 +1,13 @@
 language: c
 
-# Default test platform: Ubuntu Trusty with sudo support.
+# Default environment: Container-based (sudo-less) Ubuntu Trusty 14.04.
 os: linux
 dist: trusty
-sudo: required
+sudo: false
 
-# Default dependency installation step #1: install dependencies for linux.
-# Other platforms can change this by redefining the 'before_install' stage in
-# the matrix below.
-before_install: tools/apt-get-install-deps.sh
-
-# Default dependency installation step #2: nop intentionally.
-# Jobs can add their own dependencies on top of 'before_install' by redefinig
-# the 'install' stage in the matrix below.
-install: true
+# Default dependency installation step: nop intentionally.
+# Jobs can add their own dependencies by redefinig the 'install' stage in the matrix below.
+install: skip
 
 # Default job task: run tests as defined in the $OPT environment variable.
 # Jobs can redefine the 'script' stage in the matrix below.
@@ -22,22 +16,86 @@ script: tools/run-tests.py $OPTS
 # All the job definitions in the matrix.
 matrix:
   include:
-    - env: OPTS="--check-signed-off=travis --check-cppcheck --check-doxygen --check-vera --check-license --check-magic-strings --check-pylint"
+    - name: "Checks"
+      env:
+        - OPTS="--check-signed-off=travis --check-cppcheck --check-doxygen --check-vera --check-license --check-magic-strings --check-pylint"
       install: pip install --user pylint==1.6.5
-    - env: OPTS="--jerry-debugger"
-    - env: OPTS="--quiet --jerry-tests --jerry-test-suite"
-    - env: OPTS="--quiet --jerry-tests --jerry-test-suite --toolchain=cmake/toolchain_linux_armv7l.cmake" TIMEOUT=300
-      install: tools/apt-get-install-qemu-arm.sh
-    - env: OPTS="--buildoption-test"
-    - env: OPTS="--quiet --jerry-tests --jerry-test-suite --buildoptions=--jerry-libc=off,--compile-flag=-m32,--cpointer-32bit=on"
-    - env: OPTS="--unittests"
-    - env: OPTS="--unittests --buildoptions=--cmake-param=-DFEATURE_INIT_FINI=ON"
-    - env: OPTS="--test262"
-      install: sudo timedatectl set-timezone America/Los_Angeles
-    - os: osx
-      before_install: tools/brew-install-deps.sh
-      env: OPTS="--quiet --jerry-tests --jerry-test-suite --unittests"
-    - install: echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
+      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
+      install: tools/brew-install-deps.sh
+
+    - 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:
+        - OPTS="--quiet --jerry-tests --jerry-test-suite --skip-list=parser-oom.js,parser-oom2.js --buildoptions=--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.
@@ -50,69 +108,69 @@ matrix:
           notification_email: rsipka.uszeged@partner.samsung.com
           build_command: "tools/build.py --clean"
           branch_pattern: master
-      script: true # Changed to nop, Coverity Scan has already built the project by the time 'script' stage is reached.
-    - compiler: gcc-5
-      addons:
-        apt:
-          sources:
-            - ubuntu-toolchain-r-test
-          packages:
-            - gcc-5
-            - gcc-5-multilib
-      env: OPTS="--quiet --jerry-tests --jerry-test-suite --skip-list=parser-oom.js --buildoptions=--compile-flag=-fsanitize=address,--compile-flag=-m32,--compile-flag=-fno-omit-frame-pointer,--compile-flag=-fno-common,--compile-flag=-O2,--debug,--jerry-libc=off,--static-link=off,--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
+      script: skip # Changed to nop, Coverity Scan has already built the project by the time 'script' stage is reached.
+
+    - name: "SonarQube"
       addons:
-        apt:
-          sources:
-            - ubuntu-toolchain-r-test
-          packages:
-            - gcc-5
-            - gcc-5-multilib
-      env: OPTS="--quiet --jerry-tests --jerry-test-suite --skip-list=parser-oom.js --buildoptions=--compile-flag=-fsanitize=undefined,--compile-flag=-m32,--compile-flag=-fno-omit-frame-pointer,--compile-flag=-fno-common,--debug,--jerry-libc=off,--static-link=off,--system-allocator=on,--linker-flag=-fuse-ld=gold" UBSAN_OPTIONS=print_stacktrace=1 TIMEOUT=600
+        sonarcloud:
+          organization: "jerryscript-project"
+          token:
+            secure: "C1QD99nllAQndSDj4uIQPWCK0jBYrC5P0IrpdhfG7li7uvdzphUM++z3zkhYeeTJR3flw/cr8d9saYlbMjGw2eZ7AdJPFy4FJ1doBXD2amIuepaG1e829SLnJner9VA+d/8j28m7lZNtvZF5efbrS4KOicijNixmJy2PKG0K2035fs6MHLdywF8cJhyMaoRiMvYahIZEjXMvPBSgG1m4+A3PpzyN8XijwOT47cVtCLav4L21Mc7LcHsrc3LeyhtEJ+cs7Lx9WDQDwXX9iCRTA5ByqrXsS4rBV/N3lJI5M9p68Yj94Qy2OvVeCmUZ4ezwuuwkX00vBUk2f4eZx3oFAp973ekA8EGm/5qEvHVcbjHoHLbfUxsAKQHVoExXGdM5r1KeVgxLDT2FSQnBZLoxIrtGOUqFEOL4WX5YaQNoUKvYFO+CNvsMQkNg65QzLinRfqcH20KjzAsVeFwVI/j87J2VjooM8910savpw53iVBNPqmO/lG3kzFL7L2p1FeOuyEg9ANAbMhAXt3SL2srT0xni+ysg4Iwq+IkU+hkQWsvM8Voz+QJmiotFsi1Pzakcu3IOlT8lVVyn5q0z59YVDht/6if7acqkZ3X5vldeNIZYkImmYhMebScxVhzAa8AS6/81A+zJ8lW1+RWJQtP3uPM1+Dq18iFkPrCEMZwtoXI="
+      script: tools/check-sonarqube.sh
+      cache:
+        directories:
+          - '${HOME}/.sonar/cache'
 
-    - env: JOBNAME="ESP8266 Build Test"
+    - name: "ESP8266 Build Test"
       cache: ccache
-      install: make -f ./targets/esp8266/Makefile.travis install
+      install: make -f ./targets/esp8266/Makefile.travis install-noapt
       script: make -f ./targets/esp8266/Makefile.travis script
-    - env: JOBNAME="Mbed/K64F Build Test"
       addons:
         apt:
-          sources:
-            - sourceline: ppa:team-gcc-arm-embedded/ppa
-          packages:
-            - gcc-arm-embedded
-      install: make -f ./targets/mbed/Makefile.travis install
-      script: make -f ./targets/mbed/Makefile.travis script
-    - env: JOBNAME="Mbed OS 5/K64F Build Test"
+          packages: [gperf, texinfo, wget]
+
+    - name: "Mbed OS 5/K64F Build Test"
       addons:
         apt:
           sources:
             - sourceline: ppa:team-gcc-arm-embedded/ppa
-          packages:
-            - gcc-arm-embedded
+          packages: [gcc-arm-embedded]
       install: make -f ./targets/mbedos5/Makefile.travis install
       script: make -f ./targets/mbedos5/Makefile.travis script
-    - env: JOBNAME="NuttX/STM32F4 Build Test"
-      install: make -f targets/nuttx-stm32f4/Makefile.travis install
+
+    - name: "NuttX/STM32F4 Build Test"
+      install: make -f targets/nuttx-stm32f4/Makefile.travis install-noapt
       script: make -f targets/nuttx-stm32f4/Makefile.travis script
-    - env: JOBNAME="RIOT/STM32F4 Build Test"
-      install: make -f ./targets/riot-stm32f4/Makefile.travis install
+      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
-    - env: JOBNAME="Tizen RT/Artik053 Build Test"
+      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
+          packages: [gcc-arm-embedded]
       install: make -f ./targets/tizenrt-artik053/Makefile.travis install
       script: make -f ./targets/tizenrt-artik053/Makefile.travis script
-    - env: JOBNAME="Zephyr/Arduino 101 Build Test"
-      install: make -f ./targets/zephyr/Makefile.travis install
+
+    - name: "Zephyr/Arduino 101 Build Test"
+      install: make -f ./targets/zephyr/Makefile.travis install-noapt
       script: make -f ./targets/zephyr/Makefile.travis script
-  allow_failures:
-    - env: JOBNAME="Mbed/K64F Build Test"
-    - env: JOBNAME="Zephyr/Arduino 101 Build Test"
+      addons:
+        apt:
+          packages: [gperf, dfu-util, device-tree-compiler, python3-ply, python3-pip]
+
   fast_finish: true
 
 # The channel name "chat.freenode.net#jerryscript"
index 262009f746e0d2ad0ad889c2701aa7d941e73d75..0fea9d8c87e8802161b63e3f177b6b48a8053539 100644 (file)
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 cmake_minimum_required (VERSION 2.8.12)
-project (Jerry C ASM)
+project (Jerry C)
 
 # Determining platform
 set(PLATFORM "${CMAKE_SYSTEM_NAME}")
@@ -32,6 +32,10 @@ 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")
@@ -43,22 +47,15 @@ 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_PORT_DEFAULT      ON  CACHE BOOL "Build default jerry port implementation?")
 set(JERRY_EXT               ON  CACHE BOOL "Build jerry-ext?")
-set(JERRY_LIBC              ON  CACHE BOOL "Build and use jerry-libc?")
 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?")
 
 # Optional build settings
-set(ENABLE_ALL_IN_ONE  OFF CACHE BOOL "Enable all-in-one build?")
+set(BUILD_SHARED_LIBS  OFF CACHE BOOL "Build shared libraries?")
 set(ENABLE_LTO         ON  CACHE BOOL "Enable LTO build?")
-if(NOT DEFINED ENABLE_STATIC_LINK)
-  set(ENABLE_STATIC_LINK ON  CACHE BOOL "Enable static linking?")
-endif()
 set(ENABLE_STRIP       ON  CACHE BOOL "Enable stripping all symbols from release binary?")
 
-# Optional features
-set(FEATURE_INIT_FINI OFF CACHE BOOL "Enable init/fini arrays?")
-
 # Option overrides
 if(JERRY_CMDLINE OR JERRY_CMDLINE_TEST OR JERRY_CMDLINE_SNAPSHOT OR UNITTESTS OR DOCTESTS)
   set(JERRY_PORT_DEFAULT ON)
@@ -73,60 +70,53 @@ if(JERRY_CMDLINE OR DOCTESTS)
 endif()
 
 if("${PLATFORM}" STREQUAL "DARWIN")
-  set(JERRY_LIBC         OFF)
   set(JERRY_LIBM         OFF)
-  set(ENABLE_ALL_IN_ONE  ON)
   set(ENABLE_LTO         OFF)
-  set(ENABLE_STATIC_LINK OFF)
   set(ENABLE_STRIP       OFF)
 
-  set(JERRY_LIBC_MESSAGE         " (FORCED BY PLATFORM)")
   set(JERRY_LIBM_MESSAGE         " (FORCED BY PLATFORM)")
-  set(ENABLE_ALL_IN_ONE_MESSAGE  " (FORCED BY PLATFORM)")
   set(ENABLE_LTO_MESSAGE         " (FORCED BY PLATFORM)")
-  set(ENABLE_STATIC_LINK_MESSAGE " (FORCED BY PLATFORM)")
   set(ENABLE_STRIP_MESSAGE       " (FORCED BY PLATFORM)")
 endif()
 
 if(USING_TI)
-  set(ENABLE_STATIC_LINK ON)
   set(ENABLE_STRIP       OFF)
 
-  set(ENABLE_STATIC_LINK_MESSAGE " (FORCED BY COMPILER)")
   set(ENABLE_STRIP_MESSAGE       " (FORCED BY COMPILER)")
 endif()
 
-# Status messages
-message(STATUS "CMAKE_BUILD_TYPE          " ${CMAKE_BUILD_TYPE})
-message(STATUS "CMAKE_SYSTEM_NAME         " ${CMAKE_SYSTEM_NAME})
-message(STATUS "CMAKE_SYSTEM_PROCESSOR    " ${CMAKE_SYSTEM_PROCESSOR})
-message(STATUS "ENABLE_ALL_IN_ONE         " ${ENABLE_ALL_IN_ONE} ${ENABLE_ALL_IN_ONE_MESSAGE})
-message(STATUS "ENABLE_LTO                " ${ENABLE_LTO} ${ENABLE_LTO_MESSAGE})
-message(STATUS "ENABLE_STATIC_LINK        " ${ENABLE_STATIC_LINK} ${ENABLE_STATIC_LINK_MESSAGE})
-message(STATUS "ENABLE_STRIP              " ${ENABLE_STRIP} ${ENABLE_STRIP_MESSAGE})
-message(STATUS "JERRY_CMDLINE             " ${JERRY_CMDLINE})
-message(STATUS "JERRY_CMDLINE_TEST        " ${JERRY_CMDLINE_TEST})
-message(STATUS "JERRY_CMDLINE_SNAPSHOT    " ${JERRY_CMDLINE_SNAPSHOT})
-message(STATUS "JERRY_PORT_DEFAULT        " ${JERRY_PORT_DEFAULT} ${JERRY_PORT_DEFAULT_MESSAGE})
-message(STATUS "JERRY_EXT                 " ${JERRY_EXT} ${JERRY_EXT_MESSAGE})
-message(STATUS "JERRY_LIBC                " ${JERRY_LIBC} ${JERRY_LIBC_MESSAGE})
-message(STATUS "JERRY_LIBM                " ${JERRY_LIBM} ${JERRY_LIBM_MESSAGE})
-message(STATUS "UNITTESTS                 " ${UNITTESTS})
-message(STATUS "DOCTESTS                  " ${DOCTESTS})
-message(STATUS "FEATURE_INIT_FINI         " ${FEATURE_INIT_FINI})
-
-# Setup directories
-# Project binary dir
-set(PROJECT_BINARY_DIR "${CMAKE_BINARY_DIR}")
+if(USING_MSVC)
+  set(JERRY_LIBM         OFF)
+  set(ENABLE_STRIP       OFF)
 
-# Library output directory
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib/")
+  set(JERRY_LIBM_MESSAGE         " (FORCED BY COMPILER)")
+  set(ENABLE_STRIP_MESSAGE       " (FORCED BY COMPILER)")
+endif()
 
-# Executable output directory
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/")
+# 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})
+message(STATUS "JERRY_CMDLINE_TEST          " ${JERRY_CMDLINE_TEST})
+message(STATUS "JERRY_CMDLINE_SNAPSHOT      " ${JERRY_CMDLINE_SNAPSHOT})
+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})
 
-# Archive targets output Directory
-set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib/")
+# 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/")
 
 # Remove rdynamic option
 set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS )
@@ -146,9 +136,7 @@ endmacro()
 macro(jerry_add_compile_warnings)
   foreach(_warning ${ARGV})
     jerry_add_compile_flags(-W${_warning})
-    if(USING_GCC)
-      jerry_add_compile_flags(-Werror=${_warning})
-    endif()
+    jerry_add_compile_flags(-Werror=${_warning})
   endforeach()
 endmacro()
 
@@ -160,16 +148,9 @@ endmacro()
 jerry_add_compile_flags(${FLAGS_COMMON_ARCH})
 jerry_add_flags(CMAKE_EXE_LINKER_FLAGS ${FLAGS_COMMON_ARCH})
 
-# Enable static build
-if(ENABLE_STATIC_LINK)
-  if (USING_GCC OR USING_CLANG)
-    jerry_add_link_flags("-static")
-  endif()
-endif()
-
 # LTO
 if(ENABLE_LTO)
-  if (USING_GCC OR USING_CLANG)
+  if(USING_GCC OR USING_CLANG)
     jerry_add_compile_flags(-flto)
     jerry_add_link_flags(-flto)
   endif()
@@ -185,75 +166,59 @@ if(ENABLE_LTO)
 endif()
 
 # Compiler / Linker flags
-if (USING_GCC OR USING_CLANG)
-  jerry_add_compile_flags(-fno-builtin)
-endif()
-if(("${PLATFORM}" STREQUAL "DARWIN"))
+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>")
-else()
+  set(CMAKE_SHARED_LINKER_FLAGS  "-undefined dynamic_lookup")
+elseif(USING_GCC OR USING_CLANG)
   jerry_add_link_flags(-Wl,-z,noexecstack)
 endif()
 
-# Turn off linking to compiler's default libc, in case jerry-libc is used
-if(JERRY_LIBC)
-  jerry_add_link_flags(-nostdlib)
-endif()
-
-# Turn off stack protector
-if (USING_GCC OR USING_CLANG)
-jerry_add_compile_flags(-fno-stack-protector)
-endif()
-
-if (USING_GCC OR USING_CLANG)
+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)
+  jerry_add_compile_flags(-Wno-stack-protector -Wno-attributes -Werror)
 endif()
 
 if(USING_GCC)
   jerry_add_compile_warnings(logical-op)
-elseif(USING_CLANG)
-  jerry_add_compile_flags(-Wno-nested-anon-types -Wno-static-in-inline)
+  # 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)
+  endif()
 endif()
 
-if(JERRY_LIBC)
-  jerry_add_compile_flags(-Werror)
+if(USING_CLANG)
+  jerry_add_compile_flags(-Wno-nested-anon-types -Wno-static-in-inline)
 endif()
 
-# C
-if (USING_GCC OR USING_CLANG)
-  jerry_add_compile_flags(-std=c99 -pedantic)
-elseif(USING_TI)
+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()
+
 # Strip binary
 if(ENABLE_STRIP AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
   jerry_add_link_flags(-s)
 endif()
 
-# TODO: Remove workaround for gcc 7 bug if the
-# fallthrough comment detection is fixed.
-if (USING_GCC AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 7.0)
-  jerry_add_compile_flags(-Wno-implicit-fallthrough)
-endif()
-
 # External compiler & linker flags
 if(DEFINED EXTERNAL_COMPILE_FLAGS)
   jerry_add_compile_flags(${EXTERNAL_COMPILE_FLAGS})
-  jerry_add_flags(CMAKE_ASM_FLAGS "${EXTERNAL_COMPILE_FLAGS}")
 endif()
 
 if(DEFINED EXTERNAL_LINKER_FLAGS)
   jerry_add_link_flags(${EXTERNAL_LINKER_FLAGS})
 endif()
 
-# Jerry's libc
-if(JERRY_LIBC)
-  add_subdirectory(jerry-libc)
-endif()
-
 # Jerry's libm
 if(JERRY_LIBM)
   add_subdirectory(jerry-libm)
@@ -262,16 +227,16 @@ endif()
 # Jerry's core
 add_subdirectory(jerry-core)
 
-# Jerry's default port implementation
-if(JERRY_PORT_DEFAULT)
-  add_subdirectory(jerry-port/default)
-endif()
-
 # Jerry's extension tools
 if(JERRY_EXT)
   add_subdirectory(jerry-ext)
 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)
   add_subdirectory(jerry-main)
index 9adf79158914a3e225e881db0e9251e2a9fee389..725b3e331ae383e72a64b8123ebb8b7bbd3ef8b4 100644 (file)
@@ -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   = NO
+DISTRIBUTE_GROUP_DOC   = YES
 
 # 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            = YES
+EXTRACT_ALL            = NO
 
 # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
 # be included in the documentation.
@@ -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          = *.h *.c
 
 # The RECURSIVE tag can be used to specify whether or not subdirectories should
 # be searched for input files as well.
@@ -793,7 +793,21 @@ RECURSIVE              = YES
 # Note that relative paths are relative to the directory from which doxygen is
 # run.
 
-EXCLUDE                =
+# 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
 
 # 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
@@ -809,7 +823,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       =
+EXCLUDE_PATTERNS       = *.inc.h
 
 # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
 # (namespaces, classes, functions, etc.) that should be excluded from the
@@ -1960,7 +1974,7 @@ ENABLE_PREPROCESSING   = YES
 # The default value is: NO.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-MACRO_EXPANSION        = NO
+MACRO_EXPANSION        = YES
 
 # 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
@@ -1968,7 +1982,7 @@ MACRO_EXPANSION        = NO
 # The default value is: NO.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-EXPAND_ONLY_PREDEF     = NO
+EXPAND_ONLY_PREDEF     = YES
 
 # If the SEARCH_INCLUDES tag is set to YES, the include files in the
 # INCLUDE_PATH will be searched if a #include is found.
@@ -2000,7 +2014,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             =
+PREDEFINED             = JERRY_STATIC_ASSERT(x,y)= JERRY_ATTR_FORMAT(x,y,z)=
 
 # 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
index 77ef8034f13653c4fed0679cf9dbf2b293f660d2..75610c5dc3cfc824ab7127f577a56b2801b43d50 100644 (file)
@@ -1,9 +1,11 @@
 ![](https://github.com/jerryscript-project/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)
-[![Build Status](https://travis-ci.org/jerryscript-project/jerryscript.svg?branch=master)](https://travis-ci.org/jerryscript-project/jerryscript)
+[![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&metric=ncloc)](https://sonarcloud.io/dashboard?id=jerryscript)
 [![IRC Channel](https://img.shields.io/badge/chat-on%20freenode-brightgreen.svg)](https://kiwiirc.com/client/irc.freenode.net/#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.
@@ -22,9 +24,10 @@ Memory usage and Binary footprint are measured at [here](https://jerryscript-pro
 
 The following table shows the latest results on the devices:
 
-|  STM32F4-Discovery  | [![Remote Testrunner](https://jerryscript-project.github.io/jerryscript-test-results/status/stm32f4dis.svg)](https://jerryscript-project.github.io/jerryscript-test-results/?view=stm32) |
+|  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://jerryscript-project.github.io/jerryscript-test-results/status/rpi2.svg)](https://jerryscript-project.github.io/jerryscript-test-results/?view=rpi2)       |
+|  **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)       |
+|  **Artik053** | [![Remote Testrunner](https://firebasestorage.googleapis.com/v0/b/jsremote-testrunner.appspot.com/o/status%2Fjerryscript%2Fartik053.svg?alt=media&token=1)](https://jerryscript-project.github.io/jerryscript-test-results/?view=artik053)       |
 
 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).
diff --git a/deps/jerry/appveyor.yml b/deps/jerry/appveyor.yml
new file mode 100644 (file)
index 0000000..6e7ad0c
--- /dev/null
@@ -0,0 +1,29 @@
+version: 1.0.{build}
+pull_requests:
+  do_not_increment_build_number: true
+branches:
+  except:
+  - coverity_scan
+  - gh_pages
+skip_tags: true
+
+# Build matrix setup.
+image:
+  - Visual Studio 2017
+configuration:
+  - Debug
+  - Release
+platform:
+  - x64
+  - Win32
+
+# Steps of a job.
+init:
+  - cmake -version
+before_build:
+  - if "%PLATFORM%"=="Win32" cmake -G"Visual Studio 15 2017" -Bbuild -H.
+  - if "%PLATFORM%"=="x64" cmake -G"Visual Studio 15 2017 Win64" -Bbuild -H.
+build:
+  project: build\Jerry.sln
+  parallel: true
+  verbosity: minimal
index 17d846c53552bd90d21b270f35227651c4a31dc8..84b7a42a5bab6ac8878dd39e41dac77f6a9d9649 100644 (file)
@@ -16,7 +16,9 @@ set(CMAKE_SYSTEM_NAME TizenRT)
 set(CMAKE_SYSTEM_PROCESSOR armv7l)
 set(CMAKE_SYSTEM_VERSION ARTIK053)
 
-set(FLAGS_COMMON_ARCH -mcpu=cortex-r4 -mfpu=vfpv3 -fno-builtin -fno-strict-aliasing -fomit-frame-pointer -fno-strength-reduce -Wall -Werror -Wshadow -Wno-error=conversion)
+set(FLAGS_COMMON_ARCH -mcpu=cortex-r4 -mthumb -mfpu=vfpv3
+                      -fno-builtin -fno-strict-aliasing -fomit-frame-pointer -fno-strength-reduce
+                      -Wall -Werror -Wshadow -Wno-error=conversion)
 
 set(CMAKE_C_COMPILER arm-none-eabi-gcc)
 set(CMAKE_C_COMPILER_WORKS TRUE)
index f416259499448b4435d0ae76f5b57f51f3c2d801..d1c593fb9c69ae42471607c3955a331011cc0ee8 100644 (file)
@@ -51,20 +51,22 @@ python tools/build.py --cmake-param=CMAKE_PARAM
 python tools/build.py --profile=es5.1|es2015-subset|minimal
 ```
 
-**Use (jerry, compiler-default, external) libc**
+See also the related [README.md](https://github.com/jerryscript-project/jerryscript/blob/master/jerry-core/profiles/README.md).
 
-The default libc is jerry-libc, but you can use compiler-default libc or an external libc:
+**Use (compiler-default, external) libc**
+
+The default libc is the compiler-default libc but you can use an external libc as well:
 
 - compiler-default libc:
 
 ```bash
-python tools/build.py --jerry-libc=off
+python tools/build.py
 ```
 
 - external libc:
 
 ```bash
-python tools/build.py --jerry-libc=off --compile-flag="-nostdlib -I/path/to/ext-libc/include" --link-lib="ext-c"
+python tools/build.py --compile-flag="-nostdlib -I/path/to/ext-libc/include" --link-lib="ext-c"
 ```
 
 **Add toolchain file**
@@ -84,7 +86,7 @@ python tools/build.py --toolchain=cmake/toolchain_linux_armv7l.cmake
 **Use system memory allocator**
 
 ```bash
-python tools/build.py --system-allocator=on --jerry-libc=off
+python tools/build.py --system-allocator=on
 ```
 
 *Note*: System allocator is only supported on 32 bit systems.
index 6607bf4a5c7a82a664284fc1bd7f43fd81cd9e6a..df3726f79cc53e8098f45a4000c62c8e257f56cb 100644 (file)
@@ -13,16 +13,17 @@ Enum that contains the following elements:
 
 ## jerry_type_t
 
-Enum that contains a set of elements to represent JavaScript type:
+Enum that contains JerryScript API value types:
 
  - JERRY_TYPE_NONE - no type information
- - JERRY_TYPE_UNDEFINED - undefined value
- - JERRY_TYPE_NULL - null value
- - JERRY_TYPE_BOOLEAN - boolean value
- - JERRY_TYPE_NUMBER - number value
- - JERRY_TYPE_STRING - string value
- - JERRY_TYPE_OBJECT - object value
- - JERRY_TYPE_FUNCTION - function value
+ - JERRY_TYPE_UNDEFINED - undefined type
+ - JERRY_TYPE_NULL - null type
+ - JERRY_TYPE_BOOLEAN - boolean type
+ - JERRY_TYPE_NUMBER - number type
+ - JERRY_TYPE_STRING - string type
+ - JERRY_TYPE_OBJECT - object type
+ - JERRY_TYPE_FUNCTION - function type
+ - JERRY_TYPE_ERROR - error/abort type
 
 ## jerry_error_t
 
@@ -59,6 +60,17 @@ Possible compile time enabled feature types:
  - JERRY_FEATURE_DATE - Date support
  - JERRY_FEATURE_REGEXP - RegExp support
  - JERRY_FEATURE_LINE_INFO - line info available
+ - JERRY_FEATURE_LOGGING - logging
+
+## jerry_regexp_flags_t
+
+RegExp object optional flags:
+
+  - JERRY_REGEXP_FLAG_GLOBAL - global match; find all matches rather than stopping after the first match
+  - JERRY_REGEXP_FLAG_IGNORE_CASE - ignore case
+  - JERRY_REGEXP_FLAG_MULTILINE - multiline; treat beginning and end characters (^ and $) as working over
+  multiple lines (i.e., match the beginning or end of each line (delimited by \n or \r), not only the
+  very beginning or end of the whole input string)
 
 ## jerry_parse_opts_t
 
@@ -68,6 +80,18 @@ Option bits for [jerry_parse](#jerry_parse) and
  - JERRY_PARSE_NO_OPTS - no options passed
  - JERRY_PARSE_STRICT_MODE - enable strict mode
 
+## jerry_gc_mode_t
+
+Set garbage collection operational mode
+
+ - JERRY_GC_SEVERITY_LOW - free unused objects
+ - JERRY_GC_SEVERITY_HIGH - free as much memory as possible
+
+The difference between `JERRY_GC_SEVERITY_LOW` and `JERRY_GC_SEVERITY_HIGH`
+is that the former keeps memory allocated for performance improvements such
+as property hash tables for large objects. The latter frees all possible
+memory blocks but the performance may drop after the garbage collection.
+
 ## jerry_generate_snapshot_opts_t
 
 Flags for [jerry_generate_snapshot](#jerry_generate_snapshot) and
@@ -129,18 +153,6 @@ Jerry's char value
 typedef uint8_t jerry_char_t;
 ```
 
-## jerry_char_ptr_t
-
-**Summary**
-
-Pointer to an array of character values
-
-**Prototype**
-
-```c
-typedef jerry_char_t *jerry_char_ptr_t;
-```
-
 ## jerry_size_t
 
 **Summary**
@@ -236,6 +248,34 @@ typedef struct
 } jerry_context_data_manager_t;
 ```
 
+## jerry_context_alloc_t
+
+**Summary**
+
+Function type for allocating buffer for JerryScript context.
+
+**Prototype**
+
+```c
+typedef void *(*jerry_context_alloc_t) (size_t size, void *cb_data_p);
+```
+
+- `size` - allocation size
+- `cb_data_p` - pointer to user data
+
+
+## jerry_context_t
+
+**Summary**
+
+An opaque declaration of the JerryScript context structure.
+
+**Prototype**
+
+```c
+typedef struct jerry_context_t jerry_context_t;
+```
+
 ## jerry_property_descriptor_t
 
 **Summary**
@@ -320,20 +360,6 @@ typedef jerry_value_t (*jerry_external_handler_t) (const jerry_value_t function_
                                                    const jerry_length_t args_count);
 ```
 
-## jerry_object_free_callback_t
-
-**Summary**
-
-**Deprecated: Please use jerry_object_native_free_callback_t instead.**
-
-Native free callback of an object.
-
-**Prototype**
-
-```c
-typedef void (*jerry_object_free_callback_t) (const uintptr_t native_p);
-```
-
 ## jerry_object_native_free_callback_t
 
 **Summary**
@@ -350,7 +376,7 @@ typedef void (*jerry_object_native_free_callback_t) (void *native_p);
 
 **Summary**
 
-The type infomation of the native pointer.
+The type information of the native pointer.
 It includes the free callback that will be called when associated JavaScript object is garbage collected. It can be left NULL in case it is not needed.
 
 Typically, one would create a `static const jerry_object_native_info_t` for
@@ -618,7 +644,7 @@ Registers an external magic string array.
 
 ```c
 void
-jerry_register_magic_strings  (const jerry_char_ptr_t *ex_str_items_p,
+jerry_register_magic_strings  (const jerry_char_t * const *ex_str_items_p,
                                uint32_t count,
                                const jerry_length_t *str_lengths_p);
 ```
@@ -641,12 +667,12 @@ main (void)
 
   // 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));
+  static const jerry_char_t * const 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[] = {
@@ -662,48 +688,7 @@ main (void)
 
 - [jerry_init](#jerry_init)
 - [jerry_cleanup](#jerry_cleanup)
-- [jerry_parse_and_save_literals](#jerry_parse_and_save_literals)
-
-
-## jerry_get_memory_limits
-
-**Summary**
-
-Gets configured memory limits of JerryScript.
-
-**Prototype**
-
-```c
-void
-jerry_get_memory_limits (size_t *out_data_bss_brk_limit_p,
-                         size_t *out_stack_limit_p);
-```
-
-- `out_data_bss_brk_limit_p` - out parameter, that gives the maximum size of data + bss + brk sections.
-- `out_stack_limit_p` - out parameter, that gives the maximum size of the stack.
-
-**Example**
-
-[doctest]: # ()
-
-```c
-#include "jerryscript.h"
-
-int
-main (void)
-{
-  jerry_init (JERRY_INIT_EMPTY);
-
-  size_t stack_limit;
-  size_t data_bss_brk_limit;
-  jerry_get_memory_limits (&stack_limit, &data_bss_brk_limit);
-}
-```
-
-**See also**
-
-- [jerry_init](#jerry_init)
-- [jerry_cleanup](#jerry_cleanup)
+- [jerry_get_literals_from_snapshot](#jerry_get_literals_from_snapshot)
 
 
 ## jerry_get_memory_stats
@@ -746,13 +731,30 @@ Performs garbage collection.
 
 ```c
 void
-jerry_gc (void);
+jerry_gc (jerry_gc_mode_t mode);
 ```
 
+- `mode` - operational mode, see [jerry_gc_mode_t](#jerry_gc_mode_t)
+
 **Example**
 
+[doctest]: # ()
+
 ```c
-jerry_gc ();
+#include "jerryscript.h"
+
+int
+main (void)
+{
+  jerry_init (JERRY_INIT_EMPTY);
+
+  jerry_value_t object_value = jerry_create_object ();
+  jerry_release_value (object_value);
+
+  jerry_gc (JERRY_GC_SEVERITY_LOW);
+
+  jerry_cleanup ();
+}
 ```
 
 **See also**
@@ -791,15 +793,14 @@ jerry_run_simple (const jerry_char_t *script_source_p,
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 
 int
 main (void)
 {
-  const jerry_char_t *script = (const jerry_char_t *) "print ('Hello, World!');";
+  const jerry_char_t script[] = "print ('Hello, World!');";
 
-  jerry_run_simple (script, strlen ((const char *) script), JERRY_INIT_EMPTY);
+  jerry_run_simple (script, sizeof (script) - 1, JERRY_INIT_EMPTY);
 }
 ```
 
@@ -847,7 +848,6 @@ jerry_parse (const jerry_char_t *resource_name_p, /**< resource name (usually a
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 
 int
@@ -856,9 +856,8 @@ main (void)
   jerry_init (JERRY_INIT_EMPTY);
 
   const jerry_char_t script[] = "print ('Hello, World!');";
-  size_t script_size = strlen ((const char *) script);
 
-  jerry_value_t parsed_code = jerry_parse (NULL, 0, script, script_size, JERRY_PARSE_NO_OPTS);
+  jerry_value_t parsed_code = jerry_parse (NULL, 0, script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
   jerry_release_value (parsed_code);
 
   jerry_cleanup ();
@@ -932,22 +931,20 @@ jerry_run (const jerry_value_t func_val);
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 
 int
 main (void)
 {
   const jerry_char_t script[] = "print ('Hello, World!');";
-  size_t script_size = strlen ((const char *) script);
 
   /* Initialize engine */
   jerry_init (JERRY_INIT_EMPTY);
 
   /* Setup Global scope code */
-  jerry_value_t parsed_code = jerry_parse (NULL, 0, script, script_size, JERRY_PARSE_NO_OPTS);
+  jerry_value_t parsed_code = jerry_parse (NULL, 0, script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
 
-  if (!jerry_value_has_error_flag (parsed_code))
+  if (!jerry_value_is_error (parsed_code))
   {
     /* Execute the parsed source code in the Global scope */
     jerry_value_t ret_value = jerry_run (parsed_code);
@@ -981,12 +978,12 @@ Perform JavaScript `eval`.
 jerry_value_t
 jerry_eval (const jerry_char_t *source_p,
             size_t source_size,
-            bool is_strict);
+            uint32_t parse_opts);
 ```
 
 - `source_p` - source code to evaluate, it must be a valid utf8 string.
 - `source_size` - length of the source code
-- `is_strict` - perform `eval` as it is called from "strict mode" code.
+- `parse_opts` - any combination of [jerry_parse_opts_t](#jerry_parse_opts_t) flags.
 - return value - result of eval, may be error value.
 
 **Example**
@@ -995,7 +992,7 @@ jerry_eval (const jerry_char_t *source_p,
 {
   jerry_value_t ret_val = jerry_eval (str_to_eval,
                                       strlen (str_to_eval),
-                                      false);
+                                      JERRY_PARSE_NO_OPTS);
 }
 ```
 
@@ -1024,7 +1021,6 @@ jerry_run_all_enqueued_jobs (void)
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 
 int
@@ -1033,9 +1029,8 @@ main (void)
   jerry_init (JERRY_INIT_EMPTY);
 
   const jerry_char_t script[] = "new Promise(function(f,r) { f('Hello, World!'); }).then(function(x) { print(x); });";
-  size_t script_size = strlen ((const char *) script);
 
-  jerry_value_t parsed_code = jerry_parse (NULL, 0, script, script_size, JERRY_PARSE_NO_OPTS);
+  jerry_value_t parsed_code = jerry_parse (NULL, 0, script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
   jerry_value_t script_value = jerry_run (parsed_code);
   jerry_value_t job_value = jerry_run_all_enqueued_jobs ();
 
@@ -1089,6 +1084,45 @@ jerry_get_global_object (void);
 
 Functions to check the type of an API value ([jerry_value_t](#jerry_value_t)).
 
+## jerry_value_is_abort
+
+**Summary**
+
+Returns whether the given `jerry_value_t` has the error and abort value set.
+
+**Prototype**
+
+```c
+bool
+jerry_value_is_abort (const jerry_value_t value);
+```
+
+- `value` - api value
+- return value
+  - true, if the given `jerry_value_t` has the error and abort value set
+  - false, otherwise
+
+**Example**
+
+```c
+{
+  jerry_value_t value;
+  ... // create or acquire value
+
+  if (jerry_value_is_abort (value))
+  {
+    ...
+  }
+
+  jerry_release_value (value);
+}
+```
+
+**See also**
+
+- [jerry_value_t](#jerry_value_t)
+- [jerry_value_is_error](#jerry_value_is_error)
+
 ## jerry_value_is_array
 
 **Summary**
@@ -1244,6 +1278,44 @@ jerry_value_is_constructor (const jerry_value_t value)
 
 - [jerry_release_value](#jerry_release_value)
 
+## jerry_value_is_error
+
+**Summary**
+
+Returns whether the given `jerry_value_t` is error value.
+
+**Prototype**
+
+```c
+bool
+jerry_value_is_error (const jerry_value_t value);
+```
+
+- `value` - api value
+- return value
+  - true, if the given `jerry_value_t` is error value.
+  - false, otherwise
+
+**Example**
+
+```c
+{
+  jerry_value_t value;
+  ... // create or acquire value
+
+  if (jerry_value_is_error (value))
+  {
+    ...
+  }
+
+  jerry_release_value (value);
+}
+```
+
+**See also**
+
+- [jerry_value_t](#jerry_value_t)
+- [jerry_value_is_abort](#jerry_value_is_abort)
 
 ## jerry_value_is_function
 
@@ -1565,7 +1637,7 @@ jerry_value_is_undefined (const jerry_value_t value)
 Returns the JavaScript type
 for a given value as a [jerry_type_t](#jerry_type_t) enum value.
 
-This is a similar operation as the 'typeof' operator
+This is a similar operation to the 'typeof' operator
 in the standard with an exception that the 'null'
 value has its own enum value.
 
@@ -1631,79 +1703,55 @@ jerry_is_feature_enabled (const jerry_feature_t feature);
 
 # Error manipulation functions
 
-## jerry_get_error_type
+## jerry_create_abort_from_value
 
 **Summary**
 
-Returns the type of the Error object if possible.
+Create (api) abort from a value.
 
-If a non-error object is used as the input for the function the method
-will return `JERRY_ERROR_NONE` indicating that the value was not
-an Error object. However it is still possible that the value contains
-error semantics. To correctly detect if a value have error use the
-[jerry_value_has_error_flag](#jerry_value_has_error_flag) method.
+This function creates an API abort value from an API value. The second argument defines
+whether the input value must be released or not. If it is set to `true`,
+then a [`jerry_release_value`](#jerry_release_value) function will be called
+for the first argument, so the api value won't be available after the call of
+`jerry_create_abort_from_value`. The second argument should be false if both value
+and created abort value are needed.
 
 **Prototype**
 
 ```c
-jerry_error_t
-jerry_get_error_type (const jerry_value_t value);
+jerry_value_t
+jerry_create_abort_from_value (jerry_value_t value, bool release);
 ```
 
-- `value` - api value (possible error object)
-- return value
-  - JERRY_ERROR_NONE if the input is not an error object
-  - one of the [jerry_error_t](#jerry_error_t) value
+- `value` - api value
+- `release` - raw boolean, defines whether input value must be released
+- return value - abort (api) value
 
-**Example**
+**Example 1**
 
 ```c
 {
-  jerry_value_t error_obj = jerry_create_error (JERRY_ERROR_RANGE,
-                                                (const jerry_char_t *) "error msg");
-  jerry_error_t error_type = jerry_get_error_type (error_obj);
+  jerry_value_t value;
+  ... // create or acquire value
 
-  // error_type is now JERRY_ERROR_RANGE.
+  jerry_value_t abort = jerry_create_abort_from_value (value, true);
+  // using the 'value' variable after release is invalid.
 
-  jerry_release_value (error_obj);
+  jerry_release_value (abort);
 }
 ```
 
-**See also**
-
-- [jerry_create_error](#jerry_create_error)
-- [jerry_value_has_error_flag](#jerry_value_has_error_flag)
-
-## jerry_value_has_error_flag
-
-**Summary**
-
-Returns whether the given `jerry_value_t` has the error flag set.
-
-**Prototype**
-
-```c
-bool
-jerry_value_has_error_flag (const jerry_value_t value);
-```
-
-- `value` - api value
-- return value
-  - true, if the given `jerry_value_t` has the error flag set
-  - false, otherwise
-
-**Example**
+**Example 2**
 
 ```c
 {
   jerry_value_t value;
   ... // create or acquire value
 
-  if (jerry_value_has_error_flag (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);
 }
 ```
@@ -1711,73 +1759,59 @@ jerry_value_has_error_flag (const jerry_value_t value);
 **See also**
 
 - [jerry_value_t](#jerry_value_t)
-- [jerry_value_has_abort_flag](#jerry_value_has_abort_flag)
-
+- [jerry_get_value_from_error](#jerry_get_value_from_error)
+- [jerry_create_error_from_value](#jerry_create_error_from_value)
 
-## jerry_value_has_abort_flag
+## jerry_create_error_from_value
 
 **Summary**
 
-Returns whether the given `jerry_value_t` has the error and abort flags set.
+Create (api) error from a value.
+
+This function creates an API error value from an API value. The second argument defines
+whether the input value must be released or not. If it is set to `true`,
+then a [`jerry_release_value`](#jerry_release_value) function will be called
+for the first argument, so the api value won't be available after the call of
+`jerry_create_error_from_value`. The second argument should be false if both value
+and created error value are needed.
 
 **Prototype**
 
 ```c
-bool
-jerry_value_has_abort_flag (const jerry_value_t value);
+jerry_value_t
+jerry_create_error_from_value (jerry_value_t value, bool release);
 ```
 
 - `value` - api value
-- return value
-  - true, if the given `jerry_value_t` has the error and abort flags set
-  - false, otherwise
+- `release` - raw boolean, defines whether input value must be released
+- return value - error (api) value
 
-**Example**
+**Example 1**
 
 ```c
 {
   jerry_value_t value;
   ... // create or acquire value
 
-  if (jerry_value_has_abort_flag (value))
-  {
-    ...
-  }
-
-  jerry_release_value (value);
-}
-```
-
-**See also**
-
-- [jerry_value_t](#jerry_value_t)
-- [jerry_value_has_error_flag](#jerry_value_has_error_flag)
+  jerry_value_t error = jerry_create_error_from_value (value, true);
+  // using the 'value' variable after release is invalid.
 
 
-## jerry_value_clear_error_flag
-
-**Summary**
-
-Clear both the error and abort flags.
-
-**Prototype**
-
-```c
-void
-jerry_value_clear_error_flag (jerry_value_t *value_p);
+  jerry_release_value (error);
+}
 ```
 
-- `value_p` - pointer to an api value
-
-**Example**
+**Example 2**
 
 ```c
 {
   jerry_value_t value;
   ... // create or acquire value
 
-  jerry_value_clear_error_flag (&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);
 }
 ```
@@ -1785,122 +1819,116 @@ jerry_value_clear_error_flag (jerry_value_t *value_p);
 **See also**
 
 - [jerry_value_t](#jerry_value_t)
-- [jerry_value_set_error_flag](#jerry_value_set_error_flag)
-- [jerry_value_set_abort_flag](#jerry_value_set_abort_flag)
+- [jerry_get_value_from_error](#jerry_get_value_from_error)
+- [jerry_create_abort_from_value](#jerry_create_abort_from_value
 
-
-## jerry_value_set_error_flag
+## jerry_get_error_type
 
 **Summary**
 
-Set the error flag.
+Returns the type of the Error object if possible.
+
+If a non-error object is used as the input for the function the method
+will return `JERRY_ERROR_NONE` indicating that the value was not
+an Error object. However it is still possible that the value contains
+error semantics. To correctly detect if a value have error use the
+[jerry_value_is_error](#jerry_value_is_error) method.
 
 **Prototype**
 
 ```c
-void
-jerry_value_set_error_flag (jerry_value_t *value_p);
+jerry_error_t
+jerry_get_error_type (const jerry_value_t value);
 ```
 
-- `value_p` - pointer to an api value
+- `value` - api value (possible error object)
+- return value
+  - JERRY_ERROR_NONE if the input is not an error object
+  - one of the [jerry_error_t](#jerry_error_t) value
 
 **Example**
 
 ```c
 {
-  jerry_value_t value;
-  ... // create or acquire value
+  jerry_value_t error_obj = jerry_create_error (JERRY_ERROR_RANGE,
+                                                (const jerry_char_t *) "error msg");
+  jerry_error_t error_type = jerry_get_error_type (error_obj);
 
-  jerry_value_set_error_flag (&value);
+  // error_type is now JERRY_ERROR_RANGE.
 
-  jerry_release_value (value);
+  jerry_release_value (error_obj);
 }
 ```
 
 **See also**
 
-- [jerry_value_t](#jerry_value_t)
-- [jerry_value_clear_error_flag](#jerry_value_clear_error_flag)
-- [jerry_value_set_abort_flag](#jerry_value_set_abort_flag)
-
+- [jerry_create_error](#jerry_create_error)
+- [jerry_value_is_error](#jerry_value_is_error)
 
-## jerry_value_set_abort_flag
+## jerry_get_value_from_error
 
 **Summary**
 
-Set both the error and abort flags.
+Get the value from an error.
+
+Many API functions cannot be called with an error value.
+This function extracts the API value from an error. The second argument defines
+whether the input error value must be released or not. If it is set to `true`,
+then a [`jerry_release_value`](#jerry_release_value) function will be called
+for the first argument, so the error value won't be available after the call of
+`jerry_get_value_from_error`. The second argument should be false if both error
+and its represented value are needed.
+
+*Note*: Returned value must be freed with [jerry_release_value](#jerry_release_value) when it
+is no longer needed.
 
 **Prototype**
 
 ```c
-void
-jerry_value_set_abort_flag (jerry_value_t *value_p);
+jerry_value_t
+jerry_get_value_from_error (jerry_value_t value, bool release)
 ```
 
-- `value_p` - pointer to an api value
+- `value` - error (api) value
+- `release` - raw boolean, defines whether input value must be released
+- return value - api value
 
-**Example**
+**Example 1**
 
 ```c
 {
   jerry_value_t value;
   ... // create or acquire value
 
-  jerry_value_set_abort_flag (&value);
+  jerry_value_t error = jerry_create_error_from_value (value, true);
+  jerry_value_t value_from_error = jerry_get_value_from_error (error, true);
+  // using the 'error' variable after release is invalid.
 
-  jerry_release_value (value);
+  jerry_release_value (value_from_error);
 }
 ```
 
-**See also**
-
-- [jerry_value_t](#jerry_value_t)
-- [jerry_value_clear_error_flag](#jerry_value_clear_error_flag)
-- [jerry_value_set_error_flag](#jerry_value_set_error_flag)
-
-
-## jerry_get_value_without_error_flag
-
-**Summary**
-
-If the input value is an error value, then return a new reference to its referenced value.
-Otherwise, return a new reference to the value itself.
-
-*Note*: Returned value must be freed with [jerry_release_value](#jerry_release_value)
-when it is no longer needed.
-
-**Prototype**
-
-```c
-jerry_value_t
-jerry_get_value_without_error_flag (jerry_value_t value)
-```
-
-- `value` - api value
-
-**Example**
+**Example 2**
 
 ```c
 {
   jerry_value_t value;
   ... // create or acquire value
 
-  jerry_value_set_error_flag (&value);
-
-  jerry_value_t real_value = jerry_get_value_without_error_flag (value);
-  ... // process the real_value. Different from `jerry_value_clear_error_flag`,
-      // the error `value` will not be automatically released after calling
-      // `jerry_get_value_without_error_flag`.
+  jerry_value_t error = jerry_create_error_from_value (value, true);
+  jerry_value_t value_from_error = jerry_get_value_from_error (error, false);
+  // both 'error' and 'value_from_error' can be used and must be released when they are no longer needed
 
-  jerry_release_value (value);
-  jerry_release_value (real_value);
+  jerry_release_value (value_from_error);
+  jerry_release_value (error);
 }
 ```
 
 **See also**
 
-- [jerry_acquire_value](#jerry_acquire_value)
-- [jerry_value_clear_error_flag](#jerry_value_clear_error_flag)
+- [jerry_value_t](#jerry_value_t)
+- [jerry_create_error_from_value](#jerry_create_error_from_value)
+- [jerry_create_abort_from_value](#jerry_create_abort_from_value)
 
 # Getter functions of 'jerry_value_t'
 
@@ -2647,7 +2675,7 @@ jerry_resolve_or_reject_promise (jerry_value_t promise,
                                                          argument,
                                                          is_resolve);
 
-  if (jerry_value_has_error_flag (is_ok))
+  if (jerry_value_is_error (is_ok))
   {
     // handle the error.
   }
@@ -2661,7 +2689,7 @@ jerry_resolve_or_reject_promise (jerry_value_t promise,
 **See also**
 
 - [jerry_release_value](#jerry_release_value)
-- [jerry_value_has_error_flag](#jerry_value_has_error_flag)
+- [jerry_value_is_error](#jerry_value_is_error)
 
 
 # Acquire and release API values
@@ -2935,9 +2963,9 @@ jerry_create_error (jerry_error_t error_type,
 
 **See also**
 
-- [jerry_value_has_error_flag](#jerry_value_has_error_flag)
-- [jerry_value_clear_error_flag](#jerry_value_clear_error_flag)
-- [jerry_value_set_error_flag](#jerry_value_set_error_flag)
+- [jerry_value_is_error](#jerry_value_is_error)
+- [jerry_get_value_from_error](#jerry_get_value_from_error)
+- [jerry_create_error_from_value](#jerry_create_error_from_value)
 
 
 ## jerry_create_error_sz
@@ -2964,10 +2992,10 @@ jerry_create_error_sz (jerry_error_t error_type,
 
 ```c
 {
-  const jerry_char_t *message = "error";
+  const jerry_char_t message[] = "error";
   jerry_value_t error_obj = jerry_create_error_sz (JERRY_ERROR_COMMON,
                                                    message,
-                                                   strlen ((const char *) message));
+                                                   sizeof (message) - 1);
 
   ... // usage of error_obj
 
@@ -3295,7 +3323,7 @@ jerry_create_string_sz (const jerry_char_t *str_p,
 {
   const jerry_char_t char_array[] = "a string";
   jerry_value_t string_value  = jerry_create_string_sz (char_array,
-                                                        strlen ((const char *) char_array));
+                                                        sizeof (char_array) - 1);
 
   ... // usage of string_value
 
@@ -3373,7 +3401,7 @@ jerry_create_string_sz (const jerry_char_t *str_p,
 {
   const jerry_char_t char_array[] = "a string";
   jerry_value_t string_value  = jerry_create_string_sz_from_utf8 (char_array,
-                                                                  strlen ((const char *) char_array));
+                                                                  sizeof (char_array) - 1);
 
   ... // usage of string_value
 
@@ -3388,6 +3416,74 @@ jerry_create_string_sz (const jerry_char_t *str_p,
 - [jerry_create_string_from_utf8](#jerry_create_string_from_utf8)
 
 
+## jerry_create_regexp
+
+**Summary**
+
+Returns a jerry_value_t RegExp object or an error, if the construction of the object fails.
+Optional flags can be set using [jerry_regexp_flags_t](#jerry_regexp_flags_t);
+
+**Prototype**
+```c
+jerry_value_t
+jerry_create_regexp (const jerry_char_t *pattern_p, jerry_regexp_flags_t flags);
+```
+
+- `pattern_p` - the RegExp pattern as a zero-terminated UTF-8 string
+- `flags` - optional flags for the RegExp object
+- return value - the RegExp object as a `jerry_value_t`
+
+**Example**
+
+```c
+{
+  jerry_char_t pattern_p = "[cgt]gggtaaa|tttaccc[acg]";
+  jerry_regexp_flags_t pattern_flags = JERRY_REGEXP_FLAG_IGNORE_CASE;
+
+  jerry_value_t regexp = jerry_create_regexp (pattern_p, pattern_flags);
+
+  ...
+
+  jerry_release_value (regexp);
+}
+```
+
+
+## jerry_create_regexp_sz
+
+**Summary**
+
+Returns a jerry_value_t RegExp object or an error, if the construction of the object fails.
+Optional flags can be set using [jerry_regexp_flags_t](#jerry_regexp_flags_t);
+
+**Prototype**
+```c
+jerry_value_t
+jerry_create_regexp_sz (const jerry_char_t *pattern_p, jerry_size_t pattern_size, jerry_regexp_flags_t flags);
+```
+
+- `pattern_p` - the RegExp pattern as a zero-terminated UTF-8 string
+- `pattern_size` - size of the `pattern`
+- `flags` - optional flags for the RegExp object
+- return value - the RegExp object as a `jerry_value_t`
+
+**Example**
+
+```c
+{
+  jerry_char_t pattern_p = "[cgt]gggtaaa|tttaccc[acg]";
+  jerry_size_t pattern_size = sizeof (pattern_p) - 1;
+  jerry_regexp_flags_t pattern_flags = JERRY_REGEXP_FLAG_IGNORE_CASE;
+
+  jerry_value_t regexp = jerry_create_regexp_sz (pattern_p, pattern_size, pattern_flags);
+
+  ...
+
+  jerry_release_value (regexp);
+}
+```
+
+
 ## jerry_create_typedarray
 
 **Summary**
@@ -3774,7 +3870,7 @@ jerry_get_property (const jerry_value_t obj_val,
   jerry_value_t global_object = jerry_get_global_object ();
   jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "my_prop");
 
-  jerry_value_t prop_value = jerry_get_property (obj_val, prop_name);
+  jerry_value_t prop_value = jerry_get_property (global_object, prop_name);
 
   jerry_release_value (prop_name);
   jerry_release_value (global_object);
@@ -4174,7 +4270,7 @@ jerry_call_function (const jerry_value_t func_obj_val,
     jerry_value_t this_val = jerry_create_undefined ();
     jerry_value_t ret_val = jerry_call_function (val, this_val, NULL, 0);
 
-    if (!jerry_value_has_error_flag (ret_val))
+    if (!jerry_value_is_error (ret_val))
     {
       ... // handle return value
     }
@@ -4229,7 +4325,7 @@ jerry_construct_object (const jerry_value_t func_obj_val,
   {
     jerry_value_t ret_val = jerry_construct_object (val, NULL, 0);
 
-    if (!jerry_value_has_error_flag (ret_val))
+    if (!jerry_value_is_error (ret_val))
     {
       ... // handle return value
     }
@@ -4364,106 +4460,6 @@ jerry_set_prototype (const jerry_value_t obj_val,
 - [jerry_get_prototype](#jerry_get_prototype)
 
 
-## jerry_get_object_native_handle
-
-**Summary**
-
-**Deprecated: Please use jerry_get_object_native_pointer instead.**
-
-Get native handle, previously associated with specified object.
-
-**Prototype**
-
-```c
-bool
-jerry_get_object_native_handle (const jerry_value_t obj_val,
-                                uintptr_t *out_handle_p);
-```
-
-- `obj_val` - object value
-- `out_handle_p` - handle value (output parameter).
-- return value
-  - true, if there is handle associated with the object
-  - false, otherwise
-
-**Example**
-
-```c
-{
-  jerry_value_t object;
-  uintptr_t handle_set;
-
-  ... // receive or construct object and handle_set value
-
-  jerry_set_object_native_handle (object, handle_set, NULL);
-
-  ...
-
-  uintptr_t handle_get;
-  bool is_there_associated_handle = jerry_get_object_native_handle (object, &handle_get);
-}
-```
-
-**See also**
-
-- [jerry_create_object](#jerry_create_object)
-- [jerry_set_object_native_handle](#jerry_set_object_native_handle)
-- [jerry_get_object_native_pointer](#jerry_get_object_native_pointer)
-
-
-## jerry_set_object_native_handle
-
-**Summary**
-
-**Deprecated: Please use jerry_set_object_native_pointer instead.**
-
-Set native handle and an optional free callback for the specified object.
-
-*Note*: If native handle was already set for the object, its value is updated.
-
-*Note*: If a non-NULL free callback is specified, it will be called
-        by the garbage collector when the object is freed. The free
-        callback always overwrites the previous value, so passing
-        a NULL value deletes the current free callback.
-
-**Prototype**
-
-```c
-void
-jerry_set_object_native_handle (const jerry_value_t obj_val,
-                                uintptr_t handle_p,
-                                jerry_object_free_callback_t freecb_p);
-```
-
-- `obj_val` - object value to set handle in
-- `handle_p` - handle value
-- `freecb_p` - pointer to "free" callback or NULL
-
-**Example**
-
-```c
-{
-  jerry_value_t object;
-  uintptr_t handle_set;
-
-  ... // receive or construct object and handle_set value
-
-  jerry_set_object_native_handle (object, handle_set, NULL);
-
-  ...
-
-  uintptr_t handle_get;
-  bool is_there_associated_handle = jerry_get_object_native_handle (object, &handle_get);
-}
-```
-
-**See also**
-
-- [jerry_create_object](#jerry_create_object)
-- [jerry_get_object_native_handle](#jerry_get_object_native_handle)
-- [jerry_set_object_native_pointer](#jerry_set_object_native_pointer)
-
-
 ## jerry_get_object_native_pointer
 
 **Summary**
@@ -4484,7 +4480,7 @@ The pointer and the type information are previously associated with the object b
         and dereferencing `out_native_pointer_p`.
 
 *Note*: `out_native_pointer_p` and `out_native_info_p` can be NULL, and it means the
-        caller doesn't want to get the native_pointer or type infomation.
+        caller doesn't want to get the native_pointer or type information.
 
 **Prototype**
 
@@ -4497,7 +4493,7 @@ jerry_get_object_native_pointer (const jerry_value_t obj_val,
 
 - `obj_val` - object value to get native pointer from.
 - `out_native_pointer_p` - native pointer (output parameter).
-- `out_native_info_p` - native pointer's type infomation (output parameter).
+- `out_native_info_p` - native pointer's type information (output parameter).
 - return value
   - true, if there is native pointer associated with the object
   - false, otherwise
@@ -4594,7 +4590,7 @@ jerry_set_object_native_pointer (const jerry_value_t obj_val,
 
 - `obj_val` - object to set native pointer in.
 - `native_p` - native pointer.
-- `info_p` - native pointer's type infomation or NULL. When used, this should
+- `info_p` - native pointer's type information or NULL. When used, this should
              be a long-lived pointer, usually a pointer to a
              `static const jerry_object_native_info_t` makes most sense.
 
@@ -4700,7 +4696,7 @@ find_my_object(const jerry_value_t candidate,
 {
   find_my_object_info_t *info_p = (find_my_object_info_t *) user_data_p;
   jerry_value_t has_property = jerry_object_has_property (candidate, info_p->property_name);
-  bool keep_searching = (jerry_value_has_error_flag (has_property) || !jerry_get_boolean_value ());
+  bool keep_searching = (jerry_value_is_error (has_property) || !jerry_get_boolean_value ());
   if (!keep_searching)
   {
     /* We found it, so we acquire the value and record it. */
@@ -4752,7 +4748,7 @@ bool jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *nat
                                            void *user_data_p);
 ```
 
-- `native_info_p` - native pointer's type infomation.
+- `native_info_p` - native pointer's type information.
 - return value
   - `true`, if the search function terminated the traversal by returning `false`
   - `false`, if the end of the list of objects was reached
@@ -4867,16 +4863,15 @@ jerry_is_valid_utf8_string (const jerry_char_t *utf8_buf_p, /**< UTF-8 string */
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 
 int
 main (void)
 {
   const jerry_char_t script[] = "print ('Hello, World!');";
-  size_t script_size = strlen ((const char *) script);
+  const jerry_size_t script_size = sizeof (script) - 1;
 
-  if (jerry_is_valid_utf8_string (script, (jerry_size_t) script_size))
+  if (jerry_is_valid_utf8_string (script, script_size))
   {
     jerry_run_simple (script, script_size, JERRY_INIT_EMPTY);
   }
@@ -4915,7 +4910,6 @@ jerry_is_valid_cesu8_string (const jerry_char_t *cesu8_buf_p, /**< CESU-8 string
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 
 int
@@ -4924,12 +4918,12 @@ main (void)
   jerry_init (JERRY_INIT_EMPTY);
 
   const jerry_char_t script[] = "Hello, World!";
-  size_t script_size = strlen ((const char *) script);
+  const jerry_size_t script_size = sizeof (script) - 1;
 
-  if (jerry_is_valid_cesu8_string (script, (jerry_size_t) script_size))
+  if (jerry_is_valid_cesu8_string (script, script_size))
   {
     jerry_value_t string_value = jerry_create_string_sz (script,
-                                                         (jerry_size_t) script_size);
+                                                         script_size);
 
     // usage of string_value
 
@@ -4950,6 +4944,151 @@ main (void)
 - [jerry_substring_to_char_buffer](#jerry_substring_to_char_buffer)
 
 
+# Dynamic memory management functions
+
+## jerry_heap_alloc
+
+**Summary**
+
+Allocate memory on the engine's heap.
+
+*Note*: This function may take away memory from the executed JavaScript code.
+If any other dynamic memory allocation API is available (e.g., libc malloc), it
+should be used instead.
+
+**Prototype**
+
+```c
+void *jerry_heap_alloc (size_t size);
+```
+
+- `size`: size of the memory block.
+- return value: non-NULL pointer, if the memory is successfully allocated,
+                NULL otherwise.
+
+**See also**
+
+- [jerry_heap_free](#jerry_heap_free)
+
+## jerry_heap_free
+
+**Summary**
+
+Free memory allocated on the engine's heap.
+
+**Prototype**
+
+```c
+void jerry_heap_free (void *mem_p, size_t size);
+```
+
+- `mem_p`: value returned by `jerry_heap_alloc`.
+- `size`: same size as passed to `jerry_heap_alloc`.
+
+**See also**
+
+- [jerry_heap_alloc](#jerry_heap_alloc)
+
+
+# External context functions
+
+## jerry_create_context
+
+**Summary**
+
+Create an external JerryScript engine context.
+
+**Prototype**
+
+```c
+jerry_context_t *
+jerry_create_context (uint32_t heap_size,
+                      jerry_context_alloc_t alloc,
+                      void *cb_data_p);
+```
+
+- `heap_size` - requested heap size of the JerryScript context
+- `alloc` - function for allocation
+- `cb_data_p` - user data
+- return value
+  - pointer to the newly created JerryScript context if success
+  - NULL otherwise.
+
+**Example**
+
+[doctest]: # (test="compile")
+
+```c
+#include <stdlib.h>
+#include <pthread.h>
+
+#include "jerryscript.h"
+#include "jerryscript-port.h"
+
+/* A different Thread Local Storage variable for each jerry context. */
+__thread jerry_context_t *tls_context;
+
+jerry_context_t *
+jerry_port_get_current_context (void)
+{
+  /* Returns the context assigned to the thread. */
+  return tls_context;
+}
+
+/* Allocate JerryScript heap for each thread. */
+static void *
+context_alloc_fn (size_t size, void *cb_data)
+{
+  (void) cb_data;
+  return malloc (size);
+}
+
+static void *
+thread_function (void *param)
+{
+  tls_context = jerry_create_context (512 * 1024,
+                                      context_alloc_fn,
+                                      NULL);
+  jerry_init (JERRY_INIT_EMPTY);
+  /* Run JerryScript in the context (e.g.: jerry_parse & jerry_run) */
+  jerry_cleanup ();
+
+  /* Deallocate JerryScript context */
+  free (tls_context);
+
+  return NULL;
+}
+
+#define NUM_OF_THREADS 8
+
+int
+main (void)
+{
+  pthread_t threads[NUM_OF_THREADS];
+
+  /* Create the threads. */
+  for (int i = 0; i < NUM_OF_THREADS; i++)
+  {
+    pthread_create (&threads[i], NULL, thread_function, (void *) (intptr_t) i);
+  }
+
+  /* Wait for the threads to complete, and release their resources. */
+  for (int i = 0; i < NUM_OF_THREADS; i++)
+  {
+    pthread_join (threads[i], NULL);
+  }
+
+  return 0;
+}
+```
+
+**See also**
+
+- [jerry_context_t](#jerry_context_t)
+- [jerry_context_alloc_t](#jerry_context_alloc_t)
+- [jerry_port_get_current_context](05.PORT-API.md#jerry_port_get_current_context)
+
+
 # Snapshot functions
 
 ## jerry_generate_snapshot
@@ -4989,7 +5128,6 @@ jerry_generate_snapshot (const jerry_char_t *resource_name_p,
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 
 int
@@ -4998,13 +5136,13 @@ main (void)
   jerry_init (JERRY_INIT_EMPTY);
 
   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'; }) ();";
+  const jerry_char_t script_to_snapshot[] = "(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),
+                                             script_to_snapshot,
+                                             sizeof (script_to_snapshot) - 1,
                                              0,
                                              global_mode_snapshot_buffer,
                                              sizeof (global_mode_snapshot_buffer) / sizeof (uint32_t));
@@ -5069,7 +5207,6 @@ jerry_generate_function_snapshot (const jerry_char_t *resource_name_p,
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 
 int
@@ -5078,16 +5215,16 @@ main (void)
   jerry_init (JERRY_INIT_EMPTY);
 
   static uint32_t func_snapshot_buffer[256];
-  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;";
+  const jerry_char_t args[] = "a, b";
+  const jerry_char_t src[] = "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),
+                                                      src,
+                                                      sizeof (src) - 1,
+                                                      args,
+                                                      sizeof (args) - 1,
                                                       0,
                                                       func_snapshot_buffer,
                                                       sizeof (func_snapshot_buffer) / sizeof (uint32_t));
@@ -5139,22 +5276,21 @@ jerry_exec_snapshot (const uint32_t *snapshot_p,
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 
 int
 main (void)
 {
   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'; }) ();";
+  const jerry_char_t script_to_snapshot[] = "(function () { return 'string from snapshot'; }) ();";
 
   jerry_init (JERRY_INIT_EMPTY);
 
   jerry_value_t generate_result;
   generate_result = jerry_generate_snapshot (NULL,
                                              0,
-                                             code_to_snapshot_p,
-                                             strlen ((const char *) code_to_snapshot_p),
+                                             script_to_snapshot,
+                                             sizeof (script_to_snapshot) - 1,
                                              0,
                                              global_mode_snapshot_buffer,
                                              sizeof (global_mode_snapshot_buffer) / sizeof (uint32_t));
@@ -5217,25 +5353,24 @@ jerry_load_function_snapshot (const uint32_t *snapshot_p,
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 
 int
 main (void)
 {
   static uint32_t snapshot_buffer[256];
-  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;";
+  const jerry_char_t func_args[] = "a, b";
+  const jerry_char_t func_src[] = "return a + b;";
 
   jerry_init (JERRY_INIT_EMPTY);
 
   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),
+                                                      func_src,
+                                                      sizeof (func_src) - 1,
+                                                      func_args,
+                                                      sizeof (func_args) - 1,
                                                       false,
                                                       snapshot_buffer,
                                                       sizeof (snapshot_buffer) / sizeof (uint32_t));
@@ -5279,30 +5414,28 @@ main (void)
 - [jerry_parse_and_save_function_snapshot](#jerry_parse_and_save_function_snapshot)
 
 
-## jerry_parse_and_save_literals
+## jerry_get_literals_from_snapshot
 
 **Summary**
 
-Collect the used literals from the given source code and save them into a specific file in a list or C format.
-These literals are generated by the parser, they are valid identifiers and none of them are magic string.
+Collect the used literals from the given snapshot and save them into a buffer in list or C format.
+None of these literals are magic strings. In C format only valid identifiers are collected.
 
 **Prototype**
 
 ```c
 size_t
-jerry_parse_and_save_literals (const jerry_char_t *source_p,
-                               size_t source_size,
-                               bool is_strict,
-                               uint32_t *buffer_p,
-                               size_t buffer_size,
-                               bool is_c_format);
+jerry_get_literals_from_snapshot (const uint32_t *snapshot_p,
+                                  size_t snapshot_size,
+                                  jerry_char_t *lit_buf_p,
+                                  size_t lit_buf_size,
+                                  bool is_c_format);
 ```
 
-- `source_p` - script source, it must be a valid utf8 string.
-- `source_size` - script source size, in bytes.
-- `is_strict` - strict mode.
-- `buffer_p` - buffer to save literals to.
-- `buffer_size` - the buffer's size.
+- `snapshot_p` - input snapshot buffer.
+- `snapshot_size` - snapshot size, in bytes.
+- `lit_buf_p` - buffer to save literals to.
+- `lit_buf_size` - the buffer's size.
 - `is_c_format` - the output format would be C-style (true) or a simple list (false).
 - return value
   - the size of the literal-list, if it was generated succesfully (i.e. the list of literals isn't empty,
@@ -5315,7 +5448,6 @@ jerry_parse_and_save_literals (const jerry_char_t *source_p,
 
 ```c
 #include <stdio.h>
-#include <string.h>
 #include "jerryscript.h"
 
 int
@@ -5323,20 +5455,30 @@ main (void)
 {
   jerry_init (JERRY_INIT_EMPTY);
 
-  static uint32_t save_literal_buffer[256];
-  const jerry_char_t *code_for_literal_save_p = (const jerry_char_t *) "var obj = { a:'aa', bb:'Bb' }";
+  static jerry_char_t literal_buffer[256];
+  static uint32_t snapshot_buffer[256];
+  const jerry_char_t script_for_literal_save[] = "var obj = { a:'aa', bb:'Bb' }";
+
+  jerry_value_t generate_result = jerry_generate_snapshot (NULL,
+                                                           0,
+                                                           script_for_literal_save,
+                                                           sizeof (script_for_literal_save) - 1,
+                                                           0,
+                                                           snapshot_buffer,
+                                                           256);
+  size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
+  jerry_release_value (generate_result);
 
-  size_t literal_sizes = jerry_parse_and_save_literals (code_for_literal_save_p,
-                                                        strlen ((const char *) code_for_literal_save_p),
-                                                        false,
-                                                        save_literal_buffer,
-                                                        sizeof (save_literal_buffer) / sizeof (uint32_t),
-                                                        true);
+  const size_t literal_size = jerry_get_literals_from_snapshot (snapshot_buffer,
+                                                                snapshot_size,
+                                                                literal_buffer,
+                                                                256,
+                                                                true);
 
-  if (literal_sizes != 0)
+  if (literal_size != 0)
   {
-    FILE *literal_file_p = fopen ("literals.txt", "w");
-    fwrite (save_literal_buffer, sizeof (uint8_t), literal_sizes, literal_file_p);
+    FILE *literal_file_p = fopen ("literals.h", "wb");
+    fwrite (literal_buffer, sizeof (uint8_t), literal_size, literal_file_p);
     fclose (literal_file_p);
   }
 
@@ -5392,7 +5534,6 @@ jerry_set_vm_exec_stop_callback (jerry_vm_exec_stop_callback_t stop_cb,
 [doctest]: # (test="link")
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 
 static int countdown = 10;
@@ -5418,11 +5559,11 @@ main (void)
   jerry_set_vm_exec_stop_callback (vm_exec_stop_callback, &countdown, 16);
 
   // Inifinte loop.
-  const char *src_p = "while(true) {}";
+  const jerry_char_t script[] = "while(true) {}";
 
-  jerry_value_t src = jerry_parse (NULL, 0, (jerry_char_t *) src_p, strlen (src_p), JERRY_PARSE_NO_OPTS);
-  jerry_release_value (jerry_run (src));
-  jerry_release_value (src);
+  jerry_value_t parsed_code = jerry_parse (NULL, 0, script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
+  jerry_release_value (jerry_run (parsed_code));
+  jerry_release_value (parsed_code);
   jerry_cleanup ();
 }
 ```
@@ -5841,9 +5982,8 @@ jerry_value_t jerry_json_parse (const jerry_char_t *string_p, jerry_size_t strin
 
 ```c
 {
-  const char *data = "{\"name\": \"John\", \"age\": 5}";
-  jerry_size_t str_length = (jerry_size_t)strlen (data);
-  jerry_value_t parsed_json = jerry_json_parse ((jerry_char_t*)data, str_length);
+  const jerry_char_t data[] = "{\"name\": \"John\", \"age\": 5}";
+  jerry_value_t parsed_json = jerry_json_parse (data, sizeof (data) - 1);
 
   // parsed_json now conatins all data stored in data_in_json
 
@@ -5851,7 +5991,7 @@ jerry_value_t jerry_json_parse (const jerry_char_t *string_p, jerry_size_t strin
 }
 ```
 
-## jerry_stringify
+## jerry_json_stringify
 
   **Summary**
 
@@ -5860,7 +6000,7 @@ jerry_value_t jerry_json_parse (const jerry_char_t *string_p, jerry_size_t strin
   **Prototype**
 
 ```c
-jerry_value_t jerry_json_stringfy (const jerry_value_t object_to_stringify)
+jerry_value_t jerry_json_stringify (const jerry_value_t object_to_stringify)
 ```
 
 - `object_to_stringify` - a jerry_value_t object to stringify
@@ -5876,7 +6016,7 @@ jerry_value_t jerry_json_stringfy (const jerry_value_t object_to_stringify)
   jerry_value_t key = jerry_create_string ((const jerry_char_t *) "name");
   jerry_value_t value = jerry_create_string ((const jerry_char_t *) "John");
   jerry_set_property (obj, key, value);
-  jerry_value_t stringified = jerry_json_stringfy (obj);
+  jerry_value_t stringified = jerry_json_stringify (obj);
 
   //stringified now contains a json formated string
 
@@ -5885,4 +6025,4 @@ jerry_value_t jerry_json_stringfy (const jerry_value_t object_to_stringify)
   jerry_release_value (value);
   jerry_release_value (stringified);
 }
-```
\ No newline at end of file
+```
index fc691a009dfbeae1b2efa95df110ccf7a2148ae8..50a008f8fa80b6d468f41475c4a8835366704924 100644 (file)
@@ -7,16 +7,14 @@ This guide is intended to introduce you to JerryScript embedding API through cre
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 
 int
 main (void)
 {
   const jerry_char_t script[] = "var str = 'Hello, World!';";
-  size_t script_size = strlen ((const char *) script);
 
-  bool ret_value = jerry_run_simple (script, script_size, JERRY_INIT_EMPTY);
+  bool ret_value = jerry_run_simple (script, sizeof (script) - 1, JERRY_INIT_EMPTY);
 
   return (ret_value ? 0 : 1);
 }
@@ -37,7 +35,6 @@ Here we perform the same actions, as `jerry_run_simple`, while splitting into se
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 #include "jerryscript-ext/handler.h"
 
@@ -45,7 +42,6 @@ int
 main (void)
 {
   const jerry_char_t script[] = "print ('Hello, World!');";
-  size_t script_size = strlen ((const char *) script);
 
   /* Initialize engine */
   jerry_init (JERRY_INIT_EMPTY);
@@ -55,9 +51,9 @@ main (void)
                                   jerryx_handler_print);
 
   /* Setup Global scope code */
-  jerry_value_t parsed_code = jerry_parse (NULL, 0, script, script_size, JERRY_PARSE_NO_OPTS);
+  jerry_value_t parsed_code = jerry_parse (NULL, 0, script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
 
-  if (!jerry_value_has_error_flag (parsed_code))
+  if (!jerry_value_is_error (parsed_code))
   {
     /* Execute the parsed source code in the Global scope */
     jerry_value_t ret_value = jerry_run (parsed_code);
@@ -83,7 +79,6 @@ Our code is more complex now, but it introduces possibilities to interact with J
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 #include "jerryscript-ext/handler.h"
 
@@ -104,16 +99,16 @@ main (void)
 
   /* Evaluate script1 */
   eval_ret = jerry_eval (script_1,
-                         strlen ((const char *) script_1),
-                         false);
+                         sizeof (script_1) - 1,
+                         JERRY_PARSE_NO_OPTS);
 
   /* Free JavaScript value, returned by eval */
   jerry_release_value (eval_ret);
 
   /* Evaluate script2 */
   eval_ret = jerry_eval (script_2,
-                         strlen ((const char *) script_2),
-                         false);
+                         sizeof (script_2) - 1,
+                         JERRY_PARSE_NO_OPTS);
 
   /* Free JavaScript value, returned by eval */
   jerry_release_value (eval_ret);
@@ -132,7 +127,6 @@ This way, we execute two independent script parts in one execution environment.
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 #include "jerryscript-ext/handler.h"
 
@@ -168,8 +162,8 @@ main (void)
 
   /* Now starting script that would output value of just initialized field */
   jerry_value_t eval_ret = jerry_eval (script,
-                                       strlen ((const char *) script),
-                                       false);
+                                       sizeof (script) - 1,
+                                       JERRY_PARSE_NO_OPTS);
 
   /* Free JavaScript value, returned by eval */
   jerry_release_value (eval_ret);
@@ -197,7 +191,6 @@ The following example function will output a JavaScript value:
 ```c
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 #include "jerryscript.h"
 
 static void
@@ -312,7 +305,7 @@ main (void)
     }
 
     /* If the command is "quit", break the loop */
-    if (!strncmp (cmd, "quit\n", strlen ("quit\n")))
+    if (!strncmp (cmd, "quit\n", sizeof ("quit\n") - 1))
     {
       break;
     }
@@ -322,10 +315,10 @@ main (void)
     /* Evaluate entered command */
     ret_val = jerry_eval ((const jerry_char_t *) cmd,
                           len,
-                          false);
+                          JERRY_PARSE_NO_OPTS);
 
     /* If command evaluated successfully, print value, returned by eval */
-    if (jerry_value_has_error_flag (ret_val))
+    if (jerry_value_is_error (ret_val))
     {
       /* Evaluated JS code thrown an exception
        *  and didn't handle it with try-catch-finally */
@@ -352,7 +345,6 @@ In this example we demonstrate how to use native function and structures in Java
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 #include "jerryscript-ext/handler.h"
 
@@ -417,10 +409,9 @@ main (void)
     var str = MyObject.myFunc (); \
     print (str); \
   ";
-  size_t script_size = strlen ((const char *) script);
 
   /* Evaluate script */
-  jerry_value_t eval_ret = jerry_eval (script, script_size, false);
+  jerry_value_t eval_ret = jerry_eval (script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
 
   /* Free JavaScript value, returned by eval */
   jerry_release_value (eval_ret);
@@ -445,7 +436,6 @@ Here we create a JS Object with `jerry_eval`, then extend it with a native funct
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include "jerryscript.h"
 #include "jerryscript-ext/handler.h"
 
@@ -462,7 +452,7 @@ add_handler (const jerry_value_t func_value, /**< function object */
   jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "x");
   jerry_value_t x_val = jerry_get_property (this_val, prop_name);
 
-  if (!jerry_value_has_error_flag (x_val))
+  if (!jerry_value_is_error (x_val))
   {
     /* Convert Jerry API values to double */
     double x = jerry_get_number_value (x_val);
@@ -508,8 +498,8 @@ main (void)
 
   /* Evaluate script */
   my_js_obj_val = jerry_eval (my_js_object,
-                              strlen ((const char *) my_js_object),
-                              false);
+                              sizeof (my_js_object) - 1,
+                              JERRY_PARSE_NO_OPTS);
 
   /* Create a JS function object and wrap into a jerry value */
   jerry_value_t add_func_obj = jerry_create_external_function (add_handler);
@@ -529,10 +519,9 @@ main (void)
     MyObject.add2x (5); \
     print (MyObject.foo ()); \
   ";
-  size_t script_size = strlen ((const char *) script);
 
   /* Evaluate script */
-  jerry_value_t eval_ret = jerry_eval (script, script_size, false);
+  jerry_value_t eval_ret = jerry_eval (script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
 
   /* Free JavaScript value, returned by eval */
   jerry_release_value (eval_ret);
@@ -559,7 +548,6 @@ A recommended method is using `jerry_port_get_current_time()` or something based
 [doctest]: # ()
 
 ```c
-#include <string.h>
 #include <stdlib.h>
 #include "jerryscript.h"
 #include "jerryscript-port.h"
@@ -573,7 +561,6 @@ main (void)
 
   /* Generate a random number, and print it */
   const jerry_char_t script[] = "var a = Math.random (); print(a)";
-  size_t script_size = strlen ((const char *) script);
 
   /* Initialize the engine */
   jerry_init (JERRY_INIT_EMPTY);
@@ -583,7 +570,7 @@ main (void)
                                   jerryx_handler_print);
 
   /* Evaluate the script */
-  jerry_value_t eval_ret = jerry_eval (script, script_size, false);
+  jerry_value_t eval_ret = jerry_eval (script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
 
   /* Free the JavaScript value returned by eval */
   jerry_release_value (eval_ret);
index 69f7337ab46dc6ea97d48d2308c41773d69d699f..759af10f394d16497ce960f195895f4ada68333e 100644 (file)
@@ -11,7 +11,8 @@ 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.
  */
@@ -62,6 +63,11 @@ typedef enum
  *
  * 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_ENABLE_LOGGING is
+ *      defined. 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, ...);
 ```
@@ -70,46 +76,71 @@ void jerry_port_log (jerry_log_level_t level, const char *fmt, ...);
 
 ```c
 /**
- * Jerry time zone structure
- */
-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
+ * 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.
  *
- * @return true  - if success
- *         false - otherwise
+ * 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
+ *      CONFIG_DISABLE_DATE_BUILTIN is _not_ defined. 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.
  */
-bool jerry_port_get_time_zone (jerry_time_zone_t *);
+double jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc);
 
 /**
  * Get system time
  *
+ * Note:
+ *      This port function is called by jerry-core when
+ *      CONFIG_DISABLE_DATE_BUILTIN is _not_ defined. 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 instance
+## External context
 
-Allow user to provide external buffer for jerry instance (which includes an isolated context and heap with other instances), so that user can config the heap size in runtime and run multiple JS apps simultaneously.
+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 instance, which contains the current context, heap and other infomation.
- * Each port should provide its own implementation of this interface.
+ * Get the current context of the engine. Each port should provide its own
+ * implementation of this interface.
  *
- *Note:
- *    This port function will be called automatically by jerry-core
- *    when JERRY_ENABLE_EXTERNAL_CONTEXT is defined. If not, this function will never be called.
+ * Note:
+ *      This port function is called by jerry-core when
+ *      JERRY_ENABLE_EXTERNAL_CONTEXT is defined. Otherwise this function is not
+ *      used.
  *
- * @return the pointer to the jerry instance.
+ * @return the pointer to the engine context.
  */
-struct jerry_instance_t *jerry_port_get_current_instance (void);
+struct jerry_context_t *jerry_port_get_current_context (void);
 ```
 
 ## Sleep
@@ -117,6 +148,12 @@ struct jerry_instance_t *jerry_port_get_current_instance (void);
 ```c
 /**
  * Makes the process sleep for a given time.
+ *
+ * Note:
+ *      This port function is called by jerry-core when JERRY_DEBUGGER is
+ *      defined. Otherwise this function is not used.
+ *
+ * @param sleep_time milliseconds to sleep.
  */
 void jerry_port_sleep (uint32_t sleep_time);
 ```
@@ -167,31 +204,26 @@ jerry_port_log (jerry_log_level_t level, /**< log level */
 ## Date
 
 ```c
+#include <time.h>
 #include <sys/time.h>
 #include "jerryscript-port.h"
 
 /**
- * Default implementation of jerry_port_get_time_zone.
+ * Default implementation of jerry_port_get_local_time_zone_adjustment.
  */
-bool jerry_port_get_time_zone (jerry_time_zone_t *tz_p)
+double jerry_port_get_local_time_zone_adjustment (double unix_ms, /**< ms since unix epoch */
+                                                  bool is_utc)    /**< is the time above in 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)
+  struct tm tm;
+  time_t now = (time_t) (unix_ms / 1000);
+  localtime_r (&now, &tm);
+  if (!is_utc)
   {
-    return false;
+    now -= tm.tm_gmtoff;
+    localtime_r (&now, &tm);
   }
-
-  tz_p->offset = tz.tz_minuteswest;
-  tz_p->daylight_saving_time = tz.tz_dsttime > 0 ? 1 : 0;
-
-  return true;
-} /* jerry_port_get_time_zone */
+  return ((double) tm.tm_gmtoff) * 1000;
+} /* jerry_port_get_local_time_zone_adjustment */
 
 /**
  * Default implementation of jerry_port_get_current_time.
@@ -208,37 +240,38 @@ 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 instance
+
+## External context
 
 ```c
 #include "jerryscript-port.h"
 #include "jerryscript-port-default.h"
 
 /**
- * Pointer to the current instance.
+ * Pointer to the current context.
  * Note that it is a global variable, and is not a thread safe implementation.
  */
-static jerry_instance_t *current_instance_p = NULL;
+static jerry_context_t *current_context_p = NULL;
 
 /**
- * Set the current_instance_p as the passed pointer.
+ * Set the current_context_p as the passed pointer.
  */
 void
-jerry_port_default_set_instance (jerry_instance_t *instance_p) /**< points to the created instance */
+jerry_port_default_set_current_context (jerry_context_t *context_p) /**< points to the created context */
 {
-  current_instance_p = instance_p;
-} /* jerry_port_default_set_instance */
+  current_context_p = context_p;
+} /* jerry_port_default_set_current_context */
 
 /**
- * Get the current instance.
+ * Get the current context.
  *
- * @return the pointer to the current instance
+ * @return the pointer to the current context
  */
-jerry_instance_t *
-jerry_port_get_current_instance (void)
+jerry_context_t *
+jerry_port_get_current_context (void)
 {
-  return current_instance_p;
-} /* jerry_port_get_current_instance */
+  return current_context_p;
+} /* jerry_port_get_current_context */
 ```
 
 ## Sleep
@@ -259,7 +292,7 @@ void jerry_port_sleep (uint32_t sleep_time)
 #ifdef HAVE_TIME_H
   nanosleep (&(const struct timespec)
   {
-    sleep_time / 1000, (sleep_time % 1000) * 1000000L /* Seconds, nanoseconds */
+    (time_t) sleep_time / 1000, ((long int) sleep_time % 1000) * 1000000L /* Seconds, nanoseconds */
   }
   , NULL);
 #elif defined (HAVE_UNISTD_H)
index 5758adc0e59a012688be13b7acb44443b63638f2..629e4e670738170207bad2e5f6aba618dc99ae67 100644 (file)
@@ -61,7 +61,7 @@ behaviour through property getting and setting.
    * prop_value contains a live reference to an error object.
    * This reference must be released as well. */
 
-  if (jerry_value_has_error_flag (prop_value))
+  if (jerry_value_is_error (prop_value))
   {
     /* Errors can be handled here. */
   }
@@ -93,7 +93,7 @@ behaviour through property getting and setting.
   /* The reference stored in the 'result' variable is live whether
    * the operation is successful or not, and must also be freed. */
 
-  if (jerry_value_has_error_flag (result))
+  if (jerry_value_is_error (result))
   {
     /* Errors can be handled here. */
   }
index 84653f2f707feb8a194abfd36cdb8cc698a404d6..3c119f7f0db68360230bfde6b01e7a0b7e39f0d1 100644 (file)
@@ -3,24 +3,23 @@
 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 two debugger clients
-are available in the /jerry-debugger subdirectory: an HTML
-and a Python application. These simple applications demonstrate
-the communication protocol between the client and server and can
-be reused by integrated development environments.
+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 --jerry-libc=off`
+`--jerry-debugger=on`
 
-At the moment only a Websocket-based implementation is provided
-by JerryScript which transmits messages over TCP/IP networks.
-This implementation requires a socket API which is not yet
-supported by jerry-libc so the standard libc is used instead.
-In the future any reliable stream or datagram based protocol
-can be used for transmitting debugger messages.
+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
 
@@ -49,8 +48,8 @@ the *Waiting for client connection* message:
 
 `--log-level 2`
 
-The HTML client can connect to the IP address of the server with
-the `connect` command. The IP address can be localhost
+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
@@ -65,9 +64,12 @@ All available commands of the client can be queried by the
 
 ## Integrating debugger support into applications using JerryScript
 
-The debugger can be enabled by calling the `jerry_debugger_init (uint16_t port)`
-function after the `jerry_init ()` function. It initializes the debugger
-and blocks until a client connects.
+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.)
 
 The resource name provided to `jerry_parse ()` is used by the client
 to identify the resource name of the source code. This resource name
@@ -76,7 +78,7 @@ is usually a file name.
 ## JerryScript debugger C-API interface
 
 The following section describes the debugger functions
-available for the host application.
+available to the host application.
 
 ## JerryScript debugger types
 
@@ -107,36 +109,6 @@ typedef jerry_value_t
 
 ## JerryScript debugger functions
 
-### jerry_debugger_init
-
-**Summary**
-
-Debugger server initialization. Must be called after `jerry_init`.
-
-**Prototype**
-
-```c
-void
-jerry_debugger_init (uint16_t port);
-```
-
-- `port` - Server port number
-
-
-**Example**
-
-```c
-{
-  jerry_init (JERRY_INIT_EMPTY);
-  jerry_debugger_init (5001);
-
-  // ...
-
-  jerry_cleanup ();
-}
-```
-
-
 ### jerry_debugger_is_connected
 
 **Summary**
@@ -152,10 +124,18 @@ 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);
-  jerry_debugger_init (5001);
+  jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
+                                 && jerryx_debugger_ws_create ());
 
   if (jerry_debugger_is_connected ())
   {
@@ -184,10 +164,18 @@ 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);
-  jerry_debugger_init (5001);
+  jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
+                                 && jerryx_debugger_ws_create ());
 
   jerry_debugger_stop ();
 
@@ -218,10 +206,18 @@ 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);
-  jerry_debugger_init (5001);
+  jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
+                                 && jerryx_debugger_ws_create ());
 
   jerry_debugger_continue ();
 
@@ -233,7 +229,7 @@ jerry_debugger_continue (void)
 
 - [jerry_debugger_stop](#jerry_debugger_stop)
 
-### jerry_debugger_disable_stop_at_breakpoint
+### jerry_debugger_stop_at_breakpoint
 
 **Summary**
 
@@ -252,15 +248,24 @@ jerry_debugger_stop_at_breakpoint (bool enable_stop_at_breakpoint)
 
 **Example**
 
+[doctest]: # (test="link")
+
 ```c
+#include "jerryscript.h"
+#include "jerryscript-ext/debugger.h"
+
+int
+main (void)
 {
   jerry_init (JERRY_INIT_EMPTY);
-  jerry_debugger_init (5001);
+  jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
+                                 && jerryx_debugger_ws_create ());
 
   jerry_debugger_stop_at_breakpoint (true);
 
   // Protected execution of JavaScript code.
-  jerry_eval (...);
+  const jerry_char_t script[] = "42";
+  jerry_eval (script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
 
   jerry_debugger_stop_at_breakpoint (false);
 
@@ -288,7 +293,12 @@ jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t
 
 **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.
  */
@@ -305,7 +315,7 @@ wait_for_source_callback (const jerry_char_t *resource_name_p, /**< resource nam
                                        source_size,
                                        JERRY_PARSE_NO_OPTS);
 
-  if (!jerry_value_has_error_flag (ret_val))
+  if (!jerry_value_is_error (ret_val))
   {
     jerry_value_t func_val = ret_val;
     ret_val = jerry_run (func_val);
@@ -315,20 +325,23 @@ wait_for_source_callback (const jerry_char_t *resource_name_p, /**< resource nam
   return ret_val;
 } /* wait_for_source_callback */
 
-int main ()
+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);
-    jerry_debugger_init (5001);
+    jerryx_debugger_after_connect (jerryx_debugger_tcp_create (5001)
+                                   && jerryx_debugger_ws_create ());
 
     do
     {
       jerry_value_t run_result;
-      jerry_debugger_wait_for_source_status_t receive_status;
 
       receive_status = jerry_debugger_wait_for_client_source (wait_for_source_callback,
                                                               NULL,
@@ -359,20 +372,67 @@ Sends the program's output to the debugger client.
 **Prototype**
 
 ```c
-  void
-  jerry_debugger_send_output (jerry_char_t buffer[], jerry_size_t string_size, uint8_t type)
+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);
-  jerry_debugger_init (5001);
+  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_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_DEBUGGER_OUTPUT_OK);
+  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 ();
+}
 ```
index 715dc04be3dcbd8488ab4da557ae7c5d93cac3d9..c6065615e8318522bf04afeb792c96865a966103 100644 (file)
@@ -244,7 +244,7 @@ my_external_handler (const jerry_value_t function_obj,
                                                                mapping,
                                                                4);
 
-  if (jerry_value_has_error_flag (rv))
+  if (jerry_value_is_error (rv))
   {
     /* Handle error. */
     return rv;
@@ -640,7 +640,7 @@ my_external_handler (const jerry_value_t function_obj,
                                                       mapping,
                                                       1);
 
-  if (jerry_value_has_error_flag (rv))
+  if (jerry_value_is_error (rv))
   {
     /* Handle error. */
     return rv;
@@ -731,7 +731,7 @@ my_external_handler (const jerry_value_t function_obj,
                                                       mapping,
                                                       1);
 
-  if (jerry_value_has_error_flag (rv))
+  if (jerry_value_is_error (rv))
   {
     /* Handle error. */
     return rv;
index 431ab8bedc14d52054719793d03e1cdb53599aa6..9d6bf46561ed9b15bca492ff07ea371a22ef8d74 100644 (file)
@@ -1,17 +1,17 @@
 #  Common external function handlers
 
-## jerryx_handler_assert
+## jerryx_handler_assert_fatal
 
 **Summary**
 
-Assert for scripts. The routine calls `jerry_port_fatal` on assertion failure.
+Hard assert for scripts. The routine calls `jerry_port_fatal` on assertion failure.
 
 **Prototype**
 
 ```c
 jerry_value_t
-jerryx_handler_assert (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);
+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).
@@ -27,11 +27,50 @@ jerryx_handler_assert (const jerry_value_t func_obj_val, const jerry_value_t thi
 - [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.
+Expose garbage collector to scripts. If the first argument of the function
+is logical true, it performs a high severity gc. Otherwise a low severity
+gc is performed, which is also the default if no parameters passed.
 
 **Prototype**
 
@@ -136,7 +175,7 @@ register_common_functions (void)
 {
   jerry_value_t ret = jerry_create_undefined ();
 
-  for (int i = 0; common_functions[i].name_p != NULL && !jerry_value_has_error_flag (ret); i++)
+  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);
index 0abbe04f1020acdeb149e5d33b1df9e6893bec33..b3c11ca8096e061db752ae3909a8f8c3ba129fd5 100644 (file)
@@ -27,6 +27,11 @@ The purpose of having resolvers is to be able to account for the fact that diffe
 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
@@ -56,7 +61,7 @@ to `jerryx_module_resolve` with a module name whose canonical name matches an al
 
 ```c
 jerry_value_t
-jerryx_module_resolve (const jerry_char_t *name,
+jerryx_module_resolve (const jerry_value_t name,
                        const jerryx_module_resolver_t *resolvers_p,
                        size_t resolver_count);
 ```
@@ -67,6 +72,26 @@ jerryx_module_resolve (const jerry_char_t *name,
 - 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**
@@ -157,7 +182,7 @@ load_and_evaluate_js_file (const jerry_value_t name, jerry_value_t *result)
     {
       /* 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, false);
+      (*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);
diff --git a/deps/jerry/docs/13.DEBUGGER-TRANSPORT.md b/deps/jerry/docs/13.DEBUGGER-TRANSPORT.md
new file mode 100644 (file)
index 0000000..de48306
--- /dev/null
@@ -0,0 +1,217 @@
+# 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);
+```
index dff2438d0edd0faff12c1f48cca74cf792836311..fdec1c297c7b45d45abfafe53852d72910ef4313 100644 (file)
@@ -16,6 +16,9 @@ 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(FEATURE_CPOINTER_32_BIT    OFF     CACHE BOOL   "Enable 32 bit compressed pointers?")
 set(FEATURE_DEBUGGER           OFF     CACHE BOOL   "Enable JerryScript debugger?")
@@ -23,6 +26,7 @@ set(FEATURE_ERROR_MESSAGES     OFF     CACHE BOOL   "Enable error messages?")
 set(FEATURE_EXTERNAL_CONTEXT   OFF     CACHE BOOL   "Enable external context?")
 set(FEATURE_JS_PARSER          ON      CACHE BOOL   "Enable js-parser?")
 set(FEATURE_LINE_INFO          OFF     CACHE BOOL   "Enable line info?")
+set(FEATURE_LOGGING            OFF     CACHE BOOL   "Enable logging?")
 set(FEATURE_MEM_STATS          OFF     CACHE BOOL   "Enable memory statistics?")
 set(FEATURE_MEM_STRESS_TEST    OFF     CACHE BOOL   "Enable mem-stress test?")
 set(FEATURE_PARSER_DUMP        OFF     CACHE BOOL   "Enable parser byte-code dumps?")
@@ -33,11 +37,16 @@ set(FEATURE_SNAPSHOT_EXEC      OFF     CACHE BOOL   "Enable executing snapshot f
 set(FEATURE_SNAPSHOT_SAVE      OFF     CACHE BOOL   "Enable saving snapshot files?")
 set(FEATURE_SYSTEM_ALLOCATOR   OFF     CACHE BOOL   "Enable system allocator?")
 set(FEATURE_VALGRIND           OFF     CACHE BOOL   "Enable Valgrind support?")
-set(FEATURE_VALGRIND_FREYA     OFF     CACHE BOOL   "Enable Valgrind-Freya support?")
 set(FEATURE_VM_EXEC_STOP       OFF     CACHE BOOL   "Enable VM execution stopping?")
 set(MEM_HEAP_SIZE_KB           "512"   CACHE STRING "Size of memory heap, 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(FEATURE_SYSTEM_ALLOCATOR)
   set(FEATURE_CPOINTER_32_BIT ON)
 
@@ -58,13 +67,21 @@ if(JERRY_CMDLINE_SNAPSHOT)
   set(FEATURE_SNAPSHOT_SAVE_MESSAGE " (FORCED BY SNAPSHOT TOOL)")
 endif()
 
+if(FEATURE_MEM_STATS OR FEATURE_PARSER_DUMP OR FEATURE_REGEXP_DUMP)
+  set(FEATURE_LOGGING ON)
+
+  set(FEATURE_LOGGING_MESSAGE " (FORCED BY STATS OR DUMP)")
+endif()
+
 # Status messages
+message(STATUS "ENABLE_ALL_IN_ONE           " ${ENABLE_ALL_IN_ONE} ${ENABLE_ALL_IN_ONE_MESSAGE})
 message(STATUS "FEATURE_CPOINTER_32_BIT     " ${FEATURE_CPOINTER_32_BIT} ${FEATURE_CPOINTER_32_BIT_MESSAGE})
 message(STATUS "FEATURE_DEBUGGER            " ${FEATURE_DEBUGGER})
 message(STATUS "FEATURE_ERROR_MESSAGES      " ${FEATURE_ERROR_MESSAGES})
 message(STATUS "FEATURE_EXTERNAL_CONTEXT    " ${FEATURE_EXTERNAL_CONTEXT})
 message(STATUS "FEATURE_JS_PARSER           " ${FEATURE_JS_PARSER})
 message(STATUS "FEATURE_LINE_INFO           " ${FEATURE_LINE_INFO})
+message(STATUS "FEATURE_LOGGING             " ${FEATURE_LOGGING} ${FEATURE_LOGGING_MESSAGE})
 message(STATUS "FEATURE_MEM_STATS           " ${FEATURE_MEM_STATS})
 message(STATUS "FEATURE_MEM_STRESS_TEST     " ${FEATURE_MEM_STRESS_TEST})
 message(STATUS "FEATURE_PARSER_DUMP         " ${FEATURE_PARSER_DUMP} ${FEATURE_PARSER_DUMP_MESSAGE})
@@ -75,12 +92,12 @@ message(STATUS "FEATURE_SNAPSHOT_EXEC       " ${FEATURE_SNAPSHOT_EXEC} ${FEATURE
 message(STATUS "FEATURE_SNAPSHOT_SAVE       " ${FEATURE_SNAPSHOT_SAVE} ${FEATURE_SNAPSHOT_SAVE_MESSAGE})
 message(STATUS "FEATURE_SYSTEM_ALLOCATOR    " ${FEATURE_SYSTEM_ALLOCATOR})
 message(STATUS "FEATURE_VALGRIND            " ${FEATURE_VALGRIND})
-message(STATUS "FEATURE_VALGRIND_FREYA      " ${FEATURE_VALGRIND_FREYA})
 message(STATUS "FEATURE_VM_EXEC_STOP        " ${FEATURE_VM_EXEC_STOP})
 message(STATUS "MEM_HEAP_SIZE_KB            " ${MEM_HEAP_SIZE_KB})
 
 # Include directories
-set(INCLUDE_CORE
+set(INCLUDE_CORE_PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
+set(INCLUDE_CORE_PRIVATE
     "${CMAKE_CURRENT_SOURCE_DIR}"
     "${CMAKE_CURRENT_SOURCE_DIR}/api"
     "${CMAKE_CURRENT_SOURCE_DIR}/debugger"
@@ -88,7 +105,6 @@ set(INCLUDE_CORE
     "${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}/include"
     "${CMAKE_CURRENT_SOURCE_DIR}/jcontext"
     "${CMAKE_CURRENT_SOURCE_DIR}/jmem"
     "${CMAKE_CURRENT_SOURCE_DIR}/jrt"
@@ -97,6 +113,9 @@ set(INCLUDE_CORE
     "${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_API                       api/*.c)
@@ -146,9 +165,7 @@ endif()
 set(INCLUDE_THIRD_PARTY_VALGRIND "${CMAKE_SOURCE_DIR}/third-party/valgrind")
 
 # build mode specific compile/link flags
-if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
-  set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_NDEBUG)
-endif()
+set(DEFINES_JERRY ${DEFINES_JERRY} $<$<NOT:$<CONFIG:Debug>>:JERRY_NDEBUG>)
 
 # Jerry heap-section
 if(DEFINED JERRY_HEAP_SECTION_ATTR)
@@ -181,6 +198,11 @@ if(FEATURE_LINE_INFO)
   set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_ENABLE_LINE_INFO)
 endif()
 
+# Logging
+if(FEATURE_LOGGING)
+  set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_ENABLE_LOGGING)
+endif()
+
 # Memory statistics
 if(FEATURE_MEM_STATS)
   set(DEFINES_JERRY ${DEFINES_JERRY} JMEM_STATS)
@@ -188,20 +210,6 @@ endif()
 
 # Enable debugger
 if(FEATURE_DEBUGGER)
-  if(JERRY_LIBC)
-    message(FATAL_ERROR "This configuration is not supported. Please build against your system libc to enable the JerryScript debugger.")
-  endif()
-
-  # Sleep function availability check
-  INCLUDE (CheckIncludeFiles)
-  CHECK_INCLUDE_FILES (time.h HAVE_TIME_H)
-  CHECK_INCLUDE_FILES (unistd.h HAVE_UNISTD_H)
-  if(HAVE_TIME_H)
-    set(DEFINES_JERRY ${DEFINES_JERRY} HAVE_TIME_H)
-  elseif(HAVE_UNISTD_H)
-    set(DEFINES_JERRY ${DEFINES_JERRY} HAVE_UNISTD_H)
-  endif()
-
   set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_DEBUGGER)
 endif()
 
@@ -229,10 +237,6 @@ else()
   message(FATAL_ERROR "Profile file: '${FEATURE_PROFILE}' doesn't exist!")
 endif()
 
-if(JERRY_LIBC AND FEATURE_SYSTEM_ALLOCATOR)
-  MESSAGE(FATAL_ERROR "This configuration is not supported. Please build against your system libc to enable the system allocator.")
-endif()
-
 # RegExp strict mode
 if(FEATURE_REGEXP_STRICT_MODE)
   set(DEFINES_JERRY ${DEFINES_JERRY} ENABLE_REGEXP_STRICT_MODE)
@@ -261,13 +265,7 @@ endif()
 # Valgrind
 if(FEATURE_VALGRIND)
   set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_VALGRIND)
-  set(INCLUDE_CORE ${INCLUDE_CORE} ${INCLUDE_THIRD_PARTY_VALGRIND})
-endif()
-
-# Valgrind Freya
-if(FEATURE_VALGRIND_FREYA)
-  set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_VALGRIND_FREYA)
-  set(INCLUDE_CORE ${INCLUDE_CORE} ${INCLUDE_THIRD_PARTY_VALGRIND})
+  set(INCLUDE_CORE_PRIVATE ${INCLUDE_CORE_PRIVATE} ${INCLUDE_THIRD_PARTY_VALGRIND})
 endif()
 
 # Enable VM execution stopping
@@ -279,23 +277,20 @@ endif()
 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})
 
-add_library(${JERRY_CORE_NAME} STATIC ${SOURCE_CORE_FILES})
+add_library(${JERRY_CORE_NAME} ${SOURCE_CORE_FILES})
 
 target_compile_definitions(${JERRY_CORE_NAME} PUBLIC ${DEFINES_JERRY})
-target_include_directories(${JERRY_CORE_NAME} PUBLIC ${INCLUDE_CORE})
+target_include_directories(${JERRY_CORE_NAME} PUBLIC ${INCLUDE_CORE_PUBLIC})
+target_include_directories(${JERRY_CORE_NAME} PRIVATE ${INCLUDE_CORE_PRIVATE})
 
 if(JERRY_LIBM)
   target_link_libraries(${JERRY_CORE_NAME} jerry-libm)
 endif()
 
-if(JERRY_LIBC)
-  target_link_libraries(${JERRY_CORE_NAME} jerry-libc)
-endif()
-
 separate_arguments(EXTERNAL_LINK_LIBS)
 foreach(EXT_LIB ${EXTERNAL_LINK_LIBS})
   target_link_libraries(${JERRY_CORE_NAME} ${EXT_LIB})
 endforeach()
 
 install(TARGETS ${JERRY_CORE_NAME} DESTINATION lib)
-install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include)
+install(DIRECTORY ${INCLUDE_CORE_PUBLIC}/ DESTINATION include)
diff --git a/deps/jerry/jerry-core/api/jerry-debugger-transport.c b/deps/jerry/jerry-core/api/jerry-debugger-transport.c
new file mode 100644 (file)
index 0000000..3dbac49
--- /dev/null
@@ -0,0 +1,250 @@
+/* Copyright JS Foundation and other contributors, http://js.foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "debugger.h"
+#include "jcontext.h"
+#include "jerryscript.h"
+
+#ifdef 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 /* JERRY_DEBUGGER */
index 627727b5dcedf0f80a55cc9879bdcafaf3f4062c..64d81e7279f934bc55578940ff103a08063243a6 100644 (file)
@@ -28,7 +28,7 @@ jerry_debugger_is_connected (void)
 {
 #ifdef JERRY_DEBUGGER
   return JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED;
-#else
+#else /* !JERRY_DEBUGGER */
   return false;
 #endif /* JERRY_DEBUGGER */
 } /* jerry_debugger_is_connected */
@@ -89,20 +89,6 @@ jerry_debugger_stop_at_breakpoint (bool enable_stop_at_breakpoint) /**< enable/d
 #endif /* JERRY_DEBUGGER */
 } /* jerry_debugger_stop_at_breakpoint */
 
-/**
- * Debugger server initialization. Must be called after jerry_init.
- */
-void
-jerry_debugger_init (uint16_t port) /**< server port number */
-{
-#ifdef JERRY_DEBUGGER
-  JERRY_CONTEXT (debugger_port) = port;
-  jerry_debugger_accept_connection ();
-#else /* !JERRY_DEBUGGER */
-  JERRY_UNUSED (port);
-#endif /* JERRY_DEBUGGER */
-} /* jerry_debugger_init */
-
 /**
  * Sets whether the engine should wait and run a source.
  *
@@ -173,7 +159,7 @@ jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t
         }
       }
 
-      jerry_debugger_sleep ();
+      jerry_debugger_transport_sleep ();
     }
 
     JERRY_ASSERT (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_SOURCE_MODE)
@@ -190,7 +176,7 @@ jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t
   }
 
   return JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED;
-#else
+#else /* !JERRY_DEBUGGER */
   JERRY_UNUSED (callback_p);
   JERRY_UNUSED (user_p);
 
@@ -202,19 +188,43 @@ jerry_debugger_wait_for_client_source (jerry_debugger_wait_for_source_callback_t
  * Send the output of the program to the debugger client.
  * Currently only sends print output.
  */
-
-#ifdef JERRY_DEBUGGER
 void
-jerry_debugger_send_output (jerry_char_t buffer[], /**< buffer */
-                            jerry_size_t str_size, /**< string size */
-                            uint8_t type) /**< type of output */
+jerry_debugger_send_output (const jerry_char_t *buffer, /**< buffer */
+                            jerry_size_t str_size) /**< string size */
 {
+#ifdef JERRY_DEBUGGER
   if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
   {
     jerry_debugger_send_string (JERRY_DEBUGGER_OUTPUT_RESULT,
-                                type,
+                                JERRY_DEBUGGER_OUTPUT_OK,
                                 (const uint8_t *) buffer,
                                 sizeof (uint8_t) * str_size);
   }
+#else /* !JERRY_DEBUGGER */
+  JERRY_UNUSED (buffer);
+  JERRY_UNUSED (str_size);
+#endif /* 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 */
+{
+#ifdef 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 /* !JERRY_DEBUGGER */
+  JERRY_UNUSED (level);
+  JERRY_UNUSED (buffer);
+  JERRY_UNUSED (str_size);
 #endif /* JERRY_DEBUGGER */
+} /* jerry_debugger_send_log */
index d9afd120b15cf2a0577b1759e14e4aeed6858869..e4271de1af7d11204090563252ad7d4454a46b01 100644 (file)
  *
  * @return configuration flags
  */
-static inline uint32_t __attr_always_inline___
-snapshot_get_global_flags (bool has_regex) /**< regex literal is present */
+static inline uint32_t JERRY_ATTR_ALWAYS_INLINE
+snapshot_get_global_flags (bool has_regex, /**< regex literal is present */
+                           bool has_class) /**< class literal is present */
 {
   JERRY_UNUSED (has_regex);
+  JERRY_UNUSED (has_class);
 
   uint32_t flags = 0;
 
-#ifdef JERRY_CPOINTER_32_BIT
-  flags |= JERRY_SNAPSHOT_FOUR_BYTE_CPOINTER;
-#endif /* JERRY_CPOINTER_32_BIT */
 #ifndef CONFIG_DISABLE_REGEXP_BUILTIN
   flags |= (has_regex ? JERRY_SNAPSHOT_HAS_REGEX_LITERAL : 0);
-#endif /* CONFIG_DISABLE_REGEXP_BUILTIN */
+#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  flags |= (has_class ? JERRY_SNAPSHOT_HAS_CLASS_LITERAL : 0);
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
 
   return flags;
 } /* snapshot_get_global_flags */
@@ -55,14 +57,17 @@ snapshot_get_global_flags (bool has_regex) /**< regex literal is present */
  *
  * @return true if global_flags accepted, false otherwise
  */
-static inline bool __attr_always_inline___
+static inline bool JERRY_ATTR_ALWAYS_INLINE
 snapshot_check_global_flags (uint32_t global_flags) /**< global flags */
 {
 #ifndef CONFIG_DISABLE_REGEXP_BUILTIN
   global_flags &= (uint32_t) ~JERRY_SNAPSHOT_HAS_REGEX_LITERAL;
 #endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  global_flags &= (uint32_t) ~JERRY_SNAPSHOT_HAS_CLASS_LITERAL;
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
 
-  return global_flags == snapshot_get_global_flags (false);
+  return global_flags == snapshot_get_global_flags (false, false);
 } /* snapshot_check_global_flags */
 
 #endif /* JERRY_ENABLE_SNAPSHOT_SAVE || JERRY_ENABLE_SNAPSHOT_EXEC */
@@ -77,6 +82,7 @@ typedef struct
   size_t snapshot_buffer_write_offset;
   ecma_value_t snapshot_error;
   bool regex_found;
+  bool class_found;
 } snapshot_globals_t;
 
 /** \addtogroup jerrysnapshot Jerry snapshot operations
@@ -92,7 +98,7 @@ typedef struct
  * @return true - if write was successful, i.e. offset + data_size doesn't exceed buffer size,
  *         false - otherwise
  */
-static inline bool __attr_always_inline___
+static inline bool JERRY_ATTR_ALWAYS_INLINE
 snapshot_write_to_buffer_by_offset (uint8_t *buffer_p, /**< buffer */
                                     size_t buffer_size, /**< size of buffer */
                                     size_t *in_out_buffer_offset_p,  /**< [in,out] offset to write to
@@ -142,7 +148,7 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
 
   if (globals_p->snapshot_buffer_write_offset > JERRY_SNAPSHOT_MAXIMUM_WRITE_OFFSET)
   {
-    const char *error_message_p = "Maximum snapshot size reached.";
+    const char * const error_message_p = "Maximum snapshot size reached.";
     globals_p->snapshot_error = jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) error_message_p);
     return 0;
   }
@@ -154,9 +160,16 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
   uint8_t *copied_code_start_p = snapshot_buffer_p + globals_p->snapshot_buffer_write_offset;
   ecma_compiled_code_t *copied_code_p = (ecma_compiled_code_t *) copied_code_start_p;
 
-  if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  if (compiled_code_p->status_flags & CBC_CODE_FLAGS_CONSTRUCTOR)
   {
+    globals_p->class_found = true;
+  }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
 #ifndef CONFIG_DISABLE_REGEXP_BUILTIN
+  if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
+  {
     /* Regular expression. */
     if (globals_p->snapshot_buffer_write_offset + sizeof (ecma_compiled_code_t) > snapshot_buffer_size)
     {
@@ -204,11 +217,11 @@ snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< compiled
 
     copied_code_p->status_flags = compiled_code_p->status_flags;
 
-#else /* CONFIG_DISABLE_REGEXP_BUILTIN */
-    JERRY_UNREACHABLE (); /* RegExp is not supported in the selected profile. */
-#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
     return start_offset;
   }
+#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
+
+  JERRY_ASSERT (compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION);
 
   if (!snapshot_write_to_buffer_by_offset (snapshot_buffer_p,
                                            snapshot_buffer_size,
@@ -275,10 +288,9 @@ static void
 static_snapshot_error_unsupported_literal (snapshot_globals_t *globals_p, /**< snapshot globals */
                                            ecma_value_t literal) /**< literal form the literal pool */
 {
-  const char *error_prefix_p = "Unsupported static snapshot literal: ";
+  const lit_utf8_byte_t error_prefix[] = "Unsupported static snapshot literal: ";
 
-  ecma_string_t *error_message_p = ecma_new_ecma_string_from_utf8 ((const lit_utf8_byte_t *) error_prefix_p,
-                                                                   (lit_utf8_size_t) strlen (error_prefix_p));
+  ecma_string_t *error_message_p = ecma_new_ecma_string_from_utf8 (error_prefix, sizeof (error_prefix) - 1);
 
   literal = ecma_op_to_string (literal);
   JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (literal));
@@ -313,7 +325,7 @@ static_snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< c
 
   if (globals_p->snapshot_buffer_write_offset >= JERRY_SNAPSHOT_MAXIMUM_WRITE_OFFSET)
   {
-    const char *error_message_p = "Maximum snapshot size reached.";
+    const char * const error_message_p = "Maximum snapshot size reached.";
     globals_p->snapshot_error = jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) error_message_p);
     return 0;
   }
@@ -328,7 +340,7 @@ static_snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< c
   if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
   {
     /* Regular expression literals are not supported. */
-    const char *error_message_p = "Regular expression literals are not supported.";
+    const char * const error_message_p = "Regular expression literals are not supported.";
     globals_p->snapshot_error = jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) error_message_p);
     return 0;
   }
@@ -339,7 +351,7 @@ static_snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< c
                                            compiled_code_p,
                                            ((size_t) compiled_code_p->size) << JMEM_ALIGNMENT_LOG))
   {
-    const char *error_message_p = "Snapshot buffer too small.";
+    const char * const error_message_p = "Snapshot buffer too small.";
     globals_p->snapshot_error = jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) error_message_p);
     return 0;
   }
@@ -404,7 +416,7 @@ static_snapshot_add_compiled_code (ecma_compiled_code_t *compiled_code_p, /**< c
     }
   }
 
-  if (compiled_code_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
+  if (CBC_NON_STRICT_ARGUMENTS_NEEDED (compiled_code_p))
   {
     buffer_p += ((size_t) compiled_code_p->size) << JMEM_ALIGNMENT_LOG;
     literal_start_p = ((ecma_value_t *) buffer_p) - argument_end;
@@ -476,7 +488,7 @@ jerry_snapshot_set_offsets (uint32_t *buffer_p, /**< buffer */
         }
       }
 
-      if (bytecode_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
+      if (CBC_NON_STRICT_ARGUMENTS_NEEDED (bytecode_p))
       {
         uint8_t *byte_p = (uint8_t *) bytecode_p;
         byte_p += ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
@@ -536,9 +548,9 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
   ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) base_addr_p;
   uint32_t code_size = ((uint32_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
 
+#ifndef CONFIG_DISABLE_REGEXP_BUILTIN
   if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
   {
-#ifndef CONFIG_DISABLE_REGEXP_BUILTIN
     const re_compiled_code_t *re_bytecode_p = NULL;
 
     const uint8_t *regex_start_p = ((const uint8_t *) bytecode_p) + sizeof (ecma_compiled_code_t);
@@ -554,10 +566,10 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
     ecma_deref_ecma_string (pattern_str_p);
 
     return (ecma_compiled_code_t *) re_bytecode_p;
-#else /* CONFIG_DISABLE_REGEXP_BUILTIN */
-    JERRY_UNREACHABLE (); /* RegExp is not supported in the selected profile. */
-#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
   }
+#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
+
+  JERRY_ASSERT (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION);
 
   size_t header_size;
   uint32_t argument_end = 0;
@@ -569,7 +581,7 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
     uint8_t *byte_p = (uint8_t *) bytecode_p;
     cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) byte_p;
 
-    if (bytecode_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
+    if (CBC_NON_STRICT_ARGUMENTS_NEEDED (bytecode_p))
     {
       argument_end = args_p->argument_end;
     }
@@ -583,7 +595,7 @@ snapshot_load_compiled_code (const uint8_t *base_addr_p, /**< base address of th
     uint8_t *byte_p = (uint8_t *) bytecode_p;
     cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) byte_p;
 
-    if (bytecode_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
+    if (CBC_NON_STRICT_ARGUMENTS_NEEDED (bytecode_p))
     {
       argument_end = args_p->argument_end;
     }
@@ -739,6 +751,7 @@ jerry_generate_snapshot_with_args (const jerry_char_t *resource_name_p, /**< scr
   globals.snapshot_buffer_write_offset = aligned_header_size;
   globals.snapshot_error = ECMA_VALUE_EMPTY;
   globals.regex_found = false;
+  globals.class_found = false;
 
   parse_status = parser_parse_script (args_p,
                                       args_size,
@@ -752,6 +765,8 @@ jerry_generate_snapshot_with_args (const jerry_char_t *resource_name_p, /**< scr
     return ecma_create_error_reference (JERRY_CONTEXT (error_value), true);
   }
 
+  JERRY_ASSERT (bytecode_data_p != NULL);
+
   if (generate_snapshot_opts & JERRY_SNAPSHOT_SAVE_STATIC)
   {
     static_snapshot_add_compiled_code (bytecode_data_p, (uint8_t *) buffer_p, buffer_size, &globals);
@@ -763,13 +778,14 @@ jerry_generate_snapshot_with_args (const jerry_char_t *resource_name_p, /**< scr
 
   if (!ecma_is_value_empty (globals.snapshot_error))
   {
+    ecma_bytecode_deref (bytecode_data_p);
     return globals.snapshot_error;
   }
 
   jerry_snapshot_header_t header;
   header.magic = JERRY_SNAPSHOT_MAGIC;
   header.version = JERRY_SNAPSHOT_VERSION;
-  header.global_flags = snapshot_get_global_flags (globals.regex_found);
+  header.global_flags = snapshot_get_global_flags (globals.regex_found, globals.class_found);
   header.lit_table_offset = (uint32_t) globals.snapshot_buffer_write_offset;
   header.number_of_funcs = 1;
   header.func_offsets[0] = aligned_header_size;
@@ -791,7 +807,8 @@ jerry_generate_snapshot_with_args (const jerry_char_t *resource_name_p, /**< scr
                                           &literals_num))
     {
       JERRY_ASSERT (lit_map_p == NULL);
-      const char *error_message_p = "Cannot allocate memory for literals.";
+      const char * const error_message_p = "Cannot allocate memory for literals.";
+      ecma_bytecode_deref (bytecode_data_p);
       return jerry_create_error (JERRY_ERROR_COMMON, (const jerry_char_t *) error_message_p);
     }
 
@@ -842,7 +859,7 @@ jerry_generate_snapshot (const jerry_char_t *resource_name_p, /**< script resour
 
   if ((generate_snapshot_opts & ~(allowed_opts)) != 0)
   {
-    const char *error_message_p = "Unsupported generate snapshot flags specified.";
+    const char * const error_message_p = "Unsupported generate snapshot flags specified.";
     return jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) error_message_p);
   }
 
@@ -895,8 +912,8 @@ jerry_snapshot_result (const uint32_t *snapshot_p, /**< snapshot */
     return ecma_create_error_reference_from_context ();
   }
 
-  static const char * const invalid_version_error_p = "Invalid snapshot version or unsupported features present";
-  static const char * const invalid_format_error_p = "Invalid snapshot format";
+  const char * const invalid_version_error_p = "Invalid snapshot version or unsupported features present";
+  const char * const invalid_format_error_p = "Invalid snapshot format";
   const uint8_t *snapshot_data_p = (uint8_t *) snapshot_p;
 
   if (snapshot_size <= sizeof (jerry_snapshot_header_t))
@@ -948,7 +965,7 @@ jerry_snapshot_result (const uint32_t *snapshot_p, /**< snapshot */
   }
   else
   {
-    const uint8_t *literal_base_p = (uint8_t *) (snapshot_data_p + header_p->lit_table_offset);
+    const uint8_t *literal_base_p = snapshot_data_p + header_p->lit_table_offset;
 
     bytecode_p = snapshot_load_compiled_code ((const uint8_t *) bytecode_p,
                                               literal_base_p,
@@ -1038,13 +1055,13 @@ scan_snapshot_functions (const uint8_t *buffer_p, /**< snapshot buffer start */
 
   do
   {
-    ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) buffer_p;
+    const ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) buffer_p;
     uint32_t code_size = ((uint32_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
 
     if ((bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
         && !(bytecode_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION))
     {
-      ecma_value_t *literal_start_p;
+      const ecma_value_t *literal_start_p;
       uint32_t argument_end;
       uint32_t const_literal_end;
 
@@ -1070,12 +1087,11 @@ scan_snapshot_functions (const uint8_t *buffer_p, /**< snapshot buffer start */
         if ((literal_start_p[i] & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_SNAPSHOT_OFFSET)
         {
           ecma_value_t lit_value = ecma_snapshot_get_literal (literal_base_p, literal_start_p[i]);
-          literal_start_p[i] = lit_value;
           ecma_save_literals_append_value (lit_value, lit_pool_p);
         }
       }
 
-      if (bytecode_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
+      if (CBC_NON_STRICT_ARGUMENTS_NEEDED (bytecode_p))
       {
         uint8_t *byte_p = (uint8_t *) bytecode_p;
         byte_p += ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
@@ -1086,7 +1102,6 @@ scan_snapshot_functions (const uint8_t *buffer_p, /**< snapshot buffer start */
           if ((literal_start_p[i] & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_SNAPSHOT_OFFSET)
           {
             ecma_value_t lit_value = ecma_snapshot_get_literal (literal_base_p, literal_start_p[i]);
-            literal_start_p[i] = lit_value;
             ecma_save_literals_append_value (lit_value, lit_pool_p);
           }
         }
@@ -1102,15 +1117,16 @@ scan_snapshot_functions (const uint8_t *buffer_p, /**< snapshot buffer start */
  * Update all literal offsets in a snapshot data.
  */
 static void
-update_literal_offsets (uint8_t *buffer_p, /**< snapshot buffer start */
+update_literal_offsets (uint8_t *buffer_p, /**< [in,out] snapshot buffer start */
                         const uint8_t *buffer_end_p, /**< snapshot buffer end */
-                        lit_mem_to_snapshot_id_map_entry_t *lit_map_p) /**< literal map */
+                        const lit_mem_to_snapshot_id_map_entry_t *lit_map_p, /**< literal map */
+                        const uint8_t *literal_base_p) /**< start of literal data */
 {
   JERRY_ASSERT (buffer_end_p > buffer_p);
 
   do
   {
-    ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) buffer_p;
+    const ecma_compiled_code_t *bytecode_p = (ecma_compiled_code_t *) buffer_p;
     uint32_t code_size = ((uint32_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
 
     if ((bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
@@ -1139,12 +1155,12 @@ update_literal_offsets (uint8_t *buffer_p, /**< snapshot buffer start */
 
       for (uint32_t i = 0; i < const_literal_end; i++)
       {
-        if (ecma_is_value_string (literal_start_p[i])
-            || ecma_is_value_float_number (literal_start_p[i]))
+        if ((literal_start_p[i] & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_SNAPSHOT_OFFSET)
         {
-          lit_mem_to_snapshot_id_map_entry_t *current_p = lit_map_p;
+          ecma_value_t lit_value = ecma_snapshot_get_literal (literal_base_p, literal_start_p[i]);
+          const lit_mem_to_snapshot_id_map_entry_t *current_p = lit_map_p;
 
-          while (current_p->literal_id != literal_start_p[i])
+          while (current_p->literal_id != lit_value)
           {
             current_p++;
           }
@@ -1153,7 +1169,7 @@ update_literal_offsets (uint8_t *buffer_p, /**< snapshot buffer start */
         }
       }
 
-      if (bytecode_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
+      if (CBC_NON_STRICT_ARGUMENTS_NEEDED (bytecode_p))
       {
         uint8_t *byte_p = (uint8_t *) bytecode_p;
         byte_p += ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
@@ -1161,11 +1177,12 @@ update_literal_offsets (uint8_t *buffer_p, /**< snapshot buffer start */
 
         for (uint32_t i = 0; i < argument_end; i++)
         {
-          if (literal_start_p[i] != ECMA_VALUE_EMPTY)
+          if ((literal_start_p[i] & ECMA_VALUE_TYPE_MASK) == ECMA_TYPE_SNAPSHOT_OFFSET)
           {
-            lit_mem_to_snapshot_id_map_entry_t *current_p = lit_map_p;
+            ecma_value_t lit_value = ecma_snapshot_get_literal (literal_base_p, literal_start_p[i]);
+            const lit_mem_to_snapshot_id_map_entry_t *current_p = lit_map_p;
 
-            while (current_p->literal_id != literal_start_p[i])
+            while (current_p->literal_id != lit_value)
             {
               current_p++;
             }
@@ -1234,7 +1251,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
 
     uint32_t start_offset = header_p->func_offsets[0];
     const uint8_t *data_p = (const uint8_t *) inp_buffers_p[i];
-    const uint8_t *literal_base_p = (uint8_t *) (data_p + header_p->lit_table_offset);
+    const uint8_t *literal_base_p = data_p + header_p->lit_table_offset;
 
     JERRY_ASSERT (header_p->number_of_funcs > 0);
 
@@ -1242,7 +1259,7 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
     functions_size += header_p->lit_table_offset - start_offset;
 
     scan_snapshot_functions (data_p + start_offset,
-                             data_p + header_p->lit_table_offset,
+                             literal_base_p,
                              lit_pool_p,
                              literal_base_p);
   }
@@ -1294,9 +1311,11 @@ jerry_merge_snapshots (const uint32_t **inp_buffers_p, /**< array of (pointers t
             ((const uint8_t *) inp_buffers_p[i]) + start_offset,
             current_header_p->lit_table_offset - start_offset);
 
+    const uint8_t *literal_base_p = ((const uint8_t *) inp_buffers_p[i]) + current_header_p->lit_table_offset;
     update_literal_offsets (dst_p,
                             dst_p + current_header_p->lit_table_offset - start_offset,
-                            lit_map_p);
+                            lit_map_p,
+                            literal_base_p);
 
     uint32_t current_offset = (uint32_t) (dst_p - (uint8_t *) out_buffer_p) - start_offset;
 
@@ -1488,15 +1507,13 @@ jerry_append_ecma_string_to_buffer (uint8_t *buffer_p, /**< buffer */
                                     uint8_t *buffer_end_p, /**< the end of the buffer */
                                     ecma_string_t *string_p) /**< ecma-string */
 {
-  uint8_t *new_buffer_p = NULL;
-
   ECMA_STRING_TO_UTF8_STRING (string_p, str_buffer_p, str_buffer_size);
 
   /* Append the string to the buffer. */
-  new_buffer_p = jerry_append_chars_to_buffer (buffer_p,
-                                               buffer_end_p,
-                                               (const char *) str_buffer_p,
-                                               str_buffer_size);
+  uint8_t *new_buffer_p = jerry_append_chars_to_buffer (buffer_p,
+                                                        buffer_end_p,
+                                                        (const char *) str_buffer_p,
+                                                        str_buffer_size);
 
   ECMA_FINALIZE_UTF8_STRING (str_buffer_p, str_buffer_size);
 
@@ -1565,48 +1582,44 @@ ecma_string_is_valid_identifier (const ecma_string_t *string_p)
 #endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
 
 /**
- * Copy certain string literals into the given buffer in a specified format,
- * which are valid identifiers and none of them are magic string.
+ * Get the literals from a snapshot. Copies certain string literals into the given
+ * buffer in a specified format.
+ *
+ * Note:
+ *      Only valid identifiers are saved in C format.
  *
  * @return size of the literal-list in bytes, at most equal to the buffer size,
- *         if the source parsed successfully and the list of the literals isn't empty,
+ *         if the list of the literals isn't empty,
  *         0 - otherwise.
  */
 size_t
-jerry_parse_and_save_literals (const jerry_char_t *source_p, /**< script source */
-                               size_t source_size, /**< script source size */
-                               bool is_strict, /**< strict mode */
-                               uint32_t *buffer_p, /**< [out] buffer to save literals to */
-                               size_t buffer_size, /**< the buffer's size */
-                               bool is_c_format) /**< format-flag */
+jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, /**< input snapshot buffer */
+                                  size_t snapshot_size, /**< size of the input snapshot buffer */
+                                  jerry_char_t *lit_buf_p, /**< [out] buffer to save literals to */
+                                  size_t lit_buf_size, /**< the buffer's size */
+                                  bool is_c_format) /**< format-flag */
 {
 #ifdef JERRY_ENABLE_SNAPSHOT_SAVE
-  ecma_value_t parse_status;
-  ecma_compiled_code_t *bytecode_data_p;
-
-#ifdef JERRY_ENABLE_LINE_INFO
-  JERRY_CONTEXT (resource_name) = ECMA_VALUE_UNDEFINED;
-#endif /* JERRY_ENABLE_LINE_INFO */
-
-  parse_status = parser_parse_script (NULL,
-                                      0,
-                                      source_p,
-                                      source_size,
-                                      is_strict,
-                                      &bytecode_data_p);
+  const uint8_t *snapshot_data_p = (uint8_t *) snapshot_p;
+  const jerry_snapshot_header_t *header_p = (const jerry_snapshot_header_t *) snapshot_data_p;
 
-  if (ECMA_IS_VALUE_ERROR (parse_status))
+  if (snapshot_size <= sizeof (jerry_snapshot_header_t)
+      || header_p->magic != JERRY_SNAPSHOT_MAGIC
+      || header_p->version != JERRY_SNAPSHOT_VERSION
+      || !snapshot_check_global_flags (header_p->global_flags))
   {
-    ecma_free_value (JERRY_CONTEXT (error_value));
+    /* Invalid snapshot format */
     return 0;
   }
 
-  ecma_free_value (parse_status);
+  JERRY_ASSERT ((header_p->lit_table_offset % sizeof (uint32_t)) == 0);
+  const uint8_t *literal_base_p = snapshot_data_p + header_p->lit_table_offset;
 
   ecma_collection_header_t *lit_pool_p = ecma_new_values_collection ();
-  ecma_save_literals_add_compiled_code (bytecode_data_p, lit_pool_p);
-
-  ecma_bytecode_deref (bytecode_data_p);
+  scan_snapshot_functions (snapshot_data_p + header_p->func_offsets[0],
+                           literal_base_p,
+                           lit_pool_p,
+                           literal_base_p);
 
   lit_utf8_size_t literal_count = 0;
   ecma_value_t *iterator_p = ecma_collection_iterator_init (lit_pool_p);
@@ -1618,9 +1631,14 @@ jerry_parse_and_save_literals (const jerry_char_t *source_p, /**< script source
     {
       ecma_string_t *literal_p = ecma_get_string_from_value (*iterator_p);
 
-      /* We don't save a literal which isn't a valid identifier or it's a magic string. */
+      /* NOTE:
+       *      We don't save a literal (in C format) which isn't a valid
+       *      identifier or it's a magic string.
+       * TODO:
+       *      Save all of the literals in C format as well.
+       */
       if (ecma_get_string_magic (literal_p) == LIT_MAGIC_STRING__COUNT
-          && ecma_string_is_valid_identifier (literal_p))
+          && (!is_c_format || ecma_string_is_valid_identifier (literal_p)))
       {
         literal_count++;
       }
@@ -1635,10 +1653,8 @@ jerry_parse_and_save_literals (const jerry_char_t *source_p, /**< script source
     return 0;
   }
 
-  uint8_t *destination_p = (uint8_t *) buffer_p;
-
-  uint8_t *const buffer_start_p = destination_p;
-  uint8_t *const buffer_end_p = destination_p + buffer_size;
+  jerry_char_t *const buffer_start_p = lit_buf_p;
+  jerry_char_t *const buffer_end_p = lit_buf_p + lit_buf_size;
 
   JMEM_DEFINE_LOCAL_ARRAY (literal_array, literal_count, ecma_string_t *);
   lit_utf8_size_t literal_idx = 0;
@@ -1651,8 +1667,14 @@ jerry_parse_and_save_literals (const jerry_char_t *source_p, /**< script source
     {
       ecma_string_t *literal_p = ecma_get_string_from_value (*iterator_p);
 
+      /* NOTE:
+       *      We don't save a literal (in C format) which isn't a valid
+       *      identifier or it's a magic string.
+       * TODO:
+       *      Save all of the literals in C format as well.
+       */
       if (ecma_get_string_magic (literal_p) == LIT_MAGIC_STRING__COUNT
-          && ecma_string_is_valid_identifier (literal_p))
+          && (!is_c_format || ecma_string_is_valid_identifier (literal_p)))
       {
         literal_array[literal_idx++] = literal_p;
       }
@@ -1669,43 +1691,43 @@ jerry_parse_and_save_literals (const jerry_char_t *source_p, /**< script source
   if (is_c_format)
   {
     /* Save literal count. */
-    destination_p = jerry_append_chars_to_buffer (destination_p,
-                                                  buffer_end_p,
-                                                  (const char *) "jerry_length_t literal_count = ",
-                                                  0);
+    lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p,
+                                              buffer_end_p,
+                                              "jerry_length_t literal_count = ",
+                                              0);
 
-    destination_p = jerry_append_number_to_buffer (destination_p, buffer_end_p, literal_count);
+    lit_buf_p = jerry_append_number_to_buffer (lit_buf_p, buffer_end_p, literal_count);
 
     /* Save the array of literals. */
-    destination_p = jerry_append_chars_to_buffer (destination_p,
-                                                  buffer_end_p,
-                                                  ";\n\njerry_char_ptr_t literals[",
-                                                  0);
+    lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p,
+                                              buffer_end_p,
+                                              ";\n\njerry_char_t *literals[",
+                                              0);
 
-    destination_p = jerry_append_number_to_buffer (destination_p, buffer_end_p, literal_count);
-    destination_p = jerry_append_chars_to_buffer (destination_p, buffer_end_p, "] =\n{\n", 0);
+    lit_buf_p = jerry_append_number_to_buffer (lit_buf_p, buffer_end_p, literal_count);
+    lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p, buffer_end_p, "] =\n{\n", 0);
 
     for (lit_utf8_size_t i = 0; i < literal_count; i++)
     {
-      destination_p = jerry_append_chars_to_buffer (destination_p, buffer_end_p, "  \"", 0);
-      destination_p = jerry_append_ecma_string_to_buffer (destination_p, buffer_end_p, literal_array[i]);
-      destination_p = jerry_append_chars_to_buffer (destination_p, buffer_end_p, "\"", 0);
+      lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p, buffer_end_p, "  \"", 0);
+      lit_buf_p = jerry_append_ecma_string_to_buffer (lit_buf_p, buffer_end_p, literal_array[i]);
+      lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p, buffer_end_p, "\"", 0);
 
       if (i < literal_count - 1)
       {
-        destination_p = jerry_append_chars_to_buffer (destination_p, buffer_end_p, ",", 0);
+        lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p, buffer_end_p, ",", 0);
       }
 
-      destination_p = jerry_append_chars_to_buffer (destination_p, buffer_end_p, "\n", 0);
+      lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p, buffer_end_p, "\n", 0);
     }
 
-    destination_p = jerry_append_chars_to_buffer (destination_p,
-                                                  buffer_end_p,
-                                                  (const char *) "};\n\njerry_length_t literal_sizes[",
-                                                  0);
+    lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p,
+                                              buffer_end_p,
+                                              "};\n\njerry_length_t literal_sizes[",
+                                              0);
 
-    destination_p = jerry_append_number_to_buffer (destination_p, buffer_end_p, literal_count);
-    destination_p = jerry_append_chars_to_buffer (destination_p, buffer_end_p, "] =\n{\n", 0);
+    lit_buf_p = jerry_append_number_to_buffer (lit_buf_p, buffer_end_p, literal_count);
+    lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p, buffer_end_p, "] =\n{\n", 0);
   }
 
   /* Save the literal sizes respectively. */
@@ -1715,51 +1737,51 @@ jerry_parse_and_save_literals (const jerry_char_t *source_p, /**< script source
 
     if (is_c_format)
     {
-      destination_p = jerry_append_chars_to_buffer (destination_p, buffer_end_p, "  ", 0);
+      lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p, buffer_end_p, "  ", 0);
     }
 
-    destination_p = jerry_append_number_to_buffer (destination_p, buffer_end_p, str_size);
-    destination_p = jerry_append_chars_to_buffer (destination_p, buffer_end_p, " ", 0);
+    lit_buf_p = jerry_append_number_to_buffer (lit_buf_p, buffer_end_p, str_size);
+    lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p, buffer_end_p, " ", 0);
 
     if (is_c_format)
     {
       /* Show the given string as a comment. */
-      destination_p = jerry_append_chars_to_buffer (destination_p, buffer_end_p, "/* ", 0);
-      destination_p = jerry_append_ecma_string_to_buffer (destination_p, buffer_end_p, literal_array[i]);
-      destination_p = jerry_append_chars_to_buffer (destination_p, buffer_end_p, " */", 0);
+      lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p, buffer_end_p, "/* ", 0);
+      lit_buf_p = jerry_append_ecma_string_to_buffer (lit_buf_p, buffer_end_p, literal_array[i]);
+      lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p, buffer_end_p, " */", 0);
 
       if (i < literal_count - 1)
       {
-        destination_p = jerry_append_chars_to_buffer (destination_p, buffer_end_p, ",", 0);
+        lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p, buffer_end_p, ",", 0);
       }
     }
     else
     {
-      destination_p = jerry_append_ecma_string_to_buffer (destination_p, buffer_end_p, literal_array[i]);
+      lit_buf_p = jerry_append_ecma_string_to_buffer (lit_buf_p, buffer_end_p, literal_array[i]);
     }
 
-    destination_p = jerry_append_chars_to_buffer (destination_p, buffer_end_p, "\n", 0);
+    lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p, buffer_end_p, "\n", 0);
   }
 
   if (is_c_format)
   {
-    destination_p = jerry_append_chars_to_buffer (destination_p, buffer_end_p, (const char *) "};\n", 0);
+    lit_buf_p = jerry_append_chars_to_buffer (lit_buf_p, buffer_end_p, "};\n", 0);
   }
 
   JMEM_FINALIZE_LOCAL_ARRAY (literal_array);
 
-  return destination_p <= buffer_end_p ? (size_t) (destination_p - buffer_start_p) : 0;
+  return lit_buf_p <= buffer_end_p ? (size_t) (lit_buf_p - buffer_start_p) : 0;
 #else /* !JERRY_ENABLE_SNAPSHOT_SAVE */
-  JERRY_UNUSED (source_p);
-  JERRY_UNUSED (source_size);
-  JERRY_UNUSED (is_strict);
-  JERRY_UNUSED (buffer_p);
-  JERRY_UNUSED (buffer_size);
+  JERRY_UNUSED (snapshot_p);
+  JERRY_UNUSED (snapshot_size);
+  JERRY_UNUSED (lit_buf_p);
+  JERRY_UNUSED (lit_buf_size);
   JERRY_UNUSED (is_c_format);
 
   return 0;
 #endif /* JERRY_ENABLE_SNAPSHOT_SAVE */
-} /* jerry_parse_and_save_literals */
+} /* jerry_get_literals_from_snapshot */
+
 
 /**
  * Generate snapshot function from specified source and arguments
@@ -1785,7 +1807,7 @@ jerry_generate_function_snapshot (const jerry_char_t *resource_name_p, /**< scri
 
   if ((generate_snapshot_opts & ~(allowed_opts)) != 0)
   {
-    const char *error_message_p = "Unsupported generate snapshot flags specified.";
+    const char * const error_message_p = "Unsupported generate snapshot flags specified.";
     return jerry_create_error (JERRY_ERROR_RANGE, (const jerry_char_t *) error_message_p);
   }
 
index 9198557696c5b9170f1a8c12cc283c4e828aa2cb..94d09178c90dfb19dd19615734f22a261f0d3f5f 100644 (file)
@@ -38,11 +38,6 @@ typedef struct
  */
 #define JERRY_SNAPSHOT_MAGIC (0x5952524Au)
 
-/**
- * Jerry snapshot format version.
- */
-#define JERRY_SNAPSHOT_VERSION (12u)
-
 /**
  * Snapshot configuration flags.
  */
@@ -50,8 +45,9 @@ 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) /**< compressed pointers are four byte long */
+  JERRY_SNAPSHOT_FOUR_BYTE_CPOINTER = (1u << 8) /**< deprecated, an unused placeholder now */
 } jerry_snapshot_global_flags_t;
 
 #endif /* !JERRY_SNAPSHOT_H */
index 3ae749b45ba7d186772eec562dff4e7b16aafdc6..6633c75112c2e40d1522fe20568da96b7101b259 100644 (file)
 #include "ecma-literal-storage.h"
 #include "ecma-objects.h"
 #include "ecma-objects-general.h"
+#include "ecma-regexp-object.h"
 #include "ecma-promise-object.h"
 #include "ecma-typedarray-object.h"
 #include "jcontext.h"
 #include "jerryscript.h"
+#include "jerryscript-debugger-transport.h"
 #include "jmem.h"
 #include "js-parser.h"
 #include "re-compiler.h"
@@ -58,6 +60,13 @@ JERRY_STATIC_ASSERT ((int) ECMA_INIT_EMPTY == (int) JERRY_INIT_EMPTY
                      && (int) ECMA_INIT_MEM_STATS == (int) JERRY_INIT_MEM_STATS,
                      ecma_init_flag_t_must_be_equal_to_jerry_init_flag_t);
 
+#ifndef CONFIG_DISABLE_REGEXP_BUILTIN
+JERRY_STATIC_ASSERT ((int) RE_FLAG_GLOBAL == (int) JERRY_REGEXP_FLAG_GLOBAL
+                     && (int) RE_FLAG_MULTILINE == (int) JERRY_REGEXP_FLAG_MULTILINE
+                     && (int) RE_FLAG_IGNORE_CASE == (int) JERRY_REGEXP_FLAG_IGNORE_CASE,
+                     re_flags_t_must_be_equal_to_jerry_regexp_flags_t);
+#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
+
 #if defined JERRY_DISABLE_JS_PARSER && !defined JERRY_ENABLE_SNAPSHOT_EXEC
 #error JERRY_ENABLE_SNAPSHOT_EXEC must be defined if JERRY_DISABLE_JS_PARSER is defined!
 #endif /* JERRY_DISABLE_JS_PARSER && !JERRY_ENABLE_SNAPSHOT_EXEC */
@@ -97,20 +106,16 @@ static const char * const wrong_args_msg_p = "wrong type of argument";
  *           - before jerry_init and after jerry_cleanup
  *           - between enter to and return from a native free callback
  */
-static inline void __attr_always_inline___
+static inline void JERRY_ATTR_ALWAYS_INLINE
 jerry_assert_api_available (void)
 {
-  if (unlikely (!(JERRY_CONTEXT (status_flags) & ECMA_STATUS_API_AVAILABLE)))
-  {
-    /* Terminates the execution. */
-    JERRY_UNREACHABLE ();
-  }
+  JERRY_ASSERT (JERRY_CONTEXT (status_flags) & ECMA_STATUS_API_AVAILABLE);
 } /* jerry_assert_api_available */
 
 /**
  * Turn on API availability
  */
-static inline void __attr_always_inline___
+static inline void JERRY_ATTR_ALWAYS_INLINE
 jerry_make_api_available (void)
 {
   JERRY_CONTEXT (status_flags) |= ECMA_STATUS_API_AVAILABLE;
@@ -119,31 +124,12 @@ jerry_make_api_available (void)
 /**
  * Turn off API availability
  */
-static inline void __attr_always_inline___
+static inline void JERRY_ATTR_ALWAYS_INLINE
 jerry_make_api_unavailable (void)
 {
   JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_API_AVAILABLE;
 } /* jerry_make_api_unavailable */
 
-/**
- * Remove the error flag from the argument value.
- *
- * Note:
- *   Compatiblity function, should go away with JerryScript 2.0
- *
- * @return return value for Jerry API functions
- */
-static inline jerry_value_t __attr_always_inline___
-jerry_get_arg_value (jerry_value_t value) /**< return value */
-{
-  if (unlikely (ecma_is_value_error_reference (value)))
-  {
-    value = ecma_get_error_reference_from_value (value)->value;
-  }
-
-  return value;
-} /* jerry_get_arg_value */
-
 /**
  * Create an API compatible return value.
  *
@@ -165,7 +151,7 @@ jerry_return (jerry_value_t value) /**< return value */
  *
  * @return return value for Jerry API functions
  */
-static inline jerry_value_t __attr_always_inline___
+static inline jerry_value_t JERRY_ATTR_ALWAYS_INLINE
 jerry_throw (jerry_value_t value) /**< return value */
 {
   JERRY_ASSERT (ECMA_IS_VALUE_ERROR (value));
@@ -178,14 +164,12 @@ jerry_throw (jerry_value_t value) /**< return value */
 void
 jerry_init (jerry_init_flag_t flags) /**< combination of Jerry flags */
 {
-  if (unlikely (JERRY_CONTEXT (status_flags) & ECMA_STATUS_API_AVAILABLE))
-  {
-    /* This function cannot be called twice unless jerry_cleanup is called. */
-    JERRY_UNREACHABLE ();
-  }
+  /* This function cannot be called twice unless jerry_cleanup is called. */
+  JERRY_ASSERT (!(JERRY_CONTEXT (status_flags) & ECMA_STATUS_API_AVAILABLE));
 
-  /* Zero out all members. */
-  memset (&JERRY_CONTEXT (JERRY_CONTEXT_FIRST_MEMBER), 0, sizeof (jerry_context_t));
+  /* Zero out all non-external members. */
+  memset (&JERRY_CONTEXT (JERRY_CONTEXT_FIRST_MEMBER), 0,
+          sizeof (jerry_context_t) - offsetof (jerry_context_t, JERRY_CONTEXT_FIRST_MEMBER));
 
   JERRY_CONTEXT (jerry_init_flags) = flags;
 
@@ -206,7 +190,7 @@ jerry_cleanup (void)
 #ifdef JERRY_DEBUGGER
   if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
   {
-    jerry_debugger_close_connection ();
+    jerry_debugger_transport_close ();
   }
 #endif /* JERRY_DEBUGGER */
 
@@ -282,37 +266,28 @@ jerry_get_context_data (const jerry_context_data_manager_t *manager_p)
  * Register external magic string array
  */
 void
-jerry_register_magic_strings (const jerry_char_ptr_t *ex_str_items_p, /**< character arrays, representing
-                                                                       *   external magic strings' contents */
+jerry_register_magic_strings (const jerry_char_t * const *ex_str_items_p, /**< character arrays, representing
+                                                                           *   external magic strings' contents */
                               uint32_t count, /**< number of the strings */
                               const jerry_length_t *str_lengths_p) /**< lengths of all strings */
 {
   jerry_assert_api_available ();
 
-  lit_magic_strings_ex_set ((const lit_utf8_byte_t **) ex_str_items_p, count, (const lit_utf8_size_t *) str_lengths_p);
+  lit_magic_strings_ex_set ((const lit_utf8_byte_t * const *) ex_str_items_p,
+                            count,
+                            (const lit_utf8_size_t *) str_lengths_p);
 } /* jerry_register_magic_strings */
 
-/**
- * Get Jerry configured memory limits
- */
-void
-jerry_get_memory_limits (size_t *out_data_bss_brk_limit_p, /**< [out] Jerry's maximum usage of
-                                                            *         data + bss + brk sections */
-                         size_t *out_stack_limit_p) /**< [out] Jerry's maximum usage of stack */
-{
-  *out_data_bss_brk_limit_p = CONFIG_MEM_HEAP_AREA_SIZE + CONFIG_MEM_DATA_LIMIT_MINUS_HEAP_SIZE;
-  *out_stack_limit_p = CONFIG_MEM_STACK_LIMIT;
-} /* jerry_get_memory_limits */
-
 /**
  * Run garbage collection
  */
 void
-jerry_gc (void)
+jerry_gc (jerry_gc_mode_t mode) /**< operational mode */
 {
   jerry_assert_api_available ();
 
-  ecma_gc_run (JMEM_FREE_UNUSED_MEMORY_SEVERITY_LOW);
+  ecma_gc_run (mode == JERRY_GC_SEVERITY_LOW ? JMEM_FREE_UNUSED_MEMORY_SEVERITY_LOW
+                                             : JMEM_FREE_UNUSED_MEMORY_SEVERITY_HIGH);
 } /* jerry_gc */
 
 /**
@@ -427,7 +402,7 @@ jerry_parse (const jerry_char_t *resource_name_p, /**< resource name (usually a
                                       0,
                                       source_p,
                                       source_size,
-                                      (parse_opts & JERRY_PARSE_STRICT_MODE) != 0,
+                                      parse_opts,
                                       &bytecode_data_p);
 
   if (ECMA_IS_VALUE_ERROR (parse_status))
@@ -502,7 +477,7 @@ jerry_parse_function (const jerry_char_t *resource_name_p, /**< resource name (u
                                       arg_list_size,
                                       source_p,
                                       source_size,
-                                      (parse_opts & JERRY_PARSE_STRICT_MODE) != 0,
+                                      parse_opts,
                                       &bytecode_data_p);
 
   if (ECMA_IS_VALUE_ERROR (parse_status))
@@ -580,14 +555,13 @@ jerry_run (const jerry_value_t func_val) /**< function to run */
 jerry_value_t
 jerry_eval (const jerry_char_t *source_p, /**< source code */
             size_t source_size, /**< length of source code */
-            bool is_strict) /**< source must conform with strict mode */
+            uint32_t parse_opts) /**< jerry_parse_opts_t option bits */
 {
   jerry_assert_api_available ();
 
   return jerry_return (ecma_op_eval_chars_buffer ((const lit_utf8_byte_t *) source_p,
                                                   source_size,
-                                                  false,
-                                                  is_strict));
+                                                  parse_opts));
 } /* jerry_eval */
 
 /**
@@ -622,10 +596,32 @@ jerry_value_t
 jerry_get_global_object (void)
 {
   jerry_assert_api_available ();
-
-  return ecma_make_object_value (ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL));
+  ecma_object_t *global_obj_p = ecma_builtin_get_global ();
+  ecma_ref_object (global_obj_p);
+  return ecma_make_object_value (global_obj_p);
 } /* jerry_get_global_object */
 
+/**
+ * Check if the specified value is an abort value.
+ *
+ * @return true  - if both the error and abort values are set,
+ *         false - otherwise
+ */
+bool
+jerry_value_is_abort (const jerry_value_t value) /**< api value */
+{
+  jerry_assert_api_available ();
+
+  if (!ecma_is_value_error_reference (value))
+  {
+    return false;
+  }
+
+  ecma_error_reference_t *error_ref_p = ecma_get_error_reference_from_value (value);
+
+  return (error_ref_p->refs_and_flags & ECMA_ERROR_REF_ABORT) != 0;
+} /* jerry_value_is_abort */
+
 /**
  * Check if the specified value is an array object value.
  *
@@ -637,9 +633,8 @@ jerry_value_is_array (const jerry_value_t value) /**< jerry api value */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t array = jerry_get_arg_value (value);
-  return (ecma_is_value_object (array)
-          && ecma_get_object_type (ecma_get_object_from_value (array)) == ECMA_OBJECT_TYPE_ARRAY);
+  return (ecma_is_value_object (value)
+          && ecma_get_object_type (ecma_get_object_from_value (value)) == ECMA_OBJECT_TYPE_ARRAY);
 } /* jerry_value_is_array */
 
 /**
@@ -653,7 +648,7 @@ jerry_value_is_boolean (const jerry_value_t value) /**< api value */
 {
   jerry_assert_api_available ();
 
-  return ecma_is_value_boolean (jerry_get_arg_value (value));
+  return ecma_is_value_boolean (value);
 } /* jerry_value_is_boolean */
 
 /**
@@ -667,9 +662,23 @@ jerry_value_is_constructor (const jerry_value_t value) /**< jerry api value */
 {
   jerry_assert_api_available ();
 
-  return ecma_is_constructor (jerry_get_arg_value (value));
+  return ecma_is_constructor (value);
 } /* jerry_value_is_constructor */
 
+/**
+ * Check if the specified value is an error or abort value.
+ *
+ * @return true  - if the specified value is an error value,
+ *         false - otherwise
+ */
+bool
+jerry_value_is_error (const jerry_value_t value) /**< api value */
+{
+  jerry_assert_api_available ();
+
+  return ecma_is_value_error_reference (value);
+} /* jerry_value_is_error */
+
 /**
  * Check if the specified value is a function object value.
  *
@@ -681,7 +690,7 @@ jerry_value_is_function (const jerry_value_t value) /**< api value */
 {
   jerry_assert_api_available ();
 
-  return ecma_op_is_callable (jerry_get_arg_value (value));
+  return ecma_op_is_callable (value);
 } /* jerry_value_is_function */
 
 /**
@@ -695,7 +704,7 @@ jerry_value_is_number (const jerry_value_t value) /**< api value */
 {
   jerry_assert_api_available ();
 
-  return ecma_is_value_number (jerry_get_arg_value (value));
+  return ecma_is_value_number (value);
 } /* jerry_value_is_number */
 
 /**
@@ -709,7 +718,7 @@ jerry_value_is_null (const jerry_value_t value) /**< api value */
 {
   jerry_assert_api_available ();
 
-  return ecma_is_value_null (jerry_get_arg_value (value));
+  return ecma_is_value_null (value);
 } /* jerry_value_is_null */
 
 /**
@@ -723,7 +732,7 @@ jerry_value_is_object (const jerry_value_t value) /**< api value */
 {
   jerry_assert_api_available ();
 
-  return ecma_is_value_object (jerry_get_arg_value (value));
+  return ecma_is_value_object (value);
 } /* jerry_value_is_object */
 
 /**
@@ -737,9 +746,8 @@ jerry_value_is_promise (const jerry_value_t value) /**< api value */
 {
   jerry_assert_api_available ();
 #ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
-  jerry_value_t promise = jerry_get_arg_value (value);
-  return (ecma_is_value_object (promise)
-          && ecma_is_promise (ecma_get_object_from_value (promise)));
+  return (ecma_is_value_object (value)
+          && ecma_is_promise (ecma_get_object_from_value (value)));
 #else /* CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */
   JERRY_UNUSED (value);
   return false;
@@ -757,7 +765,7 @@ jerry_value_is_string (const jerry_value_t value) /**< api value */
 {
   jerry_assert_api_available ();
 
-  return ecma_is_value_string (jerry_get_arg_value (value));
+  return ecma_is_value_string (value);
 } /* jerry_value_is_string */
 
 /**
@@ -771,7 +779,7 @@ jerry_value_is_undefined (const jerry_value_t value) /**< api value */
 {
   jerry_assert_api_available ();
 
-  return ecma_is_value_undefined (jerry_get_arg_value (value));
+  return ecma_is_value_undefined (value);
 } /* jerry_value_is_undefined */
 
 /**
@@ -784,8 +792,12 @@ jerry_value_get_type (const jerry_value_t value) /**< input value to check */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t argument = jerry_get_arg_value (value);
-  lit_magic_string_id_t lit_id = ecma_get_typeof_lit_id (argument);
+  if (ecma_is_value_error_reference (value))
+  {
+    return JERRY_TYPE_ERROR;
+  }
+
+  lit_magic_string_id_t lit_id = ecma_get_typeof_lit_id (value);
 
   JERRY_ASSERT (lit_id != LIT_MAGIC_STRING__EMPTY);
 
@@ -811,21 +823,16 @@ jerry_value_get_type (const jerry_value_t value) /**< input value to check */
     {
       return JERRY_TYPE_FUNCTION;
     }
-    case LIT_MAGIC_STRING_OBJECT:
+    default:
     {
+      JERRY_ASSERT (lit_id == LIT_MAGIC_STRING_OBJECT);
+
       /* Based on the ECMA 262 5.1 standard the 'null' value is an object.
        * Thus we'll do an extra check for 'null' here.
        */
-      return ecma_is_value_null (argument) ? JERRY_TYPE_NULL : JERRY_TYPE_OBJECT;
-    }
-    default:
-    {
-      JERRY_UNREACHABLE ();
-      break;
+      return ecma_is_value_null (value) ? JERRY_TYPE_NULL : JERRY_TYPE_OBJECT;
     }
   }
-
-  return JERRY_TYPE_NONE;
 } /* jerry_value_get_type */
 
 /**
@@ -834,7 +841,8 @@ jerry_value_get_type (const jerry_value_t value) /**< input value to check */
  * @return true  - if the specified feature is enabled,
  *         false - otherwise
  */
-bool jerry_is_feature_enabled (const jerry_feature_t feature)
+bool
+jerry_is_feature_enabled (const jerry_feature_t feature) /**< feature to check */
 {
   JERRY_ASSERT (feature < JERRY_FEATURE__COUNT);
 
@@ -887,117 +895,112 @@ bool jerry_is_feature_enabled (const jerry_feature_t feature)
 #ifdef JERRY_ENABLE_LINE_INFO
           || feature == JERRY_FEATURE_LINE_INFO
 #endif /* JERRY_ENABLE_LINE_INFO */
+#ifdef JERRY_ENABLE_LOGGING
+          || feature == JERRY_FEATURE_LOGGING
+#endif /* JERRY_ENABLE_LOGGING */
           );
 } /* jerry_is_feature_enabled */
 
 /**
- * Check if the specified value is an error or abort value.
+ * Create abort from an api value.
  *
- * @return true  - if the error flag of the specified value is true,
- *         false - otherwise
- */
-bool
-jerry_value_has_error_flag (const jerry_value_t value) /**< api value */
-{
-  jerry_assert_api_available ();
-
-  return ecma_is_value_error_reference (value);
-} /* jerry_value_has_error_flag */
-
-/**
- * Check if the specified value is an abort value.
+ * Create abort value from an api value. If the second argument is true
+ * it will release the input api value.
  *
- * @return true  - if both the error and abort flags of the specified value are true,
- *         false - otherwise
+ * @return api abort value
  */
-bool
-jerry_value_has_abort_flag (const jerry_value_t value) /**< api value */
-{
-  jerry_assert_api_available ();
-
-  if (!ecma_is_value_error_reference (value))
-  {
-    return false;
-  }
-
-  ecma_error_reference_t *error_ref_p = ecma_get_error_reference_from_value (value);
-
-  return (error_ref_p->refs_and_flags & ECMA_ERROR_REF_ABORT) != 0;
-} /* jerry_value_has_abort_flag */
-
-/**
- * Clear the error flag
- */
-void
-jerry_value_clear_error_flag (jerry_value_t *value_p)
-{
-  jerry_assert_api_available ();
-
-  if (ecma_is_value_error_reference (*value_p))
-  {
-    *value_p = ecma_clear_error_reference (*value_p, false);
-  }
-} /* jerry_value_clear_error_flag */
-
-/**
- * Set the error flag if the value is not an error reference.
- */
-void
-jerry_value_set_error_flag (jerry_value_t *value_p)
+jerry_value_t
+jerry_create_abort_from_value (jerry_value_t value, /**< api value */
+                               bool release) /**< release api value */
 {
   jerry_assert_api_available ();
 
-  if (unlikely (ecma_is_value_error_reference (*value_p)))
+  if (JERRY_UNLIKELY (ecma_is_value_error_reference (value)))
   {
     /* This is a rare case so it is optimized for
      * binary size rather than performance. */
-    if (!jerry_value_has_abort_flag (*value_p))
+    if (jerry_value_is_abort (value))
     {
-      return;
+      return release ? value : jerry_acquire_value (value);
     }
 
-    jerry_value_clear_error_flag (value_p);
+    value = jerry_get_value_from_error (value, release);
+    release = true;
+  }
+
+  if (!release)
+  {
+    value = ecma_copy_value (value);
   }
 
-  *value_p = ecma_create_error_reference (*value_p, true);
-} /* jerry_value_set_error_flag */
+  return ecma_create_error_reference (value, false);
+} /* jerry_create_abort_from_value */
 
 /**
- * Set both the abort and error flags if the value is not an error reference.
+ * Create error from an api value.
+ *
+ * Create error value from an api value. If the second argument is true
+ * it will release the input api value.
+ *
+ * @return api error value
  */
-void
-jerry_value_set_abort_flag (jerry_value_t *value_p)
+jerry_value_t
+jerry_create_error_from_value (jerry_value_t value, /**< api value */
+                               bool release) /**< release api value */
 {
   jerry_assert_api_available ();
 
-  if (unlikely (ecma_is_value_error_reference (*value_p)))
+  if (JERRY_UNLIKELY (ecma_is_value_error_reference (value)))
   {
     /* This is a rare case so it is optimized for
      * binary size rather than performance. */
-    if (jerry_value_has_abort_flag (*value_p))
+    if (!jerry_value_is_abort (value))
     {
-      return;
+      return release ? value : jerry_acquire_value (value);
     }
 
-    jerry_value_clear_error_flag (value_p);
+    value = jerry_get_value_from_error (value, release);
+    release = true;
+  }
+
+  if (!release)
+  {
+    value = ecma_copy_value (value);
   }
 
-  *value_p = ecma_create_error_reference (*value_p, false);
-} /* jerry_value_set_abort_flag */
+  return ecma_create_error_reference (value, true);
+} /* jerry_create_error_from_value */
 
 /**
- * If the input value is an error value, then return a new reference to its referenced value.
- * Otherwise, return a new reference to the value itself.
+ * Get the value from an error value.
+ *
+ * Extract the api value from an error. If the second argument is true
+ * it will release the input error value.
  *
  * Note:
  *      returned value must be freed with jerry_release_value, when it is no longer needed.
  *
- * @return the real value of the jerry_value
+ * @return jerry_value_t value
  */
-jerry_value_t jerry_get_value_without_error_flag (jerry_value_t value) /**< api value */
+jerry_value_t
+jerry_get_value_from_error (jerry_value_t value, /**< api value */
+                            bool release) /**< release api value */
 {
-  return jerry_acquire_value (jerry_get_arg_value (value));
-} /* jerry_get_value_without_error_flag */
+  jerry_assert_api_available ();
+
+  if (!ecma_is_value_error_reference (value))
+  {
+    return release ? value : ecma_copy_value (value);
+  }
+
+  jerry_value_t ret_val = jerry_acquire_value (ecma_get_error_reference_from_value (value)->value);
+
+  if (release)
+  {
+    jerry_release_value (value);
+  }
+  return ret_val;
+} /* jerry_get_value_from_error */
 
 /**
  * Return the type of the Error object if possible.
@@ -1006,16 +1009,19 @@ jerry_value_t jerry_get_value_without_error_flag (jerry_value_t value) /**< api
  *         JERRY_ERROR_NONE - if the input value is not an Error object
  */
 jerry_error_t
-jerry_get_error_type (const jerry_value_t value) /**< api value */
+jerry_get_error_type (jerry_value_t value) /**< api value */
 {
-  jerry_value_t object = jerry_get_arg_value (value);
+  if (JERRY_UNLIKELY (ecma_is_value_error_reference (value)))
+  {
+    value = ecma_get_error_reference_from_value (value)->value;
+  }
 
-  if (!ecma_is_value_object (object))
+  if (!ecma_is_value_object (value))
   {
     return JERRY_ERROR_NONE;
   }
 
-  ecma_object_t *object_p = ecma_get_object_from_value (object);
+  ecma_object_t *object_p = ecma_get_object_from_value (value);
   ecma_standard_error_t error_type = ecma_get_error_type (object_p);
 
   return (jerry_error_t) error_type;
@@ -1031,14 +1037,7 @@ jerry_get_boolean_value (const jerry_value_t value) /**< api value */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t boolean = jerry_get_arg_value (value);
-
-  if (!ecma_is_value_boolean (boolean))
-  {
-    return false;
-  }
-
-  return ecma_is_value_true (boolean);
+  return ecma_is_value_true (value);
 } /* jerry_get_boolean_value */
 
 /**
@@ -1051,14 +1050,12 @@ jerry_get_number_value (const jerry_value_t value) /**< api value */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t number = jerry_get_arg_value (value);
-
-  if (!ecma_is_value_number (number))
+  if (!ecma_is_value_number (value))
   {
     return 0;
   }
 
-  return (double) ecma_get_number_from_value (number);
+  return (double) ecma_get_number_from_value (value);
 } /* jerry_get_number_value */
 
 /**
@@ -1182,7 +1179,7 @@ jerry_acquire_value (jerry_value_t value) /**< API value */
 {
   jerry_assert_api_available ();
 
-  if (unlikely (ecma_is_value_error_reference (value)))
+  if (JERRY_UNLIKELY (ecma_is_value_error_reference (value)))
   {
     ecma_ref_error_reference (ecma_get_error_reference_from_value (value));
     return value;
@@ -1199,7 +1196,7 @@ jerry_release_value (jerry_value_t value) /**< API value */
 {
   jerry_assert_api_available ();
 
-  if (unlikely (ecma_is_value_error_reference (value)))
+  if (JERRY_UNLIKELY (ecma_is_value_error_reference (value)))
   {
     ecma_deref_error_reference (ecma_get_error_reference_from_value (value));
     return;
@@ -1496,6 +1493,52 @@ jerry_create_string_sz (const jerry_char_t *str_p, /**< pointer to string */
   return ecma_make_string_value (ecma_str_p);
 } /* jerry_create_string_sz */
 
+/**
+ * Calculates the size of the given pattern and creates a RegExp object.
+ *
+ * @return value of the constructed RegExp object.
+ */
+jerry_value_t
+jerry_create_regexp (const jerry_char_t *pattern_p, /**< zero-terminated UTF-8 string as RegExp pattern */
+                     jerry_regexp_flags_t flags) /**< optional RegExp flags */
+{
+  return jerry_create_regexp_sz (pattern_p, lit_zt_utf8_string_size (pattern_p), flags);
+} /* jerry_create_regexp */
+
+/**
+ * Creates a RegExp object with the given pattern and flags.
+ *
+ * @return value of the constructed RegExp object.
+ */
+jerry_value_t
+jerry_create_regexp_sz (const jerry_char_t *pattern_p, /**< zero-terminated UTF-8 string as RegExp pattern */
+                        jerry_size_t pattern_size, /**< length of the pattern */
+                        jerry_regexp_flags_t flags) /**< optional RegExp flags */
+{
+  jerry_assert_api_available ();
+
+#ifndef CONFIG_DISABLE_REGEXP_BUILTIN
+  if (!lit_is_valid_utf8_string (pattern_p, pattern_size))
+  {
+    return jerry_throw (ecma_raise_common_error (ECMA_ERR_MSG ("Input must be a valid utf8 string")));
+  }
+
+  ecma_string_t *ecma_pattern = ecma_new_ecma_string_from_utf8 (pattern_p, pattern_size);
+
+  jerry_value_t ret_val = ecma_op_create_regexp_object (ecma_pattern, flags);
+
+  ecma_deref_ecma_string (ecma_pattern);
+  return ret_val;
+
+#else /* CONFIG_DISABLE_REGEXP_BUILTIN */
+  JERRY_UNUSED (pattern_p);
+  JERRY_UNUSED (pattern_size);
+  JERRY_UNUSED (flags);
+
+  return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("RegExp is not supported.")));
+#endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
+} /* jerry_create_regexp_sz */
+
 /**
  * Get length of an array object
  *
@@ -1505,18 +1548,16 @@ jerry_create_string_sz (const jerry_char_t *str_p, /**< pointer to string */
  * @return length of the given array
  */
 uint32_t
-jerry_get_array_length (const jerry_value_t value)
+jerry_get_array_length (const jerry_value_t value) /**< api value */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t array = jerry_get_arg_value (value);
-
-  if (!jerry_value_is_array (array))
+  if (!jerry_value_is_array (value))
   {
     return 0;
   }
 
-  ecma_value_t len_value = ecma_op_object_get_by_magic_id (ecma_get_object_from_value (array),
+  ecma_value_t len_value = ecma_op_object_get_by_magic_id (ecma_get_object_from_value (value),
                                                            LIT_MAGIC_STRING_LENGTH);
 
   jerry_length_t length = ecma_number_to_uint32 (ecma_get_number_from_value (len_value));
@@ -1538,14 +1579,12 @@ jerry_get_string_size (const jerry_value_t value) /**< input string */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t string = jerry_get_arg_value (value);
-
-  if (!ecma_is_value_string (string))
+  if (!ecma_is_value_string (value))
   {
     return 0;
   }
 
-  return ecma_string_get_size (ecma_get_string_from_value (string));
+  return ecma_string_get_size (ecma_get_string_from_value (value));
 } /* jerry_get_string_size */
 
 /**
@@ -1557,18 +1596,16 @@ jerry_get_string_size (const jerry_value_t value) /**< input string */
  * @return number of bytes in the buffer needed to represent the UTF-8 encoded string
  */
 jerry_size_t
-jerry_get_utf8_string_size (const jerry_value_t value)
+jerry_get_utf8_string_size (const jerry_value_t value) /**< input string */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t string = jerry_get_arg_value (value);
-
-  if (!ecma_is_value_string (string))
+  if (!ecma_is_value_string (value))
   {
     return 0;
   }
 
-  return ecma_string_get_utf8_size (ecma_get_string_from_value (string));
+  return ecma_string_get_utf8_size (ecma_get_string_from_value (value));
 } /* jerry_get_utf8_string_size */
 
 /**
@@ -1584,14 +1621,12 @@ jerry_get_string_length (const jerry_value_t value) /**< input string */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t string = jerry_get_arg_value (value);
-
-  if (!ecma_is_value_string (string))
+  if (!ecma_is_value_string (value))
   {
     return 0;
   }
 
-  return ecma_string_get_length (ecma_get_string_from_value (string));
+  return ecma_string_get_length (ecma_get_string_from_value (value));
 } /* jerry_get_string_length */
 
 /**
@@ -1607,14 +1642,12 @@ jerry_get_utf8_string_length (const jerry_value_t value) /**< input string */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t string = jerry_get_arg_value (value);
-
-  if (!ecma_is_value_string (string))
+  if (!ecma_is_value_string (value))
   {
     return 0;
   }
 
-  return ecma_string_get_utf8_length (ecma_get_string_from_value (string));
+  return ecma_string_get_utf8_length (ecma_get_string_from_value (value));
 } /* jerry_get_utf8_string_length */
 
 /**
@@ -1639,14 +1672,12 @@ jerry_string_to_char_buffer (const jerry_value_t value, /**< input string value
 {
   jerry_assert_api_available ();
 
-  jerry_value_t string = jerry_get_arg_value (value);
-
-  if (!ecma_is_value_string (string) || buffer_p == NULL)
+  if (!ecma_is_value_string (value) || buffer_p == NULL)
   {
     return 0;
   }
 
-  ecma_string_t *str_p = ecma_get_string_from_value (string);
+  ecma_string_t *str_p = ecma_get_string_from_value (value);
 
   if (ecma_string_get_size (str_p) > buffer_size)
   {
@@ -1680,14 +1711,12 @@ jerry_string_to_utf8_char_buffer (const jerry_value_t value, /**< input string v
 {
   jerry_assert_api_available ();
 
-  jerry_value_t string = jerry_get_arg_value (value);
-
-  if (!ecma_is_value_string (string) || buffer_p == NULL)
+  if (!ecma_is_value_string (value) || buffer_p == NULL)
   {
     return 0;
   }
 
-  ecma_string_t *str_p = ecma_get_string_from_value (string);
+  ecma_string_t *str_p = ecma_get_string_from_value (value);
 
   if (ecma_string_get_utf8_size (str_p) > buffer_size)
   {
@@ -1719,14 +1748,12 @@ jerry_substring_to_char_buffer (const jerry_value_t value, /**< input string val
 {
   jerry_assert_api_available ();
 
-  jerry_value_t string = jerry_get_arg_value (value);
-
-  if (!ecma_is_value_string (string) || buffer_p == NULL)
+  if (!ecma_is_value_string (value) || buffer_p == NULL)
   {
     return 0;
   }
 
-  ecma_string_t *str_p = ecma_get_string_from_value (string);
+  ecma_string_t *str_p = ecma_get_string_from_value (value);
 
   return ecma_substring_copy_to_cesu8_buffer (str_p,
                                               start_pos,
@@ -1755,14 +1782,12 @@ jerry_substring_to_utf8_char_buffer (const jerry_value_t value, /**< input strin
 {
   jerry_assert_api_available ();
 
-  jerry_value_t string = jerry_get_arg_value (value);
-
-  if (!ecma_is_value_string (string) || buffer_p == NULL)
+  if (!ecma_is_value_string (value) || buffer_p == NULL)
   {
     return 0;
   }
 
-  ecma_string_t *str_p = ecma_get_string_from_value (string);
+  ecma_string_t *str_p = ecma_get_string_from_value (value);
 
   return ecma_substring_copy_to_utf8_buffer (str_p,
                                              start_pos,
@@ -1783,17 +1808,14 @@ jerry_has_property (const jerry_value_t obj_val, /**< object value */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-  jerry_value_t prop_name_value = jerry_get_arg_value (prop_name_val);
-
-  if (!ecma_is_value_object (obj_value)
-      || !ecma_is_value_string (prop_name_value))
+  if (!ecma_is_value_object (obj_val)
+      || !ecma_is_value_string (prop_name_val))
   {
-    return ecma_make_boolean_value (false);
+    return ECMA_VALUE_FALSE;
   }
 
-  bool has_property = ecma_op_object_has_property (ecma_get_object_from_value (obj_value),
-                                                   ecma_get_string_from_value (prop_name_value));
+  bool has_property = ecma_op_object_has_property (ecma_get_object_from_value (obj_val),
+                                                   ecma_get_string_from_value (prop_name_val));
 
   return ecma_make_boolean_value (has_property);
 } /* jerry_has_property */
@@ -1810,17 +1832,14 @@ jerry_has_own_property (const jerry_value_t obj_val, /**< object value */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-  jerry_value_t prop_name_value = jerry_get_arg_value (prop_name_val);
-
-  if (!ecma_is_value_object (obj_value)
-      || !ecma_is_value_string (prop_name_value))
+  if (!ecma_is_value_object (obj_val)
+      || !ecma_is_value_string (prop_name_val))
   {
-    return ecma_make_boolean_value (false);
+    return ECMA_VALUE_FALSE;
   }
 
-  bool has_property = ecma_op_object_has_own_property (ecma_get_object_from_value (obj_value),
-                                                       ecma_get_string_from_value (prop_name_value));
+  bool has_property = ecma_op_object_has_own_property (ecma_get_object_from_value (obj_val),
+                                                       ecma_get_string_from_value (prop_name_val));
 
   return ecma_make_boolean_value (has_property);
 } /* jerry_has_own_property */
@@ -1837,17 +1856,14 @@ jerry_delete_property (const jerry_value_t obj_val, /**< object value */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-  jerry_value_t prop_name_value = jerry_get_arg_value (prop_name_val);
-
-  if (!ecma_is_value_object (obj_value)
-      || !ecma_is_value_string (prop_name_value))
+  if (!ecma_is_value_object (obj_val)
+      || !ecma_is_value_string (prop_name_val))
   {
     return false;
   }
 
-  ecma_value_t ret_value = ecma_op_object_delete (ecma_get_object_from_value (obj_value),
-                                                  ecma_get_string_from_value (prop_name_value),
+  ecma_value_t ret_value = ecma_op_object_delete (ecma_get_object_from_value (obj_val),
+                                                  ecma_get_string_from_value (prop_name_val),
                                                   false);
   return ecma_is_value_true (ret_value);
 } /* jerry_delete_property */
@@ -1864,15 +1880,13 @@ jerry_delete_property_by_index (const jerry_value_t obj_val, /**< object value *
 {
   jerry_assert_api_available ();
 
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-
-  if (!ecma_is_value_object (obj_value))
+  if (!ecma_is_value_object (obj_val))
   {
     return false;
   }
 
   ecma_string_t *str_idx_p = ecma_new_ecma_string_from_uint32 (index);
-  ecma_value_t ret_value = ecma_op_object_delete (ecma_get_object_from_value (obj_value),
+  ecma_value_t ret_value = ecma_op_object_delete (ecma_get_object_from_value (obj_val),
                                                   str_idx_p,
                                                   false);
   ecma_deref_ecma_string (str_idx_p);
@@ -1895,17 +1909,14 @@ jerry_get_property (const jerry_value_t obj_val, /**< object value */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-  jerry_value_t prop_name_value = jerry_get_arg_value (prop_name_val);
-
-  if (!ecma_is_value_object (obj_value)
-      || !ecma_is_value_string (prop_name_value))
+  if (!ecma_is_value_object (obj_val)
+      || !ecma_is_value_string (prop_name_val))
   {
     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
   }
 
-  jerry_value_t ret_value = ecma_op_object_get (ecma_get_object_from_value (obj_value),
-                                                ecma_get_string_from_value (prop_name_value));
+  jerry_value_t ret_value = ecma_op_object_get (ecma_get_object_from_value (obj_val),
+                                                ecma_get_string_from_value (prop_name_val));
   return jerry_return (ret_value);
 } /* jerry_get_property */
 
@@ -1924,15 +1935,13 @@ jerry_get_property_by_index (const jerry_value_t obj_val, /**< object value */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-
-  if (!ecma_is_value_object (obj_value))
+  if (!ecma_is_value_object (obj_val))
   {
     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
   }
 
   ecma_string_t *str_idx_p = ecma_new_ecma_string_from_uint32 (index);
-  ecma_value_t ret_value = ecma_op_object_get (ecma_get_object_from_value (obj_value), str_idx_p);
+  ecma_value_t ret_value = ecma_op_object_get (ecma_get_object_from_value (obj_val), str_idx_p);
   ecma_deref_ecma_string (str_idx_p);
 
   return jerry_return (ret_value);
@@ -1954,18 +1963,15 @@ jerry_set_property (const jerry_value_t obj_val, /**< object value */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-  jerry_value_t prop_name_value = jerry_get_arg_value (prop_name_val);
-
   if (ecma_is_value_error_reference (value_to_set)
-      || !ecma_is_value_object (obj_value)
-      || !ecma_is_value_string (prop_name_value))
+      || !ecma_is_value_object (obj_val)
+      || !ecma_is_value_string (prop_name_val))
   {
     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
   }
 
-  return jerry_return (ecma_op_object_put (ecma_get_object_from_value (obj_value),
-                                           ecma_get_string_from_value (prop_name_value),
+  return jerry_return (ecma_op_object_put (ecma_get_object_from_value (obj_val),
+                                           ecma_get_string_from_value (prop_name_val),
                                            value_to_set,
                                            true));
 } /* jerry_set_property */
@@ -1986,16 +1992,14 @@ jerry_set_property_by_index (const jerry_value_t obj_val, /**< object value */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-
   if (ecma_is_value_error_reference (value_to_set)
-      || !ecma_is_value_object (obj_value))
+      || !ecma_is_value_object (obj_val))
   {
     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
   }
 
   ecma_string_t *str_idx_p = ecma_new_ecma_string_from_uint32 ((uint32_t) index);
-  ecma_value_t ret_value = ecma_op_object_put (ecma_get_object_from_value (obj_value),
+  ecma_value_t ret_value = ecma_op_object_put (ecma_get_object_from_value (obj_val),
                                                str_idx_p,
                                                value_to_set,
                                                true);
@@ -2040,11 +2044,8 @@ jerry_define_own_property (const jerry_value_t obj_val, /**< object value */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-  jerry_value_t prop_name_value = jerry_get_arg_value (prop_name_val);
-
-  if (!ecma_is_value_object (obj_value)
-      || !ecma_is_value_string (prop_name_value))
+  if (!ecma_is_value_object (obj_val)
+      || !ecma_is_value_string (prop_name_val))
   {
     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
   }
@@ -2123,8 +2124,8 @@ jerry_define_own_property (const jerry_value_t obj_val, /**< object value */
     }
   }
 
-  return ecma_op_object_define_own_property (ecma_get_object_from_value (obj_value),
-                                             ecma_get_string_from_value (prop_name_value),
+  return ecma_op_object_define_own_property (ecma_get_object_from_value (obj_val),
+                                             ecma_get_string_from_value (prop_name_val),
                                              &prop_desc,
                                              true);
 } /* jerry_define_own_property */
@@ -2142,19 +2143,16 @@ jerry_get_own_property_descriptor (const jerry_value_t  obj_val, /**< object val
 {
   jerry_assert_api_available ();
 
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-  jerry_value_t prop_name_value = jerry_get_arg_value (prop_name_val);
-
-  if (!ecma_is_value_object (obj_value)
-      || !ecma_is_value_string (prop_name_value))
+  if (!ecma_is_value_object (obj_val)
+      || !ecma_is_value_string (prop_name_val))
   {
     return false;
   }
 
   ecma_property_descriptor_t prop_desc;
 
-  if (!ecma_op_object_get_own_property_descriptor (ecma_get_object_from_value (obj_value),
-                                                   ecma_get_string_from_value (prop_name_value),
+  if (!ecma_op_object_get_own_property_descriptor (ecma_get_object_from_value (obj_val),
+                                                   ecma_get_string_from_value (prop_name_val),
                                                    &prop_desc))
   {
     return false;
@@ -2270,6 +2268,7 @@ jerry_invoke_function (bool is_invoke_as_constructor, /**< true - invoke functio
     JERRY_ASSERT (jerry_value_is_constructor (func_obj_val));
 
     return jerry_return (ecma_op_function_construct (ecma_get_object_from_value (func_obj_val),
+                                                     ECMA_VALUE_UNDEFINED,
                                                      args_p,
                                                      args_count));
   }
@@ -2349,14 +2348,12 @@ jerry_get_object_keys (const jerry_value_t obj_val) /**< object value */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-
-  if (!ecma_is_value_object (obj_value))
+  if (!ecma_is_value_object (obj_val))
   {
     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
   }
 
-  return ecma_builtin_helper_object_get_properties (ecma_get_object_from_value (obj_value), true);
+  return ecma_builtin_helper_object_get_properties (ecma_get_object_from_value (obj_val), true);
 } /* jerry_get_object_keys */
 
 /**
@@ -2370,14 +2367,12 @@ jerry_get_prototype (const jerry_value_t obj_val) /**< object value */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-
-  if (!ecma_is_value_object (obj_value))
+  if (!ecma_is_value_object (obj_val))
   {
     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
   }
 
-  ecma_object_t *proto_obj_p = ecma_get_object_prototype (ecma_get_object_from_value (obj_value));
+  ecma_object_t *proto_obj_p = ecma_get_object_prototype (ecma_get_object_from_value (obj_val));
 
   if (proto_obj_p == NULL)
   {
@@ -2399,9 +2394,7 @@ jerry_set_prototype (const jerry_value_t obj_val, /**< object value */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-
-  if (!ecma_is_value_object (obj_value)
+  if (!ecma_is_value_object (obj_val)
       || ecma_is_value_error_reference (proto_obj_val)
       || (!ecma_is_value_object (proto_obj_val) && !ecma_is_value_null (proto_obj_val)))
   {
@@ -2410,92 +2403,26 @@ jerry_set_prototype (const jerry_value_t obj_val, /**< object value */
 
   if (ecma_is_value_null (proto_obj_val))
   {
-    ECMA_SET_POINTER (ecma_get_object_from_value (obj_value)->prototype_or_outer_reference_cp, NULL);
+    ECMA_SET_POINTER (ecma_get_object_from_value (obj_val)->prototype_or_outer_reference_cp, NULL);
   }
   else
   {
-    ECMA_SET_POINTER (ecma_get_object_from_value (obj_value)->prototype_or_outer_reference_cp,
+    ECMA_SET_POINTER (ecma_get_object_from_value (obj_val)->prototype_or_outer_reference_cp,
                       ecma_get_object_from_value (proto_obj_val));
   }
 
   return ECMA_VALUE_TRUE;
 } /* jerry_set_prototype */
 
-/**
- * Get native handle, associated with specified object.
- *
- * Note: This API is deprecated, please use jerry_get_object_native_pointer instaed.
- *
- * @return true - if there is an associated handle (handle is returned through out_handle_p),
- *         false - otherwise
- */
-bool
-jerry_get_object_native_handle (const jerry_value_t obj_val, /**< object to get handle from */
-                                uintptr_t *out_handle_p) /**< [out] handle value */
-{
-  jerry_assert_api_available ();
-
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-
-  if (!ecma_is_value_object (obj_value))
-  {
-    return false;
-  }
-
-  ecma_native_pointer_t *native_pointer_p;
-  native_pointer_p = ecma_get_native_pointer_value (ecma_get_object_from_value (obj_value),
-                                                    LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE);
-
-  if (native_pointer_p == NULL)
-  {
-    return false;
-  }
-
-  *out_handle_p = (uintptr_t) native_pointer_p->data_p;
-  return true;
-} /* jerry_get_object_native_handle */
-
-/**
- * Set native handle and an optional free callback for the specified object.
- *
- * Note: This API is deprecated, please use jerry_set_object_native_pointer instaed.
- *
- * Note:
- *      If native handle was already set for the object, its value is updated.
- *
- * Note:
- *      If a non-NULL free callback is specified, it will be called
- *      by the garbage collector when the object is freed. The free
- *      callback always overwrites the previous value, so passing
- *      a NULL value deletes the current free callback.
- */
-void
-jerry_set_object_native_handle (const jerry_value_t obj_val, /**< object to set handle in */
-                                uintptr_t handle_p, /**< handle value */
-                                jerry_object_free_callback_t freecb_p) /**< object free callback or NULL */
-{
-  jerry_assert_api_available ();
-
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-
-  if (ecma_is_value_object (obj_value))
-  {
-    ecma_object_t *object_p = ecma_get_object_from_value (obj_value);
-
-    ecma_create_native_handle_property (object_p,
-                                        (void *) handle_p,
-                                        (void *) (ecma_external_pointer_t) freecb_p);
-  }
-} /* jerry_set_object_native_handle */
-
 /**
  * Traverse objects.
  *
  * @return true - traversal was interrupted by the callback.
  *         false - otherwise - traversal visited all objects.
  */
-bool jerry_objects_foreach (jerry_objects_foreach_t foreach_p,
-                            void *user_data_p)
+bool
+jerry_objects_foreach (jerry_objects_foreach_t foreach_p, /**< function pointer of the iterator function */
+                       void *user_data_p) /**< pointer to user data */
 {
   jerry_assert_api_available ();
 
@@ -2522,9 +2449,11 @@ bool jerry_objects_foreach (jerry_objects_foreach_t foreach_p,
  *         false - otherwise - traversal visited all objects.
  */
 bool
-jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *native_info_p,
-                                      jerry_objects_foreach_by_native_info_t foreach_p,
-                                      void *user_data_p)
+jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *native_info_p, /**< the type info
+                                                                                        *   of the native pointer */
+                                      jerry_objects_foreach_by_native_info_t foreach_p, /**< function to apply for
+                                                                                         *   each matching object */
+                                      void *user_data_p) /**< pointer to user data */
 {
   jerry_assert_api_available ();
 
@@ -2539,9 +2468,9 @@ jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *native_i
   {
     if (!ecma_is_lexical_environment (iter_p))
     {
-      native_pointer_p = ecma_get_native_pointer_value (iter_p, LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
+      native_pointer_p = ecma_get_native_pointer_value (iter_p);
       if (native_pointer_p
-          && ((const jerry_object_native_info_t *) native_pointer_p->u.info_p) == native_info_p
+          && ((const jerry_object_native_info_t *) native_pointer_p->info_p) == native_info_p
           && !foreach_p (ecma_make_object_value (iter_p), native_pointer_p->data_p, user_data_p))
       {
         return true;
@@ -2570,16 +2499,13 @@ jerry_get_object_native_pointer (const jerry_value_t obj_val, /**< object to get
 {
   jerry_assert_api_available ();
 
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-
-  if (!ecma_is_value_object (obj_value))
+  if (!ecma_is_value_object (obj_val))
   {
     return false;
   }
 
   ecma_native_pointer_t *native_pointer_p;
-  native_pointer_p = ecma_get_native_pointer_value (ecma_get_object_from_value (obj_value),
-                                                    LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
+  native_pointer_p = ecma_get_native_pointer_value (ecma_get_object_from_value (obj_val));
 
   if (native_pointer_p == NULL)
   {
@@ -2593,7 +2519,7 @@ jerry_get_object_native_pointer (const jerry_value_t obj_val, /**< object to get
 
   if (out_native_info_p != NULL)
   {
-    *out_native_info_p = (const jerry_object_native_info_t *) native_pointer_p->u.info_p;
+    *out_native_info_p = (const jerry_object_native_info_t *) native_pointer_p->info_p;
   }
 
   return true;
@@ -2619,11 +2545,9 @@ jerry_set_object_native_pointer (const jerry_value_t obj_val, /**< object to set
 {
   jerry_assert_api_available ();
 
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-
-  if (ecma_is_value_object (obj_value))
+  if (ecma_is_value_object (obj_val))
   {
-    ecma_object_t *object_p = ecma_get_object_from_value (obj_value);
+    ecma_object_t *object_p = ecma_get_object_from_value (obj_val);
 
     ecma_create_native_pointer_property (object_p, native_pointer_p, (void *) native_info_p);
   }
@@ -2645,15 +2569,13 @@ jerry_foreach_object_property (const jerry_value_t obj_val, /**< object value */
 {
   jerry_assert_api_available ();
 
-  jerry_value_t obj_value = jerry_get_arg_value (obj_val);
-
-  if (!ecma_is_value_object (obj_value))
+  if (!ecma_is_value_object (obj_val))
   {
     return false;
   }
 
-  ecma_object_t *object_p = ecma_get_object_from_value (obj_value);
-  ecma_collection_header_t *names_p = ecma_op_object_get_property_names (object_p, false, true, true);
+  ecma_object_t *object_p = ecma_get_object_from_value (obj_val);
+  ecma_collection_header_t *names_p = ecma_op_object_get_property_names (object_p, ECMA_LIST_ENUMERABLE_PROTOTYPE);
   ecma_value_t *ecma_value_p = ecma_collection_iterator_init (names_p);
 
   ecma_value_t property_value = ECMA_VALUE_EMPTY;
@@ -2757,21 +2679,52 @@ jerry_is_valid_cesu8_string (const jerry_char_t *cesu8_buf_p, /**< CESU-8 string
                                     (lit_utf8_size_t) buf_size);
 } /* jerry_is_valid_cesu8_string */
 
-/*
- * Create a jerry instance for external context.
+/**
+ * Allocate memory on the engine's heap.
  *
- * @return the pointer to the instance.
+ * Note:
+ *      This function may take away memory from the executed JavaScript code.
+ *      If any other dynamic memory allocation API is available (e.g., libc
+ *      malloc), it should be used instead.
+ *
+ * @return allocated memory on success
+ *         NULL otherwise
+ */
+void *
+jerry_heap_alloc (size_t size) /**< size of the memory block */
+{
+  jerry_assert_api_available ();
+
+  return jmem_heap_alloc_block_null_on_error (size);
+} /* jerry_heap_alloc */
+
+/**
+ * Free memory allocated on the engine's heap.
  */
-jerry_instance_t *
-jerry_create_instance (uint32_t heap_size, /**< the size of heap */
-                       jerry_instance_alloc_t alloc, /**< the alloc function */
-                       void *cb_data_p) /**< the cb_data for alloc function */
+void
+jerry_heap_free (void *mem_p, /**< value returned by jerry_heap_alloc */
+                 size_t size) /**< same size as passed to jerry_heap_alloc */
+{
+  jerry_assert_api_available ();
+
+  jmem_heap_free_block (mem_p, size);
+} /* jerry_heap_free */
+
+/**
+ * Create an external engine context.
+ *
+ * @return the pointer to the context.
+ */
+jerry_context_t *
+jerry_create_context (uint32_t heap_size, /**< the size of heap */
+                      jerry_context_alloc_t alloc, /**< the alloc function */
+                      void *cb_data_p) /**< the cb_data for alloc function */
 {
   JERRY_UNUSED (heap_size);
 
 #ifdef JERRY_ENABLE_EXTERNAL_CONTEXT
 
-  size_t total_size = sizeof (jerry_instance_t) + JMEM_ALIGNMENT;
+  size_t total_size = sizeof (jerry_context_t) + JMEM_ALIGNMENT;
 
 #ifndef JERRY_SYSTEM_ALLOCATOR
   heap_size = JERRY_ALIGNUP (heap_size, JMEM_ALIGNMENT);
@@ -2785,41 +2738,32 @@ jerry_create_instance (uint32_t heap_size, /**< the size of heap */
   total_size += heap_size;
 #endif /* !JERRY_SYSTEM_ALLOCATOR */
 
-#ifndef CONFIG_ECMA_LCACHE_DISABLE
-  total_size += sizeof (jerry_hash_table_t);
-#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
-
   total_size = JERRY_ALIGNUP (total_size, JMEM_ALIGNMENT);
 
-  jerry_instance_t *instance_p = (jerry_instance_t *) alloc (total_size, cb_data_p);
+  jerry_context_t *context_p = (jerry_context_t *) alloc (total_size, cb_data_p);
 
-  if (instance_p == NULL)
+  if (context_p == NULL)
   {
     return NULL;
   }
 
-  memset (instance_p, 0, total_size);
+  memset (context_p, 0, total_size);
 
-  uintptr_t instance_ptr = ((uintptr_t) instance_p) + sizeof (jerry_instance_t);
-  instance_ptr = JERRY_ALIGNUP (instance_ptr, (uintptr_t) JMEM_ALIGNMENT);
+  uintptr_t context_ptr = ((uintptr_t) context_p) + sizeof (jerry_context_t);
+  context_ptr = JERRY_ALIGNUP (context_ptr, (uintptr_t) JMEM_ALIGNMENT);
 
-  uint8_t *byte_p = (uint8_t *) instance_ptr;
+  uint8_t *byte_p = (uint8_t *) context_ptr;
 
 #ifndef JERRY_SYSTEM_ALLOCATOR
-  instance_p->heap_p = (jmem_heap_t *) byte_p;
-  instance_p->heap_size = heap_size;
+  context_p->heap_p = (jmem_heap_t *) byte_p;
+  context_p->heap_size = heap_size;
   byte_p += heap_size;
 #endif /* !JERRY_SYSTEM_ALLOCATOR */
 
-#ifndef CONFIG_ECMA_LCACHE_DISABLE
-  instance_p->lcache_p = byte_p;
-  byte_p += sizeof (jerry_hash_table_t);
-#endif /* !JERRY_SYSTEM_ALLOCATOR */
-
-  JERRY_ASSERT (byte_p <= ((uint8_t *) instance_p) + total_size);
+  JERRY_ASSERT (byte_p <= ((uint8_t *) context_p) + total_size);
 
   JERRY_UNUSED (byte_p);
-  return instance_p;
+  return context_p;
 
 #else /* !JERRY_ENABLE_EXTERNAL_CONTEXT */
 
@@ -2829,7 +2773,7 @@ jerry_create_instance (uint32_t heap_size, /**< the size of heap */
   return NULL;
 
 #endif /* JERRY_ENABLE_EXTERNAL_CONTEXT */
-} /* jerry_create_instance */
+} /* jerry_create_context */
 
 /**
  * If JERRY_VM_EXEC_STOP is defined the callback passed to this function is
@@ -2866,7 +2810,7 @@ jerry_set_vm_exec_stop_callback (jerry_vm_exec_stop_callback_t stop_cb, /**< per
  * @return array value
  */
 jerry_value_t
-jerry_get_backtrace (uint32_t max_depth)
+jerry_get_backtrace (uint32_t max_depth) /**< depth limit of the backtrace */
 {
   return vm_get_backtrace (max_depth);
 } /* jerry_get_backtrace */
@@ -2883,8 +2827,7 @@ jerry_value_is_arraybuffer (const jerry_value_t value) /**< value to check if it
   jerry_assert_api_available ();
 
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
-  jerry_value_t buffer = jerry_get_arg_value (value);
-  return ecma_is_arraybuffer (buffer);
+  return ecma_is_arraybuffer (value);
 #else /* CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
   JERRY_UNUSED (value);
   return false;
@@ -2967,14 +2910,12 @@ jerry_arraybuffer_write (const jerry_value_t value, /**< target ArrayBuffer */
   jerry_assert_api_available ();
 
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
-  jerry_value_t buffer = jerry_get_arg_value (value);
-
-  if (!ecma_is_arraybuffer (buffer))
+  if (!ecma_is_arraybuffer (value))
   {
     return 0;
   }
 
-  ecma_object_t *buffer_p = ecma_get_object_from_value (buffer);
+  ecma_object_t *buffer_p = ecma_get_object_from_value (value);
   jerry_length_t length = ecma_arraybuffer_get_length (buffer_p);
 
   if (offset >= length)
@@ -3018,14 +2959,12 @@ jerry_arraybuffer_read (const jerry_value_t value, /**< ArrayBuffer to read from
   jerry_assert_api_available ();
 
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
-  jerry_value_t buffer = jerry_get_arg_value (value);
-
-  if (!ecma_is_arraybuffer (buffer))
+  if (!ecma_is_arraybuffer (value))
   {
     return 0;
   }
 
-  ecma_object_t *buffer_p = ecma_get_object_from_value (buffer);
+  ecma_object_t *buffer_p = ecma_get_object_from_value (value);
   jerry_length_t length = ecma_arraybuffer_get_length (buffer_p);
 
   if (offset >= length)
@@ -3066,10 +3005,9 @@ jerry_get_arraybuffer_byte_length (const jerry_value_t value) /**< ArrayBuffer *
   jerry_assert_api_available ();
 
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
-  jerry_value_t buffer = jerry_get_arg_value (value);
-  if (ecma_is_arraybuffer (buffer))
+  if (ecma_is_arraybuffer (value))
   {
-    ecma_object_t *buffer_p = ecma_get_object_from_value (buffer);
+    ecma_object_t *buffer_p = ecma_get_object_from_value (value);
     return ecma_arraybuffer_get_length (buffer_p);
   }
 #else /* CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
@@ -3096,14 +3034,12 @@ jerry_get_arraybuffer_pointer (const jerry_value_t value) /**< Array Buffer to u
 {
   jerry_assert_api_available ();
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
-  jerry_value_t buffer = jerry_get_arg_value (value);
-
-  if (!ecma_is_arraybuffer (buffer))
+  if (!ecma_is_arraybuffer (value))
   {
     return NULL;
   }
 
-  ecma_object_t *buffer_p = ecma_get_object_from_value (buffer);
+  ecma_object_t *buffer_p = ecma_get_object_from_value (value);
   if (ECMA_ARRAYBUFFER_HAS_EXTERNAL_MEMORY (buffer_p))
   {
     jerry_acquire_value (value);
@@ -3134,8 +3070,7 @@ jerry_value_is_typedarray (jerry_value_t value) /**< value to check if it is a T
   jerry_assert_api_available ();
 
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
-  jerry_value_t array = jerry_get_arg_value (value);
-  return ecma_is_typedarray (array);
+  return ecma_is_typedarray (value);
 #else /* CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
   JERRY_UNUSED (value);
   return false;
@@ -3143,14 +3078,20 @@ jerry_value_is_typedarray (jerry_value_t value) /**< value to check if it is a T
 } /* jerry_value_is_typedarray */
 
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
+/**
+ * TypedArray mapping type
+ */
 typedef struct
 {
-  jerry_typedarray_type_t api_type;
-  ecma_builtin_id_t prototype_id;
-  lit_magic_string_id_t lit_id;
-  uint8_t element_size_shift;
+  jerry_typedarray_type_t api_type; /**< api type */
+  ecma_builtin_id_t prototype_id; /**< prototype ID */
+  lit_magic_string_id_t lit_id; /**< literal ID */
+  uint8_t element_size_shift; /**< element size shift */
 } jerry_typedarray_mapping_t;
 
+/**
+ * List of TypedArray mappings
+ */
 static jerry_typedarray_mapping_t jerry_typedarray_mappings[] =
 {
 #define TYPEDARRAY_ENTRY(NAME, LIT_NAME, SIZE_SHIFT) \
@@ -3237,7 +3178,6 @@ jerry_create_typedarray (jerry_typedarray_type_t type_name, /**< type of TypedAr
                                                                         prototype_obj_p,
                                                                         element_size_shift,
                                                                         lit_id);
-  ecma_deref_object (prototype_obj_p);
 
   JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (array_value));
 
@@ -3276,8 +3216,7 @@ jerry_create_typedarray_for_arraybuffer_sz (jerry_typedarray_type_t type_name, /
     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("incorrect type for TypedArray.")));
   }
 
-  jerry_value_t buffer = jerry_get_arg_value (arraybuffer);
-  if (!ecma_is_arraybuffer (buffer))
+  if (!ecma_is_arraybuffer (arraybuffer))
   {
     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an ArrayBuffer")));
   }
@@ -3293,7 +3232,6 @@ jerry_create_typedarray_for_arraybuffer_sz (jerry_typedarray_type_t type_name, /
   ecma_value_t array_value = ecma_op_create_typedarray (arguments_p, 3, prototype_obj_p, element_size_shift, lit_id);
   ecma_free_value (arguments_p[1]);
   ecma_free_value (arguments_p[2]);
-  ecma_deref_object (prototype_obj_p);
 
   return jerry_return (array_value);
 #else /* CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
@@ -3335,13 +3273,12 @@ jerry_get_typedarray_type (jerry_value_t value) /**< object to get the TypedArra
   jerry_assert_api_available ();
 
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
-  jerry_value_t array = jerry_get_arg_value (value);
-  if (!ecma_is_typedarray (array))
+  if (!ecma_is_typedarray (value))
   {
     return JERRY_TYPEDARRAY_INVALID;
   }
 
-  ecma_object_t *array_p = ecma_get_object_from_value (array);
+  ecma_object_t *array_p = ecma_get_object_from_value (value);
 
   lit_magic_string_id_t class_name_id = ecma_object_get_class_name (array_p);
   for (uint32_t i = 0; i < sizeof (jerry_typedarray_mappings) / sizeof (jerry_typedarray_mappings[0]); i++)
@@ -3369,10 +3306,9 @@ jerry_get_typedarray_length (jerry_value_t value) /**< TypedArray to query */
   jerry_assert_api_available ();
 
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
-  jerry_value_t array = jerry_get_arg_value (value);
-  if (ecma_is_typedarray (array))
+  if (ecma_is_typedarray (value))
   {
-    ecma_object_t *array_p = ecma_get_object_from_value (array);
+    ecma_object_t *array_p = ecma_get_object_from_value (value);
     return ecma_typedarray_get_length (array_p);
   }
 #else /* CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
@@ -3402,13 +3338,12 @@ jerry_get_typedarray_buffer (jerry_value_t value, /**< TypedArray to get the arr
   jerry_assert_api_available ();
 
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
-  jerry_value_t array = jerry_get_arg_value (value);
-  if (!ecma_is_typedarray (array))
+  if (!ecma_is_typedarray (value))
   {
     return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG ("Object is not a TypedArray.")));
   }
 
-  ecma_object_t *array_p = ecma_get_object_from_value (array);
+  ecma_object_t *array_p = ecma_get_object_from_value (value);
   uint8_t shift = ecma_typedarray_get_element_size_shift (array_p);
 
   if (byte_length != NULL)
@@ -3470,7 +3405,7 @@ jerry_json_parse (const jerry_char_t *string_p, /**< json string */
  * @return json formated jerry_value_t or an error massage
  */
 jerry_value_t
-jerry_json_stringfy (const jerry_value_t object_to_stringify) /**< a jerry_object_t to stringify */
+jerry_json_stringify (const jerry_value_t object_to_stringify) /**< a jerry_object_t to stringify */
 {
   jerry_assert_api_available ();
 #ifndef CONFIG_DISABLE_JSON_BUILTIN
@@ -3487,7 +3422,7 @@ jerry_json_stringfy (const jerry_value_t object_to_stringify) /**< a jerry_objec
 
   return jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("The JSON has been disabled.")));
 #endif /* !CONFIG_DISABLE_JSON_BUILTIN */
-} /* jerry_json_stringfy */
+} /* jerry_json_stringify */
 
 /**
  * @}
index 69feb92d7f6cc07c4d2a50ea5ff4da1c90783970..f74a31eccdfd6f8a212cde061f1390635dc66ac7 100644 (file)
 #ifdef CONFIG_DISABLE_ES2015
 # define CONFIG_DISABLE_ES2015_ARROW_FUNCTION
 # define CONFIG_DISABLE_ES2015_BUILTIN
+# define CONFIG_DISABLE_ES2015_CLASS
+# define CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER
+# define CONFIG_DISABLE_ES2015_MAP_BUILTIN
+# define CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
 # define CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
 # define CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS
 # define CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 #endif /* CONFIG_DISABLE_ES2015 */
 
-/**
- * Limit of data (system heap, engine's data except engine's own heap)
- */
-#define CONFIG_MEM_DATA_LIMIT_MINUS_HEAP_SIZE (1024)
-
-/**
- * Limit of stack size
- */
-#define CONFIG_MEM_STACK_LIMIT (4096)
-
 /**
  * Size of heap
  */
  */
 #define CONFIG_ECMA_GC_NEW_OBJECTS_SHARE_TO_START_GC (16)
 
-/**
- * Link Global Environment to an empty declarative lexical environment
- * instead of lexical environment bound to Global Object.
- */
-// #define CONFIG_ECMA_GLOBAL_ENVIRONMENT_DECLARATIVE
-
-/**
- * Number of ecma values inlined into VM stack frame
- */
-#define CONFIG_VM_STACK_FRAME_INLINED_VALUES_NUMBER (16)
-
 #endif /* !CONFIG_H */
diff --git a/deps/jerry/jerry-core/debugger/debugger-sha1.c b/deps/jerry/jerry-core/debugger/debugger-sha1.c
deleted file mode 100644 (file)
index 7078424..0000000
+++ /dev/null
@@ -1,370 +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.
- */
-
-/*
- *  FIPS-180-1 compliant SHA-1 implementation
- *
- *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
- *  SPDX-License-Identifier: Apache-2.0
- *
- *  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.
- *
- *  This file is part of mbed TLS (https://tls.mbed.org)
- */
-
-/*
- *  The SHA-1 standard was published by NIST in 1993.
- *
- *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
- */
-
-#include "debugger.h"
-
-#ifdef JERRY_DEBUGGER
-
-/**
- * SHA-1 context structure.
- */
-typedef struct
-{
-  uint32_t total[2]; /**< number of bytes processed */
-  uint32_t state[5]; /**< intermediate digest state */
-  uint8_t buffer[64]; /**< data block being processed */
-} jerry_sha1_context;
-
-/* 32-bit integer manipulation macros (big endian). */
-
-#define JERRY_SHA1_GET_UINT32_BE(n, b, i) \
-{ \
-  (n) = (((uint32_t) (b)[(i) + 0]) << 24) \
-        | (((uint32_t) (b)[(i) + 1]) << 16) \
-        | (((uint32_t) (b)[(i) + 2]) << 8) \
-        | ((uint32_t) (b)[(i) + 3]); \
-}
-
-#define JERRY_SHA1_PUT_UINT32_BE(n, b, i) \
-{ \
-  (b)[(i) + 0] = (uint8_t) ((n) >> 24); \
-  (b)[(i) + 1] = (uint8_t) ((n) >> 16); \
-  (b)[(i) + 2] = (uint8_t) ((n) >> 8); \
-  (b)[(i) + 3] = (uint8_t) ((n)); \
-}
-
-/**
- * Initialize SHA-1 context.
- */
-static void
-jerry_sha1_init (jerry_sha1_context *sha1_context_p) /**< SHA-1 context */
-{
-  memset (sha1_context_p, 0, sizeof (jerry_sha1_context));
-
-  sha1_context_p->total[0] = 0;
-  sha1_context_p->total[1] = 0;
-
-  sha1_context_p->state[0] = 0x67452301;
-  sha1_context_p->state[1] = 0xEFCDAB89;
-  sha1_context_p->state[2] = 0x98BADCFE;
-  sha1_context_p->state[3] = 0x10325476;
-  sha1_context_p->state[4] = 0xC3D2E1F0;
-} /* jerry_sha1_init */
-
-#define JERRY_SHA1_P(a, b, c, d, e, x) \
-do { \
-  e += JERRY_SHA1_SHIFT (a, 5) + JERRY_SHA1_F (b, c, d) + K + x; \
-  b = JERRY_SHA1_SHIFT (b, 30); \
-} while (0)
-
-/**
- * Update SHA-1 internal buffer status.
- */
-static void
-jerry_sha1_process (jerry_sha1_context *sha1_context_p, /**< SHA-1 context */
-                    const uint8_t data[64]) /**< data buffer */
-{
-  uint32_t temp, W[16], A, B, C, D, E;
-
-  JERRY_SHA1_GET_UINT32_BE (W[0], data, 0);
-  JERRY_SHA1_GET_UINT32_BE (W[1], data, 4);
-  JERRY_SHA1_GET_UINT32_BE (W[2], data, 8);
-  JERRY_SHA1_GET_UINT32_BE (W[3], data, 12);
-  JERRY_SHA1_GET_UINT32_BE (W[4], data, 16);
-  JERRY_SHA1_GET_UINT32_BE (W[5], data, 20);
-  JERRY_SHA1_GET_UINT32_BE (W[6], data, 24);
-  JERRY_SHA1_GET_UINT32_BE (W[7], data, 28);
-  JERRY_SHA1_GET_UINT32_BE (W[8], data, 32);
-  JERRY_SHA1_GET_UINT32_BE (W[9], data, 36);
-  JERRY_SHA1_GET_UINT32_BE (W[10], data, 40);
-  JERRY_SHA1_GET_UINT32_BE (W[11], data, 44);
-  JERRY_SHA1_GET_UINT32_BE (W[12], data, 48);
-  JERRY_SHA1_GET_UINT32_BE (W[13], data, 52);
-  JERRY_SHA1_GET_UINT32_BE (W[14], data, 56);
-  JERRY_SHA1_GET_UINT32_BE (W[15], data, 60);
-
-#define JERRY_SHA1_SHIFT(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
-
-#define JERRY_SHA1_R(t) \
-( \
-  temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ W[(t - 14) & 0x0F] ^ W[t & 0x0F], \
-  W[t & 0x0F] = JERRY_SHA1_SHIFT (temp, 1) \
-)
-
-  A = sha1_context_p->state[0];
-  B = sha1_context_p->state[1];
-  C = sha1_context_p->state[2];
-  D = sha1_context_p->state[3];
-  E = sha1_context_p->state[4];
-
-  uint32_t K = 0x5A827999;
-
-#define JERRY_SHA1_F(x, y, z) (z ^ (x & (y ^ z)))
-
-  JERRY_SHA1_P (A, B, C, D, E, W[0]);
-  JERRY_SHA1_P (E, A, B, C, D, W[1]);
-  JERRY_SHA1_P (D, E, A, B, C, W[2]);
-  JERRY_SHA1_P (C, D, E, A, B, W[3]);
-  JERRY_SHA1_P (B, C, D, E, A, W[4]);
-  JERRY_SHA1_P (A, B, C, D, E, W[5]);
-  JERRY_SHA1_P (E, A, B, C, D, W[6]);
-  JERRY_SHA1_P (D, E, A, B, C, W[7]);
-  JERRY_SHA1_P (C, D, E, A, B, W[8]);
-  JERRY_SHA1_P (B, C, D, E, A, W[9]);
-  JERRY_SHA1_P (A, B, C, D, E, W[10]);
-  JERRY_SHA1_P (E, A, B, C, D, W[11]);
-  JERRY_SHA1_P (D, E, A, B, C, W[12]);
-  JERRY_SHA1_P (C, D, E, A, B, W[13]);
-  JERRY_SHA1_P (B, C, D, E, A, W[14]);
-  JERRY_SHA1_P (A, B, C, D, E, W[15]);
-  JERRY_SHA1_P (E, A, B, C, D, JERRY_SHA1_R (16));
-  JERRY_SHA1_P (D, E, A, B, C, JERRY_SHA1_R (17));
-  JERRY_SHA1_P (C, D, E, A, B, JERRY_SHA1_R (18));
-  JERRY_SHA1_P (B, C, D, E, A, JERRY_SHA1_R (19));
-
-#undef JERRY_SHA1_F
-
-  K = 0x6ED9EBA1;
-
-#define JERRY_SHA1_F(x, y, z) (x ^ y ^ z)
-
-  JERRY_SHA1_P (A, B, C, D, E, JERRY_SHA1_R (20));
-  JERRY_SHA1_P (E, A, B, C, D, JERRY_SHA1_R (21));
-  JERRY_SHA1_P (D, E, A, B, C, JERRY_SHA1_R (22));
-  JERRY_SHA1_P (C, D, E, A, B, JERRY_SHA1_R (23));
-  JERRY_SHA1_P (B, C, D, E, A, JERRY_SHA1_R (24));
-  JERRY_SHA1_P (A, B, C, D, E, JERRY_SHA1_R (25));
-  JERRY_SHA1_P (E, A, B, C, D, JERRY_SHA1_R (26));
-  JERRY_SHA1_P (D, E, A, B, C, JERRY_SHA1_R (27));
-  JERRY_SHA1_P (C, D, E, A, B, JERRY_SHA1_R (28));
-  JERRY_SHA1_P (B, C, D, E, A, JERRY_SHA1_R (29));
-  JERRY_SHA1_P (A, B, C, D, E, JERRY_SHA1_R (30));
-  JERRY_SHA1_P (E, A, B, C, D, JERRY_SHA1_R (31));
-  JERRY_SHA1_P (D, E, A, B, C, JERRY_SHA1_R (32));
-  JERRY_SHA1_P (C, D, E, A, B, JERRY_SHA1_R (33));
-  JERRY_SHA1_P (B, C, D, E, A, JERRY_SHA1_R (34));
-  JERRY_SHA1_P (A, B, C, D, E, JERRY_SHA1_R (35));
-  JERRY_SHA1_P (E, A, B, C, D, JERRY_SHA1_R (36));
-  JERRY_SHA1_P (D, E, A, B, C, JERRY_SHA1_R (37));
-  JERRY_SHA1_P (C, D, E, A, B, JERRY_SHA1_R (38));
-  JERRY_SHA1_P (B, C, D, E, A, JERRY_SHA1_R (39));
-
-#undef JERRY_SHA1_F
-
-  K = 0x8F1BBCDC;
-
-#define JERRY_SHA1_F(x, y, z) ((x & y) | (z & (x | y)))
-
-  JERRY_SHA1_P (A, B, C, D, E, JERRY_SHA1_R (40));
-  JERRY_SHA1_P (E, A, B, C, D, JERRY_SHA1_R (41));
-  JERRY_SHA1_P (D, E, A, B, C, JERRY_SHA1_R (42));
-  JERRY_SHA1_P (C, D, E, A, B, JERRY_SHA1_R (43));
-  JERRY_SHA1_P (B, C, D, E, A, JERRY_SHA1_R (44));
-  JERRY_SHA1_P (A, B, C, D, E, JERRY_SHA1_R (45));
-  JERRY_SHA1_P (E, A, B, C, D, JERRY_SHA1_R (46));
-  JERRY_SHA1_P (D, E, A, B, C, JERRY_SHA1_R (47));
-  JERRY_SHA1_P (C, D, E, A, B, JERRY_SHA1_R (48));
-  JERRY_SHA1_P (B, C, D, E, A, JERRY_SHA1_R (49));
-  JERRY_SHA1_P (A, B, C, D, E, JERRY_SHA1_R (50));
-  JERRY_SHA1_P (E, A, B, C, D, JERRY_SHA1_R (51));
-  JERRY_SHA1_P (D, E, A, B, C, JERRY_SHA1_R (52));
-  JERRY_SHA1_P (C, D, E, A, B, JERRY_SHA1_R (53));
-  JERRY_SHA1_P (B, C, D, E, A, JERRY_SHA1_R (54));
-  JERRY_SHA1_P (A, B, C, D, E, JERRY_SHA1_R (55));
-  JERRY_SHA1_P (E, A, B, C, D, JERRY_SHA1_R (56));
-  JERRY_SHA1_P (D, E, A, B, C, JERRY_SHA1_R (57));
-  JERRY_SHA1_P (C, D, E, A, B, JERRY_SHA1_R (58));
-  JERRY_SHA1_P (B, C, D, E, A, JERRY_SHA1_R (59));
-
-#undef JERRY_SHA1_F
-
-  K = 0xCA62C1D6;
-
-#define JERRY_SHA1_F(x, y, z) (x ^ y ^ z)
-
-  JERRY_SHA1_P (A, B, C, D, E, JERRY_SHA1_R (60));
-  JERRY_SHA1_P (E, A, B, C, D, JERRY_SHA1_R (61));
-  JERRY_SHA1_P (D, E, A, B, C, JERRY_SHA1_R (62));
-  JERRY_SHA1_P (C, D, E, A, B, JERRY_SHA1_R (63));
-  JERRY_SHA1_P (B, C, D, E, A, JERRY_SHA1_R (64));
-  JERRY_SHA1_P (A, B, C, D, E, JERRY_SHA1_R (65));
-  JERRY_SHA1_P (E, A, B, C, D, JERRY_SHA1_R (66));
-  JERRY_SHA1_P (D, E, A, B, C, JERRY_SHA1_R (67));
-  JERRY_SHA1_P (C, D, E, A, B, JERRY_SHA1_R (68));
-  JERRY_SHA1_P (B, C, D, E, A, JERRY_SHA1_R (69));
-  JERRY_SHA1_P (A, B, C, D, E, JERRY_SHA1_R (70));
-  JERRY_SHA1_P (E, A, B, C, D, JERRY_SHA1_R (71));
-  JERRY_SHA1_P (D, E, A, B, C, JERRY_SHA1_R (72));
-  JERRY_SHA1_P (C, D, E, A, B, JERRY_SHA1_R (73));
-  JERRY_SHA1_P (B, C, D, E, A, JERRY_SHA1_R (74));
-  JERRY_SHA1_P (A, B, C, D, E, JERRY_SHA1_R (75));
-  JERRY_SHA1_P (E, A, B, C, D, JERRY_SHA1_R (76));
-  JERRY_SHA1_P (D, E, A, B, C, JERRY_SHA1_R (77));
-  JERRY_SHA1_P (C, D, E, A, B, JERRY_SHA1_R (78));
-  JERRY_SHA1_P (B, C, D, E, A, JERRY_SHA1_R (79));
-
-#undef JERRY_SHA1_F
-
-  sha1_context_p->state[0] += A;
-  sha1_context_p->state[1] += B;
-  sha1_context_p->state[2] += C;
-  sha1_context_p->state[3] += D;
-  sha1_context_p->state[4] += E;
-
-#undef JERRY_SHA1_SHIFT
-#undef JERRY_SHA1_R
-} /* jerry_sha1_process */
-
-#undef JERRY_SHA1_P
-
-/**
- * SHA-1 update buffer.
- */
-static void
-jerry_sha1_update (jerry_sha1_context *sha1_context_p, /**< SHA-1 context */
-                   const uint8_t *source_p, /**< source buffer */
-                   size_t source_length) /**< length of source buffer */
-{
-  size_t fill;
-  uint32_t left;
-
-  if (source_length == 0)
-  {
-    return;
-  }
-
-  left = sha1_context_p->total[0] & 0x3F;
-  fill = 64 - left;
-
-  sha1_context_p->total[0] += (uint32_t) source_length;
-
-  /* Check overflow. */
-  if (sha1_context_p->total[0] < (uint32_t) source_length)
-  {
-    sha1_context_p->total[1]++;
-  }
-
-  if (left && source_length >= fill)
-  {
-    memcpy ((void *) (sha1_context_p->buffer + left), source_p, fill);
-    jerry_sha1_process (sha1_context_p, sha1_context_p->buffer);
-    source_p += fill;
-    source_length -= fill;
-    left = 0;
-  }
-
-  while (source_length >= 64)
-  {
-    jerry_sha1_process (sha1_context_p, source_p);
-    source_p += 64;
-    source_length -= 64;
-  }
-
-  if (source_length > 0)
-  {
-    memcpy ((void *) (sha1_context_p->buffer + left), source_p, source_length);
-  }
-} /* jerry_sha1_update */
-
-/**
- * SHA-1 final digest.
- */
-static void
-jerry_sha1_finish (jerry_sha1_context *sha1_context_p, /**< SHA-1 context */
-                   uint8_t destination_p[20]) /**< result */
-{
-  uint8_t buffer[16];
-
-  uint32_t high = (sha1_context_p->total[0] >> 29) | (sha1_context_p->total[1] << 3);
-  uint32_t low = (sha1_context_p->total[0] << 3);
-
-  uint32_t last = sha1_context_p->total[0] & 0x3F;
-  uint32_t padn = (last < 56) ? (56 - last) : (120 - last);
-
-  memset (buffer, 0, sizeof (buffer));
-  buffer[0] = 0x80;
-
-  while (padn > sizeof (buffer))
-  {
-    jerry_sha1_update (sha1_context_p, buffer, sizeof (buffer));
-    buffer[0] = 0;
-    padn -= (uint32_t) sizeof (buffer);
-  }
-
-  jerry_sha1_update (sha1_context_p, buffer, padn);
-
-  JERRY_SHA1_PUT_UINT32_BE (high, buffer, 0);
-  JERRY_SHA1_PUT_UINT32_BE (low, buffer, 4);
-
-  jerry_sha1_update (sha1_context_p, buffer, 8);
-
-  JERRY_SHA1_PUT_UINT32_BE (sha1_context_p->state[0], destination_p, 0);
-  JERRY_SHA1_PUT_UINT32_BE (sha1_context_p->state[1], destination_p, 4);
-  JERRY_SHA1_PUT_UINT32_BE (sha1_context_p->state[2], destination_p, 8);
-  JERRY_SHA1_PUT_UINT32_BE (sha1_context_p->state[3], destination_p, 12);
-  JERRY_SHA1_PUT_UINT32_BE (sha1_context_p->state[4], destination_p, 16);
-} /* jerry_sha1_finish */
-
-#undef JERRY_SHA1_GET_UINT32_BE
-#undef JERRY_SHA1_PUT_UINT32_BE
-
-/**
- * Computes the SHA-1 value of the combination of the two input buffers.
- */
-void
-jerry_debugger_compute_sha1 (const uint8_t *source1_p, /**< first part of the input */
-                             size_t source1_length, /**< length of the first part */
-                             const uint8_t *source2_p, /**< second part of the input */
-                             size_t source2_length, /**< length of the second part */
-                             uint8_t destination_p[20]) /**< result */
-{
-  JMEM_DEFINE_LOCAL_ARRAY (sha1_context_p, 1, jerry_sha1_context);
-
-  jerry_sha1_init (sha1_context_p);
-  jerry_sha1_update (sha1_context_p, source1_p, source1_length);
-  jerry_sha1_update (sha1_context_p, source2_p, source2_length);
-  jerry_sha1_finish (sha1_context_p, destination_p);
-
-  JMEM_FINALIZE_LOCAL_ARRAY (sha1_context_p);
-} /* jerry_debugger_compute_sha1 */
-
-#endif /* JERRY_DEBUGGER */
diff --git a/deps/jerry/jerry-core/debugger/debugger-ws.c b/deps/jerry/jerry-core/debugger/debugger-ws.c
deleted file mode 100644 (file)
index a19f4e8..0000000
+++ /dev/null
@@ -1,611 +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-port.h"
-
-#ifdef JERRY_DEBUGGER
-
-#include <arpa/inet.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-/* JerryScript debugger protocol is a simplified version of RFC-6455 (WebSockets). */
-
-/**
- * Last fragment of a Websocket package.
- */
-#define JERRY_DEBUGGER_WEBSOCKET_FIN_BIT 0x80
-
-/**
- * Masking-key is available.
- */
-#define JERRY_DEBUGGER_WEBSOCKET_MASK_BIT 0x80
-
-/**
- * Opcode type mask.
- */
-#define JERRY_DEBUGGER_WEBSOCKET_OPCODE_MASK 0x0fu
-
-/**
- * Packet length mask.
- */
-#define JERRY_DEBUGGER_WEBSOCKET_LENGTH_MASK 0x7fu
-
-/**
- * Size of websocket header size.
- */
-#define JERRY_DEBUGGER_WEBSOCKET_HEADER_SIZE 2
-
-/**
- * Payload mask size in bytes of a websocket package.
- */
-#define JERRY_DEBUGGER_WEBSOCKET_MASK_SIZE 4
-
-/**
- * Maximum message size with 1 byte size field.
- */
-#define JERRY_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX 125
-
-/**
- * Waiting for data from the client.
- */
-#define JERRY_DEBUGGER_RECEIVE_DATA_MODE \
-  (JERRY_DEBUGGER_BREAKPOINT_MODE | JERRY_DEBUGGER_CLIENT_SOURCE_MODE)
-
-/**
- * WebSocket opcode types.
- */
-typedef enum
-{
-  JERRY_DEBUGGER_WEBSOCKET_TEXT_FRAME = 1, /**< text frame */
-  JERRY_DEBUGGER_WEBSOCKET_BINARY_FRAME = 2, /**< binary frame */
-  JERRY_DEBUGGER_WEBSOCKET_CLOSE_CONNECTION = 8, /**< close connection */
-  JERRY_DEBUGGER_WEBSOCKET_PING = 9, /**< ping (keep alive) frame */
-  JERRY_DEBUGGER_WEBSOCKET_PONG = 10, /**< reply to ping frame */
-} jerry_websocket_opcode_type_t;
-
-/**
- * Header for incoming packets.
- */
-typedef struct
-{
-  uint8_t ws_opcode; /**< websocket opcode */
-  uint8_t size; /**< size of the message */
-  uint8_t mask[4]; /**< mask bytes */
-} jerry_debugger_receive_header_t;
-
-/**
- * Close the socket connection to the client.
- */
-static void
-jerry_debugger_close_connection_tcp (bool log_error) /**< log error */
-{
-  JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
-
-  JERRY_CONTEXT (debugger_flags) = JERRY_DEBUGGER_VM_IGNORE;
-
-  if (log_error)
-  {
-    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", strerror (errno));
-  }
-
-  jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Debugger client connection closed.\n");
-
-  close (JERRY_CONTEXT (debugger_connection));
-  JERRY_CONTEXT (debugger_connection) = -1;
-
-  jerry_debugger_free_unreferenced_byte_code ();
-} /* jerry_debugger_close_connection_tcp */
-
-/**
- * Send message to the client side.
- *
- * @return true - if the data was sent successfully to the client side
- *         false - otherwise
- */
-static bool
-jerry_debugger_send_tcp (const uint8_t *data_p, /**< data pointer */
-                         size_t data_size) /**< data size */
-{
-  JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
-
-  do
-  {
-    ssize_t sent_bytes = send (JERRY_CONTEXT (debugger_connection), data_p, data_size, 0);
-
-    if (sent_bytes < 0)
-    {
-      if (errno == EWOULDBLOCK)
-      {
-        continue;
-      }
-
-      jerry_debugger_close_connection_tcp (true);
-      return false;
-    }
-
-    data_size -= (size_t) sent_bytes;
-    data_p += sent_bytes;
-  }
-  while (data_size > 0);
-
-  return true;
-} /* jerry_debugger_send_tcp */
-
-/**
- * Convert a 6-bit value to a Base64 character.
- *
- * @return Base64 character
- */
-static uint8_t
-jerry_to_base64_character (uint8_t value) /**< 6-bit value */
-{
-  if (value < 26)
-  {
-    return (uint8_t) (value + 'A');
-  }
-
-  if (value < 52)
-  {
-    return (uint8_t) (value - 26 + 'a');
-  }
-
-  if (value < 62)
-  {
-    return (uint8_t) (value - 52 + '0');
-  }
-
-  if (value == 62)
-  {
-    return (uint8_t) '+';
-  }
-
-  return (uint8_t) '/';
-} /* jerry_to_base64_character */
-
-/**
- * Encode a byte sequence into Base64 string.
- */
-static void
-jerry_to_base64 (const uint8_t *source_p, /**< source data */
-                 uint8_t *destination_p, /**< destination buffer */
-                 size_t length) /**< length of source, must be divisible by 3 */
-{
-  while (length >= 3)
-  {
-    uint8_t value = (source_p[0] >> 2);
-    destination_p[0] = jerry_to_base64_character (value);
-
-    value = (uint8_t) (((source_p[0] << 4) | (source_p[1] >> 4)) & 0x3f);
-    destination_p[1] = jerry_to_base64_character (value);
-
-    value = (uint8_t) (((source_p[1] << 2) | (source_p[2] >> 6)) & 0x3f);
-    destination_p[2] = jerry_to_base64_character (value);
-
-    value = (uint8_t) (source_p[2] & 0x3f);
-    destination_p[3] = jerry_to_base64_character (value);
-
-    source_p += 3;
-    destination_p += 4;
-    length -= 3;
-  }
-} /* jerry_to_base64 */
-
-/**
- * Process WebSocket handshake.
- *
- * @return true - if the handshake was completed successfully
- *         false - otherwise
- */
-static bool
-jerry_process_handshake (int client_socket, /**< client socket */
-                         uint8_t *request_buffer_p) /**< temporary buffer */
-{
-  size_t request_buffer_size = 1024;
-  uint8_t *request_end_p = request_buffer_p;
-
-  /* Buffer request text until the double newlines are received. */
-  while (true)
-  {
-    size_t length = request_buffer_size - 1u - (size_t) (request_end_p - request_buffer_p);
-
-    if (length == 0)
-    {
-      jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Handshake buffer too small.\n");
-      return false;
-    }
-
-    ssize_t size = recv (client_socket, request_end_p, length, 0);
-
-    if (size < 0)
-    {
-      jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", strerror (errno));
-      return false;
-    }
-
-    request_end_p += (size_t) size;
-    *request_end_p = 0;
-
-    if (request_end_p > request_buffer_p + 4
-        && memcmp (request_end_p - 4, "\r\n\r\n", 4) == 0)
-    {
-      break;
-    }
-  }
-
-  /* Check protocol. */
-  const char *text_p = "GET /jerry-debugger";
-  size_t text_len = strlen (text_p);
-
-  if ((size_t) (request_end_p - request_buffer_p) < text_len
-      || memcmp (request_buffer_p, text_p, text_len) != 0)
-  {
-    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Invalid handshake format.\n");
-    return false;
-  }
-
-  uint8_t *websocket_key_p = request_buffer_p + text_len;
-
-  text_p = "Sec-WebSocket-Key:";
-  text_len = strlen (text_p);
-
-  while (true)
-  {
-    if ((size_t) (request_end_p - websocket_key_p) < text_len)
-    {
-      jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Sec-WebSocket-Key not found.\n");
-      return false;
-    }
-
-    if (websocket_key_p[0] == 'S'
-        && websocket_key_p[-1] == '\n'
-        && websocket_key_p[-2] == '\r'
-        && memcmp (websocket_key_p, text_p, text_len) == 0)
-    {
-      websocket_key_p += text_len;
-      break;
-    }
-
-    websocket_key_p++;
-  }
-
-  /* String terminated by double newlines. */
-
-  while (*websocket_key_p == ' ')
-  {
-    websocket_key_p++;
-  }
-
-  uint8_t *websocket_key_end_p = websocket_key_p;
-
-  while (*websocket_key_end_p > ' ')
-  {
-    websocket_key_end_p++;
-  }
-
-  /* Since the request_buffer_p is not needed anymore it can
-   * be reused for storing the SHA-1 key and Base64 string. */
-
-  const size_t sha1_length = 20;
-
-  jerry_debugger_compute_sha1 (websocket_key_p,
-                               (size_t) (websocket_key_end_p - websocket_key_p),
-                               (const uint8_t *) "258EAFA5-E914-47DA-95CA-C5AB0DC85B11",
-                               36,
-                               request_buffer_p);
-
-  /* The SHA-1 key is 20 bytes long but jerry_to_base64 expects
-   * a length divisible by 3 so an extra 0 is appended at the end. */
-  request_buffer_p[sha1_length] = 0;
-
-  jerry_to_base64 (request_buffer_p, request_buffer_p + sha1_length + 1, sha1_length + 1);
-
-  /* Last value must be replaced by equal sign. */
-
-  text_p = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: ";
-
-  if (!jerry_debugger_send_tcp ((const uint8_t *) text_p, strlen (text_p))
-      || !jerry_debugger_send_tcp (request_buffer_p + sha1_length + 1, 27))
-  {
-    return false;
-  }
-
-  text_p = "=\r\n\r\n";
-  return jerry_debugger_send_tcp ((const uint8_t *) text_p, strlen (text_p));
-} /* jerry_process_handshake */
-
-/**
- * Initialize the socket connection.
- *
- * @return true - if the connection succeeded
- *         false - otherwise
- */
-bool
-jerry_debugger_accept_connection (void)
-{
-  int server_socket;
-  struct sockaddr_in addr;
-  socklen_t sin_size = sizeof (struct sockaddr_in);
-
-  uint8_t *payload_p = JERRY_CONTEXT (debugger_send_buffer) + JERRY_DEBUGGER_WEBSOCKET_HEADER_SIZE;
-  JERRY_CONTEXT (debugger_send_buffer_payload_p) = payload_p;
-
-  uint8_t max_send_size = (JERRY_DEBUGGER_MAX_BUFFER_SIZE - JERRY_DEBUGGER_WEBSOCKET_HEADER_SIZE);
-  if (max_send_size > JERRY_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX)
-  {
-    max_send_size = JERRY_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX;
-  }
-  JERRY_CONTEXT (debugger_max_send_size) = max_send_size;
-
-  uint8_t receive_header_size = (JERRY_DEBUGGER_WEBSOCKET_HEADER_SIZE + JERRY_DEBUGGER_WEBSOCKET_MASK_SIZE);
-  uint8_t max_receive_size = (uint8_t) (JERRY_DEBUGGER_MAX_BUFFER_SIZE - receive_header_size);
-
-  if (max_receive_size > JERRY_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX)
-  {
-    max_receive_size = JERRY_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX;
-  }
-  JERRY_CONTEXT (debugger_max_receive_size) = max_receive_size;
-
-  addr.sin_family = AF_INET;
-  addr.sin_port = htons (JERRY_CONTEXT (debugger_port));
-  addr.sin_addr.s_addr = INADDR_ANY;
-
-  if ((server_socket = socket (AF_INET, SOCK_STREAM, 0)) == -1)
-  {
-    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", strerror (errno));
-    return false;
-  }
-
-  int opt_value = 1;
-
-  if (setsockopt (server_socket, SOL_SOCKET, SO_REUSEADDR, &opt_value, sizeof (int)) == -1)
-  {
-    close (server_socket);
-    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", strerror (errno));
-    return false;
-  }
-
-  if (bind (server_socket, (struct sockaddr *)&addr, sizeof (struct sockaddr)) == -1)
-  {
-    close (server_socket);
-    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", strerror (errno));
-    return false;
-  }
-
-  if (listen (server_socket, 1) == -1)
-  {
-    close (server_socket);
-    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", strerror (errno));
-    return false;
-  }
-
-  jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Waiting for client connection\n");
-
-  JERRY_CONTEXT (debugger_connection) = accept (server_socket, (struct sockaddr *)&addr, &sin_size);
-
-  if (JERRY_CONTEXT (debugger_connection) == -1)
-  {
-    close (server_socket);
-    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", strerror (errno));
-    return false;
-  }
-
-  close (server_socket);
-
-  JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_CONNECTED);
-
-  bool is_handshake_ok = false;
-
-  JMEM_DEFINE_LOCAL_ARRAY (request_buffer_p, 1024, uint8_t);
-
-  is_handshake_ok = jerry_process_handshake (JERRY_CONTEXT (debugger_connection),
-                                             request_buffer_p);
-
-  JMEM_FINALIZE_LOCAL_ARRAY (request_buffer_p);
-
-  if (!is_handshake_ok)
-  {
-    jerry_debugger_close_connection ();
-    return false;
-  }
-
-  if (!jerry_debugger_send_configuration (max_receive_size))
-  {
-    return false;
-  }
-
-  /* Set non-blocking mode. */
-  int socket_flags = fcntl (JERRY_CONTEXT (debugger_connection), F_GETFL, 0);
-
-  if (socket_flags < 0)
-  {
-    jerry_debugger_close_connection_tcp (true);
-    return false;
-  }
-
-  if (fcntl (JERRY_CONTEXT (debugger_connection), F_SETFL, socket_flags | O_NONBLOCK) == -1)
-  {
-    jerry_debugger_close_connection_tcp (true);
-    return false;
-  }
-
-  jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Connected from: %s\n", inet_ntoa (addr.sin_addr));
-
-  JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);
-  JERRY_CONTEXT (debugger_stop_context) = NULL;
-
-  return true;
-} /* jerry_debugger_accept_connection */
-
-/**
- * Close the socket connection to the client.
- */
-inline void __attr_always_inline___
-jerry_debugger_close_connection (void)
-{
-  jerry_debugger_close_connection_tcp (false);
-} /* jerry_debugger_close_connection */
-
-/**
- * Send message to the client side
- *
- * @return true - if the data was sent successfully to the debugger client,
- *         false - otherwise
- */
-bool
-jerry_debugger_send (size_t data_size) /**< data size */
-{
-  JERRY_ASSERT (data_size <= JERRY_CONTEXT (debugger_max_send_size));
-
-  uint8_t *header_p = JERRY_CONTEXT (debugger_send_buffer);
-  header_p[0] = JERRY_DEBUGGER_WEBSOCKET_FIN_BIT | JERRY_DEBUGGER_WEBSOCKET_BINARY_FRAME;
-  header_p[1] = (uint8_t) data_size;
-
-  return jerry_debugger_send_tcp (header_p, data_size + JERRY_DEBUGGER_WEBSOCKET_HEADER_SIZE);
-} /* jerry_debugger_send */
-
-/**
- * Receive message from the client.
- *
- * Note:
- *   If the function returns with true, the value of
- *   JERRY_DEBUGGER_VM_STOP flag should be ignored.
- *
- * @return true - if execution should be resumed,
- *         false - otherwise
- */
-bool
-jerry_debugger_receive (jerry_debugger_uint8_data_t **message_data_p) /**< [out] data received from client */
-{
-  JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
-  JERRY_ASSERT (JERRY_CONTEXT (debugger_max_receive_size) <= JERRY_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX);
-
-  JERRY_ASSERT (message_data_p != NULL ? !!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_RECEIVE_DATA_MODE)
-                                       : !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_RECEIVE_DATA_MODE));
-
-  JERRY_CONTEXT (debugger_message_delay) = JERRY_DEBUGGER_MESSAGE_FREQUENCY;
-
-  uint8_t *recv_buffer_p = JERRY_CONTEXT (debugger_receive_buffer);
-  bool resume_exec = false;
-  uint8_t expected_message_type = 0;
-
-  while (true)
-  {
-    uint32_t offset = JERRY_CONTEXT (debugger_receive_buffer_offset);
-
-    ssize_t byte_recv = recv (JERRY_CONTEXT (debugger_connection),
-                              recv_buffer_p + offset,
-                              JERRY_DEBUGGER_MAX_BUFFER_SIZE - offset,
-                              0);
-
-    if (byte_recv < 0)
-    {
-      if (errno != EWOULDBLOCK)
-      {
-        jerry_debugger_close_connection_tcp (true);
-        return true;
-      }
-
-      byte_recv = 0;
-    }
-
-    offset += (uint32_t) byte_recv;
-    JERRY_CONTEXT (debugger_receive_buffer_offset) = (uint16_t) offset;
-
-    if (offset < sizeof (jerry_debugger_receive_header_t))
-    {
-      if (expected_message_type != 0)
-      {
-        continue;
-      }
-
-      return resume_exec;
-    }
-
-    if ((recv_buffer_p[0] & ~JERRY_DEBUGGER_WEBSOCKET_OPCODE_MASK) != JERRY_DEBUGGER_WEBSOCKET_FIN_BIT
-        || (recv_buffer_p[1] & JERRY_DEBUGGER_WEBSOCKET_LENGTH_MASK) > JERRY_CONTEXT (debugger_max_receive_size)
-        || !(recv_buffer_p[1] & JERRY_DEBUGGER_WEBSOCKET_MASK_BIT))
-    {
-      jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Unsupported Websocket message.\n");
-      jerry_debugger_close_connection ();
-      return true;
-    }
-
-    if ((recv_buffer_p[0] & JERRY_DEBUGGER_WEBSOCKET_OPCODE_MASK) != JERRY_DEBUGGER_WEBSOCKET_BINARY_FRAME)
-    {
-      jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Unsupported Websocket opcode.\n");
-      jerry_debugger_close_connection ();
-      return true;
-    }
-
-    uint32_t message_size = (uint32_t) (recv_buffer_p[1] & JERRY_DEBUGGER_WEBSOCKET_LENGTH_MASK);
-    uint32_t message_total_size = (uint32_t) (message_size + sizeof (jerry_debugger_receive_header_t));
-
-    if (offset < message_total_size)
-    {
-      if (expected_message_type != 0)
-      {
-        continue;
-      }
-
-      return resume_exec;
-    }
-
-    /* Unmask data bytes. */
-    uint8_t *data_p = recv_buffer_p + sizeof (jerry_debugger_receive_header_t);
-    const uint8_t *mask_p = data_p - JERRY_DEBUGGER_WEBSOCKET_MASK_SIZE;
-    const uint8_t *mask_end_p = data_p;
-    const uint8_t *data_end_p = data_p + message_size;
-
-    while (data_p < data_end_p)
-    {
-      /* Invert certain bits with xor operation. */
-      *data_p = *data_p ^ *mask_p;
-
-      data_p++;
-      mask_p++;
-
-      if (mask_p >= mask_end_p)
-      {
-        mask_p -= JERRY_DEBUGGER_WEBSOCKET_MASK_SIZE;
-      }
-    }
-
-    /* The jerry_debugger_process_message function is inlined
-     * so passing these arguments is essentially free. */
-    if (!jerry_debugger_process_message (recv_buffer_p + sizeof (jerry_debugger_receive_header_t),
-                                         message_size,
-                                         &resume_exec,
-                                         &expected_message_type,
-                                         message_data_p))
-    {
-      return true;
-    }
-
-    if (message_total_size < offset)
-    {
-      memmove (recv_buffer_p,
-               recv_buffer_p + message_total_size,
-               offset - message_total_size);
-    }
-
-    JERRY_CONTEXT (debugger_receive_buffer_offset) = (uint16_t) (offset - message_total_size);
-  }
-} /* jerry_debugger_receive */
-
-#endif /* JERRY_DEBUGGER */
diff --git a/deps/jerry/jerry-core/debugger/debugger-ws.h b/deps/jerry/jerry-core/debugger/debugger-ws.h
deleted file mode 100644 (file)
index 3a7c97c..0000000
+++ /dev/null
@@ -1,59 +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_WS_H
-#define DEBUGGER_WS_H
-
-#include "ecma-globals.h"
-
-#ifdef JERRY_DEBUGGER
-
-/* JerryScript debugger protocol is a simplified version of RFC-6455 (WebSockets). */
-
-/**
- * Maximum number of bytes transmitted or received.
- */
-#define JERRY_DEBUGGER_MAX_BUFFER_SIZE 128
-
-/**
- * Incoming message: next message of string data.
- */
-typedef struct
-{
-  uint8_t type; /**< type of the message */
-} jerry_debugger_receive_uint8_data_part_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;
-
-bool jerry_debugger_accept_connection (void);
-void jerry_debugger_close_connection (void);
-
-bool jerry_debugger_send (size_t data_size);
-bool jerry_debugger_receive (jerry_debugger_uint8_data_t **message_data_p);
-
-void jerry_debugger_compute_sha1 (const uint8_t *input1, size_t input1_len,
-                                  const uint8_t *input2, size_t input2_len,
-                                  uint8_t output[20]);
-
-#endif /* JERRY_DEBUGGER */
-
-#endif /* !DEBUGGER_WS_H */
index 0a128b31da4a391a156303d872de16b62a7841ae..75b58962d3e07264f0c49664256664dcc5aea897 100644 (file)
 #include "ecma-builtin-helpers.h"
 #include "ecma-conversion.h"
 #include "ecma-eval.h"
+#include "ecma-function-object.h"
 #include "ecma-objects.h"
 #include "jcontext.h"
+#include "jerryscript-port.h"
 #include "lit-char-helpers.h"
 
 #ifdef JERRY_DEBUGGER
 
+/**
+ * Incoming message: next message of string data.
+ */
+typedef struct
+{
+  uint8_t type; /**< type of the message */
+} jerry_debugger_receive_uint8_data_part_t;
+
 /**
  * The number of message types in the debugger should reflect the
  * debugger versioning.
  */
-JERRY_STATIC_ASSERT (JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT == 27
-                     && JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT == 19
-                     && JERRY_DEBUGGER_VERSION == 3,
+JERRY_STATIC_ASSERT (JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT == 32
+                     && JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT == 21
+                     && JERRY_DEBUGGER_VERSION == 8,
                      debugger_version_correlates_to_message_type_count);
 
+/**
+ * Waiting for data from the client.
+ */
+#define JERRY_DEBUGGER_RECEIVE_DATA_MODE \
+  (JERRY_DEBUGGER_BREAKPOINT_MODE | JERRY_DEBUGGER_CLIENT_SOURCE_MODE)
+
 /**
  * Type cast the debugger send buffer into a specific type.
  */
@@ -70,14 +86,33 @@ jerry_debugger_free_unreferenced_byte_code (void)
   }
 } /* jerry_debugger_free_unreferenced_byte_code */
 
+/**
+ * Send data over an active connection.
+ *
+ * @return true - if the data was sent successfully
+ *         false - otherwise
+ */
+static bool
+jerry_debugger_send (size_t message_length) /**< message length in bytes */
+{
+  JERRY_ASSERT (message_length <= JERRY_CONTEXT (debugger_max_send_size));
+
+  jerry_debugger_transport_header_t *header_p = JERRY_CONTEXT (debugger_transport_header_p);
+  uint8_t *payload_p = JERRY_CONTEXT (debugger_send_buffer_payload_p);
+
+  return header_p->send (header_p, payload_p, message_length);
+} /* jerry_debugger_send */
+
 /**
  * Send backtrace.
  */
 static void
-jerry_debugger_send_backtrace (uint8_t *recv_buffer_p) /**< pointer to the received data */
+jerry_debugger_send_backtrace (const uint8_t *recv_buffer_p) /**< pointer to the received data */
 {
   JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_get_backtrace_t, get_backtrace_p);
 
+  uint32_t min_depth;
+  memcpy (&min_depth, get_backtrace_p->min_depth, sizeof (uint32_t));
   uint32_t max_depth;
   memcpy (&max_depth, get_backtrace_p->max_depth, sizeof (uint32_t));
 
@@ -86,6 +121,26 @@ jerry_debugger_send_backtrace (uint8_t *recv_buffer_p) /**< pointer to the recei
     max_depth = UINT32_MAX;
   }
 
+  if (get_backtrace_p->get_total_frame_count != 0)
+  {
+    JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_backtrace_total_t, backtrace_total_p);
+    backtrace_total_p->type = JERRY_DEBUGGER_BACKTRACE_TOTAL;
+
+    vm_frame_ctx_t *iter_frame_ctx_p = JERRY_CONTEXT (vm_top_context_p);
+    uint32_t frame_count = 0;
+    while (iter_frame_ctx_p != NULL)
+    {
+      if (!(iter_frame_ctx_p->bytecode_header_p->status_flags & (CBC_CODE_FLAGS_STATIC_FUNCTION)))
+      {
+        frame_count++;
+      }
+      iter_frame_ctx_p = iter_frame_ctx_p->prev_context_p;
+    }
+    memcpy (backtrace_total_p->frame_count, &frame_count, sizeof (frame_count));
+
+    jerry_debugger_send (sizeof (jerry_debugger_send_type_t) + sizeof (frame_count));
+  }
+
   JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_backtrace_t, backtrace_p);
 
   backtrace_p->type = JERRY_DEBUGGER_BACKTRACE;
@@ -96,35 +151,46 @@ jerry_debugger_send_backtrace (uint8_t *recv_buffer_p) /**< pointer to the recei
   const size_t max_frame_count = JERRY_DEBUGGER_SEND_MAX (jerry_debugger_frame_t);
   const size_t max_message_size = JERRY_DEBUGGER_SEND_SIZE (max_frame_count, jerry_debugger_frame_t);
 
-  while (frame_ctx_p != NULL && max_depth > 0)
+  if (min_depth <= max_depth)
   {
-    if (frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_DEBUGGER_IGNORE)
+    uint32_t min_depth_offset = 0;
+
+    while (frame_ctx_p != NULL && min_depth_offset < min_depth)
     {
       frame_ctx_p = frame_ctx_p->prev_context_p;
-      continue;
+      min_depth_offset++;
     }
 
-    if (current_frame >= max_frame_count)
+    while (frame_ctx_p != NULL && min_depth_offset++ < max_depth)
     {
-      if (!jerry_debugger_send (max_message_size))
+      if (frame_ctx_p->bytecode_header_p->status_flags
+          & (CBC_CODE_FLAGS_DEBUGGER_IGNORE | CBC_CODE_FLAGS_STATIC_FUNCTION))
       {
-        return;
+        frame_ctx_p = frame_ctx_p->prev_context_p;
+        continue;
       }
-      current_frame = 0;
-    }
 
-    jerry_debugger_frame_t *frame_p = backtrace_p->frames + current_frame;
+      if (current_frame >= max_frame_count)
+      {
+        if (!jerry_debugger_send (max_message_size))
+        {
+          return;
+        }
+        current_frame = 0;
+      }
 
-    jmem_cpointer_t byte_code_cp;
-    JMEM_CP_SET_NON_NULL_POINTER (byte_code_cp, frame_ctx_p->bytecode_header_p);
-    memcpy (frame_p->byte_code_cp, &byte_code_cp, sizeof (jmem_cpointer_t));
+      jerry_debugger_frame_t *frame_p = backtrace_p->frames + current_frame;
 
-    uint32_t offset = (uint32_t) (frame_ctx_p->byte_code_p - (uint8_t *) frame_ctx_p->bytecode_header_p);
-    memcpy (frame_p->offset, &offset, sizeof (uint32_t));
+      jmem_cpointer_t byte_code_cp;
+      JMEM_CP_SET_NON_NULL_POINTER (byte_code_cp, frame_ctx_p->bytecode_header_p);
+      memcpy (frame_p->byte_code_cp, &byte_code_cp, sizeof (jmem_cpointer_t));
+
+      uint32_t offset = (uint32_t) (frame_ctx_p->byte_code_p - (uint8_t *) frame_ctx_p->bytecode_header_p);
+      memcpy (frame_p->offset, &offset, sizeof (uint32_t));
 
-    frame_ctx_p = frame_ctx_p->prev_context_p;
-    current_frame++;
-    max_depth--;
+      frame_ctx_p = frame_ctx_p->prev_context_p;
+      current_frame++;
+    }
   }
 
   size_t message_size = current_frame * sizeof (jerry_debugger_frame_t);
@@ -134,6 +200,325 @@ jerry_debugger_send_backtrace (uint8_t *recv_buffer_p) /**< pointer to the recei
   jerry_debugger_send (sizeof (jerry_debugger_send_type_t) + message_size);
 } /* jerry_debugger_send_backtrace */
 
+/**
+ * Send the scope chain types.
+ */
+static void
+jerry_debugger_send_scope_chain (void)
+{
+  vm_frame_ctx_t *iter_frame_ctx_p = JERRY_CONTEXT (vm_top_context_p);
+
+  const size_t max_byte_count = JERRY_DEBUGGER_SEND_MAX (uint8_t);
+  const size_t max_message_size = JERRY_DEBUGGER_SEND_SIZE (max_byte_count, uint8_t);
+
+  JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_string_t, message_type_p);
+  message_type_p->type = JERRY_DEBUGGER_SCOPE_CHAIN;
+
+  size_t buffer_pos = 0;
+  bool next_func_is_local = true;
+  ecma_object_t *lex_env_p = iter_frame_ctx_p->lex_env_p;
+
+  while (true)
+  {
+    JERRY_ASSERT (ecma_is_lexical_environment (lex_env_p));
+
+    if (buffer_pos == max_byte_count)
+    {
+      if (!jerry_debugger_send (max_message_size))
+      {
+        return;
+      }
+
+      buffer_pos = 0;
+    }
+
+    if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
+    {
+      if ((lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_NON_CLOSURE) != 0)
+      {
+        message_type_p->string[buffer_pos++] = JERRY_DEBUGGER_SCOPE_NON_CLOSURE;
+      }
+      else if (next_func_is_local)
+      {
+        message_type_p->string[buffer_pos++] = JERRY_DEBUGGER_SCOPE_LOCAL;
+        next_func_is_local = false;
+      }
+      else
+      {
+        message_type_p->string[buffer_pos++] = JERRY_DEBUGGER_SCOPE_CLOSURE;
+      }
+    }
+    else if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND)
+    {
+      if (ecma_get_lex_env_outer_reference (lex_env_p) == NULL)
+      {
+        message_type_p->string[buffer_pos++] = JERRY_DEBUGGER_SCOPE_GLOBAL;
+        break;
+      }
+      else
+      {
+        message_type_p->string[buffer_pos++] = JERRY_DEBUGGER_SCOPE_WITH;
+      }
+    }
+
+    lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
+  }
+
+  message_type_p->type = JERRY_DEBUGGER_SCOPE_CHAIN_END;
+
+  jerry_debugger_send (sizeof (jerry_debugger_send_type_t) + buffer_pos);
+} /* jerry_debugger_send_scope_chain */
+
+/**
+ * Get type of the scope variable property.
+ */
+static jerry_debugger_scope_variable_type_t
+jerry_debugger_get_variable_type (ecma_value_t value) /**< input ecma value */
+{
+  jerry_debugger_scope_variable_type_t ret_value = JERRY_DEBUGGER_VALUE_NONE;
+
+  if (ecma_is_value_undefined (value))
+  {
+    ret_value = JERRY_DEBUGGER_VALUE_UNDEFINED;
+  }
+  else if (ecma_is_value_null (value))
+  {
+    ret_value = JERRY_DEBUGGER_VALUE_NULL;
+  }
+  else if (ecma_is_value_boolean (value))
+  {
+    ret_value = JERRY_DEBUGGER_VALUE_BOOLEAN;
+  }
+  else if (ecma_is_value_number (value))
+  {
+    ret_value = JERRY_DEBUGGER_VALUE_NUMBER;
+  }
+  else if (ecma_is_value_string (value))
+  {
+    ret_value = JERRY_DEBUGGER_VALUE_STRING;
+  }
+  else
+  {
+    JERRY_ASSERT (ecma_is_value_object (value));
+
+    if (ecma_object_get_class_name (ecma_get_object_from_value (value)) == LIT_MAGIC_STRING_ARRAY_UL)
+    {
+      ret_value = JERRY_DEBUGGER_VALUE_ARRAY;
+    }
+    else
+    {
+      ret_value = ecma_op_is_callable (value) ? JERRY_DEBUGGER_VALUE_FUNCTION : JERRY_DEBUGGER_VALUE_OBJECT;
+    }
+  }
+
+  JERRY_ASSERT (ret_value != JERRY_DEBUGGER_VALUE_NONE);
+
+  return ret_value;
+} /* jerry_debugger_get_variable_type */
+
+/**
+ * Helper function for jerry_debugger_send_scope_variables.
+ *
+ * It will copies the given scope values type, length and value into the outgoing message string.
+ *
+ * @return true - if the copy was successfully
+ *         false - otherwise
+ */
+static bool
+jerry_debugger_copy_variables_to_string_message (jerry_debugger_scope_variable_type_t variable_type, /**< type */
+                                                 ecma_string_t *value_str, /**< property name or value string */
+                                                 jerry_debugger_send_string_t *message_string_p, /**< msg pointer */
+                                                 size_t *buffer_pos) /**< string data position of the message */
+{
+  const size_t max_byte_count = JERRY_DEBUGGER_SEND_MAX (uint8_t);
+  const size_t max_message_size = JERRY_DEBUGGER_SEND_SIZE (max_byte_count, uint8_t);
+
+  ECMA_STRING_TO_UTF8_STRING (value_str, str_buff, str_buff_size);
+
+  size_t str_size = 0;
+  size_t str_limit = 255;
+  bool result = true;
+
+  bool type_processed = false;
+
+  while (true)
+  {
+    if (*buffer_pos == max_byte_count)
+    {
+      if (!jerry_debugger_send (max_message_size))
+      {
+        result = false;
+        break;
+      }
+
+      *buffer_pos = 0;
+    }
+
+    if (!type_processed)
+    {
+      if (variable_type != JERRY_DEBUGGER_VALUE_NONE)
+      {
+        message_string_p->string[*buffer_pos] = variable_type;
+        *buffer_pos += 1;
+      }
+      type_processed = true;
+      continue;
+    }
+
+    if (variable_type == JERRY_DEBUGGER_VALUE_FUNCTION)
+    {
+      str_size = 0; // do not copy function values
+    }
+    else
+    {
+      str_size = (str_buff_size > str_limit) ? str_limit : str_buff_size;
+    }
+
+    message_string_p->string[*buffer_pos] = (uint8_t) str_size;
+    *buffer_pos += 1;
+    break;
+  }
+
+  if (result)
+  {
+    size_t free_bytes = max_byte_count - *buffer_pos;
+    const uint8_t *string_p = str_buff;
+
+    while (str_size > free_bytes)
+    {
+      memcpy (message_string_p->string + *buffer_pos, string_p, free_bytes);
+
+      if (!jerry_debugger_send (max_message_size))
+      {
+        result = false;
+        break;
+      }
+
+      string_p += free_bytes;
+      str_size -= free_bytes;
+      free_bytes = max_byte_count;
+      *buffer_pos = 0;
+    }
+
+    if (result)
+    {
+      memcpy (message_string_p->string + *buffer_pos, string_p, str_size);
+      *buffer_pos += str_size;
+    }
+  }
+
+  ECMA_FINALIZE_UTF8_STRING (str_buff, str_buff_size);
+
+  return result;
+} /* jerry_debugger_copy_variables_to_string_message */
+
+/**
+ * Send variables of the given scope chain level.
+ */
+static void
+jerry_debugger_send_scope_variables (const uint8_t *recv_buffer_p) /**< pointer to the received data */
+{
+  JERRY_DEBUGGER_RECEIVE_BUFFER_AS (jerry_debugger_receive_get_scope_variables_t, get_scope_variables_p);
+
+  uint32_t chain_index;
+  memcpy (&chain_index, get_scope_variables_p->chain_index, sizeof (uint32_t));
+
+  vm_frame_ctx_t *iter_frame_ctx_p = JERRY_CONTEXT (vm_top_context_p);
+  ecma_object_t *lex_env_p = iter_frame_ctx_p->lex_env_p;
+
+  while (chain_index != 0)
+  {
+    lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
+
+    if (JERRY_UNLIKELY (lex_env_p == NULL))
+    {
+      jerry_debugger_send_type (JERRY_DEBUGGER_SCOPE_VARIABLES_END);
+      return;
+    }
+
+    if ((ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND)
+        || (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE))
+    {
+      chain_index--;
+    }
+  }
+
+  ecma_property_header_t *prop_iter_p;
+
+  if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
+  {
+    prop_iter_p = ecma_get_property_list (lex_env_p);
+  }
+  else
+  {
+    JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
+    ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
+    prop_iter_p =  ecma_get_property_list (binding_obj_p);
+  }
+
+  JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_string_t, message_string_p);
+  message_string_p->type = JERRY_DEBUGGER_SCOPE_VARIABLES;
+
+  size_t buffer_pos = 0;
+
+  while (prop_iter_p != NULL)
+  {
+    JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
+
+    ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
+
+    for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
+    {
+      if (ECMA_PROPERTY_IS_NAMED_PROPERTY (prop_iter_p->types[i]))
+      {
+        if (ECMA_PROPERTY_GET_NAME_TYPE (prop_iter_p->types[i]) == ECMA_DIRECT_STRING_MAGIC
+            && prop_pair_p->names_cp[i] >= LIT_NON_INTERNAL_MAGIC_STRING__COUNT)
+        {
+          continue;
+        }
+
+        ecma_string_t *prop_name = ecma_string_from_property_name (prop_iter_p->types[i],
+                                                                   prop_pair_p->names_cp[i]);
+
+        if (!jerry_debugger_copy_variables_to_string_message (JERRY_DEBUGGER_VALUE_NONE,
+                                                              prop_name,
+                                                              message_string_p,
+                                                              &buffer_pos))
+        {
+          ecma_deref_ecma_string (prop_name);
+          return;
+        }
+
+        ecma_deref_ecma_string (prop_name);
+
+        ecma_property_value_t prop_value_p = prop_pair_p->values[i];
+        ecma_value_t property_value;
+
+        jerry_debugger_scope_variable_type_t variable_type = jerry_debugger_get_variable_type (prop_value_p.value);
+
+        property_value = ecma_op_to_string (prop_value_p.value);
+
+        if (!jerry_debugger_copy_variables_to_string_message (variable_type,
+                                                              ecma_get_string_from_value (property_value),
+                                                              message_string_p,
+                                                              &buffer_pos))
+        {
+          ecma_free_value (property_value);
+          return;
+        }
+
+        ecma_free_value (property_value);
+      }
+    }
+
+    prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
+                                    prop_iter_p->next_property_cp);
+  }
+
+  message_string_p->type = JERRY_DEBUGGER_SCOPE_VARIABLES_END;
+  jerry_debugger_send (sizeof (jerry_debugger_send_type_t) + buffer_pos);
+} /* jerry_debugger_send_scope_variables */
+
 /**
  * Send result of evaluated expression or throw an error.
  *
@@ -148,12 +533,17 @@ jerry_debugger_send_eval (const lit_utf8_byte_t *eval_string_p, /**< evaluated s
   JERRY_ASSERT (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_IGNORE));
 
   JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_IGNORE);
-  ecma_value_t result = ecma_op_eval_chars_buffer (eval_string_p + 1, eval_string_size - 1, true, false);
+
+  uint32_t chain_index;
+  memcpy (&chain_index, eval_string_p, sizeof (uint32_t));
+  uint32_t parse_opts = ECMA_PARSE_DIRECT_EVAL | (chain_index << ECMA_PARSE_CHAIN_INDEX_SHIFT);
+
+  ecma_value_t result = ecma_op_eval_chars_buffer (eval_string_p + 5, eval_string_size - 5, parse_opts);
   JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE);
 
   if (!ECMA_IS_VALUE_ERROR (result))
   {
-    if (eval_string_p[0] != JERRY_DEBUGGER_EVAL_EVAL)
+    if (eval_string_p[4] != JERRY_DEBUGGER_EVAL_EVAL)
     {
       JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_EXCEPTION_THROWN);
       JERRY_CONTEXT (error_value) = result;
@@ -162,7 +552,7 @@ jerry_debugger_send_eval (const lit_utf8_byte_t *eval_string_p, /**< evaluated s
       JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);
       JERRY_CONTEXT (debugger_stop_context) = NULL;
 
-      if (eval_string_p[0] == JERRY_DEBUGGER_EVAL_THROW)
+      if (eval_string_p[4] == JERRY_DEBUGGER_EVAL_THROW)
       {
         JERRY_CONTEXT (status_flags) |= ECMA_STATUS_EXCEPTION;
       }
@@ -231,24 +621,14 @@ jerry_debugger_send_eval (const lit_utf8_byte_t *eval_string_p, /**< evaluated s
   return false;
 } /* jerry_debugger_send_eval */
 
-/**
- * Suspend execution for a given time.
- * Note: If the platform does not have nanosleep or usleep, this function does not sleep at all.
- */
-void
-jerry_debugger_sleep (void)
-{
-  jerry_port_sleep (JERRY_DEBUGGER_TIMEOUT);
-} /* jerry_debugger_sleep */
-
 /**
  * Check received packet size.
  */
 #define JERRY_DEBUGGER_CHECK_PACKET_SIZE(type) \
   if (message_size != sizeof (type)) \
   { \
-    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Invalid message size\n"); \
-    jerry_debugger_close_connection (); \
+    JERRY_ERROR_MSG ("Invalid message size\n"); \
+    jerry_debugger_transport_close (); \
     return false; \
   }
 
@@ -258,8 +638,8 @@ jerry_debugger_sleep (void)
  * @return true - if message is processed successfully
  *         false - otherwise
  */
-inline bool __attr_always_inline___
-jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the received data */
+static inline bool JERRY_ATTR_ALWAYS_INLINE
+jerry_debugger_process_message (const uint8_t *recv_buffer_p, /**< pointer to the received data */
                                 uint32_t message_size, /**< message size */
                                 bool *resume_exec_p, /**< pointer to the resume exec flag */
                                 uint8_t *expected_message_type_p, /**< message type */
@@ -270,8 +650,8 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
   if (recv_buffer_p[0] >= JERRY_DEBUGGER_CONTINUE
       && !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_BREAKPOINT_MODE))
   {
-    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Message requires breakpoint mode\n");
-    jerry_debugger_close_connection ();
+    JERRY_ERROR_MSG ("Message requires breakpoint mode\n");
+    jerry_debugger_transport_close ();
     return false;
   }
 
@@ -285,8 +665,8 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
     if (recv_buffer_p[0] != *expected_message_type_p)
     {
       jmem_heap_free_block (uint8_data_p, uint8_data_p->uint8_size + sizeof (jerry_debugger_uint8_data_t));
-      jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Unexpected message\n");
-      jerry_debugger_close_connection ();
+      JERRY_ERROR_MSG ("Unexpected message\n");
+      jerry_debugger_transport_close ();
       return false;
     }
 
@@ -295,8 +675,8 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
     if (message_size < sizeof (jerry_debugger_receive_uint8_data_part_t) + 1)
     {
       jmem_heap_free_block (uint8_data_p, uint8_data_p->uint8_size + sizeof (jerry_debugger_uint8_data_t));
-      jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Invalid message size\n");
-      jerry_debugger_close_connection ();
+      JERRY_ERROR_MSG ("Invalid message size\n");
+      jerry_debugger_transport_close ();
       return false;
     }
 
@@ -307,8 +687,8 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
     if (message_size > expected_data)
     {
       jmem_heap_free_block (uint8_data_p, uint8_data_p->uint8_size + sizeof (jerry_debugger_uint8_data_t));
-      jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Invalid message size\n");
-      jerry_debugger_close_connection ();
+      JERRY_ERROR_MSG ("Invalid message size\n");
+      jerry_debugger_transport_close ();
       return false;
     }
 
@@ -357,8 +737,8 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
 
       if (byte_code_free_cp != JERRY_CONTEXT (debugger_byte_code_free_tail))
       {
-        jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Invalid byte code free order\n");
-        jerry_debugger_close_connection ();
+        JERRY_ERROR_MSG ("Invalid byte code free order\n");
+        jerry_debugger_transport_close ();
         return false;
       }
 
@@ -474,6 +854,24 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
       return true;
     }
 
+    case JERRY_DEBUGGER_GET_SCOPE_CHAIN:
+    {
+      JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_type_t);
+
+      jerry_debugger_send_scope_chain ();
+
+      return true;
+    }
+
+    case JERRY_DEBUGGER_GET_SCOPE_VARIABLES:
+    {
+      JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_get_scope_variables_t);
+
+      jerry_debugger_send_scope_variables (recv_buffer_p);
+
+      return true;
+    }
+
     case JERRY_DEBUGGER_EXCEPTION_CONFIG:
     {
       JERRY_DEBUGGER_CHECK_PACKET_SIZE (jerry_debugger_receive_exception_config_t);
@@ -482,12 +880,12 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
       if (exception_config_p->enable == 0)
       {
         JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_IGNORE_EXCEPTION);
-        jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Stop at exception disabled\n");
+        JERRY_DEBUG_MSG ("Stop at exception disabled\n");
       }
       else
       {
         JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE_EXCEPTION);
-        jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Stop at exception enabled\n");
+        JERRY_DEBUG_MSG ("Stop at exception enabled\n");
       }
 
       return true;
@@ -501,12 +899,12 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
       if (parser_config_p->enable_wait != 0)
       {
         JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_PARSER_WAIT);
-        jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Waiting after parsing enabled\n");
+        JERRY_DEBUG_MSG ("Waiting after parsing enabled\n");
       }
       else
       {
         JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_PARSER_WAIT);
-        jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "Waiting after parsing disabled\n");
+        JERRY_DEBUG_MSG ("Waiting after parsing disabled\n");
       }
 
       return true;
@@ -518,8 +916,8 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
 
       if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_PARSER_WAIT_MODE))
       {
-        jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Not in parser wait mode\n");
-        jerry_debugger_close_connection ();
+        JERRY_ERROR_MSG ("Not in parser wait mode\n");
+        jerry_debugger_transport_close ();
         return false;
       }
 
@@ -529,10 +927,10 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
 
     case JERRY_DEBUGGER_EVAL:
     {
-      if (message_size < sizeof (jerry_debugger_receive_eval_first_t) + 1)
+      if (message_size < sizeof (jerry_debugger_receive_eval_first_t) + 5)
       {
-        jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Invalid message size\n");
-        jerry_debugger_close_connection ();
+        JERRY_ERROR_MSG ("Invalid message size\n");
+        jerry_debugger_transport_close ();
         return false;
       }
 
@@ -545,8 +943,8 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
       {
         if (eval_size != message_size - sizeof (jerry_debugger_receive_eval_first_t))
         {
-          jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Invalid message size\n");
-          jerry_debugger_close_connection ();
+          JERRY_ERROR_MSG ("Invalid message size\n");
+          jerry_debugger_transport_close ();
           return false;
         }
 
@@ -581,15 +979,15 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
     {
       if (message_size <= sizeof (jerry_debugger_receive_client_source_first_t))
       {
-        jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Invalid message size\n");
-        jerry_debugger_close_connection ();
+        JERRY_ERROR_MSG ("Invalid message size\n");
+        jerry_debugger_transport_close ();
         return false;
       }
 
       if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_SOURCE_MODE))
       {
-        jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Not in client source mode\n");
-        jerry_debugger_close_connection ();
+        JERRY_ERROR_MSG ("Not in client source mode\n");
+        jerry_debugger_transport_close ();
         return false;
       }
 
@@ -603,8 +1001,8 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
       if (client_source_size <= JERRY_CONTEXT (debugger_max_receive_size) - header_size
           && client_source_size != message_size - header_size)
       {
-        jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Invalid message size\n");
-        jerry_debugger_close_connection ();
+        JERRY_ERROR_MSG ("Invalid message size\n");
+        jerry_debugger_transport_close ();
         return false;
       }
 
@@ -640,8 +1038,8 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
     {
       if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_SOURCE_MODE))
       {
-        jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Not in client source mode\n");
-        jerry_debugger_close_connection ();
+        JERRY_ERROR_MSG ("Not in client source mode\n");
+        jerry_debugger_transport_close ();
         return false;
       }
 
@@ -658,8 +1056,8 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
     {
       if (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CLIENT_SOURCE_MODE))
       {
-        jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Not in client source mode\n");
-        jerry_debugger_close_connection ();
+        JERRY_ERROR_MSG ("Not in client source mode\n");
+        jerry_debugger_transport_close ();
         return false;
       }
 
@@ -674,13 +1072,76 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
 
     default:
     {
-      jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Unexpected message.");
-      jerry_debugger_close_connection ();
+      JERRY_ERROR_MSG ("Unexpected message.");
+      jerry_debugger_transport_close ();
       return false;
     }
   }
 } /* jerry_debugger_process_message */
 
+/**
+ * Receive message from the client.
+ *
+ * Note:
+ *   If the function returns with true, the value of
+ *   JERRY_DEBUGGER_VM_STOP flag should be ignored.
+ *
+ * @return true - if execution should be resumed,
+ *         false - otherwise
+ */
+bool
+jerry_debugger_receive (jerry_debugger_uint8_data_t **message_data_p) /**< [out] data received from client */
+{
+  JERRY_ASSERT (jerry_debugger_transport_is_connected ());
+
+  JERRY_ASSERT (message_data_p != NULL ? !!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_RECEIVE_DATA_MODE)
+                                       : !(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_RECEIVE_DATA_MODE));
+
+  JERRY_CONTEXT (debugger_message_delay) = JERRY_DEBUGGER_MESSAGE_FREQUENCY;
+
+  bool resume_exec = false;
+  uint8_t expected_message_type = 0;
+
+  while (true)
+  {
+    jerry_debugger_transport_receive_context_t context;
+    if (!jerry_debugger_transport_receive (&context))
+    {
+      JERRY_ASSERT (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED));
+      return true;
+    }
+
+    if (context.message_p == NULL)
+    {
+      if (expected_message_type != 0)
+      {
+        jerry_debugger_transport_sleep ();
+        continue;
+      }
+
+      return resume_exec;
+    }
+
+    /* Only datagram packets are supported. */
+    JERRY_ASSERT (context.message_total_length > 0);
+
+    /* The jerry_debugger_process_message function is inlined
+     * so passing these arguments is essentially free. */
+    if (!jerry_debugger_process_message (context.message_p,
+                                         (uint32_t) context.message_length,
+                                         &resume_exec,
+                                         &expected_message_type,
+                                         message_data_p))
+    {
+      JERRY_ASSERT (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED));
+      return true;
+    }
+
+    jerry_debugger_transport_receive_completed (&context);
+  }
+} /* jerry_debugger_receive */
+
+
 #undef JERRY_DEBUGGER_CHECK_PACKET_SIZE
 
 /**
@@ -715,7 +1176,7 @@ jerry_debugger_breakpoint_hit (uint8_t message_type) /**< message type */
 
   while (!jerry_debugger_receive (&uint8_data))
   {
-    jerry_debugger_sleep ();
+    jerry_debugger_transport_sleep ();
   }
 
   if (uint8_data != NULL)
@@ -766,10 +1227,18 @@ jerry_debugger_send_configuration (uint8_t max_message_size) /**< maximum messag
   endian_data.uint16_value = 1;
 
   configuration_p->type = JERRY_DEBUGGER_CONFIGURATION;
+  configuration_p->configuration = 0;
+
+  if (endian_data.uint8_value[0] == 1)
+  {
+    configuration_p->configuration |= (uint8_t) JERRY_DEBUGGER_LITTLE_ENDIAN;
+  }
+
+  uint32_t version = JERRY_DEBUGGER_VERSION;
+  memcpy (configuration_p->version, &version, sizeof (uint32_t));
+
   configuration_p->max_message_size = max_message_size;
   configuration_p->cpointer_size = sizeof (jmem_cpointer_t);
-  configuration_p->little_endian = (endian_data.uint8_value[0] == 1);
-  configuration_p->version = JERRY_DEBUGGER_VERSION;
 
   return jerry_debugger_send (sizeof (jerry_debugger_send_configuration_t));
 } /* jerry_debugger_send_configuration */
@@ -786,7 +1255,7 @@ jerry_debugger_send_data (jerry_debugger_header_type_t type, /**< message type *
 
   JERRY_DEBUGGER_SEND_BUFFER_AS (jerry_debugger_send_type_t, message_type_p);
 
-  message_type_p->type = type;
+  message_type_p->type = (uint8_t) type;
   memcpy (message_type_p + 1, data, size);
 
   jerry_debugger_send (sizeof (jerry_debugger_send_type_t) + size);
index 94d701423ddbd07961f435449d1d1d48f8bbecee..731314df7651a7c43dd6385be0e0a8e2faaacbcc 100644 (file)
 #ifndef DEBUGGER_H
 #define DEBUGGER_H
 
-#include "debugger-ws.h"
 #include "ecma-globals.h"
+#include "jerryscript-debugger-transport.h"
 
 #ifdef JERRY_DEBUGGER
 
 /* JerryScript debugger protocol is a simplified version of RFC-6455 (WebSockets). */
 
-/**
- * JerryScript debugger protocol version.
- */
-#define JERRY_DEBUGGER_VERSION (3)
-
 /**
  * Frequency of calling jerry_debugger_receive() by the VM.
  */
 #define JERRY_DEBUGGER_MESSAGE_FREQUENCY 5
 
 /**
- * Sleep time in milliseconds between each jerry_debugger_receive call
+ * This constant represents that the string to be sent has no subtype.
  */
-#define JERRY_DEBUGGER_TIMEOUT 100
-
-/**
-  * 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_MAX_BUFFER_SIZE < 64 || JERRY_DEBUGGER_MAX_BUFFER_SIZE > 256
+#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_MAX_BUFFER_SIZE < 64 || JERRY_DEBUGGER_MAX_BUFFER_SIZE > 256 */
+#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
@@ -154,14 +144,18 @@ typedef enum
   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 = 20, /**< backtrace data */
-  JERRY_DEBUGGER_BACKTRACE_END = 21, /**< last backtrace data */
-  JERRY_DEBUGGER_EVAL_RESULT = 22, /**< eval result */
-  JERRY_DEBUGGER_EVAL_RESULT_END = 23, /**< last part of eval result */
-  JERRY_DEBUGGER_WAIT_FOR_SOURCE = 24, /**< engine waiting for source code */
-  JERRY_DEBUGGER_OUTPUT_RESULT = 25, /**< output sent by the program to the debugger */
-  JERRY_DEBUGGER_OUTPUT_RESULT_END = 26, /**< last output result data */
-
+  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_MESSAGES_OUT_MAX_COUNT, /**< number of different type of output messages by the debugger */
 
   /* Messages sent by the client to server. */
@@ -191,10 +185,19 @@ typedef enum
   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.
  */
@@ -216,6 +219,10 @@ typedef enum
 
 /**
  * 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
 {
@@ -226,6 +233,43 @@ typedef enum
   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.
  */
@@ -241,10 +285,10 @@ typedef struct
 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 */
-  uint8_t little_endian; /**< little endian machine */
-  uint8_t version; /**< debugger version */
 } jerry_debugger_send_configuration_t;
 
 /**
@@ -352,6 +396,24 @@ typedef struct
   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.
  */
@@ -376,7 +438,9 @@ typedef struct
 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;
 
 /**
@@ -388,6 +452,15 @@ typedef struct
   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.
  */
@@ -399,11 +472,8 @@ typedef struct
 
 void jerry_debugger_free_unreferenced_byte_code (void);
 
-void jerry_debugger_sleep (void);
+bool jerry_debugger_receive (jerry_debugger_uint8_data_t **message_data_p);
 
-bool jerry_debugger_process_message (uint8_t *recv_buffer_p, uint32_t message_size,
-                                     bool *resume_exec_p, uint8_t *expected_message_p,
-                                     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);
index 4b7b5d56b87b108ec73a642194460e7df7ede23f..c178a1e86aee489e6bfa10515bda283443aaa49d 100644 (file)
@@ -16,7 +16,6 @@
 #include "ecma-alloc.h"
 #include "ecma-globals.h"
 #include "ecma-gc.h"
-#include "ecma-lcache.h"
 #include "jrt.h"
 #include "jmem.h"
 
@@ -51,43 +50,31 @@ JERRY_STATIC_ASSERT (sizeof (ecma_extended_object_t) - sizeof (ecma_object_t) <=
  */
 
 /**
- * Template of an allocation routine.
- */
-#define ALLOC(ecma_type) ecma_ ## ecma_type ## _t * \
-  ecma_alloc_ ## ecma_type (void) \
-{ \
-  ecma_ ## ecma_type ## _t *ecma_type ## _p; \
-  ecma_type ## _p = (ecma_ ## ecma_type ## _t *) jmem_pools_alloc (sizeof (ecma_ ## ecma_type ## _t)); \
-  \
-  JERRY_ASSERT (ecma_type ## _p != NULL); \
-  \
-  return ecma_type ## _p; \
-}
-
-/**
- * Deallocation routine template
+ * Allocate memory for ecma-number
+ *
+ * @return pointer to allocated memory
  */
-#define DEALLOC(ecma_type) void \
-  ecma_dealloc_ ## ecma_type (ecma_ ## ecma_type ## _t *ecma_type ## _p) \
-{ \
-  jmem_pools_free ((uint8_t *) ecma_type ## _p, sizeof (ecma_ ## ecma_type ## _t)); \
-}
+ecma_number_t *
+ecma_alloc_number (void)
+{
+  return (ecma_number_t *) jmem_pools_alloc (sizeof (ecma_number_t));
+} /* ecma_alloc_number */
 
 /**
- * Declaration of alloc/free routine for specified ecma-type.
+ * Dealloc memory from an ecma-number
  */
-#define DECLARE_ROUTINES_FOR(ecma_type) \
-  ALLOC (ecma_type) \
-  DEALLOC (ecma_type)
-
-DECLARE_ROUTINES_FOR (number)
+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 */
 
 /**
  * Allocate memory for ecma-object
  *
  * @return pointer to allocated memory
  */
-inline ecma_object_t * __attr_always_inline___
+inline ecma_object_t * JERRY_ATTR_ALWAYS_INLINE
 ecma_alloc_object (void)
 {
 #ifdef JMEM_STATS
@@ -100,7 +87,7 @@ ecma_alloc_object (void)
 /**
  * Dealloc memory from an ecma-object
  */
-inline void __attr_always_inline___
+inline void JERRY_ATTR_ALWAYS_INLINE
 ecma_dealloc_object (ecma_object_t *object_p) /**< object to be freed */
 {
 #ifdef JMEM_STATS
@@ -115,7 +102,7 @@ ecma_dealloc_object (ecma_object_t *object_p) /**< object to be freed */
  *
  * @return pointer to allocated memory
  */
-inline ecma_extended_object_t * __attr_always_inline___
+inline ecma_extended_object_t * JERRY_ATTR_ALWAYS_INLINE
 ecma_alloc_extended_object (size_t size) /**< size of object */
 {
 #ifdef JMEM_STATS
@@ -128,7 +115,7 @@ ecma_alloc_extended_object (size_t size) /**< size of object */
 /**
  * Dealloc memory of an extended object
  */
-inline void __attr_always_inline___
+inline void JERRY_ATTR_ALWAYS_INLINE
 ecma_dealloc_extended_object (ecma_object_t *object_p, /**< extended object */
                               size_t size) /**< size of object */
 {
@@ -144,7 +131,7 @@ ecma_dealloc_extended_object (ecma_object_t *object_p, /**< extended object */
  *
  * @return pointer to allocated memory
  */
-inline ecma_string_t * __attr_always_inline___
+inline ecma_string_t * JERRY_ATTR_ALWAYS_INLINE
 ecma_alloc_string (void)
 {
 #ifdef JMEM_STATS
@@ -157,7 +144,7 @@ ecma_alloc_string (void)
 /**
  * Dealloc memory from ecma-string descriptor
  */
-inline void __attr_always_inline___
+inline void JERRY_ATTR_ALWAYS_INLINE
 ecma_dealloc_string (ecma_string_t *string_p) /**< string to be freed */
 {
 #ifdef JMEM_STATS
@@ -172,7 +159,7 @@ ecma_dealloc_string (ecma_string_t *string_p) /**< string to be freed */
  *
  * @return pointer to allocated memory
  */
-inline ecma_string_t * __attr_always_inline___
+inline ecma_string_t * JERRY_ATTR_ALWAYS_INLINE
 ecma_alloc_string_buffer (size_t size) /**< size of string */
 {
 #ifdef JMEM_STATS
@@ -185,7 +172,7 @@ ecma_alloc_string_buffer (size_t size) /**< size of string */
 /**
  * Dealloc memory of a string with character data
  */
-inline void __attr_always_inline___
+inline void JERRY_ATTR_ALWAYS_INLINE
 ecma_dealloc_string_buffer (ecma_string_t *string_p, /**< string with data */
                             size_t size) /**< size of string */
 {
@@ -196,41 +183,12 @@ ecma_dealloc_string_buffer (ecma_string_t *string_p, /**< string with data */
   jmem_heap_free_block (string_p, size);
 } /* ecma_dealloc_string_buffer */
 
-/**
- * Allocate memory for getter-setter pointer pair
- *
- * @return pointer to allocated memory
- */
-inline ecma_getter_setter_pointers_t * __attr_always_inline___
-ecma_alloc_getter_setter_pointers (void)
-{
-#ifdef JMEM_STATS
-  jmem_stats_allocate_property_bytes (sizeof (ecma_property_pair_t));
-#endif /* JMEM_STATS */
-
-  return (ecma_getter_setter_pointers_t *) jmem_pools_alloc (sizeof (ecma_getter_setter_pointers_t));
-} /* ecma_alloc_getter_setter_pointers */
-
-/**
- * Dealloc memory from getter-setter pointer pair
- */
-inline void __attr_always_inline___
-ecma_dealloc_getter_setter_pointers (ecma_getter_setter_pointers_t *getter_setter_pointers_p) /**< pointer pair
-                                                                                                * to be freed */
-{
-#ifdef JMEM_STATS
-  jmem_stats_free_property_bytes (sizeof (ecma_property_pair_t));
-#endif /* JMEM_STATS */
-
-  jmem_pools_free (getter_setter_pointers_p, sizeof (ecma_getter_setter_pointers_t));
-} /* ecma_dealloc_getter_setter_pointers */
-
 /**
  * Allocate memory for ecma-property pair
  *
  * @return pointer to allocated memory
  */
-inline ecma_property_pair_t * __attr_always_inline___
+inline ecma_property_pair_t * JERRY_ATTR_ALWAYS_INLINE
 ecma_alloc_property_pair (void)
 {
 #ifdef JMEM_STATS
@@ -243,7 +201,7 @@ ecma_alloc_property_pair (void)
 /**
  * Dealloc memory of an ecma-property
  */
-inline void __attr_always_inline___
+inline void JERRY_ATTR_ALWAYS_INLINE
 ecma_dealloc_property_pair (ecma_property_pair_t *property_pair_p) /**< property pair to be freed */
 {
 #ifdef JMEM_STATS
index 512aee84a0234566e174188f1594ff07c1ca1831..da75f690feb449ebe081506d295f1e393f5fecba 100644 (file)
@@ -85,18 +85,6 @@ ecma_string_t *ecma_alloc_string_buffer (size_t size);
  */
 void ecma_dealloc_string_buffer (ecma_string_t *string_p, size_t size);
 
-/**
- * Allocate memory for getter-setter pointer pair
- *
- * @return pointer to allocated memory
- */
-ecma_getter_setter_pointers_t *ecma_alloc_getter_setter_pointers (void);
-
-/**
- * Dealloc memory from getter-setter pointer pair
- */
-void ecma_dealloc_getter_setter_pointers (ecma_getter_setter_pointers_t *getter_setter_pointers_p);
-
 /**
  * Allocate memory for ecma-property pair
  *
index 6bd2c53a1c3a8981116b0d92e5346c33d8072fb6..c16275671fbd34171585706eec302531fabb863b 100644 (file)
@@ -21,7 +21,6 @@
 #include "ecma-globals.h"
 #include "ecma-gc.h"
 #include "ecma-helpers.h"
-#include "ecma-lcache.h"
 #include "ecma-property-hashmap.h"
 #include "jcontext.h"
 #include "jrt.h"
 
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 #include "ecma-typedarray-object.h"
-#endif
+#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
 #ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
 #include "ecma-promise-object.h"
-#endif
+#endif /* !CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */
+#ifndef CONFIG_DISABLE_ES2015_MAP_BUILTIN
+#include "ecma-map-object.h"
+#endif /* !CONFIG_DISABLE_ES2015_MAP_BUILTIN */
 
 /* TODO: Extract GC to a separate component */
 
@@ -55,6 +57,9 @@
 
 /**
  * Get next object in list of objects with same generation.
+ *
+ * @return pointer to the next ecma-object
+ *         NULL - if there is no next ecma-object
  */
 static inline ecma_object_t *
 ecma_gc_get_object_next (ecma_object_t *object_p) /**< object */
@@ -78,6 +83,9 @@ ecma_gc_set_object_next (ecma_object_t *object_p, /**< object */
 
 /**
  * Get visited flag of the object.
+ *
+ * @return true  - if visited
+ *         false - otherwise
  */
 static inline bool
 ecma_gc_is_object_visited (ecma_object_t *object_p) /**< object */
@@ -124,7 +132,7 @@ ecma_init_gc_info (ecma_object_t *object_p) /**< object */
 void
 ecma_ref_object (ecma_object_t *object_p) /**< object */
 {
-  if (likely (object_p->type_flags_refs < ECMA_OBJECT_MAX_REF))
+  if (JERRY_LIKELY (object_p->type_flags_refs < ECMA_OBJECT_MAX_REF))
   {
     object_p->type_flags_refs = (uint16_t) (object_p->type_flags_refs + ECMA_OBJECT_REF_ONE);
   }
@@ -137,7 +145,7 @@ ecma_ref_object (ecma_object_t *object_p) /**< object */
 /**
  * Decrease reference counter of an object
  */
-inline void __attr_always_inline___
+inline void JERRY_ATTR_ALWAYS_INLINE
 ecma_deref_object (ecma_object_t *object_p) /**< object */
 {
   JERRY_ASSERT (object_p->type_flags_refs >= ECMA_OBJECT_REF_ONE);
@@ -157,12 +165,6 @@ ecma_gc_mark_property (ecma_property_pair_t *property_pair_p, /**< property pair
   {
     case ECMA_PROPERTY_TYPE_NAMEDDATA:
     {
-      if (ECMA_PROPERTY_GET_NAME_TYPE (property) == ECMA_DIRECT_STRING_MAGIC
-          && property_pair_p->names_cp[index] >= LIT_NEED_MARK_MAGIC_STRING__COUNT)
-      {
-        break;
-      }
-
       ecma_value_t value = property_pair_p->values[index].value;
 
       if (ecma_is_value_object (value))
@@ -190,20 +192,104 @@ ecma_gc_mark_property (ecma_property_pair_t *property_pair_p, /**< property pair
       }
       break;
     }
-    case ECMA_PROPERTY_TYPE_SPECIAL:
+    case ECMA_PROPERTY_TYPE_INTERNAL:
     {
-      JERRY_ASSERT (property == ECMA_PROPERTY_TYPE_HASHMAP
-                    || property == ECMA_PROPERTY_TYPE_DELETED);
+      JERRY_ASSERT (ECMA_PROPERTY_GET_NAME_TYPE (property) == ECMA_DIRECT_STRING_MAGIC
+                    && property_pair_p->names_cp[index] >= LIT_FIRST_INTERNAL_MAGIC_STRING);
       break;
     }
     default:
     {
-      JERRY_UNREACHABLE ();
+      JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_SPECIAL);
+
+      JERRY_ASSERT (property == ECMA_PROPERTY_TYPE_HASHMAP
+                    || property == ECMA_PROPERTY_TYPE_DELETED);
       break;
     }
   }
 } /* ecma_gc_mark_property */
 
+#ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
+
+/**
+ * Mark objects referenced by Promise built-in.
+ */
+static void
+ecma_gc_mark_promise_object (ecma_extended_object_t *ext_object_p) /**< extended object */
+{
+  /* Mark promise result. */
+  ecma_value_t result = ext_object_p->u.class_prop.u.value;
+
+  if (ecma_is_value_object (result))
+  {
+    ecma_gc_set_object_visited (ecma_get_object_from_value (result));
+  }
+
+  /* Mark all reactions. */
+  ecma_value_t *ecma_value_p;
+  ecma_value_p = ecma_collection_iterator_init (((ecma_promise_object_t *) ext_object_p)->fulfill_reactions);
+
+  while (ecma_value_p != NULL)
+  {
+    ecma_gc_set_object_visited (ecma_get_object_from_value (*ecma_value_p));
+    ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
+  }
+
+  ecma_value_p = ecma_collection_iterator_init (((ecma_promise_object_t *) ext_object_p)->reject_reactions);
+
+  while (ecma_value_p != NULL)
+  {
+    ecma_gc_set_object_visited (ecma_get_object_from_value (*ecma_value_p));
+    ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
+  }
+} /* ecma_gc_mark_promise_object */
+
+#endif /* !CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */
+
+#ifndef CONFIG_DISABLE_ES2015_MAP_BUILTIN
+
+/**
+ * Mark objects referenced by Map built-in.
+ */
+static void
+ecma_gc_mark_map_object (ecma_extended_object_t *ext_object_p) /**< extended object */
+{
+  ecma_map_object_t *map_object_p = (ecma_map_object_t *) ext_object_p;
+
+  jmem_cpointer_t first_chunk_cp = map_object_p->first_chunk_cp;
+
+  if (JERRY_UNLIKELY (first_chunk_cp == ECMA_NULL_POINTER))
+  {
+    return;
+  }
+
+  ecma_value_t *item_p = ECMA_GET_NON_NULL_POINTER (ecma_map_object_chunk_t, first_chunk_cp)->items;
+
+  while (true)
+  {
+    ecma_value_t item = *item_p++;
+
+    if (!ecma_is_value_pointer (item))
+    {
+      if (ecma_is_value_object (item))
+      {
+        ecma_gc_set_object_visited (ecma_get_object_from_value (item));
+      }
+    }
+    else
+    {
+      item_p = (ecma_value_t *) ecma_get_pointer_from_value (item);
+
+      if (item_p == NULL)
+      {
+        return;
+      }
+    }
+  }
+} /* ecma_gc_mark_map_object */
+
+#endif /* !CONFIG_DISABLE_ES2015_MAP_BUILTIN */
+
 /**
  * Mark objects as visited starting from specified object as root
  */
@@ -241,57 +327,40 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
 
     switch (ecma_get_object_type (object_p))
     {
-#ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
       case ECMA_OBJECT_TYPE_CLASS:
       {
         ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
 
-        if (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_PROMISE_UL)
+        switch (ext_object_p->u.class_prop.class_id)
         {
-          /* Mark promise result. */
-          ecma_value_t result = ext_object_p->u.class_prop.u.value;
-
-          if (ecma_is_value_object (result))
+#ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
+          case LIT_MAGIC_STRING_PROMISE_UL:
           {
-            ecma_gc_set_object_visited (ecma_get_object_from_value (result));
+            ecma_gc_mark_promise_object (ext_object_p);
+            break;
           }
-
-          /* Mark all reactions. */
-          ecma_value_t *ecma_value_p;
-          ecma_value_p = ecma_collection_iterator_init (((ecma_promise_object_t *) ext_object_p)->fulfill_reactions);
-
-          while (ecma_value_p != NULL)
+#endif /* !CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */
+#ifndef CONFIG_DISABLE_ES2015_MAP_BUILTIN
+          case LIT_MAGIC_STRING_MAP_UL:
           {
-            ecma_gc_set_object_visited (ecma_get_object_from_value (*ecma_value_p));
-            ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
+            ecma_gc_mark_map_object (ext_object_p);
+            break;
           }
-
-          ecma_value_p = ecma_collection_iterator_init (((ecma_promise_object_t *) ext_object_p)->reject_reactions);
-
-          while (ecma_value_p != NULL)
+#endif /* !CONFIG_DISABLE_ES2015_MAP_BUILTIN */
+          default:
           {
-            ecma_gc_set_object_visited (ecma_get_object_from_value (*ecma_value_p));
-            ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
+            break;
           }
         }
 
         break;
       }
-#endif /*! CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */
       case ECMA_OBJECT_TYPE_PSEUDO_ARRAY:
       {
         ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
 
         switch (ext_object_p->u.pseudo_array.type)
         {
-          case ECMA_PSEUDO_ARRAY_ARGUMENTS:
-          {
-            ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
-                                                                        ext_object_p->u.pseudo_array.u2.lex_env_cp);
-
-            ecma_gc_set_object_visited (lex_env_p);
-            break;
-          }
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
           case ECMA_PSEUDO_ARRAY_TYPEDARRAY:
           case ECMA_PSEUDO_ARRAY_TYPEDARRAY_WITH_INFO:
@@ -302,7 +371,12 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
           default:
           {
-            JERRY_UNREACHABLE ();
+            JERRY_ASSERT (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS);
+
+            ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
+                                                                        ext_object_p->u.pseudo_array.u2.lex_env_cp);
+
+            ecma_gc_set_object_visited (lex_env_p);
             break;
           }
         }
@@ -404,39 +478,27 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
  * Free the native handle/pointer by calling its free callback.
  */
 static void
-ecma_gc_free_native_pointer (ecma_property_t *property_p, /**< property */
-                             lit_magic_string_id_t id) /**< identifier of internal property */
+ecma_gc_free_native_pointer (ecma_property_t *property_p) /**< property */
 {
   JERRY_ASSERT (property_p != NULL);
 
-  JERRY_ASSERT (id == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
-                || id == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
-
   ecma_property_value_t *value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
   ecma_native_pointer_t *native_pointer_p;
 
   native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t,
                                                       value_p->value);
 
-  if (id == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE)
+  if (native_pointer_p->info_p != NULL)
   {
-    if (native_pointer_p->u.callback_p != NULL)
+    ecma_object_native_free_callback_t free_cb = native_pointer_p->info_p->free_cb;
+
+    if (free_cb != NULL)
     {
-      native_pointer_p->u.callback_p ((uintptr_t) native_pointer_p->data_p);
+      free_cb (native_pointer_p->data_p);
     }
   }
-  else
-  {
-    if (native_pointer_p->u.info_p != NULL)
-    {
-      ecma_object_native_free_callback_t free_cb = native_pointer_p->u.info_p->free_cb;
 
-      if (free_cb != NULL)
-      {
-        free_cb (native_pointer_p->data_p);
-      }
-    }
-  }
+  jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t));
 } /* ecma_gc_free_native_pointer */
 
 /**
@@ -479,10 +541,9 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
 
         /* Call the native's free callback. */
         if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC
-            && (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
-                || name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER))
+            && (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER))
         {
-          ecma_gc_free_native_pointer (property_p, (lit_magic_string_id_t) name_cp);
+          ecma_gc_free_native_pointer (property_p);
         }
 
         if (prop_iter_p->types[i] != ECMA_PROPERTY_TYPE_DELETED)
@@ -531,15 +592,6 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
 
       switch (ext_object_p->u.class_prop.class_id)
       {
-        /* The undefined id represents an uninitialized class. */
-        case LIT_MAGIC_STRING_UNDEFINED:
-        case LIT_MAGIC_STRING_ARGUMENTS_UL:
-        case LIT_MAGIC_STRING_BOOLEAN_UL:
-        case LIT_MAGIC_STRING_ERROR_UL:
-        {
-          break;
-        }
-
         case LIT_MAGIC_STRING_STRING_UL:
         case LIT_MAGIC_STRING_NUMBER_UL:
         {
@@ -607,9 +659,21 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
           return;
         }
 #endif /* !CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */
+#ifndef CONFIG_DISABLE_ES2015_MAP_BUILTIN
+        case LIT_MAGIC_STRING_MAP_UL:
+        {
+          ecma_op_map_clear_map ((ecma_map_object_t *) object_p);
+          ecma_dealloc_extended_object (object_p, sizeof (ecma_map_object_t));
+          return;
+        }
+#endif /* !CONFIG_DISABLE_ES2015_MAP_BUILTIN */
         default:
         {
-          JERRY_UNREACHABLE ();
+          /* The undefined id represents an uninitialized class. */
+          JERRY_ASSERT (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_UNDEFINED
+                        || ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_ARGUMENTS_UL
+                        || ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_BOOLEAN_UL
+                        || ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_ERROR_UL);
           break;
         }
       }
@@ -683,8 +747,22 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
 
       switch (ext_object_p->u.pseudo_array.type)
       {
-        case ECMA_PSEUDO_ARRAY_ARGUMENTS:
+#ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
+        case ECMA_PSEUDO_ARRAY_TYPEDARRAY:
+        {
+          ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_object_t));
+          return;
+        }
+        case ECMA_PSEUDO_ARRAY_TYPEDARRAY_WITH_INFO:
         {
+          ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_typedarray_object_t));
+          return;
+        }
+#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
+        default:
+        {
+          JERRY_ASSERT (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS);
+
           ecma_length_t formal_params_number = ext_object_p->u.pseudo_array.u1.length;
           ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1);
 
@@ -701,26 +779,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
           ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_object_t) + formal_params_size);
           return;
         }
-#ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
-        case ECMA_PSEUDO_ARRAY_TYPEDARRAY:
-        {
-          ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_object_t));
-          return;
-        }
-        case ECMA_PSEUDO_ARRAY_TYPEDARRAY_WITH_INFO:
-        {
-          ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_typedarray_object_t));
-          return;
-        }
-#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-        default:
-        {
-          JERRY_UNREACHABLE ();
-          break;
-        }
       }
-
-      JERRY_UNREACHABLE ();
     }
 
     if (object_type == ECMA_OBJECT_TYPE_BOUND_FUNCTION)
@@ -778,7 +837,7 @@ ecma_gc_run (jmem_free_unused_memory_severity_t severity) /**< gc severity */
     if (ecma_gc_is_object_visited (obj_iter_p))
     {
       /* Moving the object to list of marked objects. */
-      if (likely (obj_prev_p != NULL))
+      if (JERRY_LIKELY (obj_prev_p != NULL))
       {
         obj_prev_p->gc_next_cp = obj_iter_p->gc_next_cp;
       }
@@ -828,7 +887,7 @@ ecma_gc_run (jmem_free_unused_memory_severity_t severity) /**< gc severity */
       if (ecma_gc_is_object_visited (obj_iter_p))
       {
         /* Moving the object to list of marked objects */
-        if (likely (obj_prev_p != NULL))
+        if (JERRY_LIKELY (obj_prev_p != NULL))
         {
           obj_prev_p->gc_next_cp = obj_iter_p->gc_next_cp;
         }
index 794bb67eba98afa5b46d3f794ae9bb37b4a4496d..375e7d17d7291856913cc3a24ecad7466229e5b1 100644 (file)
  * @{
  */
 
-/**
- * Ecma-pointer field is used to calculate ecma value's address.
- *
- * Ecma-pointer contains value's shifted offset from common Ecma-pointers' base.
- * The offset is shifted right by JMEM_ALIGNMENT_LOG.
- * Least significant JMEM_ALIGNMENT_LOG bits of non-shifted offset are zeroes.
- */
-#ifdef JERRY_CPOINTER_32_BIT
-#define ECMA_POINTER_FIELD_WIDTH 32
-#else /* !JERRY_CPOINTER_32_BIT */
-#define ECMA_POINTER_FIELD_WIDTH 16
-#endif /* JERRY_CPOINTER_32_BIT */
-
 /**
  * The NULL value for compressed pointers
  */
@@ -87,12 +74,37 @@ typedef enum
   ECMA_TYPE_FLOAT = 2, /**< pointer to a 64 or 32 bit floating point number */
   ECMA_TYPE_OBJECT = 3, /**< pointer to description of an object */
   ECMA_TYPE_DIRECT_STRING = 5, /**< directly encoded string values */
-  ECMA_TYPE_ERROR = 7, /**< pointer to description of an error reference */
-  ECMA_TYPE_COLLECTION_CHUNK = ECMA_TYPE_ERROR, /**< pointer to description of a collection chunk */
+  ECMA_TYPE_ERROR = 7, /**< pointer to description of an error reference (only supported by C API) */
+  ECMA_TYPE_POINTER = ECMA_TYPE_ERROR, /**< a generic aligned pointer */
   ECMA_TYPE_SNAPSHOT_OFFSET = ECMA_TYPE_ERROR, /**< offset to a snapshot number/string */
   ECMA_TYPE___MAX = ECMA_TYPE_ERROR /** highest value for ecma types */
 } ecma_type_t;
 
+#ifdef JERRY_DEBUGGER
+/**
+ * Shift for scope chain index part in ecma_parse_opts
+ */
+#define ECMA_PARSE_CHAIN_INDEX_SHIFT 16
+#endif
+
+/**
+ * Option flags for script parsing.
+ * Note:
+ *      The enum members must be kept in sync with parser_general_flags_t
+ *      The last 16 bits are reserved for scope chain index
+ */
+typedef enum
+{
+  ECMA_PARSE_NO_OPTS = 0, /**< no options passed */
+  ECMA_PARSE_STRICT_MODE = (1u << 0), /**< enable strict mode */
+  ECMA_PARSE_DIRECT_EVAL = (1u << 1), /**< eval is called directly (ECMA-262 v5, 15.1.2.1.1) */
+  /* These three status flags must be in this order. See PARSER_CLASS_PARSE_OPTS_OFFSET. */
+  ECMA_PARSE_CLASS_CONSTRUCTOR = (1u << 2), /**< a class constructor is being parsed (this value must be kept in
+                                             *   in sync with PARSER_CLASS_CONSTRUCTOR) */
+  ECMA_PARSE_HAS_SUPER = (1u << 3), /**< the current context has super reference */
+  ECMA_PARSE_HAS_STATIC_SUPER = (1u << 4), /**< the current context is a static class method */
+} ecma_parse_opts_t;
+
 /**
  * Description of an ecma value
  *
@@ -144,7 +156,9 @@ typedef int32_t ecma_integer_value_t;
  */
 #define ECMA_DIRECT_SHIFT 4
 
-/* ECMA make simple value */
+/**
+ * ECMA make simple value
+ */
 #define ECMA_MAKE_VALUE(value) \
   ((((ecma_value_t) (value)) << ECMA_DIRECT_SHIFT) | ECMA_DIRECT_TYPE_SIMPLE_VALUE)
 
@@ -166,32 +180,51 @@ enum
   ECMA_VALUE_UNDEFINED = ECMA_MAKE_VALUE (4), /**< undefined value */
   ECMA_VALUE_NULL = ECMA_MAKE_VALUE (5), /**< null value */
   ECMA_VALUE_ARRAY_HOLE = ECMA_MAKE_VALUE (6), /**< array hole, used for
-                                                              *   initialization of an array literal */
+                                                *   initialization of an array literal */
   ECMA_VALUE_NOT_FOUND = ECMA_MAKE_VALUE (7), /**< a special value returned by
-                                                             *   ecma_op_object_find */
+                                               *   ecma_op_object_find */
   ECMA_VALUE_REGISTER_REF = ECMA_MAKE_VALUE (8), /**< register reference,
-                                                                *   a special "base" value for vm */
+                                                  *   a special "base" value for vm */
+  ECMA_VALUE_IMPLICIT_CONSTRUCTOR = ECMA_MAKE_VALUE (9), /**< special value for bound class constructors */
 };
 
+#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32
 /**
  * Maximum integer number for an ecma value
  */
-#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32
 #define ECMA_INTEGER_NUMBER_MAX         0x7fffff
+/**
+ * Maximum integer number for an ecma value (shifted left with ECMA_DIRECT_SHIFT)
+ */
 #define ECMA_INTEGER_NUMBER_MAX_SHIFTED 0x7fffff0
 #else /* CONFIG_ECMA_NUMBER_TYPE != CONFIG_ECMA_NUMBER_FLOAT32 */
+/**
+ * Maximum integer number for an ecma value
+ */
 #define ECMA_INTEGER_NUMBER_MAX         0x7ffffff
+/**
+ * Maximum integer number for an ecma value (shifted left with ECMA_DIRECT_SHIFT)
+ */
 #define ECMA_INTEGER_NUMBER_MAX_SHIFTED 0x7ffffff0
 #endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32 */
 
+#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32
 /**
  * Minimum integer number for an ecma value
  */
-#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32
 #define ECMA_INTEGER_NUMBER_MIN         -0x7fffff
+/**
+ * Minimum integer number for an ecma value (shifted left with ECMA_DIRECT_SHIFT)
+ */
 #define ECMA_INTEGER_NUMBER_MIN_SHIFTED -0x7fffff0
 #else /* CONFIG_ECMA_NUMBER_TYPE != CONFIG_ECMA_NUMBER_FLOAT32 */
+/**
+ * Minimum integer number for an ecma value
+ */
 #define ECMA_INTEGER_NUMBER_MIN         -0x8000000
+/**
+ * Minimum integer number for an ecma value (shifted left with ECMA_DIRECT_SHIFT)
+ */
 #define ECMA_INTEGER_NUMBER_MIN_SHIFTED (-0x7fffffff - 1) /* -0x80000000 */
 #endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32 */
 
@@ -218,7 +251,7 @@ enum
  * Checks whether the error flag is set.
  */
 #define ECMA_IS_VALUE_ERROR(value) \
-  (unlikely ((value) == ECMA_VALUE_ERROR))
+  (JERRY_UNLIKELY ((value) == ECMA_VALUE_ERROR))
 
 /**
  * Representation for native external pointer
@@ -243,11 +276,6 @@ typedef ecma_value_t (*ecma_external_handler_t) (const ecma_value_t function_obj
                                                  const ecma_value_t args_p[],
                                                  const ecma_length_t args_count);
 
-/**
- * Native free callback of an object (deprecated).
- */
-typedef void (*ecma_object_free_callback_t) (const uintptr_t native_p);
-
 /**
  * Native free callback of an object.
  */
@@ -267,11 +295,7 @@ typedef struct
 typedef struct
 {
   void *data_p; /**< points to the data of the object */
-  union
-  {
-    ecma_object_free_callback_t callback_p; /**< callback */
-    ecma_object_native_info_t *info_p; /**< native info */
-  } u;
+  ecma_object_native_info_t *info_p; /**< native info */
 } ecma_native_pointer_t;
 
 /**
@@ -318,14 +342,33 @@ typedef enum
  */
 typedef enum
 {
-  ECMA_PROPERTY_TYPE_SPECIAL, /**< internal property */
+  ECMA_PROPERTY_TYPE_SPECIAL, /**< special purpose property (deleted / hashmap) */
   ECMA_PROPERTY_TYPE_NAMEDDATA, /**< property is named data */
   ECMA_PROPERTY_TYPE_NAMEDACCESSOR, /**< property is named accessor */
-  ECMA_PROPERTY_TYPE_VIRTUAL, /**< property is virtual */
+  ECMA_PROPERTY_TYPE_INTERNAL, /**< internal property with custom data field */
+  ECMA_PROPERTY_TYPE_VIRTUAL = ECMA_PROPERTY_TYPE_INTERNAL, /**< property is virtual data property */
 
   ECMA_PROPERTY_TYPE__MAX = ECMA_PROPERTY_TYPE_VIRTUAL, /**< highest value for property types. */
 } ecma_property_types_t;
 
+/**
+ * Property name listing options.
+ */
+typedef enum
+{
+  ECMA_LIST_NO_OPTS = (0), /**< no options are provided */
+  ECMA_LIST_ARRAY_INDICES = (1 << 0), /**< exclude properties with names
+                                       *   that are not indices */
+  ECMA_LIST_ENUMERABLE = (1 << 1), /**< exclude non-enumerable properties */
+  ECMA_LIST_PROTOTYPE = (1 << 2), /**< list properties from prototype chain */
+} ecma_list_properties_options_t;
+
+/**
+ * List enumerable properties and include the prototype chain.
+ */
+#define ECMA_LIST_ENUMERABLE_PROTOTYPE (ECMA_LIST_ENUMERABLE | ECMA_LIST_PROTOTYPE)
+
+
 /**
  * Property type mask.
  */
@@ -382,6 +425,18 @@ typedef enum
  */
 #define ECMA_PROPERTY_NAME_TYPE_SHIFT (ECMA_PROPERTY_FLAG_SHIFT + 4)
 
+/**
+ * Convert data property to internal property.
+ */
+#define ECMA_CONVERT_DATA_PROPERTY_TO_INTERNAL_PROPERTY(property_p) \
+   *(property_p) = (uint8_t) (*(property_p) + (ECMA_PROPERTY_TYPE_INTERNAL - ECMA_PROPERTY_TYPE_NAMEDDATA))
+
+/**
+ * Convert internal property to data property.
+ */
+#define ECMA_CONVERT_INTERNAL_PROPERTY_TO_DATA_PROPERTY(property_p) \
+   *(property_p) = (uint8_t) (*(property_p) - (ECMA_PROPERTY_TYPE_INTERNAL - ECMA_PROPERTY_TYPE_NAMEDDATA))
+
 /**
  * Special property identifiers.
  */
@@ -393,7 +448,7 @@ typedef enum
   ECMA_SPECIAL_PROPERTY_DELETED, /**< deleted property */
 
   ECMA_SPECIAL_PROPERTY__COUNT /**< Number of special property types */
-} ecma_internal_property_id_t;
+} ecma_special_property_id_t;
 
 /**
  * Define special property type.
@@ -411,15 +466,6 @@ typedef enum
  */
 #define ECMA_PROPERTY_TYPE_HASHMAP ECMA_SPECIAL_PROPERTY_VALUE (ECMA_SPECIAL_PROPERTY_HASHMAP)
 
-/**
- * Name constant of a deleted property.
- */
-#ifdef JERRY_CPOINTER_32_BIT
-#define ECMA_PROPERTY_DELETED_NAME 0xffffffffu
-#else /* !JERRY_CPOINTER_32_BIT */
-#define ECMA_PROPERTY_DELETED_NAME 0xffffu
-#endif /* JERRY_CPOINTER_32_BIT */
-
 /**
  * Type of property not found.
  */
@@ -522,8 +568,7 @@ typedef struct
  * Returns true if the property pointer is a property pair.
  */
 #define ECMA_PROPERTY_IS_PROPERTY_PAIR(property_header_p) \
-  (ECMA_PROPERTY_GET_TYPE ((property_header_p)->types[0]) != ECMA_PROPERTY_TYPE_VIRTUAL \
-   && (property_header_p)->types[0] != ECMA_PROPERTY_TYPE_HASHMAP)
+  ((property_header_p)->types[0] != ECMA_PROPERTY_TYPE_HASHMAP)
 
 /**
  * Returns true if the property is named property.
@@ -626,15 +671,44 @@ typedef enum
   /* Types between 0 - 12 are ecma_object_type_t which can have a built-in flag. */
 
   ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE = 13, /**< declarative lexical environment */
-  ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND = 14, /**< object-bound lexical environment */
-  ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND = 15, /**< object-bound lexical environment
-                                                   *   with provideThis flag */
+  ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND = 14, /**< object-bound lexical environment
+                                                    *   with provideThis flag */
+  ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND = 15, /**< object-bound lexical environment
+                                                     *   with provided super reference */
 
   ECMA_LEXICAL_ENVIRONMENT_TYPE_START = ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE, /**< first lexical
-                                                                               *    environment type */
-  ECMA_LEXICAL_ENVIRONMENT_TYPE__MAX = ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND /**< maximum value */
+                                                                               *   environment type */
+  ECMA_LEXICAL_ENVIRONMENT_TYPE__MAX = ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND /**< maximum value */
 } ecma_lexical_environment_type_t;
 
+/**
+ * Offset for JERRY_CONTEXT (status_flags) top 8 bits.
+ */
+#define ECMA_SUPER_EVAL_OPTS_OFFSET (32 - 8)
+
+/**
+ * Set JERRY_CONTEXT (status_flags) top 8 bits to the specified 'opts'.
+ */
+#define ECMA_SET_SUPER_EVAL_PARSER_OPTS(opts) \
+  do \
+  { \
+    JERRY_CONTEXT (status_flags) |= ((uint32_t) opts << ECMA_SUPER_EVAL_OPTS_OFFSET) | ECMA_STATUS_DIRECT_EVAL; \
+  } while (0)
+
+/**
+ * Get JERRY_CONTEXT (status_flags) top 8 bits.
+ */
+#define ECMA_GET_SUPER_EVAL_PARSER_OPTS() (JERRY_CONTEXT (status_flags) >> ECMA_SUPER_EVAL_OPTS_OFFSET)
+
+/**
+ * Clear JERRY_CONTEXT (status_flags) top 8 bits.
+ */
+#define ECMA_CLEAR_SUPER_EVAL_PARSER_OPTS() \
+  do \
+  { \
+    JERRY_CONTEXT (status_flags) &= ((1 << ECMA_SUPER_EVAL_OPTS_OFFSET) - 1); \
+  } while (0)
+
 /**
  * Ecma object type mask for getting the object type.
  */
@@ -652,6 +726,13 @@ typedef enum
  */
 #define ECMA_OBJECT_FLAG_EXTENSIBLE 0x20
 
+/**
+ * Non closure flag for debugger.
+ */
+#ifdef JERRY_DEBUGGER
+#define ECMA_OBJECT_FLAG_NON_CLOSURE 0x20
+#endif /* JERRY_DEBUGGER */
+
 /**
  * Value for increasing or decreasing the object reference counter.
  */
@@ -671,7 +752,7 @@ typedef struct
   /** type : 4 bit : ecma_object_type_t or ecma_lexical_environment_type_t
                      depending on ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV
       flags : 2 bit : ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV,
-                      ECMA_OBJECT_FLAG_EXTENSIBLE
+                      ECMA_OBJECT_FLAG_EXTENSIBLE or ECMA_OBJECT_FLAG_NON_CLOSURE
       refs : 10 bit (max 1023) */
   uint16_t type_flags_refs;
 
@@ -711,33 +792,33 @@ typedef struct
 {
   ecma_object_t object; /**< object header */
 
-  /*
-   * Description of extra fields. These extra fields depends on the object type.
+  /**
+   * Description of extra fields. These extra fields depend on the object type.
    */
   union
   {
     ecma_built_in_props_t built_in; /**< built-in object part */
 
-    /*
+    /**
      * Description of objects with class.
      */
     struct
     {
       uint16_t class_id; /**< class id of the object */
       uint16_t extra_info; /**< extra information for the object
-                                e.g. array buffer type info (external/internal) */
+                            *   e.g. array buffer type info (external/internal) */
 
-      /*
-       * Description of extra fields. These extra fields depends on the class_id.
+      /**
+       * Description of extra fields. These extra fields depend on the class_id.
        */
       union
       {
         ecma_value_t value; /**< value of the object (e.g. boolean, number, string, etc.) */
-        uint32_t length; /**< length related property  (e.g. length of ArrayBuffer) */
+        uint32_t length; /**< length related property (e.g. length of ArrayBuffer) */
       } u;
     } class_prop;
 
-    /*
+    /**
      * Description of function objects.
      */
     struct
@@ -746,7 +827,7 @@ typedef struct
       ecma_value_t bytecode_cp; /**< function byte code */
     } function;
 
-    /*
+    /**
      * Description of array objects.
      */
     struct
@@ -755,14 +836,14 @@ typedef struct
       ecma_property_t length_prop; /**< length property */
     } array;
 
-    /*
+    /**
      * Description of pseudo array objects.
      */
     struct
     {
       uint8_t type; /**< pseudo array type, e.g. Arguments, TypedArray*/
-      uint8_t extra_info; /**< extra infomations about the object.
-                            *  e.g. element_width_shift for typed arrays */
+      uint8_t extra_info; /**< extra information about the object.
+                             e.g. element_width_shift for typed arrays */
       union
       {
         uint16_t length; /**< for arguments: length of names */
@@ -775,7 +856,7 @@ typedef struct
       } u2;
     } pseudo_array;
 
-    /*
+    /**
      * Description of bound function object.
      */
     struct
@@ -805,10 +886,10 @@ typedef struct
   uint16_t size;                    /**< real size >> JMEM_ALIGNMENT_LOG */
   uint16_t refs;                    /**< reference counter for the byte code */
   uint16_t status_flags;            /**< various status flags:
-                                      *    CBC_CODE_FLAGS_FUNCTION flag tells whether
-                                      *    the byte code is function or regular expression.
-                                      *    If function, the other flags must be CBC_CODE_FLAGS...
-                                      *    If regexp, the other flags must be RE_FLAG... */
+                                     *   CBC_CODE_FLAGS_FUNCTION flag tells whether
+                                     *   the byte code is function or regular expression.
+                                     *   If function, the other flags must be CBC_CODE_FLAGS...
+                                     *   If regexp, the other flags must be RE_FLAG... */
 } ecma_compiled_code_t;
 
 #ifdef JERRY_ENABLE_SNAPSHOT_EXEC
@@ -818,8 +899,8 @@ typedef struct
  */
 typedef struct
 {
-  ecma_extended_object_t header;
-  const ecma_compiled_code_t *bytecode_p;
+  ecma_extended_object_t header; /**< header part */
+  const ecma_compiled_code_t *bytecode_p; /**< real byte code pointer */
 } ecma_static_function_t;
 
 #endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
@@ -852,6 +933,34 @@ typedef struct
 
 #endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
 
+#ifndef CONFIG_DISABLE_ES2015_MAP_BUILTIN
+
+/**
+ * Map item count of chunks
+ */
+#define ECMA_MAP_OBJECT_ITEM_COUNT 3
+
+/**
+ * Description of Map objects.
+ */
+typedef struct
+{
+  ecma_extended_object_t header; /**< header part */
+  jmem_cpointer_t first_chunk_cp; /**< first chunk of item list */
+  jmem_cpointer_t last_chunk_cp; /**< last chunk of item list */
+} ecma_map_object_t;
+
+/**
+ * Description of Map memory chunk.
+ */
+typedef struct
+{
+  ecma_value_t items[ECMA_MAP_OBJECT_ITEM_COUNT + 1]; /**< the last item is always a pointer to the next chunk,
+                                                       *   the rest can be ECMA_VALUE_ARRAY_HOLE or any valid value. */
+} ecma_map_object_chunk_t;
+
+#endif /* !CONFIG_DISABLE_ES2015_MAP_BUILTIN */
+
 /**
  * Description of ECMA property descriptor
  *
@@ -905,6 +1014,7 @@ typedef struct
  * Description of an ecma-number
  */
 typedef float ecma_number_t;
+
 #define DOUBLE_TO_ECMA_NUMBER_T(value) (ecma_number_t) (value)
 
 /**
@@ -940,6 +1050,7 @@ typedef float ecma_number_t;
  * Description of an ecma-number
  */
 typedef double ecma_number_t;
+
 #define DOUBLE_TO_ECMA_NUMBER_T(value) value
 
 /**
@@ -997,21 +1108,28 @@ typedef double ecma_number_t;
  */
 #define ECMA_NUMBER_MINUS_ONE ((ecma_number_t) -1)
 
+#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32
 /**
- * Minimum positive and maximum value of ecma-number
+ * Number.MIN_VALUE (i.e., the smallest positive value of ecma-number)
+ *
+ * See also: ECMA_262 v5, 15.7.3.3
  */
-#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32
 # define ECMA_NUMBER_MIN_VALUE (FLT_MIN)
+/**
+ * Number.MAX_VALUE (i.e., the maximum value of ecma-number)
+ *
+ * See also: ECMA_262 v5, 15.7.3.2
+ */
 # define ECMA_NUMBER_MAX_VALUE (FLT_MAX)
 #elif CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
 /**
- * Number.MAX_VALUE
+ * Number.MAX_VALUE (i.e., the maximum value of ecma-number)
  *
  * See also: ECMA_262 v5, 15.7.3.2
  */
 # define ECMA_NUMBER_MAX_VALUE ((ecma_number_t) 1.7976931348623157e+308)
 /**
- * Number.MIN_VALUE
+ * Number.MIN_VALUE (i.e., the smallest positive value of ecma-number)
  *
  * See also: ECMA_262 v5, 15.7.3.3
  */
index 9d7ada14f71ac385335d0b0c00bc200073a13d3d..58bf763ba17c2e3b473dc3ba8a2a5447b8dd71fb 100644 (file)
  *
  * \addtogroup ecmahelpers Helpers for operations with ECMA data types
  * @{
- *
+ */
+
+#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
+
+/**
  * \addtogroup ecmahelpersbigintegers Helpers for operations intermediate 128-bit integers
  * @{
  */
 
 /**
- * Check that parts of 128-bit integer are 32-bit.
+ * 128-bit integer type
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT(name) \
-{ \
-  JERRY_ASSERT (name[0] <= UINT32_MAX); \
-  JERRY_ASSERT (name[1] <= UINT32_MAX); \
-  JERRY_ASSERT (name[2] <= UINT32_MAX); \
-  JERRY_ASSERT (name[3] <= UINT32_MAX); \
-}
+typedef struct
+{
+  uint64_t lo; /**< low 64 bits */
+  uint64_t hi; /**< high 64 bits */
+} ecma_uint128_t;
 
 /**
- * Declare 128-bit integer.
+ * Round high part of 128-bit integer to uint64_t
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER(name) uint64_t name[4] = { 0, 0, 0, 0 }
+#define ECMA_UINT128_ROUND_HIGH_TO_UINT64(name) \
+  (name.hi + (name.lo >> 63u))
 
 /**
- * Declare 128-bit in-out argument integer.
+ * Check if 128-bit integer is zero
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER_ARG(name) uint64_t name[4]
+#define ECMA_UINT128_IS_ZERO(name) \
+  (name.hi == 0 && name.lo == 0)
 
 /**
- * Initialize 128-bit integer with given 32-bit parts
+ * Left shift 128-bit integer by max 63 bits
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER_INIT(name, high, mid_high, mid_low, low) \
+#define ECMA_UINT128_LEFT_SHIFT_MAX63(name, shift) \
 { \
-  name[3] = high; \
-  name[2] = mid_high; \
-  name[1] = mid_low; \
-  name[0] = low; \
- \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name); \
+  name.hi = (name.hi << (shift)) | (name.lo >> (64 - (shift))); \
+  name.lo <<= (shift); \
 }
 
 /**
- * Copy specified 128-bit integer
+ * Right shift 128-bit integer by max 63 bits
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER_COPY(name_copy_to, name_copy_from) \
+#define ECMA_UINT128_RIGHT_SHIFT_MAX63(name, shift) \
 { \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name_copy_to); \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name_copy_from); \
-  \
-  name_copy_to[0] = name_copy_from[0]; \
-  name_copy_to[1] = name_copy_from[1]; \
-  name_copy_to[2] = name_copy_from[2]; \
-  name_copy_to[3] = name_copy_from[3]; \
+  name.lo = (name.lo >> (shift)) | (name.hi << (64 - (shift))); \
+  name.hi >>= (shift); \
 }
 
 /**
- * Copy high and middle parts of 128-bit integer to specified uint64_t variable
+ * Add 128-bit integer
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER_ROUND_HIGH_AND_MIDDLE_TO_UINT64(name, uint64_var) \
+#define ECMA_UINT128_ADD(name_add_to, name_to_add) \
 { \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name); \
-  uint64_var = ((name[3] << 32u) | (name[2])) + (((name[1] >> 31u) != 0 ? 1 : 0)); \
+  name_add_to.hi += name_to_add.hi; \
+  name_add_to.lo += name_to_add.lo; \
+  if (name_add_to.lo < name_to_add.lo) \
+  { \
+    name_add_to.hi++; \
+  } \
 }
 
 /**
- * Copy middle and low parts of 128-bit integer to specified uint64_t variable
+ * Multiply 128-bit integer by 10
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER_ROUND_MIDDLE_AND_LOW_TO_UINT64(name, uint64_var) \
+#define ECMA_UINT128_MUL10(name) \
 { \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name); \
-  uint64_var = (name[1] << 32u) | (name[0]); \
+  ECMA_UINT128_LEFT_SHIFT_MAX63 (name, 1u); \
+  \
+  ecma_uint128_t name ## _tmp = name; \
+  \
+  ECMA_UINT128_LEFT_SHIFT_MAX63 (name ## _tmp, 2u); \
+  \
+  ECMA_UINT128_ADD (name, name ## _tmp); \
 }
 
 /**
- * Check if specified 128-bit integers are equal
+ * Divide 128-bit integer by 10
+ *
+ * N = N3 *2^96  + N2 *2^64  + N1 *2^32  + N0 *2^0     // 128-bit dividend
+ * T = T3 *2^-32 + T2 *2^-64 + T1 *2^-96 + T0 *2^-128  // 128-bit divisor reciprocal, 1/10 * 2^-128
+ *
+ * N * T    = N3*T3 *2^64 + N2*T3 *2^32 + N1*T3 *2^0 + N0*T3 *2^-32
+ *          +               N3*T2 *2^32 + N2*T2 *2^0 + N1*T2 *2^-32 + N0*T2 *2^-64
+ *          +                             N3*T1 *2^0 + N2*T1 *2^-32 + N1*T1 *2^-64 + N0*T1 *2^-96
+ *          +                                          N3*T0 *2^-32 + N2*T0 *2^-64 + N1*T0 *2^-96 + N0*T0 *2^-128
+ *
+ *  Q3=carry  Q2=^+carry    Q1=^+carry    Q0=^+carry   fraction=^...
+ *
+ * Q = Q3 *2^96  + Q2 *2^64  + Q1 *2^32  + Q0 *2^0     // 128-bit quotient
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER_ARE_EQUAL(name1, name2) \
-  ((name1)[0] == (name2[0]) \
-   && (name1)[1] == (name2[1]) \
-   && (name1)[2] == (name2[2]) \
-   && (name1)[3] == (name2[3]))
+#define ECMA_UINT128_DIV10(name) \
+{ \
+  /* estimation of reciprocal of 10, 128 bits right of the binary point (T1 == T2) */ \
+  const uint64_t tenth_l = 0x9999999aul; \
+  const uint64_t tenth_m = 0x99999999ul; \
+  const uint64_t tenth_h = 0x19999999ul; \
+  \
+  uint64_t l0 = ((uint32_t) name.lo) * tenth_l; \
+  uint64_t l1 = (name.lo >> 32u) * tenth_l; \
+  uint64_t l2 = ((uint32_t) name.hi) * tenth_l; \
+  uint64_t l3 = (name.hi >> 32u) * tenth_l; \
+  uint64_t m0 = ((uint32_t) name.lo) * tenth_m; \
+  uint64_t m1 = (name.lo >> 32u) * tenth_m; \
+  uint64_t m2 = ((uint32_t) name.hi) * tenth_m; \
+  uint64_t m3 = (name.hi >> 32u) * tenth_m; \
+  uint64_t h0 = ((uint32_t) name.lo) * tenth_h; \
+  uint64_t h1 = (name.lo >> 32u) * tenth_h; \
+  uint64_t h2 = ((uint32_t) name.hi) * tenth_h; \
+  uint64_t h3 = (name.hi >> 32u) * tenth_h; \
+  \
+  uint64_t q0 = l0 >> 32u; \
+  q0 += (uint32_t) l1; \
+  q0 += (uint32_t) m0; \
+  \
+  q0 >>= 32u; \
+  q0 += l1 >> 32u; \
+  q0 += m0 >> 32u; \
+  q0 += (uint32_t) l2; \
+  q0 += (uint32_t) m1; \
+  q0 += (uint32_t) m0; \
+  \
+  q0 >>= 32u; \
+  q0 += l2 >> 32u; \
+  q0 += m1 >> 32u; \
+  q0 += m0 >> 32u; \
+  q0 += (uint32_t) l3; \
+  q0 += (uint32_t) m2; \
+  q0 += (uint32_t) m1; \
+  q0 += (uint32_t) h0; \
+  \
+  q0 >>=32u; \
+  q0 += l3 >> 32u; \
+  q0 += m2 >> 32u; \
+  q0 += m1 >> 32u; \
+  q0 += h0 >> 32u; \
+  q0 += (uint32_t) m3; \
+  q0 += (uint32_t) m2; \
+  q0 += (uint32_t) h1; \
+  \
+  uint64_t q1 = q0 >> 32u; \
+  q1 += m3 >> 32u; \
+  q1 += m2 >> 32u; \
+  q1 += h1 >> 32u; \
+  q1 += (uint32_t) m3; \
+  q1 += (uint32_t) h2; \
+  \
+  uint64_t q32 = q1 >> 32u; \
+  q32 += m3 >> 32u; \
+  q32 += h2 >> 32u; \
+  q32 += h3; \
+  \
+  name.lo = (q1 << 32u) | ((uint32_t) q0); \
+  name.hi = q32; \
+}
+
+#if defined (__GNUC__) || defined (__clang__)
 
 /**
- * Check if bits [lowest_bit, 128) are zero
+ * Count leading zeros in the topmost 64 bits of a 128-bit integer.
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_HIGH_BIT_MASK_ZERO(name, lowest_bit) \
-  ((lowest_bit) >= 96 ? ((name[3] >> ((lowest_bit) - 96)) == 0) : \
-   ((lowest_bit) >= 64 ? (name[3] == 0 \
-                          && ((name[2] >> ((lowest_bit) - 64)) == 0)) : \
-   ((lowest_bit) >= 32 ? (name[3] == 0 \
-                          && name[2] == 0 && ((name[1] >> ((lowest_bit) - 32)) == 0)) : \
-   (name[3] == 0 && name[2] == 0 && name[1] == 0 && ((name[0] >> (lowest_bit)) == 0)))))
+#define ECMA_UINT128_CLZ_MAX63(name) \
+  __builtin_clzll (name.hi)
 
 /**
- * Check if bits [0, highest_bit] are zero
+ * Count leading zeros in the topmost 4 bits of a 128-bit integer.
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_LOW_BIT_MASK_ZERO(name, highest_bit) \
-  ((highest_bit >= 96) ? (name[2] == 0 && name[1] == 0 && name[0] == 0 \
-                          && (((uint32_t) name[3] << (127 - (highest_bit))) == 0)) : \
-   ((highest_bit >= 64) ? (name[1] == 0 && name[0] == 0 \
-                           && (((uint32_t) name[2] << (95 - (highest_bit))) == 0)) : \
-   ((highest_bit >= 32) ? (name[0] == 0 \
-                           && (((uint32_t) name[1] << (63 - (highest_bit))) == 0)) : \
-    (((uint32_t) name[0] << (31 - (highest_bit))) == 0))))
+#define ECMA_UINT128_CLZ_MAX4(name) \
+  __builtin_clzll (name.hi)
+
+#else /* !__GNUC__ && !__clang__ */
 
 /**
- * Check if 128-bit integer is zero
+ * Count leading zeros in a 64-bit integer. The behaviour is undefined for 0.
+ *
+ * @return number of leading zeros.
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_ZERO(name) \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_HIGH_BIT_MASK_ZERO (name, 0)
+static inline int JERRY_ATTR_ALWAYS_INLINE
+ecma_uint64_clz (uint64_t n) /**< integer to count leading zeros in */
+{
+  JERRY_ASSERT (n != 0);
+
+  int cnt = 0;
+  uint64_t one = 0x8000000000000000ull;
+  while ((n & one) == 0)
+  {
+    cnt++;
+    one >>= 1;
+  }
+  return cnt;
+} /* ecma_uint64_clz */
 
 /**
- * Shift 128-bit integer one bit left
+ * Number of leading zeros in 4-bit integers.
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER_LEFT_SHIFT(name) \
-{ \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name); \
-  \
-  name[3] = (uint32_t) (name[3] << 1u); \
-  name[3] |= name[2] >> 31u; \
-  name[2] = (uint32_t) (name[2] << 1u); \
-  name[2] |= name[1] >> 31u; \
-  name[1] = (uint32_t) (name[1] << 1u); \
-  name[1] |= name[0] >> 31u; \
-  name[0] = (uint32_t) (name[0] << 1u); \
-  \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name); \
-}
+static const uint8_t ecma_uint4_clz[] = { 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
 
 /**
- * Shift 128-bit integer one bit right
+ * Count leading zeros in the topmost 64 bits of a 128-bit integer.
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER_RIGHT_SHIFT(name) \
-{ \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name); \
-  \
-  name[0] >>= 1u; \
-  name[0] |= (uint32_t) (name[1] << 31u); \
-  name[1] >>= 1u; \
-  name[1] |= (uint32_t) (name[2] << 31u); \
-  name[2] >>= 1u; \
-  name[2] |= (uint32_t) (name[3] << 31u); \
-  name[3] >>= 1u; \
-  \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name); \
-}
+#define ECMA_UINT128_CLZ_MAX63(name) \
+  ecma_uint64_clz (name.hi)
 
 /**
- * Increment 128-bit integer
+ * Count leading zeros in the topmost 4 bits of a 128-bit integer.
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER_INC(name) \
-{ \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name); \
-  \
-  name[0] += 1ull; \
-  name[1] += (name[0] >> 32u); \
-  name[0] = (uint32_t) name[0]; \
-  name[2] += (name[1] >> 32u); \
-  name[1] = (uint32_t) name[1]; \
-  name[3] += (name[2] >> 32u); \
-  name[2] = (uint32_t) name[2]; \
-  \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name); \
-}
+#define ECMA_UINT128_CLZ_MAX4(name) \
+  ecma_uint4_clz[name.hi >> 60]
+
+#endif /* __GNUC__ || __clang__ */
 
 /**
- * Add 128-bit integer
+ * @}
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER_ADD(name_add_to, name_to_add) \
-{ \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name_add_to); \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name_to_add); \
-  \
-  name_add_to[0] += name_to_add[0]; \
-  name_add_to[1] += name_to_add[1]; \
-  name_add_to[2] += name_to_add[2]; \
-  name_add_to[3] += name_to_add[3]; \
-  \
-  name_add_to[1] += (name_add_to[0] >> 32u); \
-  name_add_to[0] = (uint32_t) name_add_to[0]; \
-  name_add_to[2] += (name_add_to[1] >> 32u); \
-  name_add_to[1] = (uint32_t) name_add_to[1]; \
-  name_add_to[3] += (name_add_to[2] >> 32u); \
-  name_add_to[2] = (uint32_t) name_add_to[2]; \
-  \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name_add_to); \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name_to_add); \
-}
 
 /**
- * Multiply 128-bit integer by 10
+ * Number.MAX_VALUE exponent part when using 64 bit float representation.
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER_MUL_10(name) \
-{ \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name); \
-  \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_LEFT_SHIFT (name); \
-  \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER (name ## _tmp); \
-  \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_COPY (name ## _tmp, name); \
-  \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_LEFT_SHIFT (name ## _tmp); \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_LEFT_SHIFT (name ## _tmp); \
-  \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_ADD (name, name ## _tmp); \
-  \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name); \
-}
-
+#define NUMBER_MAX_DECIMAL_EXPONENT 308
 /**
- * Divide 128-bit integer by 10
+ * Number.MIN_VALUE exponent part when using 64 bit float representation.
  */
-#define ECMA_NUMBER_CONVERSION_128BIT_INTEGER_DIV_10(name) \
-{ \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name); \
-  \
-  /* estimation of reciprocal of 10 */ \
-  const uint64_t div10_p_low = 0x9999999aul; \
-  const uint64_t div10_p_mid = 0x99999999ul; \
-  const uint64_t div10_p_high = 0x19999999ul; \
-  \
-  uint64_t intermediate[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; \
-  uint64_t l0, l1, l2, l3, m0, m1, m2, m3, h0, h1, h2, h3; \
-  l0 = name[0] * div10_p_low; \
-  l1 = name[1] * div10_p_low; \
-  l2 = name[2] * div10_p_low; \
-  l3 = name[3] * div10_p_low; \
-  m0 = name[0] * div10_p_mid; \
-  m1 = name[1] * div10_p_mid; \
-  m2 = name[2] * div10_p_mid; \
-  m3 = name[3] * div10_p_mid; \
-  h0 = name[0] * div10_p_high; \
-  h1 = name[1] * div10_p_high; \
-  h2 = name[2] * div10_p_high; \
-  h3 = name[3] * div10_p_high; \
-  intermediate[0] += (uint32_t) l0; \
-  intermediate[1] += l0 >> 32u; \
-  \
-  intermediate[1] += (uint32_t) l1; \
-  intermediate[2] += l1 >> 32u; \
-  intermediate[1] += (uint32_t) m0; \
-  intermediate[2] += m0 >> 32u; \
-  \
-  intermediate[2] += (uint32_t) l2; \
-  intermediate[3] += l2 >> 32u; \
-  intermediate[2] += (uint32_t) m1; \
-  intermediate[3] += m1 >> 32u; \
-  intermediate[2] += (uint32_t) m0; \
-  intermediate[3] += m0 >> 32u; \
-  \
-  intermediate[3] += (uint32_t) l3; \
-  intermediate[4] += l3 >> 32u; \
-  intermediate[3] += (uint32_t) m2; \
-  intermediate[4] += m2 >> 32u; \
-  intermediate[3] += (uint32_t) m1; \
-  intermediate[4] += m1 >> 32u; \
-  intermediate[3] += (uint32_t) h0; \
-  intermediate[4] += h0 >> 32u; \
-  \
-  intermediate[4] += (uint32_t) m3; \
-  intermediate[5] += m3 >> 32u; \
-  intermediate[4] += (uint32_t) m2; \
-  intermediate[5] += m2 >> 32u; \
-  intermediate[4] += (uint32_t) h1; \
-  intermediate[5] += h1 >> 32u; \
-  \
-  intermediate[5] += (uint32_t) m3; \
-  intermediate[6] += m3 >> 32u; \
-  intermediate[5] += (uint32_t) h2; \
-  intermediate[6] += h2 >> 32u; \
-  \
-  intermediate[6] += (uint32_t) h3; \
-  intermediate[7] += h3 >> 32u; \
-  \
-  intermediate[1] += intermediate[0] >> 32u; \
-  intermediate[0] = (uint32_t) intermediate[0]; \
-  intermediate[2] += intermediate[1] >> 32u; \
-  intermediate[1] = (uint32_t) intermediate[1]; \
-  intermediate[3] += intermediate[2] >> 32u; \
-  intermediate[2] = (uint32_t) intermediate[2]; \
-  intermediate[4] += intermediate[3] >> 32u; \
-  intermediate[3] = (uint32_t) intermediate[3]; \
-  intermediate[5] += intermediate[4] >> 32u; \
-  intermediate[4] = (uint32_t) intermediate[4]; \
-  intermediate[6] += intermediate[5] >> 32u; \
-  intermediate[5] = (uint32_t) intermediate[5]; \
-  intermediate[7] += intermediate[6] >> 32u; \
-  intermediate[6] = (uint32_t) intermediate[6]; \
-  \
-  name[0] = intermediate[4]; \
-  name[1] = intermediate[5]; \
-  name[2] = intermediate[6]; \
-  name[3] = intermediate[7]; \
-  \
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_CHECK_PARTS_ARE_32BIT (name); \
-}
+#define NUMBER_MIN_DECIMAL_EXPONENT -324
 
-#define EPSILON 0.0000001
+#elif CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32
 
-#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
 /**
- * Number.MAX_VALUE and Number.MIN_VALUE exponent parts while using 64 bit float representation
+ * Number.MAX_VALUE exponent part when using 32 bit float representation.
  */
-# define NUMBER_MAX_DECIMAL_EXPONENT 308
-# define NUMBER_MIN_DECIMAL_EXPONENT -324
-#elif CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32
+#define NUMBER_MAX_DECIMAL_EXPONENT 38
 /**
- * Number.MAX_VALUE and Number.MIN_VALUE exponent parts while using 32 bit float representation
+ * Number.MIN_VALUE exponent part when using 32 bit float representation.
  */
-# define NUMBER_MAX_DECIMAL_EXPONENT 38
-# define NUMBER_MIN_DECIMAL_EXPONENT -45
+#define NUMBER_MIN_DECIMAL_EXPONENT -45
+
 #endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */
 
 /**
- * @}
+ * Value of epsilon
  */
+#define EPSILON 0.0000001
 
 /**
  * ECMA-defined conversion of string to Number.
@@ -644,30 +569,24 @@ ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
   }
 
 #if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
-  int32_t binary_exponent = 33;
-
   /*
    * 128-bit mantissa storage
    *
-   * Normalized: |4 bits zero|124-bit mantissa with highest bit set to 1 if mantissa is non-zero|
+   * Normalized: |4 bits zero|124-bit mantissa with highest bit set to 1|
    */
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER (fraction_uint128);
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_INIT (fraction_uint128,
-                                              0ull,
-                                              fraction_uint64 >> 32u,
-                                              (uint32_t) fraction_uint64,
-                                              0ull);
+  ecma_uint128_t fraction_uint128 = { 0, fraction_uint64 };
 
   /* Normalizing mantissa */
-  JERRY_ASSERT (ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_HIGH_BIT_MASK_ZERO (fraction_uint128, 124));
-
-  while (ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_HIGH_BIT_MASK_ZERO (fraction_uint128, 123))
+  int shift = 4 - ECMA_UINT128_CLZ_MAX63 (fraction_uint128);
+  if (shift < 0)
   {
-    ECMA_NUMBER_CONVERSION_128BIT_INTEGER_LEFT_SHIFT (fraction_uint128);
-    binary_exponent--;
-
-    JERRY_ASSERT (!ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_ZERO (fraction_uint128));
+    ECMA_UINT128_LEFT_SHIFT_MAX63 (fraction_uint128, -shift);
+  }
+  else
+  {
+    ECMA_UINT128_RIGHT_SHIFT_MAX63 (fraction_uint128, shift);
   }
+  int32_t binary_exponent = 1 + shift;
 
   if (!e_sign)
   {
@@ -676,27 +595,17 @@ ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
 
     while (e > 0)
     {
-      JERRY_ASSERT (ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_HIGH_BIT_MASK_ZERO (fraction_uint128, 124));
+      JERRY_ASSERT (ECMA_UINT128_CLZ_MAX63 (fraction_uint128) == 4);
 
-      ECMA_NUMBER_CONVERSION_128BIT_INTEGER_MUL_10 (fraction_uint128);
+      ECMA_UINT128_MUL10 (fraction_uint128);
 
       e--;
 
       /* Normalizing mantissa */
-      while (!ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_HIGH_BIT_MASK_ZERO (fraction_uint128, 124))
-      {
-        ECMA_NUMBER_CONVERSION_128BIT_INTEGER_RIGHT_SHIFT (fraction_uint128);
-
-        binary_exponent++;
-      }
-      while (ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_HIGH_BIT_MASK_ZERO (fraction_uint128, 123))
-      {
-        ECMA_NUMBER_CONVERSION_128BIT_INTEGER_LEFT_SHIFT (fraction_uint128);
-
-        binary_exponent--;
-
-        JERRY_ASSERT (!ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_ZERO (fraction_uint128));
-      }
+      shift = 4 - ECMA_UINT128_CLZ_MAX4 (fraction_uint128);
+      JERRY_ASSERT (shift >= 0);
+      ECMA_UINT128_RIGHT_SHIFT_MAX63 (fraction_uint128, shift);
+      binary_exponent += shift;
     }
   }
   else
@@ -706,68 +615,44 @@ ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
 
     while (e > 0)
     {
-      /* Denormalizing mantissa, moving highest 1 to 95-bit */
-      while (ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_HIGH_BIT_MASK_ZERO (fraction_uint128, 127))
-      {
-        ECMA_NUMBER_CONVERSION_128BIT_INTEGER_LEFT_SHIFT (fraction_uint128);
+      /* Denormalizing mantissa, moving highest 1 to bit 127 */
+      shift = ECMA_UINT128_CLZ_MAX4 (fraction_uint128);
+      JERRY_ASSERT (shift <= 4);
+      ECMA_UINT128_LEFT_SHIFT_MAX63 (fraction_uint128, shift);
+      binary_exponent -= shift;
 
-        binary_exponent--;
-
-        JERRY_ASSERT (!ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_ZERO (fraction_uint128));
-      }
+      JERRY_ASSERT (!ECMA_UINT128_IS_ZERO (fraction_uint128));
 
-      ECMA_NUMBER_CONVERSION_128BIT_INTEGER_DIV_10 (fraction_uint128);
+      ECMA_UINT128_DIV10 (fraction_uint128);
 
       e--;
     }
 
     /* Normalizing mantissa */
-    while (!ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_HIGH_BIT_MASK_ZERO (fraction_uint128, 124))
-    {
-      ECMA_NUMBER_CONVERSION_128BIT_INTEGER_RIGHT_SHIFT (fraction_uint128);
-
-      binary_exponent++;
-    }
-    while (ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_HIGH_BIT_MASK_ZERO (fraction_uint128, 123))
-    {
-      ECMA_NUMBER_CONVERSION_128BIT_INTEGER_LEFT_SHIFT (fraction_uint128);
+    shift = 4 - ECMA_UINT128_CLZ_MAX4 (fraction_uint128);
+    JERRY_ASSERT (shift >= 0);
+    ECMA_UINT128_RIGHT_SHIFT_MAX63 (fraction_uint128, shift);
+    binary_exponent += shift;
 
-      binary_exponent--;
-
-      JERRY_ASSERT (!ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_ZERO (fraction_uint128));
-    }
+    JERRY_ASSERT (ECMA_UINT128_CLZ_MAX63 (fraction_uint128) == 4);
   }
 
-  JERRY_ASSERT (!ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_ZERO (fraction_uint128));
-  JERRY_ASSERT (ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_HIGH_BIT_MASK_ZERO (fraction_uint128, 124));
+  JERRY_ASSERT (!ECMA_UINT128_IS_ZERO (fraction_uint128));
+  JERRY_ASSERT (ECMA_UINT128_CLZ_MAX63 (fraction_uint128) == 4);
 
   /*
    * Preparing mantissa for conversion to 52-bit representation, converting it to:
    *
-   * |12 zero bits|116 mantissa bits|
+   * |11 zero bits|1|116 mantissa bits|
    */
-  while (!ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_HIGH_BIT_MASK_ZERO (fraction_uint128, 116 + 1))
-  {
-    ECMA_NUMBER_CONVERSION_128BIT_INTEGER_RIGHT_SHIFT (fraction_uint128);
-
-    binary_exponent++;
-  }
-  while (ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_HIGH_BIT_MASK_ZERO (fraction_uint128, 116))
-  {
-    ECMA_NUMBER_CONVERSION_128BIT_INTEGER_LEFT_SHIFT (fraction_uint128);
-
-    binary_exponent--;
-
-    JERRY_ASSERT (!ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_ZERO (fraction_uint128));
-  }
+  ECMA_UINT128_RIGHT_SHIFT_MAX63 (fraction_uint128, 7u);
+  binary_exponent += 7;
 
-  JERRY_ASSERT (ECMA_NUMBER_CONVERSION_128BIT_INTEGER_IS_HIGH_BIT_MASK_ZERO (fraction_uint128, 116 + 1));
+  JERRY_ASSERT (ECMA_UINT128_CLZ_MAX63 (fraction_uint128) == 11);
 
-  ECMA_NUMBER_CONVERSION_128BIT_INTEGER_ROUND_HIGH_AND_MIDDLE_TO_UINT64 (fraction_uint128, fraction_uint64);
+  fraction_uint64 = ECMA_UINT128_ROUND_HIGH_TO_UINT64 (fraction_uint128);
 
-  return ecma_number_make_from_sign_mantissa_and_exponent (sign,
-                                                           fraction_uint64,
-                                                           binary_exponent);
+  return ecma_number_make_from_sign_mantissa_and_exponent (sign, fraction_uint64, binary_exponent);
 #elif CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32
   /* Less precise conversion */
   ecma_number_t num = (ecma_number_t) (uint32_t) fraction_uint64;
@@ -818,7 +703,7 @@ ecma_uint32_to_utf8_string (uint32_t value, /**< value to convert */
 
   lit_utf8_size_t bytes_copied = (lit_utf8_size_t) (out_buffer_p + buffer_size - buf_p);
 
-  if (likely (buf_p != out_buffer_p))
+  if (JERRY_LIKELY (buf_p != out_buffer_p))
   {
     memmove (out_buffer_p, buf_p, bytes_copied);
   }
@@ -934,13 +819,15 @@ ecma_number_to_int32 (ecma_number_t num) /**< ecma-number */
 } /* ecma_number_to_int32 */
 
 /**
-  * Perform conversion of ecma-number to decimal representation with decimal exponent
+  * Perform conversion of ecma-number to decimal representation with decimal exponent.
   *
   * Note:
   *      The calculated values correspond to s, n, k parameters in ECMA-262 v5, 9.8.1, item 5:
   *         - parameter out_digits_p corresponds to s, the digits of the number;
   *         - parameter out_decimal_exp_p corresponds to n, the decimal exponent;
   *         - return value corresponds to k, the number of digits.
+  *
+  * @return the number of digits
   */
 lit_utf8_size_t
 ecma_number_to_decimal (ecma_number_t num, /**< ecma-number */
@@ -960,7 +847,7 @@ ecma_number_to_decimal (ecma_number_t num, /**< ecma-number */
  *
  * @return number of digits
  */
-inline static int32_t __attr_always_inline___
+inline static int32_t JERRY_ATTR_ALWAYS_INLINE
 ecma_number_of_digits (double val) /**< ecma number */
 {
   JERRY_ASSERT (fabs (fmod (val, 1.0)) < EPSILON);
@@ -978,7 +865,7 @@ ecma_number_of_digits (double val) /**< ecma number */
 /**
  * Convert double value to ASCII
  */
-inline static void __attr_always_inline___
+inline static void JERRY_ATTR_ALWAYS_INLINE
 ecma_double_to_ascii (double val, /**< ecma number */
                       lit_utf8_byte_t *buffer_p, /**< buffer to generate digits into */
                       int32_t num_of_digits, /**< number of digits */
@@ -1012,7 +899,7 @@ ecma_double_to_ascii (double val, /**< ecma number */
  *
  * @return number of generated digits
  */
-static inline lit_utf8_size_t __attr_always_inline___
+static inline lit_utf8_size_t JERRY_ATTR_ALWAYS_INLINE
 ecma_double_to_binary_floating_point (double val, /**< ecma number */
                                       lit_utf8_byte_t *buffer_p, /**< buffer to generate digits into */
                                       int32_t *exp_p) /**< [out] exponent */
@@ -1068,14 +955,16 @@ ecma_double_to_binary_floating_point (double val, /**< ecma number */
 } /* ecma_double_to_binary_floating_point */
 
 /**
-  * Perform conversion of ecma-number to equivalent binary floating-point number representation with decimal exponent
-  *
-  * Note:
-  *      The calculated values correspond to s, n, k parameters in ECMA-262 v5, 9.8.1, item 5:
-  *         - parameter out_digits_p corresponds to s, the digits of the number;
-  *         - parameter out_decimal_exp_p corresponds to n, the decimal exponent;
-  *         - return value corresponds to k, the number of digits.
-  */
+ * Perform conversion of ecma-number to equivalent binary floating-point number representation with decimal exponent.
+ *
+ * Note:
+ *      The calculated values correspond to s, n, k parameters in ECMA-262 v5, 9.8.1, item 5:
+ *         - parameter out_digits_p corresponds to s, the digits of the number;
+ *         - parameter out_decimal_exp_p corresponds to n, the decimal exponent;
+ *         - return value corresponds to k, the number of digits.
+ *
+ * @return the number of digits
+ */
 lit_utf8_size_t
 ecma_number_to_binary_floating_point_number (ecma_number_t num, /**< ecma-number */
                                              lit_utf8_byte_t *out_digits_p, /**< [out] buffer to fill with digits */
index 5da88489ec13056c0f5c70e67e4ff328fe3399e1..c73e1e43f7c1c7fde288b37cdf4e6ccf7d6cae63 100644 (file)
  */
 
 /**
- * Floating point format definitions
+ * Floating point format definitions (next float value)
  */
 #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
 
 /**
@@ -73,7 +79,7 @@ typedef struct
 /**
  * Normalize the number by factoring in the error.
  */
-static inline void __attr_always_inline___
+static inline void JERRY_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;
@@ -85,7 +91,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 __attr_always_inline___
+static inline void JERRY_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;
@@ -127,7 +133,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 __attr_always_inline___
+inline lit_utf8_size_t JERRY_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 */
index bb77067a85f92b2bf285650c9aaf66de6a792c88..0fb4421f2b12a0c687203cb06c1401b9b713c71b 100644 (file)
  */
 
 /**
- * Create internal property with specified identifier and store native handle/pointer of the object.
- *
- * Note:
- *      property identifier should be one of the following:
- *        - LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
- *        - LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER
+ * 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
  */
-static bool
-ecma_create_native_property (ecma_object_t *obj_p, /**< object to create property in */
-                             lit_magic_string_id_t id, /**< identifier of internal
-                                                        *   property to create */
-                             void *data_p, /**< native pointer data */
-                             void *info_p) /**< native pointer's info */
+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 */
 {
-  JERRY_ASSERT (id == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
-                || id == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
-
-  ecma_string_t *name_p = ecma_get_magic_string (id);
+  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);
@@ -55,7 +45,9 @@ ecma_create_native_property (ecma_object_t *obj_p, /**< object to create propert
   if (is_new)
   {
     ecma_property_value_t *value_p;
-    value_p = ecma_create_named_data_property (obj_p, name_p, ECMA_PROPERTY_FLAG_WRITABLE, NULL);
+    value_p = ecma_create_named_data_property (obj_p, name_p, ECMA_PROPERTY_FLAG_WRITABLE, &property_p);
+
+    ECMA_CONVERT_DATA_PROPERTY_TO_INTERNAL_PROPERTY (property_p);
 
     native_pointer_p = jmem_heap_alloc_block (sizeof (ecma_native_pointer_t));
 
@@ -68,44 +60,10 @@ ecma_create_native_property (ecma_object_t *obj_p, /**< object to create propert
     native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t, value_p->value);
   }
 
-  native_pointer_p->data_p = data_p;
-  native_pointer_p->u.info_p = info_p;
+  native_pointer_p->data_p = native_p;
+  native_pointer_p->info_p = info_p;
 
   return is_new;
-} /* ecma_create_native_property */
-
-/**
- * Create a native handle property to store the native handle and its free callback.
- *
- * @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_handle_property (ecma_object_t *obj_p, /**< object to create property in */
-                                    void *handle_p, /**< native handle */
-                                    void *free_cb) /**< native handle's free callback*/
-{
-  return ecma_create_native_property (obj_p,
-                                      LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE,
-                                      handle_p,
-                                      free_cb);
-} /* ecma_create_native_handle_property */
-
-/**
- * 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 */
-{
-  return ecma_create_native_property (obj_p,
-                                      LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER,
-                                      native_p,
-                                      info_p);
 } /* ecma_create_native_pointer_property */
 
 /**
@@ -113,21 +71,16 @@ ecma_create_native_pointer_property (ecma_object_t *obj_p, /**< object to create
  *
  * Note:
  *      property identifier should be one of the following:
- *        - LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
  *        - LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER
  *
  * @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 */
-                               lit_magic_string_id_t id) /**< identifier of internal property
-                                                          *   to get value from */
+ecma_get_native_pointer_value (ecma_object_t *obj_p) /**< object to get property value from */
 {
-  JERRY_ASSERT (id == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
-                || id == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
-
-  ecma_property_t *property_p = ecma_find_named_property (obj_p, ecma_get_magic_string (id));
+  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)
   {
@@ -139,20 +92,6 @@ ecma_get_native_pointer_value (ecma_object_t *obj_p, /**< object to get property
   return ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t, value_p->value);
 } /* ecma_get_native_pointer_value */
 
-/**
- * Free the allocated native package struct.
- */
-void
-ecma_free_native_pointer (ecma_property_t *prop_p) /**< native property */
-{
-  ecma_property_value_t *value_p = ECMA_PROPERTY_VALUE_PTR (prop_p);
-
-  ecma_native_pointer_t *native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t,
-                                                                             value_p->value);
-
-  jmem_heap_free_block (native_pointer_p, sizeof (ecma_native_pointer_t));
-} /* ecma_free_native_pointer */
-
 /**
  * @}
  * @}
index ea43c5071491331320aad1465668e0ebdd4f3e1a..ddc968425161650acba970b885e9a1ba3ab6d039 100644 (file)
@@ -31,7 +31,9 @@ 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)
 
@@ -238,7 +240,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 __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_number_is_nan (ecma_number_t num) /**< ecma-number */
 {
   bool is_nan = (num != num);
@@ -291,7 +293,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 __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_number_is_negative (ecma_number_t num) /**< ecma-number */
 {
   JERRY_ASSERT (!ecma_number_is_nan (num));
@@ -349,7 +351,7 @@ ecma_number_is_infinity (ecma_number_t num) /**< ecma-number */
  *
  * @return shift of dot in the fraction
  */
-int32_t
+static 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 */
@@ -360,7 +362,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 (unlikely (biased_exp == 0))
+  if (JERRY_UNLIKELY (biased_exp == 0))
   {
     /* IEEE-754 2008, 3.4, d */
     if (ecma_number_is_zero (num))
@@ -408,7 +410,7 @@ ecma_number_get_fraction_and_exponent (ecma_number_t num, /**< ecma-number */
  *
  * @return ecma-number
  */
-ecma_number_t
+static ecma_number_t
 ecma_number_make_normal_positive_from_fraction_and_exponent (uint64_t fraction, /**< fraction */
                                                              int32_t exponent) /**< exponent */
 {
@@ -658,18 +660,18 @@ ecma_number_calc_remainder (ecma_number_t left_num, /**< left operand */
  *
  * @return number - result of multiplication.
  */
-inline ecma_value_t __attr_always_inline___
+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 */
 {
 #if defined (__GNUC__) || defined (__clang__)
   /* Check if left_integer is power of 2 */
-  if (unlikely ((left_integer & (left_integer - 1)) == 0))
+  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 (unlikely ((right_integer & (right_integer - 1)) == 0))
+  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)));
index 5b538bbdb4152d5b18bb95bd60518c7b9b40ea2a..41a11120c7e1c1bb5022528b7e5a0105f373679e 100644 (file)
@@ -17,7 +17,6 @@
 #include "ecma-gc.h"
 #include "ecma-globals.h"
 #include "ecma-helpers.h"
-#include "ecma-lcache.h"
 #include "jrt.h"
 #include "jrt-libc-includes.h"
 #include "lit-char-helpers.h"
@@ -175,6 +174,30 @@ ecma_string_get_chars_fast (const ecma_string_t *string_p, /**< ecma-string */
   }
 } /* ecma_string_get_chars_fast */
 
+/**
+ * Allocate new ecma-string and fill it with reference to ECMA magic string
+ *
+ * @return pointer to ecma-string descriptor
+ */
+static ecma_string_t *
+ecma_new_ecma_string_from_magic_string_ex_id (lit_magic_string_ex_id_t id) /**< identifier of externl magic string */
+{
+  JERRY_ASSERT (id < lit_get_magic_string_ex_count ());
+
+  if (JERRY_LIKELY (id <= ECMA_DIRECT_STRING_MAX_IMM))
+  {
+    return (ecma_string_t *) ECMA_CREATE_DIRECT_STRING (ECMA_DIRECT_STRING_MAGIC_EX, (uintptr_t) id);
+  }
+
+  ecma_string_t *string_desc_p = ecma_alloc_string ();
+
+  string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_MAGIC_STRING_EX | ECMA_STRING_REF_ONE;
+  string_desc_p->hash = (lit_string_hash_t) (LIT_MAGIC_STRING__COUNT + id);
+  string_desc_p->u.magic_string_ex_id = id;
+
+  return string_desc_p;
+} /* ecma_new_ecma_string_from_magic_string_ex_id */
+
 /**
  * Allocate new ecma-string and fill it with characters from the utf8 string
  *
@@ -219,7 +242,7 @@ ecma_new_ecma_string_from_utf8 (const lit_utf8_byte_t *string_p, /**< utf-8 stri
   ecma_string_t *string_desc_p;
   lit_utf8_byte_t *data_p;
 
-  if (likely (string_size <= UINT16_MAX))
+  if (JERRY_LIKELY (string_size <= UINT16_MAX))
   {
     string_desc_p = ecma_alloc_string_buffer (sizeof (ecma_string_t) + string_size);
 
@@ -307,7 +330,7 @@ ecma_new_ecma_string_from_utf8_converted_to_cesu8 (const lit_utf8_byte_t *string
 
     lit_utf8_byte_t *data_p;
 
-    if (likely (converted_string_size <= UINT16_MAX))
+    if (JERRY_LIKELY (converted_string_size <= UINT16_MAX))
     {
       string_desc_p = ecma_alloc_string_buffer (sizeof (ecma_string_t) + converted_string_size);
 
@@ -387,7 +410,7 @@ ecma_new_ecma_string_from_code_unit (ecma_char_t code_unit) /**< code unit */
 ecma_string_t *
 ecma_new_ecma_string_from_uint32 (uint32_t uint32_number) /**< uint32 value of the string */
 {
-  if (likely (uint32_number <= ECMA_DIRECT_STRING_MAX_IMM))
+  if (JERRY_LIKELY (uint32_number <= ECMA_DIRECT_STRING_MAX_IMM))
   {
     return (ecma_string_t *) ECMA_CREATE_DIRECT_STRING (ECMA_DIRECT_STRING_UINT, (uintptr_t) uint32_number);
   }
@@ -410,7 +433,7 @@ ecma_new_ecma_string_from_uint32 (uint32_t uint32_number) /**< uint32 value of t
  * @return pointer to ecma-string descriptor
  */
 ecma_string_t *
-ecma_get_ecma_string_from_uint32 (uint32_t uint32_number)
+ecma_get_ecma_string_from_uint32 (uint32_t uint32_number) /**< input number */
 {
   JERRY_ASSERT (uint32_number <= ECMA_DIRECT_STRING_MAX_IMM);
 
@@ -473,37 +496,13 @@ ecma_new_ecma_string_from_number (ecma_number_t num) /**< ecma-number */
  *
  * @return pointer to ecma-string descriptor
  */
-inline ecma_string_t * __attr_always_inline___
+inline ecma_string_t * JERRY_ATTR_ALWAYS_INLINE
 ecma_get_magic_string (lit_magic_string_id_t id) /**< identifier of magic string */
 {
   JERRY_ASSERT (id < LIT_MAGIC_STRING__COUNT);
   return (ecma_string_t *) ECMA_CREATE_DIRECT_STRING (ECMA_DIRECT_STRING_MAGIC, (uintptr_t) id);
 } /* ecma_get_magic_string */
 
-/**
- * Allocate new ecma-string and fill it with reference to ECMA magic string
- *
- * @return pointer to ecma-string descriptor
- */
-ecma_string_t *
-ecma_new_ecma_string_from_magic_string_ex_id (lit_magic_string_ex_id_t id) /**< identifier of externl magic string */
-{
-  JERRY_ASSERT (id < lit_get_magic_string_ex_count ());
-
-  if (likely (id <= ECMA_DIRECT_STRING_MAX_IMM))
-  {
-    return (ecma_string_t *) ECMA_CREATE_DIRECT_STRING (ECMA_DIRECT_STRING_MAGIC_EX, (uintptr_t) id);
-  }
-
-  ecma_string_t *string_desc_p = ecma_alloc_string ();
-
-  string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_MAGIC_STRING_EX | ECMA_STRING_REF_ONE;
-  string_desc_p->hash = (lit_string_hash_t) (LIT_MAGIC_STRING__COUNT + id);
-  string_desc_p->u.magic_string_ex_id = id;
-
-  return string_desc_p;
-} /* ecma_new_ecma_string_from_magic_string_ex_id */
-
 /**
  * Append a cesu8 string after an ecma-string
  *
@@ -521,7 +520,7 @@ ecma_append_chars_to_string (ecma_string_t *string1_p, /**< base ecma-string */
 {
   JERRY_ASSERT (string1_p != NULL && cesu8_string2_size > 0 && cesu8_string2_length > 0);
 
-  if (unlikely (ecma_string_is_empty (string1_p)))
+  if (JERRY_UNLIKELY (ecma_string_is_empty (string1_p)))
   {
     return ecma_new_ecma_string_from_utf8 (cesu8_string2_p, cesu8_string2_size);
   }
@@ -673,7 +672,7 @@ ecma_append_chars_to_string (ecma_string_t *string1_p, /**< base ecma-string */
   ecma_string_t *string_desc_p;
   lit_utf8_byte_t *data_p;
 
-  if (likely (new_size <= UINT16_MAX))
+  if (JERRY_LIKELY (new_size <= UINT16_MAX))
   {
     string_desc_p = ecma_alloc_string_buffer (sizeof (ecma_string_t) + new_size);
 
@@ -734,12 +733,12 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
 {
   JERRY_ASSERT (string1_p != NULL && string2_p != NULL);
 
-  if (unlikely (ecma_string_is_empty (string1_p)))
+  if (JERRY_UNLIKELY (ecma_string_is_empty (string1_p)))
   {
     ecma_ref_ecma_string (string2_p);
     return string2_p;
   }
-  else if (unlikely (ecma_string_is_empty (string2_p)))
+  else if (JERRY_UNLIKELY (ecma_string_is_empty (string2_p)))
   {
     return string1_p;
   }
@@ -839,10 +838,10 @@ ecma_concat_ecma_strings (ecma_string_t *string1_p, /**< first ecma-string */
  * @return concatenation of an ecma-string and a magic string
  */
 ecma_string_t *
-ecma_append_magic_string_to_string (ecma_string_t *string1_p,
-                                    lit_magic_string_id_t string2_id)
+ecma_append_magic_string_to_string (ecma_string_t *string1_p, /**< string descriptor */
+                                    lit_magic_string_id_t string2_id) /**< magic string ID */
 {
-  if (unlikely (ecma_string_is_empty (string1_p)))
+  if (JERRY_UNLIKELY (ecma_string_is_empty (string1_p)))
   {
     return ecma_get_magic_string (string2_id);
   }
@@ -868,7 +867,7 @@ ecma_ref_ecma_string (ecma_string_t *string_p) /**< string descriptor */
 
   JERRY_ASSERT (string_p->refs_and_container >= ECMA_STRING_REF_ONE);
 
-  if (likely (string_p->refs_and_container < ECMA_STRING_MAX_REF))
+  if (JERRY_LIKELY (string_p->refs_and_container < ECMA_STRING_MAX_REF))
   {
     /* Increase reference counter. */
     string_p->refs_and_container = (uint16_t) (string_p->refs_and_container + ECMA_STRING_REF_ONE);
@@ -930,12 +929,6 @@ ecma_deref_ecma_string (ecma_string_t *string_p) /**< ecma-string */
       ecma_dealloc_string_buffer (string_p, string_p->u.long_utf8_string_size + sizeof (ecma_long_string_t));
       return;
     }
-    case ECMA_STRING_CONTAINER_UINT32_IN_DESC:
-    case ECMA_STRING_CONTAINER_MAGIC_STRING_EX:
-    {
-      /* only the string descriptor itself should be freed */
-      break;
-    }
     case ECMA_STRING_LITERAL_NUMBER:
     {
       ecma_free_value (string_p->u.lit_number);
@@ -943,7 +936,10 @@ ecma_deref_ecma_string (ecma_string_t *string_p) /**< ecma-string */
     }
     default:
     {
-      JERRY_UNREACHABLE ();
+      JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_UINT32_IN_DESC
+                    || ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);
+
+      /* only the string descriptor itself should be freed */
       break;
     }
   }
@@ -953,6 +949,8 @@ ecma_deref_ecma_string (ecma_string_t *string_p) /**< ecma-string */
 
 /**
  * Convert ecma-string to number
+ *
+ * @return converted ecma-number
  */
 ecma_number_t
 ecma_string_to_number (const ecma_string_t *string_p) /**< ecma-string */
@@ -990,7 +988,7 @@ ecma_string_to_number (const ecma_string_t *string_p) /**< ecma-string */
  * @return ECMA_STRING_NOT_ARRAY_INDEX if string is not array index
  *         the array index otherwise
  */
-inline uint32_t __attr_always_inline___
+inline uint32_t JERRY_ATTR_ALWAYS_INLINE
 ecma_string_get_array_index (const ecma_string_t *str_p) /**< ecma-string */
 {
   if (ECMA_IS_DIRECT_STRING (str_p))
@@ -1021,7 +1019,7 @@ ecma_string_get_array_index (const ecma_string_t *str_p) /**< ecma-string */
  *
  * @return number of bytes, actually copied to the buffer.
  */
-lit_utf8_size_t __attr_return_value_should_be_checked___
+lit_utf8_size_t JERRY_ATTR_WARN_UNUSED_RESULT
 ecma_string_copy_to_cesu8_buffer (const ecma_string_t *string_p, /**< ecma-string descriptor */
                                   lit_utf8_byte_t *buffer_p, /**< destination buffer pointer
                                                               * (can be NULL if buffer_size == 0) */
@@ -1071,7 +1069,7 @@ ecma_string_copy_to_cesu8_buffer (const ecma_string_t *string_p, /**< ecma-strin
  *
  * @return number of bytes, actually copied to the buffer.
  */
-lit_utf8_size_t __attr_return_value_should_be_checked___
+lit_utf8_size_t JERRY_ATTR_WARN_UNUSED_RESULT
 ecma_string_copy_to_utf8_buffer (const ecma_string_t *string_p, /**< ecma-string descriptor */
                                  lit_utf8_byte_t *buffer_p, /**< destination buffer pointer
                                                              * (can be NULL if buffer_size == 0) */
@@ -1227,7 +1225,7 @@ ecma_substring_copy_to_utf8_buffer (const ecma_string_t *string_desc_p, /**< ecm
                                     lit_utf8_size_t buffer_size) /**< size of buffer */
 {
   JERRY_ASSERT (string_desc_p != NULL);
-  JERRY_ASSERT (string_desc_p->refs_and_container >= ECMA_STRING_REF_ONE);
+  JERRY_ASSERT (ECMA_IS_DIRECT_STRING (string_desc_p) || string_desc_p->refs_and_container >= ECMA_STRING_REF_ONE);
   JERRY_ASSERT (buffer_p != NULL || buffer_size == 0);
 
   lit_utf8_size_t size = 0;
@@ -1347,7 +1345,7 @@ ecma_substring_copy_to_utf8_buffer (const ecma_string_t *string_desc_p, /**< ecm
  * It is the caller's responsibility to make sure that the string fits in the buffer.
  * Check if the size of the string is equal with the size of the buffer.
  */
-inline void __attr_always_inline___
+inline void JERRY_ATTR_ALWAYS_INLINE
 ecma_string_to_utf8_bytes (const ecma_string_t *string_desc_p, /**< ecma-string descriptor */
                            lit_utf8_byte_t *buffer_p, /**< destination buffer pointer
                                                        * (can be NULL if buffer_size == 0) */
@@ -1364,7 +1362,7 @@ ecma_string_to_utf8_bytes (const ecma_string_t *string_desc_p, /**< ecma-string
  *
  * @return size in bytes
  */
-static inline ecma_length_t __attr_always_inline___
+static inline ecma_length_t JERRY_ATTR_ALWAYS_INLINE
 ecma_string_get_uint32_size (const uint32_t uint32_number) /**< number in the string-descriptor */
 {
   uint32_t prev_number = 1;
@@ -1453,7 +1451,7 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
         result_p = lit_get_magic_string_ex_utf8 (id);
         length = 0;
 
-        if (unlikely (*flags_p & ECMA_STRING_FLAG_IS_ASCII))
+        if (JERRY_UNLIKELY (*flags_p & ECMA_STRING_FLAG_IS_ASCII))
         {
           length = lit_utf8_string_length (result_p, size);
         }
@@ -1500,7 +1498,7 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
         size = lit_get_magic_string_ex_size (string_p->u.magic_string_ex_id);
         length = 0;
 
-        if (unlikely (*flags_p & ECMA_STRING_FLAG_IS_ASCII))
+        if (JERRY_UNLIKELY (*flags_p & ECMA_STRING_FLAG_IS_ASCII))
         {
           length = lit_utf8_string_length (lit_get_magic_string_ex_utf8 (string_p->u.magic_string_ex_id), size);
         }
@@ -1512,12 +1510,10 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
   }
 
   *size_p = size;
-  if (*flags_p & ECMA_STRING_FLAG_IS_ASCII)
+  if ((*flags_p & ECMA_STRING_FLAG_IS_ASCII)
+      && length != size)
   {
-    if (length != size)
-    {
-      *flags_p = (uint8_t) (*flags_p & ~ECMA_STRING_FLAG_IS_ASCII);
-    }
+    *flags_p = (uint8_t) (*flags_p & ~ECMA_STRING_FLAG_IS_ASCII);
   }
 
   return result_p;
@@ -1529,7 +1525,7 @@ ecma_string_get_chars (const ecma_string_t *string_p, /**< ecma-string */
  * @return true - if the string equals to the magic string id
  *         false - otherwise
  */
-inline bool __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_compare_ecma_string_to_magic_id (const ecma_string_t *string_p, /**< property name */
                                       lit_magic_string_id_t id) /**< magic string id */
 {
@@ -1542,7 +1538,7 @@ ecma_compare_ecma_string_to_magic_id (const ecma_string_t *string_p, /**< proper
  * @return true - if the string is an empty string
  *         false - otherwise
  */
-inline bool __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_string_is_empty (const ecma_string_t *string_p) /**< ecma-string */
 {
   return ecma_compare_ecma_string_to_magic_id (string_p, LIT_MAGIC_STRING__EMPTY);
@@ -1554,14 +1550,18 @@ ecma_string_is_empty (const ecma_string_t *string_p) /**< ecma-string */
  * @return true - if the string equals to "length"
  *         false - otherwise
  */
-inline bool __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_string_is_length (const ecma_string_t *string_p) /**< property name */
 {
   return ecma_compare_ecma_string_to_magic_id (string_p, LIT_MAGIC_STRING_LENGTH);
 } /* ecma_string_is_length */
 
-
-static inline ecma_string_t * __attr_always_inline___
+/**
+ * Converts a property name into a string
+ *
+ * @return pointer to the converted ecma string
+ */
+static inline ecma_string_t * JERRY_ATTR_ALWAYS_INLINE
 ecma_property_to_string (ecma_property_t property, /**< property name type */
                          jmem_cpointer_t prop_name_cp) /**< property name compressed pointer */
 {
@@ -1575,7 +1575,7 @@ ecma_property_to_string (ecma_property_t property, /**< property name type */
  *
  * @return the compressed pointer part of the name
  */
-inline jmem_cpointer_t __attr_always_inline___
+inline jmem_cpointer_t JERRY_ATTR_ALWAYS_INLINE
 ecma_string_to_property_name (ecma_string_t *prop_name_p, /**< property name */
                               ecma_property_t *name_type_p) /**< [out] property name type */
 {
@@ -1619,7 +1619,7 @@ ecma_string_from_property_name (ecma_property_t property, /**< property name typ
  *
  * @return hash code of property name
  */
-inline lit_string_hash_t __attr_always_inline___
+inline lit_string_hash_t JERRY_ATTR_ALWAYS_INLINE
 ecma_string_get_property_name_hash (ecma_property_t property, /**< property name type */
                                     jmem_cpointer_t prop_name_cp) /**< property name compressed pointer */
 {
@@ -1675,7 +1675,7 @@ ecma_string_get_property_index (ecma_property_t property, /**< property name typ
  * @return true if they are equals
  *         false otherwise
  */
-inline bool __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_string_compare_to_property_name (ecma_property_t property, /**< property name type */
                                       jmem_cpointer_t prop_name_cp, /**< property name compressed pointer */
                                       const ecma_string_t *string_p) /**< other string */
@@ -1703,7 +1703,7 @@ ecma_string_compare_to_property_name (ecma_property_t property, /**< property na
  * @return true - if strings are equal;
  *         false - otherwise
  */
-static bool __attr_noinline___
+static bool JERRY_ATTR_NOINLINE
 ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /**< ecma-string */
                                     const ecma_string_t *string2_p) /**< ecma-string */
 {
@@ -1743,7 +1743,7 @@ ecma_compare_ecma_strings_longpath (const ecma_string_t *string1_p, /**< ecma-st
  * @return true - if strings are equal;
  *         false - otherwise
  */
-inline bool __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_compare_ecma_strings (const ecma_string_t *string1_p, /**< ecma-string */
                            const ecma_string_t *string2_p) /**< ecma-string */
 {
@@ -1787,7 +1787,7 @@ ecma_compare_ecma_strings (const ecma_string_t *string1_p, /**< ecma-string */
  * @return true - if strings are equal;
  *         false - otherwise
  */
-inline bool __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_compare_ecma_non_direct_strings (const ecma_string_t *string1_p, /**< ecma-string */
                                       const ecma_string_t *string2_p) /**< ecma-string */
 {
@@ -1914,7 +1914,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
                                               utf8_string2_size);
 } /* ecma_compare_ecma_strings_relational */
 
-/*
+/**
  * Special value to represent that no size is available.
  */
 #define ECMA_STRING_NO_ASCII_SIZE 0xffff
@@ -2052,7 +2052,7 @@ ecma_string_get_utf8_length (const ecma_string_t *string_p) /**< ecma-string */
         return (ecma_length_t) (long_string_p->long_utf8_string_length);
       }
 
-      return lit_get_utf8_length_of_cesu8_string ((const lit_utf8_byte_t *) (string_p + 1),
+      return lit_get_utf8_length_of_cesu8_string ((const lit_utf8_byte_t *) (long_string_p + 1),
                                                   (lit_utf8_size_t) string_p->u.long_utf8_string_size);
     }
     default:
@@ -2101,6 +2101,7 @@ ecma_string_get_size (const ecma_string_t *string_p) /**< ecma-string */
     default:
     {
       JERRY_ASSERT (ECMA_STRING_GET_CONTAINER (string_p) == ECMA_STRING_CONTAINER_MAGIC_STRING_EX);
+
       return lit_get_magic_string_ex_size (string_p->u.magic_string_ex_id);
     }
   }
@@ -2219,7 +2220,7 @@ ecma_get_string_magic (const ecma_string_t *string_p) /**< ecma-string */
  *
  * @return calculated hash
  */
-inline lit_string_hash_t __attr_always_inline___
+inline lit_string_hash_t JERRY_ATTR_ALWAYS_INLINE
 ecma_string_hash (const ecma_string_t *string_p) /**< ecma-string to calculate hash for */
 {
   if (!ECMA_IS_DIRECT_STRING (string_p))
index ae596e03bbc27010e5eefc18139868a50a691d0e..1235cac25e7f892024e8e2100319224f5749965e 100644 (file)
 
 #include "ecma-function-object.h"
 
-/** \addtogroup ecma ECMA
- * @{
- *
- * \addtogroup ecmahelpers Helpers for operations with ECMA data types
- * @{
- */
-
 JERRY_STATIC_ASSERT (ECMA_TYPE___MAX <= ECMA_VALUE_TYPE_MASK,
                      ecma_types_must_be_less_than_mask);
 
@@ -58,12 +51,19 @@ JERRY_STATIC_ASSERT ((ECMA_VALUE_FALSE | (1 << ECMA_DIRECT_SHIFT)) == ECMA_VALUE
                      && ECMA_VALUE_FALSE != ECMA_VALUE_TRUE,
                      only_the_lowest_bit_must_be_different_for_simple_value_true_and_false);
 
+/** \addtogroup ecma ECMA
+ * @{
+ *
+ * \addtogroup ecmahelpers Helpers for operations with ECMA data types
+ * @{
+ */
+
 /**
  * Get type field of ecma value
  *
  * @return type field
  */
-static inline ecma_type_t __attr_const___ __attr_always_inline___
+static inline ecma_type_t JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_get_value_type_field (ecma_value_t value) /**< ecma value */
 {
   return value & ECMA_VALUE_TYPE_MASK;
@@ -74,7 +74,7 @@ ecma_get_value_type_field (ecma_value_t value) /**< ecma value */
  *
  * @return ecma value
  */
-static inline ecma_value_t __attr_pure___ __attr_always_inline___
+static inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
 ecma_pointer_to_ecma_value (const void *ptr) /**< pointer */
 {
 #ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
@@ -98,7 +98,7 @@ ecma_pointer_to_ecma_value (const void *ptr) /**< pointer */
  *
  * @return pointer
  */
-static inline void * __attr_pure___ __attr_always_inline___
+static inline void * JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
 ecma_get_pointer_from_ecma_value (ecma_value_t value) /**< value */
 {
 #ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
@@ -116,7 +116,7 @@ ecma_get_pointer_from_ecma_value (ecma_value_t value) /**< value */
  * @return true - if the value is a direct value,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_direct (ecma_value_t value) /**< ecma value */
 {
   return (ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT);
@@ -128,7 +128,7 @@ ecma_is_value_direct (ecma_value_t value) /**< ecma value */
  * @return true - if the value is a simple value,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_simple (ecma_value_t value) /**< ecma value */
 {
   return (value & ECMA_DIRECT_TYPE_MASK) == ECMA_DIRECT_TYPE_SIMPLE_VALUE;
@@ -140,7 +140,7 @@ ecma_is_value_simple (ecma_value_t value) /**< ecma value */
  * @return true - if the value is equal to the given simple value,
  *         false - otherwise
  */
-static inline bool __attr_const___ __attr_always_inline___
+static inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_equal_to_simple_value (ecma_value_t value, /**< ecma value */
                                      ecma_value_t simple_value) /**< simple value */
 {
@@ -153,7 +153,7 @@ ecma_is_value_equal_to_simple_value (ecma_value_t value, /**< ecma value */
  * @return true - if the value contains implementation-defined empty simple value,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_empty (ecma_value_t value) /**< ecma value */
 {
   return ecma_is_value_equal_to_simple_value (value, ECMA_VALUE_EMPTY);
@@ -165,7 +165,7 @@ ecma_is_value_empty (ecma_value_t value) /**< ecma value */
  * @return true - if the value contains ecma-undefined simple value,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_undefined (ecma_value_t value) /**< ecma value */
 {
   return ecma_is_value_equal_to_simple_value (value, ECMA_VALUE_UNDEFINED);
@@ -177,7 +177,7 @@ ecma_is_value_undefined (ecma_value_t value) /**< ecma value */
  * @return true - if the value contains ecma-null simple value,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_null (ecma_value_t value) /**< ecma value */
 {
   return ecma_is_value_equal_to_simple_value (value, ECMA_VALUE_NULL);
@@ -189,7 +189,7 @@ ecma_is_value_null (ecma_value_t value) /**< ecma value */
  * @return true - if the value contains ecma-true or ecma-false simple values,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_boolean (ecma_value_t value) /**< ecma value */
 {
   return ecma_is_value_true (value | (1 << ECMA_DIRECT_SHIFT));
@@ -201,7 +201,7 @@ ecma_is_value_boolean (ecma_value_t value) /**< ecma value */
  * @return true - if the value contains ecma-true simple value,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_true (ecma_value_t value) /**< ecma value */
 {
   return ecma_is_value_equal_to_simple_value (value, ECMA_VALUE_TRUE);
@@ -213,7 +213,7 @@ ecma_is_value_true (ecma_value_t value) /**< ecma value */
  * @return true - if the value contains ecma-false simple value,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_false (ecma_value_t value) /**< ecma value */
 {
   return ecma_is_value_equal_to_simple_value (value, ECMA_VALUE_FALSE);
@@ -225,7 +225,7 @@ ecma_is_value_false (ecma_value_t value) /**< ecma value */
  * @return true - if the value contains ecma-not-found simple value,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_found (ecma_value_t value) /**< ecma value */
 {
   return value != ECMA_VALUE_NOT_FOUND;
@@ -237,7 +237,7 @@ ecma_is_value_found (ecma_value_t value) /**< ecma value */
  * @return true - if the value contains ecma-array-hole simple value,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_array_hole (ecma_value_t value) /**< ecma value */
 {
   return ecma_is_value_equal_to_simple_value (value, ECMA_VALUE_ARRAY_HOLE);
@@ -249,7 +249,7 @@ ecma_is_value_array_hole (ecma_value_t value) /**< ecma value */
  * @return true - if the value contains an integer ecma-number value,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_integer_number (ecma_value_t value) /**< ecma value */
 {
   return (value & ECMA_DIRECT_TYPE_MASK) == ECMA_DIRECT_TYPE_INTEGER_VALUE;
@@ -261,7 +261,7 @@ ecma_is_value_integer_number (ecma_value_t value) /**< ecma value */
  * @return true - if both values contain integer ecma-number values,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_are_values_integer_numbers (ecma_value_t first_value, /**< first ecma value */
                                  ecma_value_t second_value) /**< second ecma value */
 {
@@ -277,7 +277,7 @@ ecma_are_values_integer_numbers (ecma_value_t first_value, /**< first ecma value
  * @return true - if the value contains a floating-point ecma-number value,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_float_number (ecma_value_t value) /**< ecma value */
 {
   return (ecma_get_value_type_field (value) == ECMA_TYPE_FLOAT);
@@ -289,7 +289,7 @@ ecma_is_value_float_number (ecma_value_t value) /**< ecma value */
  * @return true - if the value contains ecma-number value,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_number (ecma_value_t value) /**< ecma value */
 {
   return (ecma_is_value_integer_number (value)
@@ -305,31 +305,43 @@ JERRY_STATIC_ASSERT ((ECMA_TYPE_STRING | 0x4) == ECMA_TYPE_DIRECT_STRING,
  * @return true - if the value contains ecma-string value,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_string (ecma_value_t value) /**< ecma value */
 {
   return ((value & (ECMA_VALUE_TYPE_MASK - 0x4)) == ECMA_TYPE_STRING);
 } /* ecma_is_value_string */
 
 /**
- * Check if the value is direct_ecma-string.
+ * Check if the value is direct ecma-string.
  *
- * @return true - if the value contains ecma-string value,
+ * @return true - if the value contains direct ecma-string value,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_direct_string (ecma_value_t value) /**< ecma value */
 {
   return (ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT_STRING);
 } /* ecma_is_value_direct_string */
 
+/**
+ * Check if the value is non-direct ecma-string.
+ *
+ * @return true - if the value contains non-direct ecma-string value,
+ *         false - otherwise
+ */
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
+ecma_is_value_non_direct_string (ecma_value_t value) /**< ecma value */
+{
+  return (ecma_get_value_type_field (value) == ECMA_TYPE_STRING);
+} /* ecma_is_value_non_direct_string */
+
 /**
  * Check if the value is object.
  *
  * @return true - if the value contains object value,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_object (ecma_value_t value) /**< ecma value */
 {
   return (ecma_get_value_type_field (value) == ECMA_TYPE_OBJECT);
@@ -341,23 +353,23 @@ ecma_is_value_object (ecma_value_t value) /**< ecma value */
  * @return true - if the value contains an error reference,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_value_error_reference (ecma_value_t value) /**< ecma value */
 {
   return (ecma_get_value_type_field (value) == ECMA_TYPE_ERROR);
 } /* ecma_is_value_error_reference */
 
 /**
- * Check if the value is collection chunk.
+ * Check if the value is an aligned pointer.
  *
- * @return true - if the value contains a collection chunk,
+ * @return true - if the value contains an aligned pointer,
  *         false - otherwise
  */
-inline bool __attr_const___ __attr_always_inline___
-ecma_is_value_collection_chunk (ecma_value_t value) /**< ecma value */
+inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
+ecma_is_value_pointer (ecma_value_t value) /**< ecma value */
 {
-  return (ecma_get_value_type_field (value) == ECMA_TYPE_COLLECTION_CHUNK);
-} /* ecma_is_value_collection_chunk */
+  return (ecma_get_value_type_field (value) == ECMA_TYPE_POINTER);
+} /* ecma_is_value_pointer */
 
 /**
  * Debug assertion that specified value's type is one of ECMA-defined
@@ -379,7 +391,7 @@ ecma_check_value_type_is_spec_defined (ecma_value_t value) /**< ecma value */
  *
  * @return boolean ecma_value
  */
-inline ecma_value_t __attr_const___ __attr_always_inline___
+inline ecma_value_t JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_make_boolean_value (bool boolean_value) /**< raw bool value from which the ecma value will be created */
 {
   return boolean_value ? ECMA_VALUE_TRUE : ECMA_VALUE_FALSE;
@@ -393,7 +405,7 @@ ecma_make_boolean_value (bool boolean_value) /**< raw bool value from which the
  *
  * @return ecma-value
  */
-inline ecma_value_t __attr_const___ __attr_always_inline___
+inline ecma_value_t JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_make_integer_value (ecma_integer_value_t integer_value) /**< integer number to be encoded */
 {
   JERRY_ASSERT (ECMA_IS_INTEGER_NUMBER (integer_value));
@@ -421,7 +433,7 @@ ecma_create_float_number (ecma_number_t ecma_number) /**< value of the float num
  *
  * @return ecma-value
  */
-inline ecma_value_t __attr_always_inline___
+inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
 ecma_make_nan_value (void)
 {
   return ecma_create_float_number (ecma_number_make_nan ());
@@ -432,7 +444,7 @@ ecma_make_nan_value (void)
  *
  * @return true, if it is +0.0, false otherwise
  */
-static inline bool __attr_const___ __attr_always_inline___
+static inline bool JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_is_number_equal_to_positive_zero (ecma_number_t ecma_number) /**< number */
 {
 #if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32
@@ -512,8 +524,10 @@ ecma_make_uint32_value (uint32_t uint32_number) /**< uint32 number to be encoded
 
 /**
  * String value constructor
+ *
+ * @return ecma-value representation of the string argument
  */
-inline ecma_value_t __attr_pure___ __attr_always_inline___
+inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
 ecma_make_string_value (const ecma_string_t *ecma_string_p) /**< string to reference in value */
 {
   JERRY_ASSERT (ecma_string_p != NULL);
@@ -528,8 +542,10 @@ ecma_make_string_value (const ecma_string_t *ecma_string_p) /**< string to refer
 
 /**
  * String value constructor
+ *
+ * @return ecma-value representation of the string argument
  */
-inline ecma_value_t __attr_pure___ __attr_always_inline___
+inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
 ecma_make_magic_string_value (lit_magic_string_id_t id) /**< magic string id */
 {
   return (ecma_value_t) ECMA_CREATE_DIRECT_STRING (ECMA_DIRECT_STRING_MAGIC, (uintptr_t) id);
@@ -537,8 +553,10 @@ ecma_make_magic_string_value (lit_magic_string_id_t id) /**< magic string id */
 
 /**
  * Object value constructor
+ *
+ * @return ecma-value representation of the object argument
  */
-inline ecma_value_t __attr_pure___ __attr_always_inline___
+inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
 ecma_make_object_value (const ecma_object_t *object_p) /**< object to reference in value */
 {
   JERRY_ASSERT (object_p != NULL);
@@ -548,8 +566,10 @@ ecma_make_object_value (const ecma_object_t *object_p) /**< object to reference
 
 /**
  * Error reference constructor
+ *
+ * @return ecma-value representation of the Error reference
  */
-inline ecma_value_t __attr_pure___ __attr_always_inline___
+inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
 ecma_make_error_reference_value (const ecma_error_reference_t *error_ref_p) /**< error reference */
 {
   JERRY_ASSERT (error_ref_p != NULL);
@@ -558,32 +578,34 @@ ecma_make_error_reference_value (const ecma_error_reference_t *error_ref_p) /**<
 } /* ecma_make_error_reference_value */
 
 /**
- * Collection chunk constructor
+ * Create an ecma value from an aligned pointer
+ *
+ * @return ecma-value representation of the aligned pointer
  */
-inline ecma_value_t __attr_pure___ __attr_always_inline___
-ecma_make_collection_chunk_value (const ecma_collection_chunk_t *collection_chunk_p) /**< collection chunk */
+inline ecma_value_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
+ecma_make_pointer_value (const void *any_p) /**< any aligned pointer */
 {
 #ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
 
-  uintptr_t uint_ptr = (uintptr_t) collection_chunk_p;
+  uintptr_t uint_ptr = (uintptr_t) any_p;
   JERRY_ASSERT ((uint_ptr & ECMA_VALUE_TYPE_MASK) == 0);
-  return ((ecma_value_t) uint_ptr) | ECMA_TYPE_COLLECTION_CHUNK;
+  return ((ecma_value_t) uint_ptr) | ECMA_TYPE_POINTER;
 
 #else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
 
   jmem_cpointer_t ptr_cp;
-  ECMA_SET_POINTER (ptr_cp, collection_chunk_p);
-  return (((ecma_value_t) ptr_cp) << ECMA_VALUE_SHIFT) | ECMA_TYPE_COLLECTION_CHUNK;
+  ECMA_SET_POINTER (ptr_cp, any_p);
+  return (((ecma_value_t) ptr_cp) << ECMA_VALUE_SHIFT) | ECMA_TYPE_POINTER;
 
 #endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
-} /* ecma_make_collection_chunk_value */
+} /* ecma_make_pointer_value */
 
 /**
  * Get integer value from an integer ecma value
  *
- * @return floating point value
+ * @return integer value
  */
-inline ecma_integer_value_t __attr_const___ __attr_always_inline___
+inline ecma_integer_value_t JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_get_integer_from_value (ecma_value_t value) /**< ecma value */
 {
   JERRY_ASSERT (ecma_is_value_integer_number (value));
@@ -591,7 +613,12 @@ ecma_get_integer_from_value (ecma_value_t value) /**< ecma value */
   return ((ecma_integer_value_t) value) >> ECMA_DIRECT_SHIFT;
 } /* ecma_get_integer_from_value */
 
-inline ecma_number_t __attr_pure___ __attr_always_inline___
+/**
+ * Get floating point value from an ecma value
+ *
+ * @return floating point value
+ */
+inline ecma_number_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
 ecma_get_float_from_value (ecma_value_t value) /**< ecma value */
 {
   JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_FLOAT);
@@ -604,7 +631,7 @@ ecma_get_float_from_value (ecma_value_t value) /**< ecma value */
  *
  * @return floating point value
  */
-ecma_number_t __attr_pure___
+ecma_number_t JERRY_ATTR_PURE
 ecma_get_number_from_value (ecma_value_t value) /**< ecma value */
 {
   if (ecma_is_value_integer_number (value))
@@ -618,9 +645,9 @@ ecma_get_number_from_value (ecma_value_t value) /**< ecma value */
 /**
  * Get pointer to ecma-string from ecma value
  *
- * @return the pointer
+ * @return the string pointer
  */
-inline ecma_string_t *__attr_pure___ __attr_always_inline___
+inline ecma_string_t *JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
 ecma_get_string_from_value (ecma_value_t value) /**< ecma value */
 {
   JERRY_ASSERT (ecma_is_value_string (value));
@@ -638,7 +665,7 @@ ecma_get_string_from_value (ecma_value_t value) /**< ecma value */
  *
  * @return the pointer
  */
-inline ecma_object_t *__attr_pure___ __attr_always_inline___
+inline ecma_object_t *JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
 ecma_get_object_from_value (ecma_value_t value) /**< ecma value */
 {
   JERRY_ASSERT (ecma_is_value_object (value));
@@ -651,7 +678,7 @@ ecma_get_object_from_value (ecma_value_t value) /**< ecma value */
  *
  * @return the pointer
  */
-inline ecma_error_reference_t *__attr_pure___ __attr_always_inline___
+inline ecma_error_reference_t *JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
 ecma_get_error_reference_from_value (ecma_value_t value) /**< ecma value */
 {
   JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_ERROR);
@@ -660,28 +687,28 @@ ecma_get_error_reference_from_value (ecma_value_t value) /**< ecma value */
 } /* ecma_get_error_reference_from_value */
 
 /**
- * Get pointer to collection chunk from ecma value
+ * Get an aligned pointer from an ecma value
  *
- * @return the pointer
+ * @return pointer value
  */
-inline ecma_collection_chunk_t *__attr_pure___ __attr_always_inline___
-ecma_get_collection_chunk_from_value (ecma_value_t value) /**< ecma value */
+inline void * JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
+ecma_get_pointer_from_value (ecma_value_t value) /**< ecma value */
 {
-  JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_COLLECTION_CHUNK);
+  JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_POINTER);
 
 #ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
-  return (ecma_collection_chunk_t *) (uintptr_t) ((value) & ~ECMA_VALUE_TYPE_MASK);
+  return (void *) (uintptr_t) ((value) & ~ECMA_VALUE_TYPE_MASK);
 #else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
-  return ECMA_GET_POINTER (ecma_collection_chunk_t, value >> ECMA_VALUE_SHIFT);
+  return ECMA_GET_POINTER (void, value >> ECMA_VALUE_SHIFT);
 #endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
-} /* ecma_get_collection_chunk_from_value */
+} /* ecma_get_pointer_from_value */
 
 /**
  * Invert a boolean value
  *
  * @return ecma value
  */
-inline ecma_value_t __attr_const___ __attr_always_inline___
+inline ecma_value_t JERRY_ATTR_CONST JERRY_ATTR_ALWAYS_INLINE
 ecma_invert_boolean_value (ecma_value_t value) /**< ecma value */
 {
   JERRY_ASSERT (ecma_is_value_boolean (value));
@@ -699,11 +726,6 @@ ecma_copy_value (ecma_value_t value)  /**< value description */
 {
   switch (ecma_get_value_type_field (value))
   {
-    case ECMA_TYPE_DIRECT:
-    case ECMA_TYPE_DIRECT_STRING:
-    {
-      return value;
-    }
     case ECMA_TYPE_FLOAT:
     {
       ecma_number_t *num_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (value);
@@ -722,8 +744,10 @@ ecma_copy_value (ecma_value_t value)  /**< value description */
     }
     default:
     {
-      JERRY_UNREACHABLE ();
-      return ECMA_VALUE_UNDEFINED;
+      JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT
+                    || ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT_STRING);
+
+      return value;
     }
   }
 } /* ecma_copy_value */
@@ -739,7 +763,7 @@ ecma_copy_value (ecma_value_t value)  /**< value description */
  *
  * @return copy of the given value
  */
-inline ecma_value_t __attr_always_inline___
+inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
 ecma_fast_copy_value (ecma_value_t value)  /**< value description */
 {
   return (ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT) ? value : ecma_copy_value (value);
@@ -890,13 +914,6 @@ ecma_free_value (ecma_value_t value) /**< value description */
 {
   switch (ecma_get_value_type_field (value))
   {
-    case ECMA_TYPE_DIRECT:
-    case ECMA_TYPE_DIRECT_STRING:
-    {
-      /* no memory is allocated */
-      break;
-    }
-
     case ECMA_TYPE_FLOAT:
     {
       ecma_number_t *number_p = (ecma_number_t *) ecma_get_pointer_from_ecma_value (value);
@@ -919,7 +936,10 @@ ecma_free_value (ecma_value_t value) /**< value description */
 
     default:
     {
-      JERRY_UNREACHABLE ();
+      JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT
+                    || ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT_STRING);
+
+      /* no memory is allocated */
       break;
     }
   }
@@ -934,7 +954,7 @@ ecma_free_value (ecma_value_t value) /**< value description */
  *   It also increases the binary size so it is recommended for
  *   critical code paths only.
  */
-inline void __attr_always_inline___
+inline void JERRY_ATTR_ALWAYS_INLINE
 ecma_fast_free_value (ecma_value_t value) /**< value description */
 {
   if (ecma_get_value_type_field (value) != ECMA_TYPE_DIRECT)
index c4739911a3bd1dc98ab6396dd5da0fb183d0b9a7..30bfdbbf76e690abaa17af4deedb03193597f946 100644 (file)
@@ -28,8 +28,8 @@
 /**
  * The type of ecma error and ecma collection chunk must be the same.
  */
-JERRY_STATIC_ASSERT (ECMA_TYPE_ERROR == ECMA_TYPE_COLLECTION_CHUNK,
-                     ecma_type_error_must_be_the_same_as_ecma_type_collection_chunk);
+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.
@@ -70,7 +70,7 @@ ecma_free_values_collection (ecma_collection_header_t *header_p, /**< collection
   {
     ecma_value_t *item_p = chunk_p->items;
 
-    JERRY_ASSERT (!ecma_is_value_collection_chunk (*item_p));
+    JERRY_ASSERT (!ecma_is_value_pointer (*item_p));
 
     do
     {
@@ -83,9 +83,9 @@ ecma_free_values_collection (ecma_collection_header_t *header_p, /**< collection
 
       item_p++;
     }
-    while (!ecma_is_value_collection_chunk (*item_p));
+    while (!ecma_is_value_pointer (*item_p));
 
-    ecma_collection_chunk_t *next_chunk_p = ecma_get_collection_chunk_from_value (*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));
 
@@ -105,7 +105,7 @@ ecma_append_to_values_collection (ecma_collection_header_t *header_p, /**< colle
   ecma_length_t item_index;
   ecma_collection_chunk_t *chunk_p;
 
-  if (unlikely (header_p->item_count == 0))
+  if (JERRY_UNLIKELY (header_p->item_count == 0))
   {
     item_index = 0;
     chunk_p = (ecma_collection_chunk_t *) jmem_heap_alloc_block (sizeof (ecma_collection_chunk_t));
@@ -120,23 +120,23 @@ ecma_append_to_values_collection (ecma_collection_header_t *header_p, /**< colle
     chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_chunk_t,
                                          header_p->last_chunk_cp);
 
-    if (unlikely (item_index == 0))
+    if (JERRY_UNLIKELY (item_index == 0))
     {
-      JERRY_ASSERT (ecma_is_value_collection_chunk (chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS])
-                    && ecma_get_collection_chunk_from_value (chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS]) == NULL);
+      JERRY_ASSERT (ecma_is_value_pointer (chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS])
+                    && ecma_get_pointer_from_value (chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS]) == NULL);
 
       ecma_collection_chunk_t *next_chunk_p;
       next_chunk_p = (ecma_collection_chunk_t *) jmem_heap_alloc_block (sizeof (ecma_collection_chunk_t));
 
-      chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS] = ecma_make_collection_chunk_value (next_chunk_p);
+      chunk_p->items[ECMA_COLLECTION_CHUNK_ITEMS] = ecma_make_pointer_value ((void *) next_chunk_p);
       ECMA_SET_POINTER (header_p->last_chunk_cp, next_chunk_p);
 
       chunk_p = next_chunk_p;
     }
     else
     {
-      JERRY_ASSERT (ecma_is_value_collection_chunk (chunk_p->items[item_index])
-                    && ecma_get_collection_chunk_from_value (chunk_p->items[item_index]) == NULL);
+      JERRY_ASSERT (ecma_is_value_pointer (chunk_p->items[item_index])
+                    && ecma_get_pointer_from_value (chunk_p->items[item_index]) == NULL);
     }
   }
 
@@ -148,7 +148,7 @@ ecma_append_to_values_collection (ecma_collection_header_t *header_p, /**< colle
   }
 
   chunk_p->items[item_index] = value;
-  chunk_p->items[item_index + 1] = ecma_make_collection_chunk_value (NULL);
+  chunk_p->items[item_index + 1] = ecma_make_pointer_value (NULL);
   header_p->item_count++;
 } /* ecma_append_to_values_collection */
 
@@ -160,7 +160,7 @@ ecma_append_to_values_collection (ecma_collection_header_t *header_p, /**< colle
 ecma_value_t *
 ecma_collection_iterator_init (ecma_collection_header_t *header_p) /**< header of collection */
 {
-  if (unlikely (!header_p || header_p->item_count == 0))
+  if (JERRY_UNLIKELY (!header_p || header_p->item_count == 0))
   {
     return NULL;
   }
@@ -183,11 +183,11 @@ ecma_collection_iterator_next (ecma_value_t *ecma_value_p) /**< current value */
 
   ecma_value_p++;
 
-  if (unlikely (ecma_is_value_collection_chunk (*ecma_value_p)))
+  if (JERRY_UNLIKELY (ecma_is_value_pointer (*ecma_value_p)))
   {
-    ecma_value_p = ecma_get_collection_chunk_from_value (*ecma_value_p)->items;
+    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_collection_chunk (*ecma_value_p));
+    JERRY_ASSERT (ecma_value_p == NULL || !ecma_is_value_pointer (*ecma_value_p));
     return ecma_value_p;
   }
 
index 3272f944ce99440976ad1d10ba28255e79509fb9..0da3bc22d2a90572d1a81dfada0d9a73ec9f82b7 100644 (file)
@@ -60,9 +60,6 @@ JERRY_STATIC_ASSERT ((ECMA_OBJECT_MAX_REF | (ECMA_OBJECT_REF_ONE - 1)) == UINT16
 JERRY_STATIC_ASSERT (ECMA_PROPERTY_TYPE_DELETED == (ECMA_DIRECT_STRING_MAGIC << ECMA_PROPERTY_NAME_TYPE_SHIFT),
                      ecma_property_type_deleted_must_have_magic_string_name_type);
 
-JERRY_STATIC_ASSERT (ECMA_PROPERTY_DELETED_NAME >= LIT_MAGIC_STRING__COUNT,
-                     ecma_property_deleted_name_must_not_be_valid_maigc_string_id);
-
 /**
  * Create an object with specified prototype object
  * (or NULL prototype if there is not prototype for the object)
@@ -130,7 +127,7 @@ ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p) /**< outer
 
 /**
  * Create a object lexical environment with specified outer lexical environment
- * (or NULL if the environment is not nested), binding object and provideThis flag.
+ * (or NULL if the environment is not nested), binding object and provided type flag.
  *
  * See also: ECMA-262 v5, 10.2.1.2
  *
@@ -141,25 +138,21 @@ ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p) /**< outer
 ecma_object_t *
 ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, /**< outer lexical environment */
                             ecma_object_t *binding_obj_p, /**< binding object */
-                            bool provide_this) /**< provideThis flag */
+                            ecma_lexical_environment_type_t type) /**< type of the new lexical environment */
 {
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  JERRY_ASSERT (type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND
+                || type == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND);
+#else /* CONFIG_DISABLE_ES2015_CLASS */
+  JERRY_ASSERT (type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
   JERRY_ASSERT (binding_obj_p != NULL
                 && !ecma_is_lexical_environment (binding_obj_p));
 
   ecma_object_t *new_lexical_environment_p = ecma_alloc_object ();
 
-  uint16_t type;
-
-  if (provide_this)
-  {
-    type = ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV | ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND;
-  }
-  else
-  {
-    type = ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV | ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND;
-  }
-
-  new_lexical_environment_p->type_flags_refs = type;
+  new_lexical_environment_p->type_flags_refs = (uint16_t) (ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV | type);
 
   ecma_init_gc_info (new_lexical_environment_p);
 
@@ -174,8 +167,11 @@ ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, /**< out
 
 /**
  * Check if the object is lexical environment.
+ *
+ * @return true  - if object is a lexical environment
+ *         false - otherwise
  */
-inline bool __attr_pure___
+inline bool JERRY_ATTR_PURE
 ecma_is_lexical_environment (const ecma_object_t *object_p) /**< object or lexical environment */
 {
   JERRY_ASSERT (object_p != NULL);
@@ -187,8 +183,11 @@ ecma_is_lexical_environment (const ecma_object_t *object_p) /**< object or lexic
 
 /**
  * Get value of [[Extensible]] object's internal property.
+ *
+ * @return true  - if object is extensible
+ *         false - otherwise
  */
-inline bool __attr_pure___
+inline bool JERRY_ATTR_PURE
 ecma_get_object_extensible (const ecma_object_t *object_p) /**< object */
 {
   JERRY_ASSERT (object_p != NULL);
@@ -219,8 +218,10 @@ ecma_set_object_extensible (ecma_object_t *object_p, /**< object */
 
 /**
  * Get object's internal implementation-defined type.
+ *
+ * @return type of the object (ecma_object_type_t)
  */
-inline ecma_object_type_t __attr_pure___
+inline ecma_object_type_t JERRY_ATTR_PURE
 ecma_get_object_type (const ecma_object_t *object_p) /**< object */
 {
   JERRY_ASSERT (object_p != NULL);
@@ -231,8 +232,11 @@ ecma_get_object_type (const ecma_object_t *object_p) /**< object */
 
 /**
  * Get object's prototype.
+ *
+ * @return pointer to the prototype object
+ *         NULL if there is no prototype
  */
-inline ecma_object_t *__attr_pure___
+inline ecma_object_t *JERRY_ATTR_PURE
 ecma_get_object_prototype (const ecma_object_t *object_p) /**< object */
 {
   JERRY_ASSERT (object_p != NULL);
@@ -245,9 +249,10 @@ ecma_get_object_prototype (const ecma_object_t *object_p) /**< object */
 /**
  * Check if the object is a built-in object
  *
- * @return true / false
+ * @return true  - if object is a built-in object
+ *         false - otherwise
  */
-inline bool __attr_pure___
+inline bool JERRY_ATTR_PURE
 ecma_get_object_is_builtin (const ecma_object_t *object_p) /**< object */
 {
   JERRY_ASSERT (object_p != NULL);
@@ -270,8 +275,10 @@ ecma_set_object_is_builtin (ecma_object_t *object_p) /**< object */
 } /* ecma_set_object_is_builtin */
 
 /**
- * Get the builtin id of the object.
+ * Get the built-in ID of the object.
  * If the object is not builtin, return ECMA_BUILTIN_ID__COUNT
+ *
+ * @return the ID of the built-in
  */
 inline uint8_t
 ecma_get_object_builtin_id (ecma_object_t *object_p) /**< object */
@@ -298,8 +305,10 @@ ecma_get_object_builtin_id (ecma_object_t *object_p) /**< object */
 
 /**
  * Get type of lexical environment.
+ *
+ * @return type of the lexical environment (ecma_lexical_environment_type_t)
  */
-inline ecma_lexical_environment_type_t __attr_pure___
+inline ecma_lexical_environment_type_t JERRY_ATTR_PURE
 ecma_get_lex_env_type (const ecma_object_t *object_p) /**< lexical environment */
 {
   JERRY_ASSERT (object_p != NULL);
@@ -310,8 +319,10 @@ ecma_get_lex_env_type (const ecma_object_t *object_p) /**< lexical environment *
 
 /**
  * Get outer reference of lexical environment.
+ *
+ * @return pointer to the outer reference
  */
-inline ecma_object_t *__attr_pure___
+inline ecma_object_t *JERRY_ATTR_PURE
 ecma_get_lex_env_outer_reference (const ecma_object_t *object_p) /**< lexical environment */
 {
   JERRY_ASSERT (object_p != NULL);
@@ -326,8 +337,10 @@ ecma_get_lex_env_outer_reference (const ecma_object_t *object_p) /**< lexical en
  *
  * See also:
  *          ecma_op_object_get_property_names
+ *
+ * @return pointer to the head of the property list
  */
-inline ecma_property_header_t *__attr_pure___
+inline ecma_property_header_t *JERRY_ATTR_PURE
 ecma_get_property_list (const ecma_object_t *object_p) /**< object or lexical environment */
 {
   JERRY_ASSERT (object_p != NULL);
@@ -338,30 +351,22 @@ ecma_get_property_list (const ecma_object_t *object_p) /**< object or lexical en
                            object_p->property_list_or_bound_object_cp);
 } /* ecma_get_property_list */
 
-/**
- * Get lexical environment's 'provideThis' property
- */
-inline bool __attr_pure___
-ecma_get_lex_env_provide_this (const ecma_object_t *object_p) /**< object-bound lexical environment */
-{
-  JERRY_ASSERT (object_p != NULL);
-  JERRY_ASSERT (ecma_is_lexical_environment (object_p));
-  JERRY_ASSERT (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND
-                || ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
-
-  return ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND;
-} /* ecma_get_lex_env_provide_this */
-
 /**
  * Get lexical environment's bound object.
+ *
+ * @return pointer to ecma object
  */
-inline ecma_object_t *__attr_pure___
+inline ecma_object_t *JERRY_ATTR_PURE
 ecma_get_lex_env_binding_object (const ecma_object_t *object_p) /**< object-bound lexical environment */
 {
   JERRY_ASSERT (object_p != NULL);
   JERRY_ASSERT (ecma_is_lexical_environment (object_p));
-  JERRY_ASSERT (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND
-                || ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
+#ifndef CONFIG_DISABLE_ES2015
+  JERRY_ASSERT (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND
+                || ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND);
+#else /* CONFIG_DISABLE_ES2015 */
+  JERRY_ASSERT (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
+#endif /* !CONFIG_DISABLE_ES2015 */
 
   return ECMA_GET_NON_NULL_POINTER (ecma_object_t,
                                     object_p->property_list_or_bound_object_cp);
@@ -471,7 +476,7 @@ ecma_create_property (ecma_object_t *object_p, /**< the object */
   /* Just copy the previous value (no need to decompress, compress). */
   first_property_pair_p->header.next_property_cp = *property_list_head_p;
   first_property_pair_p->header.types[0] = ECMA_PROPERTY_TYPE_DELETED;
-  first_property_pair_p->names_cp[0] = ECMA_PROPERTY_DELETED_NAME;
+  first_property_pair_p->names_cp[0] = LIT_INTERNAL_MAGIC_STRING_DELETED;
 
   if (name_p == NULL)
   {
@@ -586,12 +591,15 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in
   JERRY_ASSERT (obj_p != NULL);
   JERRY_ASSERT (name_p != NULL);
 
-  ecma_property_t *property_p = ecma_lcache_lookup (obj_p, name_p);
+  ecma_property_t *property_p = NULL;
 
+#ifndef CONFIG_ECMA_LCACHE_DISABLE
+  property_p = ecma_lcache_lookup (obj_p, name_p);
   if (property_p != NULL)
   {
     return property_p;
   }
+#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
 
   ecma_property_header_t *prop_iter_p = ecma_get_property_list (obj_p);
 
@@ -603,11 +611,13 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in
                                              name_p,
                                              &property_real_name_cp);
 
+#ifndef CONFIG_ECMA_LCACHE_DISABLE
     if (property_p != NULL
         && !ecma_is_property_lcached (property_p))
     {
       ecma_lcache_insert (obj_p, property_real_name_cp, property_p);
     }
+#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
 
     return property_p;
   }
@@ -699,11 +709,13 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in
     ecma_property_hashmap_create (obj_p);
   }
 
+#ifndef CONFIG_ECMA_LCACHE_DISABLE
   if (property_p != NULL
       && !ecma_is_property_lcached (property_p))
   {
     ecma_lcache_insert (obj_p, property_name_cp, property_p);
   }
+#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
 
   return property_p;
 } /* ecma_find_named_property */
@@ -746,16 +758,6 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to
   {
     case ECMA_PROPERTY_TYPE_NAMEDDATA:
     {
-      if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC)
-      {
-        if (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE
-            || name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER)
-        {
-          ecma_free_native_pointer (property_p);
-          break;
-        }
-      }
-
       ecma_free_value_if_not_object (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
       break;
     }
@@ -771,15 +773,21 @@ ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to
     }
     default:
     {
-      JERRY_UNREACHABLE ();
-      return;
+      JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_INTERNAL);
+
+      /* Must be a native pointer. */
+      JERRY_ASSERT (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_MAGIC
+                    && name_cp >= LIT_FIRST_INTERNAL_MAGIC_STRING);
+      break;
     }
   }
 
+#ifndef CONFIG_ECMA_LCACHE_DISABLE
   if (ecma_is_property_lcached (property_p))
   {
     ecma_lcache_invalidate (object_p, name_cp, property_p);
   }
+#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
 
   if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_PTR)
   {
@@ -831,7 +839,7 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */
 
         ecma_free_property (object_p, prop_pair_p->names_cp[i], cur_prop_p->types + i);
         cur_prop_p->types[i] = ECMA_PROPERTY_TYPE_DELETED;
-        prop_pair_p->names_cp[i] = ECMA_PROPERTY_DELETED_NAME;
+        prop_pair_p->names_cp[i] = LIT_INTERNAL_MAGIC_STRING_DELETED;
 
         JERRY_ASSERT (ECMA_PROPERTY_PAIR_ITEM_COUNT == 2);
 
@@ -973,7 +981,7 @@ ecma_delete_array_properties (ecma_object_t *object_p, /**< object */
 
           ecma_free_property (object_p, prop_pair_p->names_cp[i], current_prop_p->types + i);
           current_prop_p->types[i] = ECMA_PROPERTY_TYPE_DELETED;
-          prop_pair_p->names_cp[i] = ECMA_PROPERTY_DELETED_NAME;
+          prop_pair_p->names_cp[i] = LIT_INTERNAL_MAGIC_STRING_DELETED;
         }
       }
     }
@@ -1031,8 +1039,9 @@ ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ec
                                     prop_iter_p->next_property_cp);
   }
 
-  while (prop_iter_p != NULL)
+  while (true)
   {
+    JERRY_ASSERT (prop_iter_p != NULL);
     JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
 
     ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
@@ -1049,9 +1058,6 @@ ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ec
     prop_iter_p = ECMA_GET_POINTER (ecma_property_header_t,
                                     prop_iter_p->next_property_cp);
   }
-
-  JERRY_UNREACHABLE ();
-
 #else /* JERRY_NDEBUG */
   JERRY_UNUSED (object_p);
   JERRY_UNUSED (prop_value_p);
@@ -1065,7 +1071,7 @@ ecma_assert_object_contains_the_property (const ecma_object_t *object_p, /**< ec
  * Note:
  *      value previously stored in the property is freed
  */
-inline void __attr_always_inline___
+inline void JERRY_ATTR_ALWAYS_INLINE
 ecma_named_data_property_assign_value (ecma_object_t *obj_p, /**< object */
                                        ecma_property_value_t *prop_value_p, /**< property value reference */
                                        ecma_value_t value) /**< value to assign */
@@ -1157,7 +1163,7 @@ ecma_set_named_accessor_property_setter (ecma_object_t *object_p, /**< the prope
  * @return true - property is writable,
  *         false - otherwise
  */
-inline bool __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_is_property_writable (ecma_property_t property) /**< property */
 {
   JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA
@@ -1191,7 +1197,7 @@ ecma_set_property_writable_attr (ecma_property_t *property_p, /**< [in,out] prop
  * @return true - property is enumerable,
  *         false - otherwise
  */
-inline bool __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_is_property_enumerable (ecma_property_t property) /**< property */
 {
   JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA
@@ -1227,7 +1233,7 @@ ecma_set_property_enumerable_attr (ecma_property_t *property_p, /**< [in,out] pr
  * @return true - property is configurable,
  *         false - otherwise
  */
-inline bool __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_is_property_configurable (ecma_property_t property) /**< property */
 {
   JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (property) == ECMA_PROPERTY_TYPE_NAMEDDATA
@@ -1257,16 +1263,19 @@ ecma_set_property_configurable_attr (ecma_property_t *property_p, /**< [in,out]
   }
 } /* ecma_set_property_configurable_attr */
 
+#ifndef CONFIG_ECMA_LCACHE_DISABLE
+
 /**
  * Check whether the property is registered in LCache
  *
  * @return true / false
  */
-inline bool __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_is_property_lcached (ecma_property_t *property_p) /**< property */
 {
   JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
-                || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
+                || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR
+                || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_INTERNAL);
 
   return (*property_p & ECMA_PROPERTY_FLAG_LCACHED) != 0;
 } /* ecma_is_property_lcached */
@@ -1274,12 +1283,13 @@ ecma_is_property_lcached (ecma_property_t *property_p) /**< property */
 /**
  * Set value of flag indicating whether the property is registered in LCache
  */
-inline void __attr_always_inline___
+inline void JERRY_ATTR_ALWAYS_INLINE
 ecma_set_property_lcached (ecma_property_t *property_p, /**< property */
                            bool is_lcached) /**< new value for lcached flag */
 {
   JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA
-                || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR);
+                || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDACCESSOR
+                || ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_INTERNAL);
 
   if (is_lcached)
   {
@@ -1291,9 +1301,13 @@ ecma_set_property_lcached (ecma_property_t *property_p, /**< property */
   }
 } /* ecma_set_property_lcached */
 
+#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
+
 /**
  * Construct empty property descriptor, i.e.:
  *  property descriptor with all is_defined flags set to false and the rest - to default value.
+ *
+ * @return empty property descriptor
  */
 ecma_property_descriptor_t
 ecma_make_empty_property_descriptor (void)
@@ -1388,7 +1402,7 @@ ecma_create_error_reference_from_context (void)
  *
  * @return error reference value
  */
-inline ecma_value_t __attr_always_inline___
+inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
 ecma_create_error_object_reference (ecma_object_t *object_p) /**< referenced object */
 {
   return ecma_create_error_reference (ecma_make_object_value (object_p), true);
@@ -1400,7 +1414,7 @@ ecma_create_error_object_reference (ecma_object_t *object_p) /**< referenced obj
 void
 ecma_ref_error_reference (ecma_error_reference_t *error_ref_p) /**< error reference */
 {
-  if (likely (error_ref_p->refs_and_flags < ECMA_ERROR_MAX_REF))
+  if (JERRY_LIKELY (error_ref_p->refs_and_flags < ECMA_ERROR_MAX_REF))
   {
     error_ref_p->refs_and_flags += ECMA_ERROR_REF_ONE;
   }
index 765b72c82fad2e34cacb60b2aaaf31c03e941cf5..78107aba81b8907856d8f9647b8752ff0be29bcf 100644 (file)
@@ -138,48 +138,49 @@ typedef enum
 #define ECMA_BOOL_TO_BITFIELD(x) ((x) ? 1 : 0)
 
 /* ecma-helpers-value.c */
-bool ecma_is_value_direct (ecma_value_t value) __attr_const___;
-bool ecma_is_value_simple (ecma_value_t value) __attr_const___;
-bool ecma_is_value_empty (ecma_value_t value) __attr_const___;
-bool ecma_is_value_undefined (ecma_value_t value) __attr_const___;
-bool ecma_is_value_null (ecma_value_t value) __attr_const___;
-bool ecma_is_value_boolean (ecma_value_t value) __attr_const___;
-bool ecma_is_value_true (ecma_value_t value) __attr_const___;
-bool ecma_is_value_false (ecma_value_t value) __attr_const___;
-bool ecma_is_value_found (ecma_value_t value) __attr_const___;
-bool ecma_is_value_array_hole (ecma_value_t value) __attr_const___;
-
-bool ecma_is_value_integer_number (ecma_value_t value) __attr_const___;
-bool ecma_are_values_integer_numbers (ecma_value_t first_value, ecma_value_t second_value) __attr_const___;
-bool ecma_is_value_float_number (ecma_value_t value) __attr_const___;
-bool ecma_is_value_number (ecma_value_t value) __attr_const___;
-bool ecma_is_value_string (ecma_value_t value) __attr_const___;
-bool ecma_is_value_direct_string (ecma_value_t value) __attr_const___;
-bool ecma_is_value_object (ecma_value_t value) __attr_const___;
-bool ecma_is_value_error_reference (ecma_value_t value) __attr_const___;
-bool ecma_is_value_collection_chunk (ecma_value_t value) __attr_const___;
+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);
+
+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);
+bool JERRY_ATTR_CONST ecma_is_value_direct_string (ecma_value_t value);
+bool JERRY_ATTR_CONST ecma_is_value_non_direct_string (ecma_value_t value);
+bool JERRY_ATTR_CONST ecma_is_value_object (ecma_value_t value);
+bool JERRY_ATTR_CONST ecma_is_value_error_reference (ecma_value_t value);
+bool JERRY_ATTR_CONST ecma_is_value_pointer (ecma_value_t value);
 
 void ecma_check_value_type_is_spec_defined (ecma_value_t value);
 
-ecma_value_t ecma_make_boolean_value (bool boolean_value) __attr_const___;
-ecma_value_t ecma_make_integer_value (ecma_integer_value_t integer_value) __attr_const___;
+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 ecma_make_string_value (const ecma_string_t *ecma_string_p) __attr_pure___;
-ecma_value_t ecma_make_magic_string_value (lit_magic_string_id_t id) __attr_pure___;
-ecma_value_t ecma_make_object_value (const ecma_object_t *object_p) __attr_pure___;
-ecma_value_t ecma_make_error_reference_value (const ecma_error_reference_t *error_ref_p) __attr_pure___;
-ecma_value_t ecma_make_collection_chunk_value (const ecma_collection_chunk_t *collection_chunk_p) __attr_pure___;
-ecma_integer_value_t ecma_get_integer_from_value (ecma_value_t value) __attr_const___;
-ecma_number_t ecma_get_float_from_value (ecma_value_t value) __attr_pure___;
-ecma_number_t ecma_get_number_from_value (ecma_value_t value) __attr_pure___;
-ecma_string_t *ecma_get_string_from_value (ecma_value_t value) __attr_pure___;
-ecma_object_t *ecma_get_object_from_value (ecma_value_t value) __attr_pure___;
-ecma_error_reference_t *ecma_get_error_reference_from_value (ecma_value_t value) __attr_pure___;
-ecma_collection_chunk_t *ecma_get_collection_chunk_from_value (ecma_value_t value) __attr_pure___;
-ecma_value_t ecma_invert_boolean_value (ecma_value_t value) __attr_const___;
+ecma_value_t JERRY_ATTR_PURE ecma_make_string_value (const ecma_string_t *ecma_string_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);
+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);
@@ -200,7 +201,6 @@ 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_new_ecma_string_from_magic_string_ex_id (lit_magic_string_ex_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,
@@ -212,11 +212,11 @@ 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);
 
-lit_utf8_size_t __attr_return_value_should_be_checked___
+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 __attr_return_value_should_be_checked___
+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);
@@ -268,10 +268,6 @@ 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);
-int32_t
-ecma_number_get_fraction_and_exponent (ecma_number_t num, uint64_t *out_fraction_p, int32_t *out_exponent_p);
-ecma_number_t
-ecma_number_make_normal_positive_from_fraction_and_exponent (uint64_t fraction, int32_t exponent);
 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);
@@ -298,20 +294,19 @@ ecma_collection_iterator_next (ecma_value_t *iterator_p);
 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,
-                                           bool provide_this);
-bool ecma_is_lexical_environment (const ecma_object_t *object_p) __attr_pure___;
-bool ecma_get_object_extensible (const ecma_object_t *object_p) __attr_pure___;
+                                           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 ecma_get_object_type (const ecma_object_t *object_p) __attr_pure___;
-ecma_object_t *ecma_get_object_prototype (const ecma_object_t *object_p) __attr_pure___;
-bool ecma_get_object_is_builtin (const ecma_object_t *object_p) __attr_pure___;
+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 ecma_get_lex_env_type (const ecma_object_t *object_p) __attr_pure___;
-ecma_object_t *ecma_get_lex_env_outer_reference (const ecma_object_t *object_p) __attr_pure___;
-ecma_property_header_t *ecma_get_property_list (const ecma_object_t *object_p) __attr_pure___;
-ecma_object_t *ecma_get_lex_env_binding_object (const ecma_object_t *object_p) __attr_pure___;
-bool ecma_get_lex_env_provide_this (const ecma_object_t *object_p) __attr_pure___;
+ecma_lexical_environment_type_t JERRY_ATTR_PURE ecma_get_lex_env_type (const ecma_object_t *object_p);
+ecma_object_t JERRY_ATTR_PURE *ecma_get_lex_env_outer_reference (const ecma_object_t *object_p);
+ecma_property_header_t JERRY_ATTR_PURE *ecma_get_property_list (const ecma_object_t *object_p);
+ecma_object_t JERRY_ATTR_PURE *ecma_get_lex_env_binding_object (const ecma_object_t *object_p);
 
 ecma_property_value_t *
 ecma_create_named_data_property (ecma_object_t *object_p, ecma_string_t *name_p, uint8_t prop_attributes,
@@ -345,8 +340,10 @@ void ecma_set_property_enumerable_attr (ecma_property_t *property_p, bool is_enu
 bool ecma_is_property_configurable (ecma_property_t property);
 void ecma_set_property_configurable_attr (ecma_property_t *property_p, bool is_configurable);
 
+#ifndef CONFIG_ECMA_LCACHE_DISABLE
 bool ecma_is_property_lcached (ecma_property_t *property_p);
 void ecma_set_property_lcached (ecma_property_t *property_p, bool is_lcached);
+#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
 
 ecma_property_descriptor_t ecma_make_empty_property_descriptor (void);
 void ecma_free_property_descriptor (ecma_property_descriptor_t *prop_desc_p);
@@ -362,10 +359,8 @@ void ecma_bytecode_ref (ecma_compiled_code_t *bytecode_p);
 void ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p);
 
 /* ecma-helpers-external-pointers.c */
-bool ecma_create_native_handle_property (ecma_object_t *obj_p, void *handle_p, void *free_cb);
 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, lit_magic_string_id_t id);
-void ecma_free_native_pointer (ecma_property_t *prop_p);
+ecma_native_pointer_t *ecma_get_native_pointer_value (ecma_object_t *obj_p);
 
 /* 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);
index d9bf0bed220df283d1cbc4b51f64786fceac95f7..e92781d66d14a1b5381d68c60b7fb33ac13f6b8e 100644 (file)
@@ -17,7 +17,6 @@
 #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"
@@ -36,7 +35,6 @@
 void
 ecma_init (void)
 {
-  ecma_lcache_init ();
   ecma_init_global_lex_env ();
 
   jmem_register_free_unused_memory_callback (ecma_free_unused_memory);
index 572a12c8e72bec36f2ff6b52263c12b5a35af370..b4465d1f88bf66f2fc78cc6c93943c74b6fc48b6 100644 (file)
  */
 #define ECMA_LCACHE_HASH_MASK (ECMA_LCACHE_HASH_ROWS_COUNT - 1)
 
-#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
-
-/**
- * Initialize LCache
- */
-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 __attr_always_inline___
+static inline void JERRY_ATTR_ALWAYS_INLINE
 ecma_lcache_invalidate_entry (ecma_lcache_hash_entry_t *entry_p) /**< entry to invalidate */
 {
   JERRY_ASSERT (entry_p != NULL);
@@ -66,7 +52,7 @@ ecma_lcache_invalidate_entry (ecma_lcache_hash_entry_t *entry_p) /**< entry to i
  *
  * @return row index
  */
-static inline size_t __attr_always_inline___
+static inline size_t JERRY_ATTR_ALWAYS_INLINE
 ecma_lcache_row_index (jmem_cpointer_t object_cp, /**< compressed pointer to object */
                        lit_string_hash_t name_hash) /**< property name hash */
 {
@@ -74,7 +60,6 @@ ecma_lcache_row_index (jmem_cpointer_t object_cp, /**< compressed pointer to obj
    * so properties of different objects with the same name can be cached effectively. */
   return (size_t) ((name_hash ^ object_cp) & ECMA_LCACHE_HASH_MASK);
 } /* ecma_lcache_row_index */
-#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
 
 /**
  * Insert an entry into LCache
@@ -87,16 +72,16 @@ ecma_lcache_insert (ecma_object_t *object_p, /**< object */
   JERRY_ASSERT (object_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_NAMEDACCESSOR
+                || ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_INTERNAL);
 
-#ifndef CONFIG_ECMA_LCACHE_DISABLE
   jmem_cpointer_t object_cp;
 
   ECMA_SET_NON_NULL_POINTER (object_cp, object_p);
 
   lit_string_hash_t name_hash = ecma_string_get_property_name_hash (*prop_p, name_cp);
   size_t row_index = ecma_lcache_row_index (object_cp, name_hash);
-  ecma_lcache_hash_entry_t *entries_p = JERRY_HASH_TABLE_CONTEXT (table)[row_index];
+  ecma_lcache_hash_entry_t *entries_p = JERRY_CONTEXT (lcache) [row_index];
 
   uint32_t entry_index;
   for (entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++)
@@ -127,31 +112,21 @@ ecma_lcache_insert (ecma_object_t *object_p, /**< object */
   entry_p->prop_p = prop_p;
 
   ecma_set_property_lcached (entry_p->prop_p, true);
-#else  /* CONFIG_ECMA_LCACHE_DISABLE */
-  JERRY_UNUSED (name_cp);
-#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
 } /* ecma_lcache_insert */
 
-#ifndef CONFIG_ECMA_LCACHE_DISABLE
-
-
-
-#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
-
 /**
  * Lookup property in the LCache
  *
  * @return a pointer to an ecma_property_t if the lookup is successful
  *         NULL otherwise
  */
-inline ecma_property_t * __attr_always_inline___
+inline ecma_property_t * JERRY_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);
 
@@ -182,7 +157,7 @@ ecma_lcache_lookup (ecma_object_t *object_p, /**< object */
 
   size_t row_index = ecma_lcache_row_index (object_cp, name_hash);
 
-  ecma_lcache_hash_entry_t *entry_p = JERRY_HASH_TABLE_CONTEXT (table) [row_index];
+  ecma_lcache_hash_entry_t *entry_p = JERRY_CONTEXT (lcache) [row_index];
   ecma_lcache_hash_entry_t *entry_end_p = entry_p + ECMA_LCACHE_HASH_ROW_LENGTH;
 
   while (entry_p < entry_end_p)
@@ -206,7 +181,6 @@ ecma_lcache_lookup (ecma_object_t *object_p, /**< object */
 
     entry_p++;
   }
-#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
 
   return NULL;
 } /* ecma_lcache_lookup */
@@ -222,18 +196,21 @@ ecma_lcache_invalidate (ecma_object_t *object_p, /**< object */
   JERRY_ASSERT (object_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_NAMEDACCESSOR
+                || ECMA_PROPERTY_GET_TYPE (*prop_p) == ECMA_PROPERTY_TYPE_INTERNAL);
 
-#ifndef CONFIG_ECMA_LCACHE_DISABLE
   jmem_cpointer_t object_cp;
   ECMA_SET_NON_NULL_POINTER (object_cp, object_p);
 
   lit_string_hash_t name_hash = ecma_string_get_property_name_hash (*prop_p, name_cp);
   size_t row_index = ecma_lcache_row_index (object_cp, name_hash);
-  ecma_lcache_hash_entry_t *entry_p = JERRY_HASH_TABLE_CONTEXT (table) [row_index];
+  ecma_lcache_hash_entry_t *entry_p = JERRY_CONTEXT (lcache) [row_index];
 
-  for (uint32_t entry_index = 0; entry_index < ECMA_LCACHE_HASH_ROW_LENGTH; entry_index++)
+  while (true)
   {
+    /* The property must be present. */
+    JERRY_ASSERT (entry_p - JERRY_CONTEXT (lcache) [row_index] < ECMA_LCACHE_HASH_ROW_LENGTH);
+
     if (entry_p->object_cp != ECMA_NULL_POINTER && entry_p->prop_p == prop_p)
     {
       JERRY_ASSERT (entry_p->object_cp == object_cp);
@@ -243,13 +220,9 @@ ecma_lcache_invalidate (ecma_object_t *object_p, /**< object */
     }
     entry_p++;
   }
+} /* ecma_lcache_invalidate */
 
-  /* The property must be present. */
-  JERRY_UNREACHABLE ();
-#else  /* CONFIG_ECMA_LCACHE_DISABLE */
-  JERRY_UNUSED (name_cp);
 #endif /* !CONFIG_ECMA_LCACHE_DISABLE */
-} /* ecma_lcache_invalidate */
 
 /**
  * @}
index d37f7e8f20dde72b5571a1b15890b7b34bc67b17..a0ab398ca591890bdeb947136d0c015e9565bb9f 100644 (file)
  * @{
  */
 
-void ecma_lcache_init (void);
+#ifndef CONFIG_ECMA_LCACHE_DISABLE
+
 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 /* !CONFIG_ECMA_LCACHE_DISABLE */
+
 /**
  * @}
  * @}
index b93bd77b23fd3ca726eb73f3b03be4ceba7e4a88..4262ea9f02c728cdaf62adc52fe57c16a969c8ca 100644 (file)
@@ -286,7 +286,7 @@ ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_
     const_literal_end = args_p->const_literal_end - register_end;
     literal_end = args_p->literal_end - register_end;
 
-    if (compiled_code_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
+    if (CBC_NON_STRICT_ARGUMENTS_NEEDED (compiled_code_p))
     {
       argument_end = args_p->argument_end;
     }
@@ -301,7 +301,7 @@ ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_
     const_literal_end = args_p->const_literal_end - register_end;
     literal_end = args_p->literal_end - register_end;
 
-    if (compiled_code_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
+    if (CBC_NON_STRICT_ARGUMENTS_NEEDED (compiled_code_p))
     {
       argument_end = args_p->argument_end;
     }
@@ -346,7 +346,7 @@ ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_
  * Save literals to specified snapshot buffer.
  *
  * Note:
- *   Frees lit_pool_p regardless of success.
+ *      Frees 'lit_pool_p' regardless of success.
  *
  * @return true - if save was performed successfully (i.e. buffer size is sufficient),
  *         false - otherwise
index aaff48387782139940e6e42890580bcd6115e7fe..5da1d10a99c866950bebd3b3d86f01564e935600 100644 (file)
@@ -99,7 +99,7 @@ ecma_property_hashmap_create (ecma_object_t *object_p) /**< object */
     {
       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)
+      if (type != ECMA_PROPERTY_TYPE_SPECIAL)
       {
         named_property_count++;
       }
@@ -539,8 +539,6 @@ ecma_property_hashmap_find (ecma_property_hashmap_t *hashmap_p, /**< hashmap */
       JERRY_ASSERT (entry_index != start_entry_index);
 #endif /* !JERRY_NDEBUG */
     }
-
-    JERRY_UNREACHABLE ();
   }
 
   while (true)
index 8318005c20cf2d64cfbf4a0a1d99fd482374b68f..04d093b45488a1f285280b7602ee2e8b5fe7af4f 100644 (file)
@@ -64,7 +64,7 @@ ecma_builtin_array_prototype_helper_set_length (ecma_object_t *object, /**< obje
   ret_value = ecma_op_object_put (object,
                                   ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH),
                                   length_value,
-                                  true),
+                                  true);
 
   ecma_free_value (length_value);
   return ret_value;
@@ -125,7 +125,7 @@ ecma_builtin_array_prototype_object_to_string (ecma_value_t this_arg) /**< this
  *         Returned value must be freed with ecma_free_value.
  */
 static ecma_value_t
-ecma_builtin_array_prototype_object_to_locale_string (const ecma_value_t this_arg) /**< this argument */
+ecma_builtin_array_prototype_object_to_locale_string (ecma_value_t this_arg) /**< this argument */
 {
   ecma_value_t ret_value = ECMA_VALUE_EMPTY;
 
@@ -223,7 +223,20 @@ ecma_builtin_array_prototype_object_concat (ecma_value_t this_arg, /**< this arg
                   ret_value);
 
   /* 2. */
-  ecma_value_t new_array = ecma_op_create_array_object (0, 0, false);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
+  ecma_value_t new_array = ecma_op_create_array_object_by_constructor (NULL, 0, false, obj_p);
+
+  if (ECMA_IS_VALUE_ERROR (new_array))
+  {
+    ecma_free_value (obj_this);
+    return new_array;
+  }
+#else /* CONFIG_DISABLE_ES2015_CLASS */
+  ecma_value_t new_array = ecma_op_create_array_object (NULL, 0, false);
+  JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
   ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
   uint32_t new_length = 0;
 
@@ -331,8 +344,8 @@ ecma_op_array_get_to_string_at_index (ecma_object_t *obj_p, /**< this object */
  *         Returned value must be freed with ecma_free_value.
  */
 static ecma_value_t
-ecma_builtin_array_prototype_join (const ecma_value_t this_arg, /**< this argument */
-                                   const ecma_value_t separator_arg) /**< separator argument */
+ecma_builtin_array_prototype_join (ecma_value_t this_arg, /**< this argument */
+                                   ecma_value_t separator_arg) /**< separator argument */
 {
   ecma_value_t ret_value = ECMA_VALUE_EMPTY;
 
@@ -825,7 +838,20 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t this_arg, /**< 'this' ar
 
   JERRY_ASSERT (start <= len && end <= len);
 
-  ecma_value_t new_array = ecma_op_create_array_object (0, 0, false);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  ecma_value_t new_array = ecma_op_create_array_object_by_constructor (NULL, 0, false, obj_p);
+
+  if (ECMA_IS_VALUE_ERROR (new_array))
+  {
+    ecma_free_value (len_value);
+    ecma_free_value (obj_this);
+    return new_array;
+  }
+#else /* CONFIG_DISABLE_ES2015_CLASS */
+  ecma_value_t new_array = ecma_op_create_array_object (NULL, 0, false);
+  JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
   ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
 
   /* 9. */
@@ -850,10 +876,8 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t this_arg, /**< 'this' ar
       ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
                                                             to_idx_str_p,
                                                             get_value,
-                                                            true, /* Writable */
-                                                            true, /* Enumerable */
-                                                            true, /* Configurable */
-                                                            false);
+                                                            ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+                                                            false); /* Failure handling */
       JERRY_ASSERT (ecma_is_value_true (put_comp));
 
       ecma_deref_ecma_string (to_idx_str_p);
@@ -890,9 +914,9 @@ ecma_builtin_array_prototype_object_slice (ecma_value_t this_arg, /**< 'this' ar
  *         Returned value must be freed with ecma_free_value.
  */
 static ecma_value_t
-ecma_builtin_array_prototype_object_sort_compare_helper (ecma_value_t j, /**< left value */
-                                                         ecma_value_t k, /**< right value */
-                                                         ecma_value_t comparefn) /**< compare function */
+ecma_builtin_array_prototype_object_sort_compare_helper (ecma_value_t lhs, /**< left value */
+                                                         ecma_value_t rhs, /**< right value */
+                                                         ecma_value_t compare_func) /**< compare function */
 {
   /*
    * ECMA-262 v5, 15.4.4.11 NOTE1: Because non-existent property values always
@@ -903,12 +927,12 @@ ecma_builtin_array_prototype_object_sort_compare_helper (ecma_value_t j, /**< le
   ecma_value_t ret_value = ECMA_VALUE_EMPTY;
   ecma_number_t result = ECMA_NUMBER_ZERO;
 
-  bool j_is_undef = ecma_is_value_undefined (j);
-  bool k_is_undef = ecma_is_value_undefined (k);
+  bool lhs_is_undef = ecma_is_value_undefined (lhs);
+  bool rhs_is_undef = ecma_is_value_undefined (rhs);
 
-  if (j_is_undef)
+  if (lhs_is_undef)
   {
-    if (k_is_undef)
+    if (rhs_is_undef)
     {
       result = ECMA_NUMBER_ZERO;
     }
@@ -919,25 +943,25 @@ ecma_builtin_array_prototype_object_sort_compare_helper (ecma_value_t j, /**< le
   }
   else
   {
-    if (k_is_undef)
+    if (rhs_is_undef)
     {
       result = ECMA_NUMBER_MINUS_ONE;
     }
     else
     {
-      if (ecma_is_value_undefined (comparefn))
+      if (ecma_is_value_undefined (compare_func))
       {
-        /* Default comparison when no comparefn is passed. */
-        ECMA_TRY_CATCH (j_value, ecma_op_to_string (j), ret_value);
-        ECMA_TRY_CATCH (k_value, ecma_op_to_string (k), ret_value);
-        ecma_string_t *j_str_p = ecma_get_string_from_value (j_value);
-        ecma_string_t *k_str_p = ecma_get_string_from_value (k_value);
+        /* Default comparison when no compare_func is passed. */
+        ECMA_TRY_CATCH (lhs_value, ecma_op_to_string (lhs), ret_value);
+        ECMA_TRY_CATCH (rhs_value, ecma_op_to_string (rhs), ret_value);
+        ecma_string_t *lhs_str_p = ecma_get_string_from_value (lhs_value);
+        ecma_string_t *rhs_str_p = ecma_get_string_from_value (rhs_value);
 
-        if (ecma_compare_ecma_strings_relational (j_str_p, k_str_p))
+        if (ecma_compare_ecma_strings_relational (lhs_str_p, rhs_str_p))
         {
           result = ECMA_NUMBER_MINUS_ONE;
         }
-        else if (!ecma_compare_ecma_strings (j_str_p, k_str_p))
+        else if (!ecma_compare_ecma_strings (lhs_str_p, rhs_str_p))
         {
           result = ECMA_NUMBER_ONE;
         }
@@ -946,19 +970,19 @@ ecma_builtin_array_prototype_object_sort_compare_helper (ecma_value_t j, /**< le
           result = ECMA_NUMBER_ZERO;
         }
 
-        ECMA_FINALIZE (k_value);
-        ECMA_FINALIZE (j_value);
+        ECMA_FINALIZE (rhs_value);
+        ECMA_FINALIZE (lhs_value);
       }
       else
       {
         /*
-         * comparefn, if not undefined, will always contain a callable function object.
+         * compare_func, if not undefined, will always contain a callable function object.
          * We checked this previously, before this function was called.
          */
-        JERRY_ASSERT (ecma_op_is_callable (comparefn));
-        ecma_object_t *comparefn_obj_p = ecma_get_object_from_value (comparefn);
+        JERRY_ASSERT (ecma_op_is_callable (compare_func));
+        ecma_object_t *comparefn_obj_p = ecma_get_object_from_value (compare_func);
 
-        ecma_value_t compare_args[] = {j, k};
+        ecma_value_t compare_args[] = { lhs, rhs };
 
         ECMA_TRY_CATCH (call_value,
                         ecma_op_function_call (comparefn_obj_p,
@@ -991,145 +1015,6 @@ ecma_builtin_array_prototype_object_sort_compare_helper (ecma_value_t j, /**< le
   return ret_value;
 } /* ecma_builtin_array_prototype_object_sort_compare_helper */
 
-/**
- * Function used to reconstruct the ordered binary tree.
- * Shifts 'index' down in the tree until it is in the correct position.
- *
- * @return ecma value
- *         Returned value must be freed with ecma_free_value.
- */
-static ecma_value_t
-ecma_builtin_array_prototype_object_array_to_heap_helper (ecma_value_t array[], /**< heap data array */
-                                                          int index, /**< current item index */
-                                                          int right, /**< right index is a maximum index */
-                                                          ecma_value_t comparefn) /**< compare function */
-{
-  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
-  /* Left child of the current index. */
-  int child = index * 2 + 1;
-  ecma_value_t swap = array[index];
-  bool should_break = false;
-
-  while (child <= right && ecma_is_value_empty (ret_value) && !should_break)
-  {
-    if (child < right)
-    {
-      /* Compare the two child nodes. */
-      ECMA_TRY_CATCH (child_compare_value,
-                      ecma_builtin_array_prototype_object_sort_compare_helper (array[child],
-                                                                               array[child + 1],
-                                                                               comparefn),
-                      ret_value);
-
-      JERRY_ASSERT (ecma_is_value_number (child_compare_value));
-
-      /* Use the child that is greater. */
-      if (ecma_get_number_from_value (child_compare_value) < ECMA_NUMBER_ZERO)
-      {
-        child++;
-      }
-
-      ECMA_FINALIZE (child_compare_value);
-    }
-
-    if (ecma_is_value_empty (ret_value))
-    {
-      JERRY_ASSERT (child <= right);
-
-      /* Compare current child node with the swap (tree top). */
-      ECMA_TRY_CATCH (swap_compare_value,
-                      ecma_builtin_array_prototype_object_sort_compare_helper (array[child],
-                                                                               swap,
-                                                                               comparefn),
-                      ret_value);
-      JERRY_ASSERT (ecma_is_value_number (swap_compare_value));
-
-      if (ecma_get_number_from_value (swap_compare_value) <= ECMA_NUMBER_ZERO)
-      {
-        /* Break from loop if current child is less than swap (tree top) */
-        should_break = true;
-      }
-      else
-      {
-        /* We have to move 'swap' lower in the tree, so shift current child up in the hierarchy. */
-        int parent = (child - 1) / 2;
-        JERRY_ASSERT (parent >= 0 && parent <= right);
-        array[parent] = array[child];
-
-        /* Update child to be the left child of the current node. */
-        child = child * 2 + 1;
-      }
-
-      ECMA_FINALIZE (swap_compare_value);
-    }
-  }
-
-  /*
-   * Loop ended, either current child does not exist, or is less than swap.
-   * This means that 'swap' should be placed in the parent node.
-   */
-  int parent = (child - 1) / 2;
-  JERRY_ASSERT (parent >= 0 && parent <= right);
-  array[parent] = swap;
-
-  if (ecma_is_value_empty (ret_value))
-  {
-    ret_value = ECMA_VALUE_UNDEFINED;
-  }
-
-  return ret_value;
-} /* ecma_builtin_array_prototype_object_array_to_heap_helper */
-
-/**
- * Heapsort function
- *
- * @return ecma value
- *         Returned value must be freed with ecma_free_value.
- */
-static ecma_value_t
-ecma_builtin_array_prototype_object_array_heap_sort_helper (ecma_value_t array[], /**< array to sort */
-                                                            int right, /**< right index */
-                                                            ecma_value_t comparefn) /**< compare function */
-{
-  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
-  /* First, construct the ordered binary tree from the array. */
-  for (int i = right / 2; i >= 0 && ecma_is_value_empty (ret_value); i--)
-  {
-    ECMA_TRY_CATCH (value,
-                    ecma_builtin_array_prototype_object_array_to_heap_helper (array,
-                                                                              i,
-                                                                              right,
-                                                                              comparefn),
-                    ret_value);
-    ECMA_FINALIZE (value);
-  }
-
-  /* Sorting elements. */
-  for (int i = right; i > 0 && ecma_is_value_empty (ret_value); i--)
-  {
-    /*
-     * The top element will always contain the largest value.
-     * Move top to the end, and remove it from the tree.
-     */
-    ecma_value_t swap = array[0];
-    array[0] = array[i];
-    array[i] = swap;
-
-    /* Rebuild binary tree from the remaining elements. */
-    ECMA_TRY_CATCH (value,
-                    ecma_builtin_array_prototype_object_array_to_heap_helper (array,
-                                                                              0,
-                                                                              i - 1,
-                                                                              comparefn),
-                    ret_value);
-    ECMA_FINALIZE (value);
-  }
-
-  return ret_value;
-} /* ecma_builtin_array_prototype_object_array_heap_sort_helper */
-
 /**
  * The Array.prototype object's 'sort' routine
  *
@@ -1165,7 +1050,7 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
 
   uint32_t len = ecma_number_to_uint32 (len_number);
 
-  ecma_collection_header_t *array_index_props_p = ecma_op_object_get_property_names (obj_p, true, false, false);
+  ecma_collection_header_t *array_index_props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_ARRAY_INDICES);
 
   uint32_t defined_prop_count = 0;
   uint32_t copied_num = 0;
@@ -1218,10 +1103,12 @@ ecma_builtin_array_prototype_object_sort (ecma_value_t this_arg, /**< this argum
   /* Sorting. */
   if (copied_num > 1 && ecma_is_value_empty (ret_value))
   {
+    const ecma_builtin_helper_sort_compare_fn_t sort_cb = &ecma_builtin_array_prototype_object_sort_compare_helper;
     ECMA_TRY_CATCH (sort_value,
-                    ecma_builtin_array_prototype_object_array_heap_sort_helper (values_buffer,
-                                                                                (int)(copied_num - 1),
-                                                                                arg1),
+                    ecma_builtin_helper_array_heap_sort_helper (values_buffer,
+                                                                (uint32_t) (copied_num - 1),
+                                                                arg1,
+                                                                sort_cb),
                     ret_value);
     ECMA_FINALIZE (sort_value);
   }
@@ -1315,7 +1202,20 @@ ecma_builtin_array_prototype_object_splice (ecma_value_t this_arg, /**< this arg
 
   const uint32_t len = ecma_number_to_uint32 (len_number);
 
-  ecma_value_t new_array = ecma_op_create_array_object (0, 0, false);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  ecma_value_t new_array = ecma_op_create_array_object_by_constructor (NULL, 0, false, obj_p);
+
+  if (ECMA_IS_VALUE_ERROR (new_array))
+  {
+    ecma_free_value (len_value);
+    ecma_free_value (obj_this);
+    return new_array;
+  }
+#else /* CONFIG_DISABLE_ES2015_CLASS */
+  ecma_value_t new_array = ecma_op_create_array_object (NULL, 0, false);
+  JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
   ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
 
   uint32_t start = 0;
@@ -1395,10 +1295,8 @@ ecma_builtin_array_prototype_object_splice (ecma_value_t this_arg, /**< this arg
       ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
                                                             idx_str_new_p,
                                                             get_value,
-                                                            true, /* Writable */
-                                                            true, /* Enumerable */
-                                                            true, /* Configurable */
-                                                            false);
+                                                            ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+                                                            false); /* Failure handling */
       JERRY_ASSERT (ecma_is_value_true (put_comp));
 
       ecma_deref_ecma_string (idx_str_new_p);
@@ -1716,13 +1614,11 @@ ecma_builtin_array_prototype_object_index_of (ecma_value_t this_arg, /**< this a
         /* 9.a */
         ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, idx_str_p), ret_value);
 
-        if (ecma_is_value_found (get_value))
+        /* 9.b.i, 9.b.ii */
+        if (ecma_is_value_found (get_value)
+            && ecma_op_strict_equality_compare (arg1, get_value))
         {
-          /* 9.b.i, 9.b.ii */
-          if (ecma_op_strict_equality_compare (arg1, get_value))
-          {
-            found_index = ((ecma_number_t) from_idx);
-          }
+          found_index = ((ecma_number_t) from_idx);
         }
 
         ECMA_FINALIZE (get_value);
@@ -1863,13 +1759,11 @@ ecma_builtin_array_prototype_object_last_index_of (ecma_value_t this_arg, /**< t
       /* 8.a */
       ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, idx_str_p), ret_value);
 
-      if (ecma_is_value_found (get_value))
+      /* 8.b.i, 8.b.ii */
+      if (ecma_is_value_found (get_value)
+          && ecma_op_strict_equality_compare (search_element, get_value))
       {
-        /* 8.b.i, 8.b.ii */
-        if (ecma_op_strict_equality_compare (search_element, get_value))
-        {
-          num = ((ecma_number_t) from_idx);
-        }
+        num = ((ecma_number_t) from_idx);
       }
 
       ECMA_FINALIZE (get_value);
@@ -2114,8 +2008,20 @@ ecma_builtin_array_prototype_object_map (ecma_value_t this_arg, /**< this argume
     /* 5. arg2 is simply used as T */
 
     /* 6. */
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+    ecma_value_t new_array = ecma_op_create_array_object_by_constructor (NULL, 0, false, obj_p);
+
+    if (ECMA_IS_VALUE_ERROR (new_array))
+    {
+      ecma_free_value (len_value);
+      ecma_free_value (obj_this);
+      return new_array;
+    }
+#else /* CONFIG_DISABLE_ES2015_CLASS */
     ecma_value_t new_array = ecma_op_create_array_object (NULL, 0, false);
     JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
     ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
 
     /* 7-8. */
@@ -2142,10 +2048,8 @@ ecma_builtin_array_prototype_object_map (ecma_value_t this_arg, /**< this argume
         ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
                                                               index_str_p,
                                                               mapped_value,
-                                                              true, /* Writable */
-                                                              true, /* Enumerable */
-                                                              true, /* Configurable */
-                                                              false);
+                                                              ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+                                                              false); /* Failure handling */
         JERRY_ASSERT (ecma_is_value_true (put_comp));
 
         ECMA_FINALIZE (mapped_value);
@@ -2221,8 +2125,20 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t this_arg, /**< this arg
     ecma_object_t *func_object_p;
 
     /* 6. */
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+    ecma_value_t new_array = ecma_op_create_array_object_by_constructor (NULL, 0, false, obj_p);
+
+    if (ECMA_IS_VALUE_ERROR (new_array))
+    {
+      ecma_free_value (len_value);
+      ecma_free_value (obj_this);
+      return new_array;
+    }
+#else /* CONFIG_DISABLE_ES2015_CLASS */
     ecma_value_t new_array = ecma_op_create_array_object (NULL, 0, false);
     JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (new_array));
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
     ecma_object_t *new_array_p = ecma_get_object_from_value (new_array);
 
     /* We already checked that arg1 is callable, so it will always be an object. */
@@ -2259,10 +2175,8 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t this_arg, /**< this arg
           ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
                                                                 to_index_string_p,
                                                                 get_value,
-                                                                true, /* Writable */
-                                                                true, /* Enumerable */
-                                                                true, /* Configurable */
-                                                                false);
+                                                                ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+                                                                false); /* Failure handling */
           JERRY_ASSERT (ecma_is_value_true (put_comp));
 
           ecma_deref_ecma_string (to_index_string_p);
@@ -2490,6 +2404,106 @@ ecma_builtin_array_prototype_object_reduce_right (ecma_value_t this_arg, /**< th
   return ecma_builtin_array_reduce_from (this_arg, args, args_number, false);
 } /* ecma_builtin_array_prototype_object_reduce_right */
 
+#ifndef CONFIG_DISABLE_ES2015_BUILTIN
+/**
+ * The Array.prototype object's 'find' routine
+ *
+ * See also:
+ *          ECMA-262 v6, 22.1.3.8
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_array_prototype_object_find (ecma_value_t this_arg, /**< this argument */
+                                          ecma_value_t predicate, /**< callback function */
+                                          ecma_value_t predicate_this_arg) /**< this argument for
+                                                                            *   invoke predicate */
+{
+  /* 1. */
+  ecma_value_t obj_this = ecma_op_to_object (this_arg);
+
+  /* 2. */
+  if (ECMA_IS_VALUE_ERROR (obj_this))
+  {
+    return obj_this;
+  }
+
+  ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
+
+  /* 3 - 4. */
+  ecma_value_t len_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_LENGTH);
+
+  if (ECMA_IS_VALUE_ERROR (len_value))
+  {
+    ecma_free_value (obj_this);
+    return len_value;
+  }
+
+  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
+
+  ECMA_OP_TO_NUMBER_TRY_CATCH (len_number, len_value, ret_value);
+
+  uint32_t len = ecma_number_to_uint32 (len_number);
+
+  /* 5. */
+  if (!ecma_op_is_callable (predicate))
+  {
+    ecma_free_value (len_value);
+    ecma_free_value (obj_this);
+    return ecma_raise_type_error (ECMA_ERR_MSG ("Callback function is not callable."));
+  }
+
+  /* We already checked that predicate is callable, so it will always be an object. */
+  JERRY_ASSERT (ecma_is_value_object (predicate));
+  ecma_object_t *func_object_p = ecma_get_object_from_value (predicate);
+
+  /* 7 - 8. */
+  for (uint32_t index = 0; index < len && ecma_is_value_empty (ret_value); index++)
+  {
+    /* 8.a */
+    ecma_string_t *index_str_p = ecma_new_ecma_string_from_uint32 (index);
+
+    /* 8.b - 8.c */
+    ECMA_TRY_CATCH (get_value, ecma_op_object_find (obj_p, index_str_p), ret_value);
+
+    if (ecma_is_value_found (get_value))
+    {
+      /* 8.d - 8.e */
+      uint32_t current_index = ecma_make_uint32_value (index);
+
+      ecma_value_t call_args[] = { get_value, current_index, obj_this };
+
+      ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, predicate_this_arg, call_args, 3), ret_value);
+
+      if (ecma_op_to_boolean (call_value))
+      {
+        /* 8.f */
+        ret_value = ecma_copy_value (get_value);
+      }
+
+      ECMA_FINALIZE (call_value);
+    }
+
+    ECMA_FINALIZE (get_value);
+
+    ecma_deref_ecma_string (index_str_p);
+  }
+
+  if (ecma_is_value_empty (ret_value))
+  {
+    /* 9. */
+    ret_value = ECMA_VALUE_UNDEFINED;
+  }
+
+  ECMA_OP_TO_NUMBER_FINALIZE (len_number);
+  ecma_free_value (len_value);
+  ecma_free_value (obj_this);
+
+  return ret_value;
+} /* ecma_builtin_array_prototype_object_find */
+#endif /* !CONFIG_DISABLE_ES2015_BUILTIN */
+
 /**
  * @}
  * @}
index 0da3c05975ff3a947bbc9cf08a26d55545735bc2..14ad3f69ecce243d6f2a776c08aeaa7e023b83b1 100644 (file)
@@ -60,6 +60,9 @@ 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)
+#ifndef CONFIG_DISABLE_ES2015_BUILTIN
+ROUTINE (LIT_MAGIC_STRING_FIND, ecma_builtin_array_prototype_object_find, 2, 1)
+#endif /* !CONFIG_DISABLE_ES2015_BUILTIN */
 
 #endif /* !CONFIG_DISABLE_ARRAY_BUILTIN */
 
index 138c8d6a5ed21512433d9ecf4865cc9dcc537b69..60623fbd40efb890e4cd2661998784e36d1ea296 100644 (file)
@@ -59,7 +59,7 @@ ecma_builtin_arraybuffer_object_is_view (ecma_value_t this_arg, /**< 'this' argu
 
   /* TODO: if arg has [[ViewArrayBuffer]], return true */
 
-  return ecma_make_boolean_value (false);
+  return ECMA_VALUE_FALSE;
 } /* ecma_builtin_arraybuffer_object_is_view */
 
 /**
index 35cde8ed0dab8508f3b1ec129213569ddcb27a58..4f0b5e5e54311e864846d8b2f358e15a249d8ddf 100644 (file)
@@ -66,7 +66,7 @@ ecma_builtin_boolean_dispatch_call (const ecma_value_t *arguments_list_p, /**< a
     arg_value = arguments_list_p[0];
   }
 
-  return ecma_op_to_boolean (arg_value) ? ECMA_VALUE_TRUE : ECMA_VALUE_FALSE;
+  return ecma_make_boolean_value (ecma_op_to_boolean (arg_value));
 } /* ecma_builtin_boolean_dispatch_call */
 
 /**
index a427b2f18682cdfaa31bcf98946744d869b54d0e..454dafa98103ce2d5fc89d8f1d90ba6805e6a488 100644 (file)
@@ -259,6 +259,7 @@ ecma_builtin_date_prototype_dispatch_get (uint16_t builtin_routine_id, /**< buil
     default:
     {
       JERRY_ASSERT (builtin_routine_id == ECMA_DATE_PROTOTYPE_GET_UTC_TIMEZONE_OFFSET);
+
       date_num = ecma_date_timezone_offset (date_num);
       break;
     }
@@ -342,6 +343,7 @@ ecma_builtin_date_prototype_dispatch_set (uint16_t builtin_routine_id, /**< buil
     {
       JERRY_ASSERT (builtin_routine_id == ECMA_DATE_PROTOTYPE_SET_HOURS
                     || builtin_routine_id == ECMA_DATE_PROTOTYPE_SET_UTC_HOURS);
+
       conversions = 4;
       break;
     }
@@ -429,6 +431,7 @@ ecma_builtin_date_prototype_dispatch_set (uint16_t builtin_routine_id, /**< buil
       {
         JERRY_ASSERT (builtin_routine_id == ECMA_DATE_PROTOTYPE_SET_DATE
                       || builtin_routine_id == ECMA_DATE_PROTOTYPE_SET_UTC_DATE);
+
         day = converted_number[0];
         break;
       }
@@ -511,6 +514,7 @@ ecma_builtin_date_prototype_dispatch_set (uint16_t builtin_routine_id, /**< buil
       {
         JERRY_ASSERT (builtin_routine_id == ECMA_DATE_PROTOTYPE_SET_UTC_MILLISECONDS
                       || builtin_routine_id == ECMA_DATE_PROTOTYPE_SET_MILLISECONDS);
+
         ms = converted_number[0];
         break;
       }
@@ -551,7 +555,7 @@ ecma_builtin_date_prototype_dispatch_routine (uint16_t builtin_routine_id, /**<
                                                                                     *   passed to routine */
                                               ecma_length_t arguments_number) /**< length of arguments' list */
 {
-  if (unlikely (builtin_routine_id == ECMA_DATE_PROTOTYPE_TO_JSON))
+  if (JERRY_UNLIKELY (builtin_routine_id == ECMA_DATE_PROTOTYPE_TO_JSON))
   {
     return ecma_builtin_date_prototype_to_json (this_arg);
   }
@@ -596,7 +600,7 @@ ecma_builtin_date_prototype_dispatch_routine (uint16_t builtin_routine_id, /**<
 
     if (!BUILTIN_DATE_FUNCTION_IS_UTC (builtin_routine_id))
     {
-      this_num += ecma_date_local_time_zone (this_num);
+      this_num += ecma_date_local_time_zone_adjustment (this_num);
     }
 
     if (builtin_routine_id <= ECMA_DATE_PROTOTYPE_GET_UTC_TIMEZONE_OFFSET)
@@ -643,6 +647,7 @@ ecma_builtin_date_prototype_dispatch_routine (uint16_t builtin_routine_id, /**<
     default:
     {
       JERRY_ASSERT (builtin_routine_id == ECMA_DATE_PROTOTYPE_TO_UTC_STRING);
+
       return ecma_date_value_to_utc_string (*prim_value_p);
     }
   }
index 440b5cedbda3de6332aa33988d1ad7e9aeba5936..080f751cbc9cbf54fb01bdfd61d62629de3017f3 100644 (file)
@@ -13,6 +13,8 @@
  * limitations under the License.
  */
 
+#include <math.h>
+
 #include "ecma-alloc.h"
 #include "ecma-builtin-helpers.h"
 #include "ecma-conversion.h"
@@ -22,7 +24,6 @@
 #include "ecma-helpers.h"
 #include "ecma-try-catch-macro.h"
 #include "lit-char-helpers.h"
-#include "math.h"
 
 #ifndef CONFIG_DISABLE_DATE_BUILTIN
 
@@ -491,8 +492,6 @@ ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**<
   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;
 
-  ecma_deref_object (prototype_obj_p);
-
   if (arguments_list_len == 0)
   {
     ECMA_TRY_CATCH (parse_res_value,
index f1f900b65a5d694b9380e9825a126d615f15d258..69312ed3473b265e234b81acf8ff05fca60adcf2 100644 (file)
@@ -81,7 +81,7 @@ ecma_builtin_error_prototype_object_to_string (ecma_value_t this_arg) /**< this
       name_to_str_completion = ecma_op_to_string (name_get_ret_value);
     }
 
-    if (unlikely (ECMA_IS_VALUE_ERROR (name_to_str_completion)))
+    if (JERRY_UNLIKELY (ECMA_IS_VALUE_ERROR (name_to_str_completion)))
     {
       ret_value = ecma_copy_value (name_to_str_completion);
     }
@@ -102,7 +102,7 @@ ecma_builtin_error_prototype_object_to_string (ecma_value_t this_arg) /**< this
         msg_to_str_completion = ecma_op_to_string (msg_get_ret_value);
       }
 
-      if (unlikely (ECMA_IS_VALUE_ERROR (msg_to_str_completion)))
+      if (JERRY_UNLIKELY (ECMA_IS_VALUE_ERROR (msg_to_str_completion)))
       {
         ret_value = ecma_copy_value (msg_to_str_completion);
       }
index 78e9a483feebe743d6ada4e591a6ed83ab4a89d7..e9a78075a85d5cfed46c18aef233624b5a134959 100644 (file)
@@ -250,15 +250,12 @@ ecma_builtin_function_prototype_object_bind (ecma_value_t this_arg, /**< this ar
     /* 4. 11. 18. */
     ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
 
-    ecma_length_t args_length = arguments_number;
     ecma_object_t *function_p;
     ecma_extended_object_t *ext_function_p;
 
     if (arguments_number == 0
         || (arguments_number == 1 && !ecma_is_value_integer_number (arguments_list_p[0])))
     {
-      args_length = 1;
-
       function_p = ecma_create_object (prototype_obj_p,
                                        sizeof (ecma_extended_object_t),
                                        ECMA_OBJECT_TYPE_BOUND_FUNCTION);
@@ -280,7 +277,7 @@ ecma_builtin_function_prototype_object_bind (ecma_value_t this_arg, /**< this ar
     {
       JERRY_ASSERT (arguments_number > 0);
 
-      size_t obj_size = sizeof (ecma_extended_object_t) + (args_length * sizeof (ecma_value_t));
+      size_t obj_size = sizeof (ecma_extended_object_t) + (arguments_number * sizeof (ecma_value_t));
 
       function_p = ecma_create_object (prototype_obj_p,
                                        obj_size,
@@ -302,12 +299,10 @@ ecma_builtin_function_prototype_object_bind (ecma_value_t this_arg, /**< this ar
         *args_p++ = ecma_copy_value_if_not_object (arguments_list_p[i]);
       }
 
-      ecma_value_t args_len_or_this = ecma_make_integer_value ((ecma_integer_value_t) args_length);
+      ecma_value_t args_len_or_this = ecma_make_integer_value ((ecma_integer_value_t) arguments_number);
       ext_function_p->u.bound_function.args_len_or_this = args_len_or_this;
     }
 
-    ecma_deref_object (prototype_obj_p);
-
     /*
      * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_FUNCTION type.
      *
index eed3378be151b77d6b7d0c6cedbde76ac87439b0..8bcde5cbc87e582d630160ff7fac7016ff2a2b92 100644 (file)
@@ -169,7 +169,7 @@ ecma_builtin_function_dispatch_construct (const ecma_value_t *arguments_list_p,
                                                 arguments_buffer_size,
                                                 function_body_buffer_p,
                                                 function_body_buffer_size,
-                                                false,
+                                                ECMA_PARSE_NO_OPTS,
                                                 &bytecode_data_p);
 
   if (!ECMA_IS_VALUE_ERROR (ret_value))
index d36cd035d8f0c9b9ef2d446d3d4f73ccbe1d32e3..b5279d6e6a989d731f49c69ceb7edfcd58f6de88 100644 (file)
@@ -63,17 +63,13 @@ ecma_builtin_global_object_eval (ecma_value_t this_arg, /**< this argument */
   JERRY_UNUSED (this_arg);
   ecma_value_t ret_value = ECMA_VALUE_EMPTY;
 
-  bool is_direct_eval = vm_is_direct_eval_form_call ();
+  uint32_t parse_opts = vm_is_direct_eval_form_call () ? ECMA_PARSE_DIRECT_EVAL : ECMA_PARSE_NO_OPTS;
 
   /* See also: ECMA-262 v5, 10.1.1 */
-  bool is_called_from_strict_mode_code;
-  if (is_direct_eval)
+  if (parse_opts && vm_is_strict_mode ())
   {
-    is_called_from_strict_mode_code = vm_is_strict_mode ();
-  }
-  else
-  {
-    is_called_from_strict_mode_code = false;
+    JERRY_ASSERT (parse_opts & ECMA_PARSE_DIRECT_EVAL);
+    parse_opts |= ECMA_PARSE_STRICT_MODE;
   }
 
   if (!ecma_is_value_string (x))
@@ -85,8 +81,7 @@ ecma_builtin_global_object_eval (ecma_value_t this_arg, /**< this argument */
   {
     /* steps 2 to 8 */
     ret_value = ecma_op_eval (ecma_get_string_from_value (x),
-                              is_direct_eval,
-                              is_called_from_strict_mode_code);
+                              parse_opts);
   }
 
   return ret_value;
@@ -190,17 +185,16 @@ ecma_builtin_global_object_parse_int (ecma_value_t this_arg, /**< this argument
       if (ecma_is_value_empty (ret_value))
       {
         /* 10. */
-        if (strip_prefix)
+        if (strip_prefix
+            && ((end_p - start_p) >= 2)
+            && (current == LIT_CHAR_0))
         {
-          if (end_p - start_p >= 2 && current == LIT_CHAR_0)
+          ecma_char_t next = *string_curr_p;
+          if (next == LIT_CHAR_LOWERCASE_X || next == LIT_CHAR_UPPERCASE_X)
           {
-            ecma_char_t next = *string_curr_p;
-            if (next == LIT_CHAR_LOWERCASE_X || next == LIT_CHAR_UPPERCASE_X)
-            {
-              /* Skip the 'x' or 'X' characters. */
-              start_p = ++string_curr_p;
-              rad = 16;
-            }
+            /* Skip the 'x' or 'X' characters. */
+            start_p = ++string_curr_p;
+            rad = 16;
           }
         }
 
@@ -264,13 +258,10 @@ ecma_builtin_global_object_parse_int (ecma_value_t this_arg, /**< this argument
           {
             current_number =  (ecma_number_t) current_char - LIT_CHAR_UPPERCASE_A + 10;
           }
-          else if (lit_char_is_decimal_digit (current_char))
-          {
-            current_number =  (ecma_number_t) current_char - LIT_CHAR_0;
-          }
           else
           {
-            JERRY_UNREACHABLE ();
+            JERRY_ASSERT (lit_char_is_decimal_digit (current_char));
+            current_number =  (ecma_number_t) current_char - LIT_CHAR_0;
           }
 
           value += current_number * multiplier;
@@ -541,9 +532,7 @@ ecma_builtin_global_object_is_nan (ecma_value_t this_arg, /**< this argument */
 
   ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
 
-  bool is_nan = ecma_number_is_nan (arg_num);
-
-  ret_value = is_nan ? ECMA_VALUE_TRUE : ECMA_VALUE_FALSE;
+  ret_value = ecma_make_boolean_value (ecma_number_is_nan (arg_num));
 
   ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
 
@@ -570,8 +559,7 @@ ecma_builtin_global_object_is_finite (ecma_value_t this_arg, /**< this argument
 
   bool is_finite = !(ecma_number_is_nan (arg_num)
                      || ecma_number_is_infinity (arg_num));
-
-  ret_value = is_finite ? ECMA_VALUE_TRUE : ECMA_VALUE_FALSE;
+  ret_value = ecma_make_boolean_value (is_finite);
 
   ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
 
@@ -591,7 +579,7 @@ ecma_builtin_global_object_character_is_in (uint32_t character, /**< character *
   return (bitset[character >> 3] & (1u << (character & 0x7))) != 0;
 } /* ecma_builtin_global_object_character_is_in */
 
-/*
+/**
  * Unescaped URI characters bitset:
  *   One bit for each character between 0 - 127.
  *   Bit is set if the character is in the unescaped URI set.
@@ -602,7 +590,7 @@ static const uint8_t unescaped_uri_set[16] =
   0xff, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x47
 };
 
-/*
+/**
  * Unescaped URI component characters bitset:
  *   One bit for each character between 0 - 127.
  *   Bit is set if the character is in the unescaped component URI set.
@@ -613,18 +601,11 @@ static const uint8_t unescaped_uri_component_set[16] =
   0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x47
 };
 
-/*
+/**
  * Format is a percent sign followed by two hex digits.
  */
 #define URI_ENCODED_BYTE_SIZE (3)
 
-/*
- * These two types shows whether the byte is present in
- * the original stream or decoded from a %xx sequence.
- */
-#define URI_DECODE_ORIGINAL_BYTE 0
-#define URI_DECODE_DECODED_BYTE 1
-
 /**
  * Helper function to decode URI.
  *
@@ -1100,17 +1081,17 @@ ecma_builtin_global_object_encode_uri_component (ecma_value_t this_arg, /**< thi
 
 #ifndef CONFIG_DISABLE_ANNEXB_BUILTIN
 
-/*
+/**
  * Maximum value of a byte.
  */
 #define ECMA_ESCAPE_MAXIMUM_BYTE_VALUE (255)
 
-/*
+/**
  * Format is a percent sign followed by lowercase u and four hex digits.
  */
 #define ECMA_ESCAPE_ENCODED_UNICODE_CHARACTER_SIZE (6)
 
-/*
+/**
  * Escape characters bitset:
  *   One bit for each character between 0 - 127.
  *   Bit is set if the character does not need to be converted to %xx form.
index 37a90bb6c78bdc40a12c38d69fde6438fdd288cf..1339e915cd164c268f280cc11c1ac824f1931cd3 100644 (file)
@@ -191,12 +191,20 @@ OBJECT_VALUE (LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL,
               ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
+
 #ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
 OBJECT_VALUE (LIT_MAGIC_STRING_PROMISE_UL,
               ECMA_BUILTIN_ID_PROMISE,
               ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
 #endif /* !CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */
 
+#ifndef CONFIG_DISABLE_ES2015_MAP_BUILTIN
+/* ECMA-262 v6, 23.1.1.1 */
+OBJECT_VALUE (LIT_MAGIC_STRING_MAP_UL,
+              ECMA_BUILTIN_ID_MAP,
+              ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
+#endif /* !CONFIG_DISABLE_ES2015_MAP_BUILTIN */
+
 /* Routine properties:
  *  (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
 
index 5907270f7a8ad52c99be1938d8cce96970890bac..ccda22b71b2d6f10988a8f87ee360d66e4bb1609 100644 (file)
@@ -41,7 +41,7 @@
  *
  * @return time value for day number
  */
-inline ecma_number_t __attr_always_inline___
+inline ecma_number_t JERRY_ATTR_ALWAYS_INLINE
 ecma_date_day (ecma_number_t time) /**< time value */
 {
   JERRY_ASSERT (!ecma_number_is_nan (time));
@@ -57,7 +57,7 @@ ecma_date_day (ecma_number_t time) /**< time value */
  *
  * @return time value within the day
  */
-inline ecma_number_t __attr_always_inline___
+inline ecma_number_t JERRY_ATTR_ALWAYS_INLINE
 ecma_date_time_within_day (ecma_number_t time) /**< time value */
 {
   JERRY_ASSERT (!ecma_number_is_nan (time));
@@ -92,7 +92,7 @@ ecma_date_day_from_year (ecma_number_t year) /**< year value */
  *
  * @return  time value of the start of a year
  */
-static inline ecma_number_t __attr_always_inline___
+static inline ecma_number_t JERRY_ATTR_ALWAYS_INLINE
 ecma_date_time_from_year (ecma_number_t year) /**< year value */
 {
   JERRY_ASSERT (!ecma_number_is_nan (year));
@@ -302,83 +302,32 @@ ecma_date_week_day (ecma_number_t time) /**< time value */
 } /* ecma_date_week_day */
 
 /**
- * Helper function to get local time zone adjustment.
+ * Helper function to get the local time zone offset at a given UTC timestamp.
+ * You can add this number to the given UTC timestamp to get local time.
  *
  * See also:
- *          ECMA-262 v5, 15.9.1.7
+ *          ECMA-262 v5, 15.9.1.9
  *
  * @return local time zone adjustment
  */
-static inline ecma_number_t __attr_always_inline___
-ecma_date_local_tza (jerry_time_zone_t *tz) /**< time zone information */
+inline ecma_number_t JERRY_ATTR_ALWAYS_INLINE
+ecma_date_local_time_zone_adjustment (ecma_number_t time) /**< time value */
 {
-  return tz->offset * -ECMA_DATE_MS_PER_MINUTE;
-} /* ecma_date_local_tza */
+  return jerry_port_get_local_time_zone_adjustment (time, true);
+} /* ecma_date_local_time_zone_adjustment */
 
 /**
- * Helper function to get the daylight saving time adjustment.
- *
- * See also:
- *          ECMA-262 v5, 15.9.1.8
- *
- * @return daylight saving time adjustment
- */
-static inline ecma_number_t __attr_always_inline___
-ecma_date_daylight_saving_ta (jerry_time_zone_t *tz, /**< time zone information */
-                              ecma_number_t time) /**< time value */
-{
-  JERRY_ASSERT (!ecma_number_is_nan (time));
-
-  /*
-   * TODO: Fix daylight saving calculation.
-   *       https://github.com/jerryscript-project/jerryscript/issues/1661
-   */
-  return tz->daylight_saving_time * ECMA_DATE_MS_PER_HOUR;
-} /* ecma_date_daylight_saving_ta */
-
-/**
- * Helper function to get local time from UTC.
+ * Helper function to get UTC time from local time.
  *
  * See also:
  *          ECMA-262 v5, 15.9.1.9
  *
- * @return local time
- */
-inline ecma_number_t __attr_always_inline___
-ecma_date_local_time_zone (ecma_number_t time) /**< time value */
-{
-  jerry_time_zone_t tz;
-
-  if (ecma_number_is_nan (time)
-      || !jerry_port_get_time_zone (&tz))
-  {
-    return ecma_number_make_nan ();
-  }
-
-  return ecma_date_local_tza (&tz) + ecma_date_daylight_saving_ta (&tz, time);
-} /* ecma_date_local_time_zone */
-
-/**
- * Helper function to get utc from local time.
- *
- * See also:
- *          ECMA-262 v5, 15.9.1.9
- *
- * @return utc time
+ * @return UTC time
  */
 ecma_number_t
 ecma_date_utc (ecma_number_t time) /**< time value */
 {
-  jerry_time_zone_t tz;
-
-  if (ecma_number_is_nan (time)
-      || !jerry_port_get_time_zone (&tz))
-  {
-    return ecma_number_make_nan ();
-  }
-
-  ecma_number_t simple_utc_time = time - ecma_date_local_tza (&tz);
-  return simple_utc_time - ecma_date_daylight_saving_ta (&tz, simple_utc_time);
+  return time - jerry_port_get_local_time_zone_adjustment (time, false);
 } /* ecma_date_utc */
 
 /**
@@ -610,12 +559,12 @@ ecma_date_time_clip (ecma_number_t time) /**< time value */
  *
  * @return timezone offset
  */
-inline ecma_number_t __attr_always_inline___
+inline ecma_number_t JERRY_ATTR_ALWAYS_INLINE
 ecma_date_timezone_offset (ecma_number_t time) /**< time value */
 {
   JERRY_ASSERT (!ecma_number_is_nan (time));
 
-  return (-ecma_date_local_time_zone (time)) / ECMA_DATE_MS_PER_MINUTE;
+  return (-ecma_date_local_time_zone_adjustment (time)) / ECMA_DATE_MS_PER_MINUTE;
 } /* ecma_date_timezone_offset */
 
 /**
@@ -628,18 +577,18 @@ static ecma_value_t
 ecma_date_to_string_format (ecma_number_t datetime_number, /**< datetime */
                             const char *format_p) /**< format buffer */
 {
-  const char *day_names_p[8] =
+  static const char * const day_names_p[8] =
   {
     "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
   };
 
-  const char *month_names_p[13] =
+  static const char * const month_names_p[13] =
   {
     "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
   };
 
   const uint32_t date_buffer_length = 34;
-  lit_utf8_byte_t date_buffer[date_buffer_length];
+  JERRY_VLA (lit_utf8_byte_t, date_buffer, date_buffer_length);
 
   lit_utf8_byte_t *dest_p = date_buffer;
 
@@ -724,7 +673,7 @@ ecma_date_to_string_format (ecma_number_t datetime_number, /**< datetime */
       }
       case LIT_CHAR_LOWERCASE_Z: /* Time zone minutes part. */
       {
-        int32_t time_zone = (int32_t) ecma_date_local_time_zone (datetime_number);
+        int32_t time_zone = (int32_t) ecma_date_local_time_zone_adjustment (datetime_number);
 
         if (time_zone >= 0)
         {
@@ -740,9 +689,11 @@ ecma_date_to_string_format (ecma_number_t datetime_number, /**< datetime */
         number_length = 2;
         break;
       }
-      case LIT_CHAR_UPPERCASE_Z: /* Time zone seconds part. */
+      default:
       {
-        int32_t time_zone = (int32_t) ecma_date_local_time_zone (datetime_number);
+        JERRY_ASSERT (*format_p == LIT_CHAR_UPPERCASE_Z); /* Time zone seconds part. */
+
+        int32_t time_zone = (int32_t) ecma_date_local_time_zone_adjustment (datetime_number);
 
         if (time_zone < 0)
         {
@@ -753,11 +704,6 @@ ecma_date_to_string_format (ecma_number_t datetime_number, /**< datetime */
         number_length = 2;
         break;
       }
-      default:
-      {
-        JERRY_UNREACHABLE ();
-        break;
-      }
     }
 
     format_p++;
@@ -808,7 +754,7 @@ ecma_date_to_string_format (ecma_number_t datetime_number, /**< datetime */
 ecma_value_t
 ecma_date_value_to_string (ecma_number_t datetime_number) /**< datetime */
 {
-  datetime_number += ecma_date_local_time_zone (datetime_number);
+  datetime_number += ecma_date_local_time_zone_adjustment (datetime_number);
   return ecma_date_to_string_format (datetime_number, "$W $M $D $Y $h:$m:$s GMT$z:$Z");
 } /* ecma_date_value_to_string */
 
index d964e4d2f9de136fec8a0408a627b918d7b13d5d..2acdda9a93cbac7667ad148c295e14e7bbe73ad9 100644 (file)
@@ -100,7 +100,7 @@ ecma_has_string_value_in_collection (ecma_collection_header_t *collection_p, /**
  * @return pointer to ecma-string
  *         Returned value must be freed with ecma_deref_ecma_string.
  */
-ecma_string_t *
+static ecma_string_t *
 ecma_builtin_helper_json_create_separated_properties (ecma_collection_header_t *partial_p, /**< key-value pairs*/
                                                       ecma_string_t *separator_p) /**< separator*/
 {
@@ -115,7 +115,7 @@ ecma_builtin_helper_json_create_separated_properties (ecma_collection_header_t *
     ecma_string_t *current_p = ecma_get_string_from_value (*ecma_value_p);
     ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
 
-    if (likely (!first))
+    if (JERRY_LIKELY (!first))
     {
       properties_str_p = ecma_concat_ecma_strings (properties_str_p, separator_p);
     }
diff --git a/deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-sort.c b/deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-helpers-sort.c
new file mode 100644 (file)
index 0000000..241cec3
--- /dev/null
@@ -0,0 +1,146 @@
+/* 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-globals.h"
+#include "ecma-try-catch-macro.h"
+
+/**
+ * Function used to reconstruct the ordered binary tree.
+ * Shifts 'index' down in the tree until it is in the correct position.
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_helper_array_to_heap (ecma_value_t *array_p, /**< heap data array */
+                                   uint32_t index, /**< current item index */
+                                   uint32_t right, /**< right index is a maximum index */
+                                   ecma_value_t compare_func, /**< compare function */
+                                   const ecma_builtin_helper_sort_compare_fn_t sort_cb) /**< sorting cb */
+{
+  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
+
+  /* Left child of the current index. */
+  uint32_t child = index * 2 + 1;
+  ecma_value_t swap = array_p[index];
+  bool should_break = false;
+
+  while (child <= right && ecma_is_value_empty (ret_value) && !should_break)
+  {
+    if (child < right)
+    {
+      /* Compare the two child nodes. */
+      ECMA_TRY_CATCH (child_compare_value, sort_cb (array_p[child], array_p[child + 1], compare_func),
+                      ret_value);
+
+      JERRY_ASSERT (ecma_is_value_number (child_compare_value));
+
+      /* Use the child that is greater. */
+      if (ecma_get_number_from_value (child_compare_value) < ECMA_NUMBER_ZERO)
+      {
+        child++;
+      }
+
+      ECMA_FINALIZE (child_compare_value);
+    }
+
+    if (ecma_is_value_empty (ret_value))
+    {
+      JERRY_ASSERT (child <= right);
+
+      /* Compare current child node with the swap (tree top). */
+      ECMA_TRY_CATCH (swap_compare_value, sort_cb (array_p[child], swap, compare_func), ret_value);
+      JERRY_ASSERT (ecma_is_value_number (swap_compare_value));
+
+      if (ecma_get_number_from_value (swap_compare_value) <= ECMA_NUMBER_ZERO)
+      {
+        /* Break from loop if current child is less than swap (tree top) */
+        should_break = true;
+      }
+      else
+      {
+        /* We have to move 'swap' lower in the tree, so shift current child up in the hierarchy. */
+        uint32_t parent = (child - 1) / 2;
+        JERRY_ASSERT (parent <= right);
+        array_p[parent] = array_p[child];
+
+        /* Update child to be the left child of the current node. */
+        child = child * 2 + 1;
+      }
+
+      ECMA_FINALIZE (swap_compare_value);
+    }
+  }
+
+  /*
+   * Loop ended, either current child does not exist, or is less than swap.
+   * This means that 'swap' should be placed in the parent node.
+   */
+  uint32_t parent = (child - 1) / 2;
+  JERRY_ASSERT (parent <= right);
+  array_p[parent] = swap;
+
+  if (ecma_is_value_empty (ret_value))
+  {
+    ret_value = ECMA_VALUE_UNDEFINED;
+  }
+
+  return ret_value;
+} /* ecma_builtin_helper_array_to_heap */
+
+/**
+ * Heapsort function
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+ecma_value_t
+ecma_builtin_helper_array_heap_sort_helper (ecma_value_t *array_p, /**< array to sort */
+                                            uint32_t right, /**< right index */
+                                            ecma_value_t compare_func, /**< compare function */
+                                            const ecma_builtin_helper_sort_compare_fn_t sort_cb) /**< sorting cb */
+{
+  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
+
+  /* First, construct the ordered binary tree from the array. */
+  for (uint32_t i = (right / 2) + 1; i > 0 && ecma_is_value_empty (ret_value); i--)
+  {
+    ECMA_TRY_CATCH (value,
+                    ecma_builtin_helper_array_to_heap (array_p, i - 1, right, compare_func, sort_cb),
+                    ret_value);
+    ECMA_FINALIZE (value);
+  }
+
+  /* Sorting elements. */
+  for (uint32_t i = right; i > 0 && ecma_is_value_empty (ret_value); i--)
+  {
+    /*
+     * The top element will always contain the largest value.
+     * Move top to the end, and remove it from the tree.
+     */
+    ecma_value_t swap = array_p[0];
+    array_p[0] = array_p[i];
+    array_p[i] = swap;
+
+    /* Rebuild binary tree from the remaining elements. */
+    ECMA_TRY_CATCH (value,
+                    ecma_builtin_helper_array_to_heap (array_p, 0, i - 1, compare_func, sort_cb),
+                    ret_value);
+    ECMA_FINALIZE (value);
+  }
+
+  return ret_value;
+} /* ecma_builtin_helper_array_heap_sort_helper */
index b14588a4027a2e537eb7770212c59129a494a4f6..bccd1aa031b8f04c7afb839bd23b8cf4b30036ec 100644 (file)
@@ -84,7 +84,7 @@ ecma_builtin_helper_object_to_string (const ecma_value_t this_arg) /**< this arg
      'Null' or one of possible object's classes.
      The string with null character is maximum 27 characters long. */
   const lit_utf8_size_t buffer_size = 27;
-  lit_utf8_byte_t str_buffer[buffer_size];
+  JERRY_VLA (lit_utf8_byte_t, str_buffer, buffer_size);
 
   lit_utf8_byte_t *buffer_ptr = str_buffer;
 
@@ -197,10 +197,9 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, /**< object */
 
   uint32_t index = 0;
 
-  ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p,
-                                                                         false,
-                                                                         only_enumerable_properties,
-                                                                         false);
+  ecma_collection_header_t *props_p;
+  props_p = ecma_op_object_get_property_names (obj_p,
+                                               only_enumerable_properties ? ECMA_LIST_ENUMERABLE : ECMA_LIST_NO_OPTS);
 
   ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
 
@@ -211,9 +210,7 @@ ecma_builtin_helper_object_get_properties (ecma_object_t *obj_p, /**< object */
     ecma_value_t completion = ecma_builtin_helper_def_prop (new_array_p,
                                                             index_string_p,
                                                             *ecma_value_p,
-                                                            true, /* Writable */
-                                                            true, /* Enumerable */
-                                                            true, /* Configurable */
+                                                            ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
                                                             false); /* Failure handling */
 
     JERRY_ASSERT (ecma_is_value_true (completion));
@@ -360,10 +357,8 @@ ecma_builtin_helper_array_concat_value (ecma_object_t *obj_p, /**< array */
         ecma_value_t put_comp = ecma_builtin_helper_def_prop (obj_p,
                                                               new_array_index_string_p,
                                                               get_value,
-                                                              true, /* Writable */
-                                                              true, /* Enumerable */
-                                                              true, /* Configurable */
-                                                              false); /* Failure handling */
+                                                              ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+                                                              false);  /* Failure handling */
 
         JERRY_ASSERT (ecma_is_value_true (put_comp));
         ecma_deref_ecma_string (new_array_index_string_p);
@@ -388,10 +383,8 @@ ecma_builtin_helper_array_concat_value (ecma_object_t *obj_p, /**< array */
     ecma_value_t put_comp = ecma_builtin_helper_def_prop (obj_p,
                                                           new_array_index_string_p,
                                                           value,
-                                                          true, /* Writable */
-                                                          true, /* Enumerable */
-                                                          true, /* Configurable */
-                                                          false); /* Failure handling */
+                                                          ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+                                                          false);  /* Failure handling */
 
     JERRY_ASSERT (ecma_is_value_true (put_comp));
 
@@ -470,7 +463,7 @@ ecma_builtin_helper_string_index_normalize (ecma_number_t index, /**< index */
  *         - The String.prototype.indexOf routine.
  *         - The String.prototype.lastIndexOf routine.
  *
- * @return uint32_t - (last) index of search string
+ * @return ecma_value_t - (last) index of search string as an ecma-value
  */
 ecma_value_t
 ecma_builtin_helper_string_prototype_object_index_of (ecma_value_t this_arg, /**< this argument */
@@ -544,14 +537,14 @@ ecma_builtin_helper_string_prototype_object_index_of (ecma_value_t this_arg, /**
  *         - The ecma_builtin_helper_string_prototype_object_index_of helper routine.
  *         - The ecma_builtin_string_prototype_object_replace_match helper routine.
  *
- * @return uint32_t - the normalized value of the index
+ * @return bool - whether there is a match for the search string
  */
 bool
 ecma_builtin_helper_string_find_index (ecma_string_t *original_str_p, /**< index */
                                        ecma_string_t *search_str_p, /**< string's length */
                                        bool first_index, /**< whether search for first (t) or last (f) index */
                                        ecma_length_t start_pos, /**< start position */
-                                       ecma_length_t *ret_index_p) /**< position found in original string */
+                                       ecma_length_t *ret_index_p) /**< [out] position found in original string */
 {
   bool match_found = false;
   const ecma_length_t original_len = ecma_string_get_length (original_str_p);
@@ -660,9 +653,7 @@ ecma_value_t
 ecma_builtin_helper_def_prop (ecma_object_t *obj_p, /**< object */
                               ecma_string_t *index_p, /**< index string */
                               ecma_value_t value, /**< value */
-                              bool writable, /**< writable */
-                              bool enumerable, /**< enumerable */
-                              bool configurable, /**< configurable */
+                              uint32_t opts, /**< any combination of ecma_property_flag_t bits */
                               bool is_throw) /**< is_throw */
 {
   ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
@@ -671,13 +662,13 @@ ecma_builtin_helper_def_prop (ecma_object_t *obj_p, /**< object */
   prop_desc.value = value;
 
   prop_desc.is_writable_defined = true;
-  prop_desc.is_writable = ECMA_BOOL_TO_BITFIELD (writable);
+  prop_desc.is_writable = (opts & ECMA_PROPERTY_FLAG_WRITABLE) != 0;
 
   prop_desc.is_enumerable_defined = true;
-  prop_desc.is_enumerable = ECMA_BOOL_TO_BITFIELD (enumerable);
+  prop_desc.is_enumerable = (opts & ECMA_PROPERTY_FLAG_ENUMERABLE) != 0;
 
   prop_desc.is_configurable_defined = true;
-  prop_desc.is_configurable = ECMA_BOOL_TO_BITFIELD (configurable);
+  prop_desc.is_configurable = (opts & ECMA_PROPERTY_FLAG_CONFIGURABLE) != 0;
 
   return ecma_op_object_define_own_property (obj_p,
                                              index_p,
index 1e14a86abbc46abb8e7cbc01d42ee02627c5b880..c061e46093ebd442fcae8dc290fe52680cca721e 100644 (file)
@@ -46,7 +46,7 @@ ecma_builtin_helper_string_find_index (ecma_string_t *original_str_p, ecma_strin
                                        ecma_length_t start_pos, ecma_length_t *ret_index_p);
 ecma_value_t
 ecma_builtin_helper_def_prop (ecma_object_t *obj_p, ecma_string_t *index_p, ecma_value_t value,
-                              bool writable, bool enumerable, bool configurable, bool is_throw);
+                              uint32_t opts, bool is_throw);
 
 #ifndef CONFIG_DISABLE_DATE_BUILTIN
 
@@ -100,7 +100,7 @@ ecma_number_t ecma_date_year_from_time (ecma_number_t time);
 ecma_number_t ecma_date_month_from_time (ecma_number_t time);
 ecma_number_t ecma_date_date_from_time (ecma_number_t time);
 ecma_number_t ecma_date_week_day (ecma_number_t time);
-ecma_number_t ecma_date_local_time_zone (ecma_number_t time);
+ecma_number_t ecma_date_local_time_zone_adjustment (ecma_number_t time);
 ecma_number_t ecma_date_utc (ecma_number_t time);
 ecma_number_t ecma_date_hour_from_time (ecma_number_t time);
 ecma_number_t ecma_date_min_from_time (ecma_number_t time);
@@ -158,8 +158,6 @@ ecma_value_t ecma_builtin_json_string_from_object (const ecma_value_t arg1);
 bool ecma_json_has_object_in_stack (ecma_json_occurence_stack_item_t *stack_p, ecma_object_t *object_p);
 bool ecma_has_string_value_in_collection (ecma_collection_header_t *collection_p, ecma_value_t string_value);
 
-ecma_string_t *
-ecma_builtin_helper_json_create_separated_properties (ecma_collection_header_t *partial_p, ecma_string_t *separator_p);
 ecma_value_t
 ecma_builtin_helper_json_create_formatted_json (lit_utf8_byte_t left_bracket, lit_utf8_byte_t right_bracket,
                                                 ecma_string_t *stepback_p, ecma_collection_header_t *partial_p,
@@ -174,6 +172,20 @@ ecma_value_t
 ecma_builtin_helper_error_dispatch_call (ecma_standard_error_t error_type, const ecma_value_t *arguments_list_p,
                                          ecma_length_t arguments_list_len);
 
+/* ecma-builtin-helpers-sort.c */
+
+/**
+ * Comparison callback function header for sorting helper routines.
+ */
+typedef ecma_value_t (*ecma_builtin_helper_sort_compare_fn_t)(ecma_value_t lhs, /**< left value */
+                                                              ecma_value_t rhs, /**< right value */
+                                                              ecma_value_t compare_func); /**< compare function */
+
+ecma_value_t ecma_builtin_helper_array_heap_sort_helper (ecma_value_t *array_p,
+                                                         uint32_t right,
+                                                         ecma_value_t compare_func,
+                                                         const ecma_builtin_helper_sort_compare_fn_t sort_cb);
+
 /**
  * @}
  * @}
index d1cd02858ba4df296fd4b7480e9e91f7298782d5..dc1da075ee8b8973ffd8d7ed417daed717e3c995 100644 (file)
@@ -543,9 +543,7 @@ ecma_builtin_json_define_value_property (ecma_object_t *obj_p, /**< this object
   ecma_value_t completion_value = ecma_builtin_helper_def_prop (obj_p,
                                                                 property_name_p,
                                                                 value,
-                                                                true, /* Writable */
-                                                                true, /* Enumerable */
-                                                                true, /* Configurable */
+                                                                ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
                                                                 false); /* Failure handling */
 
   JERRY_ASSERT (ecma_is_value_boolean (completion_value));
@@ -685,9 +683,7 @@ ecma_builtin_json_parse_value (ecma_json_token_t *token_p) /**< token argument *
         ecma_value_t completion = ecma_builtin_helper_def_prop (array_p,
                                                                 index_str_p,
                                                                 value,
-                                                                true, /* Writable */
-                                                                true, /* Enumerable */
-                                                                true, /* Configurable */
+                                                                ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
                                                                 false); /* Failure handling */
 
         JERRY_ASSERT (ecma_is_value_true (completion));
@@ -741,7 +737,7 @@ ecma_builtin_json_walk (ecma_object_t *reviver_p, /**< reviver function */
   {
     ecma_object_t *object_p = ecma_get_object_from_value (value_get);
 
-    ecma_collection_header_t *props_p = ecma_op_object_get_property_names (object_p, false, true, false);
+    ecma_collection_header_t *props_p = ecma_op_object_get_property_names (object_p, ECMA_LIST_ENUMERABLE);
 
     ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
 
@@ -923,13 +919,16 @@ static ecma_value_t ecma_builtin_json_str_helper (const ecma_value_t arg1, /**<
                                                   empty_str_p,
                                                   arg1,
                                                   false);
-  JERRY_ASSERT (ecma_is_value_true (put_comp_val));
-  ecma_free_value (put_comp_val);
-  ECMA_TRY_CATCH (str_val,
-                  ecma_builtin_json_str (empty_str_p, obj_wrapper_p, &context),
-                  ret_value);
-  ret_value = ecma_copy_value (str_val);
-  ECMA_FINALIZE (str_val);
+
+  if (ecma_is_value_true (put_comp_val))
+  {
+    ret_value = ecma_builtin_json_str (empty_str_p, obj_wrapper_p, &context);
+  }
+  else
+  {
+    ret_value = ECMA_VALUE_UNDEFINED;
+  }
+
   ecma_free_value (put_comp_val);
   ecma_deref_ecma_string (empty_str_p);
   ecma_deref_object (obj_wrapper_p);
@@ -1213,106 +1212,137 @@ ecma_builtin_json_stringify (ecma_value_t this_arg, /**< 'this' argument */
 static ecma_value_t
 ecma_builtin_json_quote (ecma_string_t *string_p) /**< string that should be quoted*/
 {
-  /* 1. */
-  ecma_string_t *product_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_DOUBLE_QUOTE_CHAR);
-
   ECMA_STRING_TO_UTF8_STRING (string_p, string_buff, string_buff_size);
-
   const lit_utf8_byte_t *str_p = string_buff;
-  const lit_utf8_byte_t *str_end_p = string_buff + string_buff_size;
+  const lit_utf8_byte_t *str_end_p = str_p + string_buff_size;
+  size_t n_bytes = 2; /* Start with 2 for surrounding quotes. */
 
   while (str_p < str_end_p)
   {
-    ecma_char_t current_char = lit_utf8_read_next (&str_p);
+    lit_utf8_byte_t c = *str_p++;
 
-    /* 2.a, b */
-    if (current_char == LIT_CHAR_BACKSLASH
-        || current_char == LIT_CHAR_DOUBLE_QUOTE
-        || current_char == LIT_CHAR_BS
-        || current_char == LIT_CHAR_FF
-        || current_char == LIT_CHAR_LF
-        || current_char == LIT_CHAR_CR
-        || current_char == LIT_CHAR_TAB)
+    if (c == LIT_CHAR_BACKSLASH || c == LIT_CHAR_DOUBLE_QUOTE)
+    {
+      n_bytes += 2;
+    }
+    else if (c >= LIT_CHAR_SP && c < LIT_UTF8_1_BYTE_CODE_POINT_MAX)
+    {
+      n_bytes++;
+    }
+    else if (c > LIT_UTF8_1_BYTE_CODE_POINT_MAX)
+    {
+      lit_utf8_size_t sz = lit_get_unicode_char_size_by_utf8_first_byte (c);
+      n_bytes += sz;
+      str_p += sz - 1;
+    }
+    else
     {
-      lit_utf8_byte_t abbrev = (lit_utf8_byte_t) current_char;
+      switch (c)
+      {
+        case LIT_CHAR_BS:
+        case LIT_CHAR_FF:
+        case LIT_CHAR_LF:
+        case LIT_CHAR_CR:
+        case LIT_CHAR_TAB:
+        {
+          n_bytes += 2;
+          break;
+        }
+        default: /* Hexadecimal. */
+        {
+          n_bytes += 2 + 4;
+          break;
+        }
+      }
+    }
+  }
 
-      switch (current_char)
+  lit_utf8_byte_t *buf_begin = jmem_heap_alloc_block (n_bytes);
+  JERRY_ASSERT (buf_begin != NULL);
+  lit_utf8_byte_t *buf = buf_begin;
+  str_p = string_buff;
+
+  *buf++ = LIT_CHAR_DOUBLE_QUOTE;
+
+  while (str_p < str_end_p)
+  {
+    lit_utf8_byte_t c = *str_p++;
+
+    if (c == LIT_CHAR_BACKSLASH || c == LIT_CHAR_DOUBLE_QUOTE)
+    {
+      *buf++ = LIT_CHAR_BACKSLASH;
+      *buf++ = c;
+    }
+    else if (c >= LIT_CHAR_SP && c < LIT_UTF8_1_BYTE_CODE_POINT_MAX)
+    {
+      *buf++ = c;
+    }
+    else if (c > LIT_UTF8_1_BYTE_CODE_POINT_MAX)
+    {
+      str_p--;
+      ecma_char_t current_char = lit_utf8_read_next (&str_p);
+      buf += lit_code_unit_to_utf8 (current_char, (lit_utf8_byte_t *) buf);
+    }
+    else
+    {
+      switch (c)
       {
         case LIT_CHAR_BS:
         {
-          abbrev = LIT_CHAR_LOWERCASE_B;
+          *buf++ = LIT_CHAR_BACKSLASH;
+          *buf++ = LIT_CHAR_LOWERCASE_B;
           break;
         }
         case LIT_CHAR_FF:
         {
-          abbrev = LIT_CHAR_LOWERCASE_F;
+          *buf++ = LIT_CHAR_BACKSLASH;
+          *buf++ = LIT_CHAR_LOWERCASE_F;
           break;
         }
         case LIT_CHAR_LF:
         {
-          abbrev = LIT_CHAR_LOWERCASE_N;
+          *buf++ = LIT_CHAR_BACKSLASH;
+          *buf++ = LIT_CHAR_LOWERCASE_N;
           break;
         }
         case LIT_CHAR_CR:
         {
-          abbrev = LIT_CHAR_LOWERCASE_R;
+          *buf++ = LIT_CHAR_BACKSLASH;
+          *buf++ = LIT_CHAR_LOWERCASE_R;
           break;
         }
         case LIT_CHAR_TAB:
         {
-          abbrev = LIT_CHAR_LOWERCASE_T;
+          *buf++ = LIT_CHAR_BACKSLASH;
+          *buf++ = LIT_CHAR_LOWERCASE_T;
           break;
         }
-        default:
+        default: /* Hexadecimal. */
         {
-          JERRY_ASSERT (current_char == LIT_CHAR_BACKSLASH || current_char == LIT_CHAR_DOUBLE_QUOTE);
+          JERRY_ASSERT (c < 0x9f);
+          *buf++ = LIT_CHAR_BACKSLASH;
+          *buf++ = LIT_CHAR_LOWERCASE_U;
+          *buf++ = LIT_CHAR_0;
+          *buf++ = LIT_CHAR_0;
+          *buf++ = (lit_utf8_byte_t) (LIT_CHAR_0 + (c >> 4)); /* Max range 0-9, hex digits unnecessary. */
+          lit_utf8_byte_t c2 = (c & 0xf);
+          *buf++ = (lit_utf8_byte_t) (c2 + ((c2 <= 9) ? LIT_CHAR_0 : (LIT_CHAR_LOWERCASE_A - 10)));
           break;
         }
       }
-
-      lit_utf8_byte_t chars[2] = { LIT_CHAR_BACKSLASH, abbrev };
-
-      product_str_p = ecma_append_chars_to_string (product_str_p, chars, 2, 2);
     }
-    /* 2.c */
-    else if (current_char < LIT_CHAR_SP)
-    {
-      lit_utf8_byte_t chars[6] = { LIT_CHAR_BACKSLASH, LIT_CHAR_LOWERCASE_U, LIT_CHAR_0, LIT_CHAR_0 };
-
-      JERRY_ASSERT (current_char < 0x9f);
-
-      chars[4] = (lit_utf8_byte_t) (LIT_CHAR_0 + (current_char >> 4));
-
-      int last_char = current_char & 0xf;
-      last_char += (last_char <= 9) ? LIT_CHAR_0 : (LIT_CHAR_LOWERCASE_A - 10);
-
-      chars[5] = (lit_utf8_byte_t) last_char;
-
-      product_str_p = ecma_append_chars_to_string (product_str_p, chars, 6, 6);
-    }
-    /* 2.d */
-    else if (current_char < LIT_UTF8_1_BYTE_CODE_POINT_MAX)
-    {
-      /* Fast case for ascii characters. */
-      lit_utf8_byte_t chars[1] = { (lit_utf8_byte_t) current_char };
+  }
 
-      product_str_p = ecma_append_chars_to_string (product_str_p, chars, 1, 1);
-    }
-    else
-    {
-      ecma_string_t *current_char_str_p = ecma_new_ecma_string_from_code_unit (current_char);
+  *buf++ = LIT_CHAR_DOUBLE_QUOTE;
 
-      product_str_p = ecma_concat_ecma_strings (product_str_p, current_char_str_p);
-      ecma_deref_ecma_string (current_char_str_p);
-    }
-  }
+  /* Make sure we didn't run off the end or allocated more than we actually wanted. */
+  JERRY_ASSERT ((size_t) (buf - buf_begin) == n_bytes);
 
+  ecma_string_t *product_str_p = ecma_new_ecma_string_from_utf8 ((const lit_utf8_byte_t *) buf_begin,
+                                                                 (lit_utf8_size_t) (buf - buf_begin));
+  jmem_heap_free_block (buf_begin, n_bytes);
   ECMA_FINALIZE_UTF8_STRING (string_buff, string_buff_size);
 
-  /* 3. */
-  product_str_p = ecma_append_magic_string_to_string (product_str_p, LIT_MAGIC_STRING_DOUBLE_QUOTE_CHAR);
-
-  /* 4. */
   return ecma_make_string_value (product_str_p);
 } /* ecma_builtin_json_quote */
 
@@ -1549,7 +1579,7 @@ ecma_builtin_json_object (ecma_object_t *obj_p, /**< the object*/
   {
     property_keys_p = ecma_new_values_collection ();
 
-    ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, false, true, false);
+    ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_ENUMERABLE);
 
     ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
 
diff --git a/deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-map-prototype.c b/deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-map-prototype.c
new file mode 100644 (file)
index 0000000..820fc69
--- /dev/null
@@ -0,0 +1,138 @@
+/* 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-map-object.h"
+
+#ifndef CONFIG_DISABLE_ES2015_MAP_BUILTIN
+
+#define ECMA_BUILTINS_INTERNAL
+#include "ecma-builtins-internal.h"
+
+#define BUILTIN_INC_HEADER_NAME "ecma-builtin-map-prototype.inc.h"
+#define BUILTIN_UNDERSCORED_ID map_prototype
+#include "ecma-builtin-internal-routines-template.inc.h"
+
+/** \addtogroup ecma ECMA
+ * @{
+ *
+ * \addtogroup ecmabuiltins
+ * @{
+ *
+ * \addtogroup map ECMA Map object built-in
+ * @{
+ */
+
+/**
+ * The Map.prototype object's 'clear' routine
+ *
+ * See also:
+ *          ECMA-262 v6, 23.1.3.1
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_map_prototype_object_clear (ecma_value_t this_arg) /**< this argument */
+{
+  return ecma_op_map_clear (this_arg);
+} /* ecma_builtin_map_prototype_object_clear */
+
+/**
+ * The Map.prototype object's 'delete' routine
+ *
+ * See also:
+ *          ECMA-262 v6, 23.1.3.3
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_map_prototype_object_delete (ecma_value_t this_arg, /**< this argument */
+                                          ecma_value_t key_arg) /**< key argument */
+{
+  return ecma_op_map_delete (this_arg, key_arg);
+} /* ecma_builtin_map_prototype_object_delete */
+
+/**
+ * The Map.prototype object's 'get' routine
+ *
+ * See also:
+ *          ECMA-262 v6, 23.1.3.6
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_map_prototype_object_get (ecma_value_t this_arg, /**< this argument */
+                                       ecma_value_t key_arg) /**< key argument */
+{
+  return ecma_op_map_get (this_arg, key_arg);
+} /* ecma_builtin_map_prototype_object_get */
+
+/**
+ * The Map.prototype object's 'has' routine
+ *
+ * See also:
+ *          ECMA-262 v6, 23.1.3.7
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_map_prototype_object_has (ecma_value_t this_arg, /**< this argument */
+                                       ecma_value_t key_arg) /**< key argument */
+{
+  return ecma_op_map_has (this_arg, key_arg);
+} /* ecma_builtin_map_prototype_object_has */
+
+/**
+ * The Map.prototype object's 'set' routine
+ *
+ * See also:
+ *          ECMA-262 v6, 23.1.3.9
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_map_prototype_object_set (ecma_value_t this_arg, /**< this argument */
+                                       ecma_value_t key_arg, /**< key argument */
+                                       ecma_value_t value_arg) /**< value argument */
+{
+  return ecma_op_map_set (this_arg, key_arg, value_arg);
+} /* ecma_builtin_map_prototype_object_set */
+
+/**
+ * The Map.prototype object's 'size' getter
+ *
+ * See also:
+ *          ECMA-262 v6, 23.1.3.10
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_map_prototype_object_size_getter (ecma_value_t this_arg) /**< this argument */
+{
+  return ecma_op_map_size (this_arg);
+} /* ecma_builtin_map_prototype_object_size_getter */
+
+/**
+ * @}
+ * @}
+ * @}
+ */
+
+#endif /* !CONFIG_DISABLE_ES2015_MAP_BUILTIN */
diff --git a/deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-map-prototype.inc.h b/deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-map-prototype.inc.h
new file mode 100644 (file)
index 0000000..41001a8
--- /dev/null
@@ -0,0 +1,52 @@
+/* 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.
+ */
+
+/*
+ * Map.prototype built-in description
+ */
+
+#include "ecma-builtin-helpers-macro-defines.inc.h"
+
+#ifndef CONFIG_DISABLE_ES2015_MAP_BUILTIN
+
+/* Object properties:
+ *  (property name, object pointer getter) */
+
+/* ECMA-262 v6, 23.1.3.2 */
+OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
+              ECMA_BUILTIN_ID_MAP,
+              ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
+
+/* ECMA-262 v6, 23.1.3 */
+STRING_VALUE (LIT_MAGIC_STRING_NAME,
+              LIT_MAGIC_STRING_MAP_UL,
+              ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
+
+/* Routine properties:
+ *  (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
+ROUTINE (LIT_MAGIC_STRING_CLEAR, ecma_builtin_map_prototype_object_clear, 0, 0)
+ROUTINE (LIT_MAGIC_STRING_DELETE, ecma_builtin_map_prototype_object_delete, 1, 1)
+ROUTINE (LIT_MAGIC_STRING_GET, ecma_builtin_map_prototype_object_get, 1, 1)
+ROUTINE (LIT_MAGIC_STRING_HAS, ecma_builtin_map_prototype_object_has, 1, 1)
+ROUTINE (LIT_MAGIC_STRING_SET, ecma_builtin_map_prototype_object_set, 2, 2)
+
+/* ECMA-262 v6, 23.1.3.10 */
+ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_SIZE,
+                    ecma_builtin_map_prototype_object_size_getter,
+                    ECMA_PROPERTY_FIXED)
+
+#endif /* !CONFIG_DISABLE_ES2015_MAP_BUILTIN */
+
+#include "ecma-builtin-helpers-macro-undefs.inc.h"
diff --git a/deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-map.c b/deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-map.c
new file mode 100644 (file)
index 0000000..084f435
--- /dev/null
@@ -0,0 +1,71 @@
+/* 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-map-object.h"
+
+#ifndef CONFIG_DISABLE_ES2015_MAP_BUILTIN
+
+#define ECMA_BUILTINS_INTERNAL
+#include "ecma-builtins-internal.h"
+
+#define BUILTIN_INC_HEADER_NAME "ecma-builtin-map.inc.h"
+#define BUILTIN_UNDERSCORED_ID map
+#include "ecma-builtin-internal-routines-template.inc.h"
+
+/** \addtogroup ecma ECMA
+ * @{
+ *
+ * \addtogroup ecmabuiltins
+ * @{
+ *
+ * \addtogroup map ECMA Map object built-in
+ * @{
+ */
+
+/**
+ * Handle calling [[Call]] of built-in Map object
+ *
+ * @return ecma value
+ */
+ecma_value_t
+ecma_builtin_map_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 Map requires 'new'."));
+} /* ecma_builtin_map_dispatch_call */
+
+/**
+ * Handle calling [[Construct]] of built-in Map object
+ *
+ * @return ecma value
+ */
+ecma_value_t
+ecma_builtin_map_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
+                                     ecma_length_t arguments_list_len) /**< number of arguments */
+{
+  return ecma_op_map_create (arguments_list_p, arguments_list_len);
+} /* ecma_builtin_map_dispatch_construct */
+
+/**
+ * @}
+ * @}
+ * @}
+ */
+
+#endif /* !CONFIG_DISABLE_ES2015_MAP_BUILTIN */
diff --git a/deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-map.inc.h b/deps/jerry/jerry-core/ecma/builtin-objects/ecma-builtin-map.inc.h
new file mode 100644 (file)
index 0000000..7869fff
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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.
+ */
+
+/*
+ * Map built-in description
+ */
+
+#include "ecma-builtin-helpers-macro-defines.inc.h"
+
+#ifndef CONFIG_DISABLE_ES2015_MAP_BUILTIN
+
+/* Number properties:
+ *  (property name, number value, writable, enumerable, configurable) */
+
+/* ECMA-262 v6, 23.1.2 */
+NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
+              0,
+              ECMA_PROPERTY_FIXED)
+
+/* Object properties:
+ *  (property name, object pointer getter) */
+
+/* ECMA-262 v6, 23.1.2.1 */
+OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
+              ECMA_BUILTIN_ID_MAP_PROTOTYPE,
+              ECMA_PROPERTY_FIXED)
+
+#endif /* !CONFIG_DISABLE_ES2015_MAP_BUILTIN */
+
+#include "ecma-builtin-helpers-macro-undefs.inc.h"
index b14aaff2422378208e34ccde170d01dab4ab995b..2a3440733253c37afe88f6e12181a116180a12d4 100644 (file)
@@ -122,7 +122,7 @@ ecma_builtin_math_object_max_min (bool is_max, /**< 'max' or 'min' operation */
       ecma_fast_free_value (value);
     }
 
-    if (unlikely (ecma_number_is_nan (arg_num)))
+    if (JERRY_UNLIKELY (ecma_number_is_nan (arg_num)))
     {
       result_num = arg_num;
       break;
@@ -213,27 +213,25 @@ ecma_builtin_math_dispatch_routine (uint16_t builtin_routine_id, /**< built-in w
       }
     }
 
-    if (builtin_routine_id >= ECMA_MATH_OBJECT_ATAN2)
+    if (builtin_routine_id >= ECMA_MATH_OBJECT_ATAN2
+        && arguments_number >= 2)
     {
-      if (arguments_number >= 2)
+      if (ecma_is_value_number (arguments_list[1]))
       {
-        if (ecma_is_value_number (arguments_list[1]))
+        y = ecma_get_number_from_value (arguments_list[1]);
+      }
+      else
+      {
+        ecma_value_t value = ecma_op_to_number (arguments_list[1]);
+
+        if (ECMA_IS_VALUE_ERROR (value))
         {
-          y = ecma_get_number_from_value (arguments_list[1]);
+          return value;
         }
-        else
-        {
-          ecma_value_t value = ecma_op_to_number (arguments_list[1]);
-
-          if (ECMA_IS_VALUE_ERROR (value))
-          {
-            return value;
-          }
 
-          y = ecma_get_number_from_value (value);
+        y = ecma_get_number_from_value (value);
 
-          ecma_fast_free_value (value);
-        }
+        ecma_fast_free_value (value);
       }
     }
 
index d8c6a753bd7c0ad4dda0fc5940d33f351ef2648d..ceada68d19e4bcf30ade4b7b7a5f431cf38fe496 100644 (file)
@@ -125,7 +125,12 @@ ecma_builtin_number_prototype_helper_to_string (lit_utf8_byte_t *digits_p, /**<
   return (lit_utf8_size_t) (p - to_digits_p);
 } /* ecma_builtin_number_prototype_helper_to_string */
 
-static inline lit_utf8_size_t __attr_always_inline___
+/**
+ * Helper function to convert a binary floating point number to string.
+ *
+ * @return size of result string
+ */
+static inline lit_utf8_size_t JERRY_ATTR_ALWAYS_INLINE
 ecma_builtin_binary_floating_number_to_string (lit_utf8_byte_t *digits_p, /**< number as string
                                                                            * in binary-floating point number */
                                                int32_t exponent, /**< decimal exponent */
@@ -164,7 +169,7 @@ ecma_builtin_binary_floating_number_to_string (lit_utf8_byte_t *digits_p, /**< n
  *
  * @return rounded number
  */
-static inline lit_utf8_size_t __attr_always_inline___
+static inline lit_utf8_size_t JERRY_ATTR_ALWAYS_INLINE
 ecma_builtin_number_prototype_helper_round (lit_utf8_byte_t *digits_p, /**< [in,out] number as a string in decimal
                                                                         *   form */
                                             lit_utf8_size_t num_digits, /**< length of the string representation */
@@ -303,7 +308,7 @@ ecma_builtin_number_prototype_object_to_string (ecma_value_t this_arg, /**< this
          * cases that can cause incorrect results due to precision issues, so we use a loop instead.
          */
         magnitude = 0;
-        double counter = this_arg_number;
+        ecma_number_t counter = this_arg_number;
         while (counter >= radix)
         {
           counter /= radix;
@@ -645,7 +650,7 @@ ecma_builtin_number_prototype_object_to_fixed (ecma_value_t this_arg, /**< this
                                                                    num_digits + 1,
                                                                    exponent + frac_digits,
                                                                    &exponent,
-                                                                   ecma_number_is_zero (this_num) ? true : false);
+                                                                   ecma_number_is_zero (this_num));
 
           /* Buffer that is used to construct the string. */
           int buffer_size = (exponent > 0) ? exponent + frac_digits + 2 : frac_digits + 3;
index 0143c43f15a47b0459497f0fa68217719d999ce9..6b1d8931a965430407db22aacd54728f4bde13ce 100644 (file)
@@ -192,7 +192,7 @@ ecma_builtin_object_prototype_object_is_prototype_of (ecma_value_t this_arg, /**
   ecma_object_t *v_obj_p = ecma_get_object_from_value (v_obj_value);
 
   bool is_prototype_of = ecma_op_object_is_prototype_of (obj_p, v_obj_p);
-  return_value = is_prototype_of ? ECMA_VALUE_TRUE : ECMA_VALUE_FALSE;
+  return_value = ecma_make_boolean_value (is_prototype_of);
   ECMA_FINALIZE (v_obj_value);
 
   ECMA_FINALIZE (obj_value);
index f74f20e6bf8393a03a01b04cacbed50b3ee9c408..87c0279779a37e5233ecc6be2331344182ca44dc 100644 (file)
@@ -153,6 +153,9 @@ ecma_builtin_object_object_get_prototype_of (ecma_value_t this_arg, /**< 'this'
  *
  * See also:
  *          ES2015 9.1.2
+ *
+ * @return true  - if success
+ *         false - otherwise
  */
 static bool
 ecma_set_prototype_of (ecma_value_t o_value, /**< O */
@@ -325,7 +328,7 @@ ecma_builtin_object_object_seal (ecma_value_t this_arg, /**< 'this' argument */
     /* 2. */
     ecma_object_t *obj_p = ecma_get_object_from_value (arg);
 
-    ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, false, false, false);
+    ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_NO_OPTS);
 
     ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
 
@@ -398,7 +401,7 @@ ecma_builtin_object_object_freeze (ecma_value_t this_arg, /**< 'this' argument *
     /* 2. */
     ecma_object_t *obj_p = ecma_get_object_from_value (arg);
 
-    ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, false, false, false);
+    ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_NO_OPTS);
 
     ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
 
@@ -483,17 +486,19 @@ ecma_builtin_object_object_prevent_extensions (ecma_value_t this_arg, /**< 'this
 } /* ecma_builtin_object_object_prevent_extensions */
 
 /**
- * The Object object's 'isSealed' routine
+ * Common helper code for the 'isFrozen' and 'isSealed' fuctions of Object.
  *
  * See also:
- *          ECMA-262 v5, 15.2.3.11
+ *         Object.isFrozen
+ *         Object.isSealed
  *
  * @return ecma value
  *         Returned value must be freed with ecma_free_value.
  */
 static ecma_value_t
-ecma_builtin_object_object_is_sealed (ecma_value_t this_arg, /**< 'this' argument */
-                                      ecma_value_t arg) /**< routine's argument */
+ecma_builtin_object_frozen_or_sealed_helper (ecma_value_t this_arg, /**< 'this' argument */
+                                             ecma_value_t arg, /**< routine's argument */
+                                             bool frozen_mode) /**< routine mode */
 {
   JERRY_UNUSED (this_arg);
   ecma_value_t ret_value = ECMA_VALUE_EMPTY;
@@ -507,20 +512,18 @@ ecma_builtin_object_object_is_sealed (ecma_value_t this_arg, /**< 'this' argumen
   {
     ecma_object_t *obj_p = ecma_get_object_from_value (arg);
 
-    bool is_sealed;
-
     /* 3. */
     if (ecma_get_object_extensible (obj_p))
     {
-      is_sealed = false;
+      ret_value = ECMA_VALUE_FALSE;
     }
     else
     {
       /* the value can be updated in the loop below */
-      is_sealed = true;
+      ret_value = ECMA_VALUE_TRUE;
 
       /* 2. */
-      ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, false, false, false);
+      ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_NO_OPTS);
 
       ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
 
@@ -535,22 +538,44 @@ ecma_builtin_object_object_is_sealed (ecma_value_t this_arg, /**< 'this' argumen
                                                                     NULL,
                                                                     ECMA_PROPERTY_GET_NO_OPTIONS);
 
-        /* 2.b */
+        /* 2.b for isFrozen */
+        if (frozen_mode
+            && ECMA_PROPERTY_GET_TYPE (property) != ECMA_PROPERTY_TYPE_NAMEDACCESSOR
+            && ecma_is_property_writable (property))
+        {
+          ret_value = ECMA_VALUE_FALSE;
+          break;
+        }
+
+        /* 2.b for isSealed, 2.c for isFrozen */
         if (ecma_is_property_configurable (property))
         {
-          is_sealed = false;
+          ret_value = ECMA_VALUE_FALSE;
           break;
         }
       }
 
       ecma_free_values_collection (props_p, 0);
     }
-
-    /* 4. */
-    ret_value = is_sealed ? ECMA_VALUE_TRUE : ECMA_VALUE_FALSE;
   }
 
   return ret_value;
+} /* ecma_builtin_object_frozen_or_sealed_helper */
+
+/**
+ * The Object object's 'isSealed' routine
+ *
+ * See also:
+ *          ECMA-262 v5, 15.2.3.11
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_object_object_is_sealed (ecma_value_t this_arg, /**< 'this' argument */
+                                      ecma_value_t arg) /**< routine's argument */
+{
+  return ecma_builtin_object_frozen_or_sealed_helper (this_arg, arg, false);
 } /* ecma_builtin_object_object_is_sealed */
 
 /**
@@ -566,69 +591,7 @@ static ecma_value_t
 ecma_builtin_object_object_is_frozen (ecma_value_t this_arg, /**< 'this' argument */
                                       ecma_value_t arg) /**< routine's argument */
 {
-  JERRY_UNUSED (this_arg);
-  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
-  /* 1. */
-  if (!ecma_is_value_object (arg))
-  {
-    ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an object."));
-  }
-  else
-  {
-    ecma_object_t *obj_p = ecma_get_object_from_value (arg);
-
-    bool is_frozen;
-
-    /* 3. */
-    if (ecma_get_object_extensible (obj_p))
-    {
-      is_frozen = false;
-    }
-    else
-    {
-      is_frozen = true;
-
-      /* 2. */
-      ecma_collection_header_t *props_p = ecma_op_object_get_property_names (obj_p, false, false, false);
-
-      ecma_value_t *ecma_value_p = ecma_collection_iterator_init (props_p);
-
-      while (ecma_value_p != NULL)
-      {
-        ecma_string_t *property_name_p = ecma_get_string_from_value (*ecma_value_p);
-        ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
-
-        /* 2.a */
-        ecma_property_t property = ecma_op_object_get_own_property (obj_p,
-                                                                    property_name_p,
-                                                                    NULL,
-                                                                    ECMA_PROPERTY_GET_NO_OPTIONS);
-
-        /* 2.b */
-        if (ECMA_PROPERTY_GET_TYPE (property) != ECMA_PROPERTY_TYPE_NAMEDACCESSOR
-            && ecma_is_property_writable (property))
-        {
-          is_frozen = false;
-          break;
-        }
-
-        /* 2.c */
-        if (ecma_is_property_configurable (property))
-        {
-          is_frozen = false;
-          break;
-        }
-      }
-
-      ecma_free_values_collection (props_p, 0);
-    }
-
-    /* 4 */
-    ret_value = is_frozen ? ECMA_VALUE_TRUE : ECMA_VALUE_FALSE;
-  }
-
-  return ret_value;
+  return ecma_builtin_object_frozen_or_sealed_helper (this_arg, arg, true);
 } /* ecma_builtin_object_object_is_frozen */
 
 /**
@@ -645,22 +608,14 @@ ecma_builtin_object_object_is_extensible (ecma_value_t this_arg, /**< 'this' arg
                                           ecma_value_t arg) /**< routine's argument */
 {
   JERRY_UNUSED (this_arg);
-  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
 
   if (!ecma_is_value_object (arg))
   {
-    ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an object."));
-  }
-  else
-  {
-    ecma_object_t *obj_p = ecma_get_object_from_value (arg);
-
-    bool extensible = ecma_get_object_extensible (obj_p);
-
-    ret_value = extensible ? ECMA_VALUE_TRUE : ECMA_VALUE_FALSE;
+    return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an object."));
   }
 
-  return ret_value;
+  ecma_object_t *obj_p = ecma_get_object_from_value (arg);
+  return ecma_make_boolean_value (ecma_get_object_extensible (obj_p));
 } /* ecma_builtin_object_object_is_extensible */
 
 /**
@@ -837,7 +792,7 @@ ecma_builtin_object_object_define_properties (ecma_value_t this_arg, /**< 'this'
 
     ecma_object_t *props_p = ecma_get_object_from_value (props);
     /* 3. */
-    ecma_collection_header_t *prop_names_p = ecma_op_object_get_property_names (props_p, false, true, false);
+    ecma_collection_header_t *prop_names_p = ecma_op_object_get_property_names (props_p, ECMA_LIST_ENUMERABLE);
     uint32_t property_number = prop_names_p->item_count;
 
     ecma_value_t *ecma_value_p = ecma_collection_iterator_init (prop_names_p);
index 274ded39cc065e909c4f2809a0df69e3616228ea..eb93270b6536cc25d3747081d95c152b6b9bbe73 100644 (file)
@@ -83,11 +83,11 @@ ecma_builtin_promise_reject_or_resolve (ecma_value_t this_arg, /**< "this" argum
 
   if (is_resolve)
   {
-    property_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_RESOLVE);
+    property_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_RESOLVE);
   }
   else
   {
-    property_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT);
+    property_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REJECT);
   }
 
   ecma_value_t func = ecma_op_object_get (ecma_get_object_from_value (capability), property_str_p);
@@ -106,7 +106,7 @@ ecma_builtin_promise_reject_or_resolve (ecma_value_t this_arg, /**< "this" argum
 
   ecma_free_value (call_ret);
 
-  ecma_string_t *promise_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_PROMISE);
+  ecma_string_t *promise_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_PROMISE);
   ecma_value_t promise_new = ecma_op_object_get (ecma_get_object_from_value (capability), promise_str_p);
   ecma_free_value (capability);
 
@@ -125,8 +125,9 @@ ecma_builtin_promise_reject_or_resolve (ecma_value_t this_arg, /**< "this" argum
 inline static ecma_value_t
 ecma_builtin_promise_reject_abrupt (ecma_value_t capability) /**< reject description */
 {
+  ecma_raise_type_error (ECMA_ERR_MSG ("Second argument is not an array."));
   ecma_value_t reason = JERRY_CONTEXT (error_value);
-  ecma_string_t *reject_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT);
+  ecma_string_t *reject_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REJECT);
   ecma_value_t reject = ecma_op_object_get (ecma_get_object_from_value (capability), reject_str_p);
 
   ecma_value_t call_ret = ecma_op_function_call (ecma_get_object_from_value (reject),
@@ -134,6 +135,7 @@ ecma_builtin_promise_reject_abrupt (ecma_value_t capability) /**< reject descrip
                                                  &reason,
                                                  1);
   ecma_free_value (reject);
+  ecma_free_value (reason);
 
   if (ECMA_IS_VALUE_ERROR (call_ret))
   {
@@ -142,7 +144,7 @@ ecma_builtin_promise_reject_abrupt (ecma_value_t capability) /**< reject descrip
 
   ecma_free_value (call_ret);
 
-  ecma_string_t *promise_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_PROMISE);
+  ecma_string_t *promise_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_PROMISE);
   ecma_value_t promise_new = ecma_op_object_get (ecma_get_object_from_value (capability), promise_str_p);
 
   return promise_new;
@@ -206,9 +208,9 @@ ecma_builtin_promise_do_race (ecma_value_t array, /**< the array for race */
   ecma_length_t len = (ecma_length_t) ecma_get_integer_from_value (len_value);
   ecma_fast_free_value (len_value);
 
-  ecma_string_t *promise_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_PROMISE);
-  ecma_string_t *resolve_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_RESOLVE);
-  ecma_string_t *reject_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT);
+  ecma_string_t *promise_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_PROMISE);
+  ecma_string_t *resolve_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_RESOLVE);
+  ecma_string_t *reject_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REJECT);
 
   ecma_value_t resolve = ecma_op_object_get (ecma_get_object_from_value (capability),
                                              resolve_str_p);
@@ -229,6 +231,13 @@ ecma_builtin_promise_do_race (ecma_value_t array, /**< the array for race */
     ecma_value_t array_item = ecma_op_object_get (array_p, index_to_str_p);
     ecma_deref_ecma_string (index_to_str_p);
 
+    /* f. */
+    if (ECMA_IS_VALUE_ERROR (array_item))
+    {
+      ret = array_item;
+      break;
+    }
+
     /* h. */
     ecma_value_t next_promise = ecma_builtin_promise_resolve (ctor, array_item);
     ecma_free_value (array_item);
@@ -316,7 +325,8 @@ ecma_builtin_promise_all_handler (const ecma_value_t function, /**< the function
   ecma_value_t ret = ECMA_VALUE_UNDEFINED;
   /* 1. */
   ecma_object_t *function_p = ecma_get_object_from_value (function);
-  ecma_string_t *already_called_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_ALREADY_CALLED);
+  ecma_string_t *already_called_str_p;
+  already_called_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_ALREADY_CALLED);
   ecma_value_t already_called = ecma_op_object_get (function_p, already_called_str_p);
 
   JERRY_ASSERT (ecma_is_value_boolean (already_called));
@@ -331,13 +341,13 @@ ecma_builtin_promise_all_handler (const ecma_value_t function, /**< the function
   /* 3. */
   ecma_op_object_put (function_p,
                       already_called_str_p,
-                      ecma_make_boolean_value (true),
+                      ECMA_VALUE_TRUE,
                       false);
 
-  ecma_string_t *str_index_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_INDEX);
-  ecma_string_t *str_value_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_VALUE);
-  ecma_string_t *str_capability_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_CAPABILITY);
-  ecma_string_t *str_remaining_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REMAINING_ELEMENT);
+  ecma_string_t *str_index_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_INDEX);
+  ecma_string_t *str_value_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_VALUE);
+  ecma_string_t *str_capability_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_CAPABILITY);
+  ecma_string_t *str_remaining_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REMAINING_ELEMENT);
 
   /* 4-7. */
   ecma_value_t index_val = ecma_op_object_get (function_p, str_index_p);
@@ -359,7 +369,7 @@ ecma_builtin_promise_all_handler (const ecma_value_t function, /**< the function
   /* 9-10. */
   if (ecma_builtin_promise_remaining_inc_or_dec (remaining, false) == 0)
   {
-    ecma_string_t *resolve_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_RESOLVE);
+    ecma_string_t *resolve_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_RESOLVE);
     ecma_value_t resolve = ecma_op_object_get (ecma_get_object_from_value (capability), resolve_str_p);
 
     ret = ecma_op_function_call (ecma_get_object_from_value (resolve),
@@ -404,14 +414,15 @@ ecma_builtin_promise_do_all (ecma_value_t array, /**< the array for all */
   ecma_length_t len = (ecma_length_t) ecma_get_integer_from_value (len_value);
   ecma_fast_free_value (len_value);
 
-  ecma_string_t *promise_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_PROMISE);
-  ecma_string_t *resolve_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_RESOLVE);
-  ecma_string_t *reject_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT);
-  ecma_string_t *already_called_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_ALREADY_CALLED);
-  ecma_string_t *index_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_INDEX);
-  ecma_string_t *value_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_VALUE);
-  ecma_string_t *capability_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_CAPABILITY);
-  ecma_string_t *remaining_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REMAINING_ELEMENT);
+  ecma_string_t *promise_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_PROMISE);
+  ecma_string_t *resolve_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_RESOLVE);
+  ecma_string_t *reject_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REJECT);
+  ecma_string_t *already_called_str_p;
+  already_called_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_ALREADY_CALLED);
+  ecma_string_t *index_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_INDEX);
+  ecma_string_t *value_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_VALUE);
+  ecma_string_t *capability_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_CAPABILITY);
+  ecma_string_t *remaining_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REMAINING_ELEMENT);
 
   ecma_value_t undefined_val = ECMA_VALUE_UNDEFINED;
   /* String '1' indicates [[Resolve]] and '2' indicates [[Reject]]. */
@@ -459,11 +470,19 @@ ecma_builtin_promise_do_all (ecma_value_t array, /**< the array for all */
     /* e. h. */
     ecma_string_t *index_to_str_p = ecma_new_ecma_string_from_uint32 (index);
     ecma_value_t array_item = ecma_op_object_get (array_p, index_to_str_p);
-    ecma_op_object_put (ecma_get_object_from_value (value_array),
-                        index_to_str_p,
-                        undefined_val,
-                        false);
+    ecma_value_t put_ret = ecma_op_object_put (ecma_get_object_from_value (value_array),
+                                               index_to_str_p,
+                                               undefined_val,
+                                               false);
     ecma_deref_ecma_string (index_to_str_p);
+
+    if (ECMA_IS_VALUE_ERROR (put_ret))
+    {
+      ecma_free_value (array_item);
+      ret = put_ret;
+      break;
+    }
+
     /* i. */
     ecma_value_t next_promise = ecma_builtin_promise_resolve (ctor, array_item);
     ecma_free_value (array_item);
@@ -481,7 +500,7 @@ ecma_builtin_promise_do_all (ecma_value_t array, /**< the array for all */
     /* l. */
     ecma_op_object_put (res_ele_p,
                         already_called_str_p,
-                        ecma_make_boolean_value (false),
+                        ECMA_VALUE_FALSE,
                         false);
     /* m. */
     ecma_op_object_put (res_ele_p,
@@ -558,16 +577,19 @@ ecma_builtin_promise_race_or_all (ecma_value_t this_arg, /**< 'this' argument */
   }
 
   ecma_value_t capability = ecma_promise_new_capability ();
+
+  if (ECMA_IS_VALUE_ERROR (capability))
+  {
+    return capability;
+  }
+
   ecma_value_t ret = ECMA_VALUE_EMPTY;
 
   if (!ecma_is_value_object (array)
       || ecma_get_object_type (ecma_get_object_from_value (array)) != ECMA_OBJECT_TYPE_ARRAY)
   {
-    ecma_raise_type_error (ECMA_ERR_MSG ("Second argument is not an array."));
     ret = ecma_builtin_promise_reject_abrupt (capability);
-    ecma_free_value (JERRY_CONTEXT (error_value));
     ecma_free_value (capability);
-
     return ret;
   }
 
index 7946f547166634137f56df00fd3b2218a86f93b0..da9d7e625d69493dd4be03cd4afe6a4946f2ef14 100644 (file)
@@ -159,28 +159,7 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument
       ecma_string_t *pattern_string_p = NULL;
 
       /* Get source string. */
-      if (!ecma_is_value_undefined (pattern_arg))
-      {
-        ECMA_TRY_CATCH (regexp_str_value,
-                        ecma_op_to_string (pattern_arg),
-                        ret_value);
-
-        if (ecma_string_is_empty (ecma_get_string_from_value (regexp_str_value)))
-        {
-          pattern_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP);
-        }
-        else
-        {
-          pattern_string_p = ecma_get_string_from_value (regexp_str_value);
-          ecma_ref_ecma_string (pattern_string_p);
-        }
-
-        ECMA_FINALIZE (regexp_str_value);
-      }
-      else
-      {
-        pattern_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP);
-      }
+      ret_value = ecma_regexp_read_pattern_str_helper (pattern_arg, &pattern_string_p);
 
       /* Parse flags. */
       if (ecma_is_value_empty (ret_value) && !ecma_is_value_undefined (flags_arg))
index 469833299f589813e8a3afce5762e308fd04674b..d4c5857e50c21a667ef92230d0b854fef9e66b96 100644 (file)
@@ -96,28 +96,7 @@ ecma_builtin_regexp_dispatch_construct (const ecma_value_t *arguments_list_p, /*
     ecma_string_t *pattern_string_p = NULL;
     ecma_string_t *flags_string_p = NULL;
 
-    if (!ecma_is_value_undefined (pattern_value))
-    {
-      ECMA_TRY_CATCH (regexp_str_value,
-                      ecma_op_to_string (pattern_value),
-                      ret_value);
-
-      if (ecma_string_is_empty (ecma_get_string_from_value (regexp_str_value)))
-      {
-        pattern_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP);
-      }
-      else
-      {
-        pattern_string_p = ecma_get_string_from_value (regexp_str_value);
-        ecma_ref_ecma_string (pattern_string_p);
-      }
-
-      ECMA_FINALIZE (regexp_str_value);
-    }
-    else
-    {
-      pattern_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP);
-    }
+    ret_value = ecma_regexp_read_pattern_str_helper (pattern_value, &pattern_string_p);
 
     if (ecma_is_value_empty (ret_value) && !ecma_is_value_undefined (flags_value))
     {
@@ -131,9 +110,15 @@ ecma_builtin_regexp_dispatch_construct (const ecma_value_t *arguments_list_p, /*
       ECMA_FINALIZE (flags_str_value);
     }
 
+    uint16_t flags = 0;
+    if (ecma_is_value_empty (ret_value) && (flags_string_p != NULL))
+    {
+      ret_value = re_parse_regexp_flags (flags_string_p, &flags);
+    }
+
     if (ecma_is_value_empty (ret_value))
     {
-      ret_value = ecma_op_create_regexp_object (pattern_string_p, flags_string_p);
+      ret_value = ecma_op_create_regexp_object (pattern_string_p, flags);
     }
 
     if (pattern_string_p != NULL)
index 1cd05a6be86663a7bc26e524d57a07f275cabea9..585532321215e5139c1a6a70cf752c71ee78313f 100644 (file)
@@ -103,57 +103,85 @@ ecma_builtin_string_prototype_object_value_of (ecma_value_t this_arg) /**< this
 } /* ecma_builtin_string_prototype_object_value_of */
 
 /**
- * The String.prototype object's 'charAt' routine
- *
- * See also:
- *          ECMA-262 v5, 15.5.4.4
+ * Helper function for the String.prototype object's 'charAt' and charCodeAt' routine
  *
  * @return ecma value
  *         Returned value must be freed with ecma_free_value.
  */
 static ecma_value_t
-ecma_builtin_string_prototype_object_char_at (ecma_value_t this_arg, /**< this argument */
-                                              ecma_value_t arg) /**< routine's argument */
+ecma_builtin_string_prototype_char_at_helper (ecma_value_t this_arg, /**< this argument */
+                                              ecma_value_t arg, /**< routine's argument */
+                                              bool charcode_mode) /**< routine mode */
 {
-  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
   /* 1 */
-  ECMA_TRY_CATCH (check_coercible_val,
-                  ecma_op_check_object_coercible (this_arg),
-                  ret_value);
+  ecma_value_t check_coercible_val = ecma_op_check_object_coercible (this_arg);
 
-  /* 2 */
-  ECMA_TRY_CATCH (to_string_val,
-                  ecma_op_to_string (this_arg),
-                  ret_value);
+  if (ECMA_IS_VALUE_ERROR (check_coercible_val))
+  {
+    return check_coercible_val;
+  }
+  ecma_free_value (check_coercible_val);
 
   /* 3 */
-  ECMA_OP_TO_NUMBER_TRY_CATCH (index_num,
-                               arg,
-                               ret_value);
+  ecma_number_t index_num;
+  ecma_value_t to_num_result = ecma_get_number (arg, &index_num);
+
+  if (JERRY_UNLIKELY (!ecma_is_value_empty (to_num_result)))
+  {
+    return to_num_result;
+  }
+  ecma_free_value (to_num_result);
+
+  /* 2 */
+  ecma_value_t to_string_val = ecma_op_to_string (this_arg);
+  if (ECMA_IS_VALUE_ERROR (to_string_val))
+  {
+    return to_string_val;
+  }
 
   /* 4 */
   ecma_string_t *original_string_p = ecma_get_string_from_value (to_string_val);
   const ecma_length_t len = ecma_string_get_length (original_string_p);
 
   /* 5 */
-  if (index_num < 0 || index_num >= len || !len)
-  {
-    ret_value = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
-  }
-  else
+  // When index_num is NaN, then the first two comparisons are false
+  if (index_num < 0 || index_num >= len || (ecma_number_is_nan (index_num) && len == 0))
   {
-    /* 6 */
-    ecma_char_t new_ecma_char = ecma_string_get_char_at_pos (original_string_p, ecma_number_to_uint32 (index_num));
-    ret_value = ecma_make_string_value (ecma_new_ecma_string_from_code_unit (new_ecma_char));
+    ecma_free_value (to_string_val);
+    return (charcode_mode ? ecma_make_nan_value ()
+                          : ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY));
   }
 
-  ECMA_OP_TO_NUMBER_FINALIZE (index_num);
+  /* 6 */
+  /*
+   * String length is currently uint32_t, but index_num may be bigger,
+   * ToInteger performs floor, while ToUInt32 performs modulo 2^32,
+   * hence after the check 0 <= index_num < len we assume to_uint32 can be used.
+   * We assume to_uint32 (NaN) is 0.
+   */
+  JERRY_ASSERT (ecma_number_is_nan (index_num) || ecma_number_to_uint32 (index_num) == ecma_number_trunc (index_num));
 
-  ECMA_FINALIZE (to_string_val);
-  ECMA_FINALIZE (check_coercible_val);
+  ecma_char_t new_ecma_char = ecma_string_get_char_at_pos (original_string_p, ecma_number_to_uint32 (index_num));
+  ecma_free_value (to_string_val);
 
-  return ret_value;
+  return (charcode_mode ? ecma_make_uint32_value (new_ecma_char)
+                        : ecma_make_string_value (ecma_new_ecma_string_from_code_unit (new_ecma_char)));
+} /* ecma_builtin_string_prototype_char_at_helper */
+
+/**
+ * The String.prototype object's 'charAt' routine
+ *
+ * See also:
+ *          ECMA-262 v5, 15.5.4.4
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_string_prototype_object_char_at (ecma_value_t this_arg, /**< this argument */
+                                              ecma_value_t arg) /**< routine's argument */
+{
+  return ecma_builtin_string_prototype_char_at_helper (this_arg, arg, false);
 } /* ecma_builtin_string_prototype_object_char_at */
 
 /**
@@ -169,54 +197,7 @@ static ecma_value_t
 ecma_builtin_string_prototype_object_char_code_at (ecma_value_t this_arg, /**< this argument */
                                                    ecma_value_t arg) /**< routine's argument */
 {
-  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
-  /* 1 */
-  ECMA_TRY_CATCH (check_coercible_val,
-                  ecma_op_check_object_coercible (this_arg),
-                  ret_value);
-
-  /* 2 */
-  ECMA_TRY_CATCH (to_string_val,
-                  ecma_op_to_string (this_arg),
-                  ret_value);
-
-  /* 3 */
-  ECMA_OP_TO_NUMBER_TRY_CATCH (index_num,
-                               arg,
-                               ret_value);
-
-  /* 4 */
-  ecma_string_t *original_string_p = ecma_get_string_from_value (to_string_val);
-  const ecma_length_t len = ecma_string_get_length (original_string_p);
-
-  /* 5 */
-  // When index_num is NaN, then the first two comparisons are false
-  if (index_num < 0 || index_num >= len || (ecma_number_is_nan (index_num) && !len))
-  {
-    ret_value = ecma_make_nan_value ();
-  }
-  else
-  {
-    /* 6 */
-    /*
-     * String length is currently uit32_t, but index_num may be bigger,
-     * ToInteger performs floor, while ToUInt32 performs modulo 2^32,
-     * hence after the check 0 <= index_num < len we assume to_uint32 can be used.
-     * We assume to_uint32 (NaN) is 0.
-     */
-    JERRY_ASSERT (ecma_number_is_nan (index_num) || ecma_number_to_uint32 (index_num) == ecma_number_trunc (index_num));
-
-    ecma_char_t new_ecma_char = ecma_string_get_char_at_pos (original_string_p, ecma_number_to_uint32 (index_num));
-    ret_value = ecma_make_uint32_value (new_ecma_char);
-  }
-
-  ECMA_OP_TO_NUMBER_FINALIZE (index_num);
-
-  ECMA_FINALIZE (to_string_val);
-  ECMA_FINALIZE (check_coercible_val);
-
-  return ret_value;
+  return ecma_builtin_string_prototype_char_at_helper (this_arg, arg, true);
 } /* ecma_builtin_string_prototype_object_char_code_at */
 
 /**
@@ -382,17 +363,17 @@ ecma_builtin_string_prototype_object_locale_compare (ecma_value_t this_arg, /**<
 #ifndef CONFIG_DISABLE_REGEXP_BUILTIN
 
 /**
- * The String.prototype object's 'match' routine
+ * The common preparation code for 'search' and 'match' functions
+ * of the String prototype.
  *
- * See also:
- *          ECMA-262 v5, 15.5.4.10
- *
- * @return ecma value
+ * @return empty value on success, error value otherwise
  *         Returned value must be freed with ecma_free_value.
  */
 static ecma_value_t
-ecma_builtin_string_prototype_object_match (ecma_value_t this_arg, /**< this argument */
-                                            ecma_value_t arg) /**< routine's argument */
+ecma_builtin_string_prepare_search (ecma_value_t this_arg, /**< this argument */
+                                    ecma_value_t *this_to_string_value_ptr, /**< [out] ptr to store as string */
+                                    ecma_value_t regexp_arg, /**< regex argument */
+                                    ecma_value_t *regexp_value) /**< [out] ptr to store the regexp object */
 {
   ecma_value_t ret_value = ECMA_VALUE_EMPTY;
 
@@ -406,26 +387,52 @@ ecma_builtin_string_prototype_object_match (ecma_value_t this_arg, /**< this arg
                   ecma_op_to_string (this_arg),
                   ret_value);
 
-  ecma_value_t regexp_value = ECMA_VALUE_EMPTY;
+  *this_to_string_value_ptr = ecma_copy_value (this_to_string_value);
+
   /* 3. */
-  if (ecma_is_value_object (arg)
-      && ecma_object_class_is (ecma_get_object_from_value (arg), LIT_MAGIC_STRING_REGEXP_UL))
+  if (ecma_is_value_object (regexp_arg)
+      && ecma_object_class_is (ecma_get_object_from_value (regexp_arg), LIT_MAGIC_STRING_REGEXP_UL))
   {
-    regexp_value = ecma_copy_value (arg);
+    *regexp_value = ecma_copy_value (regexp_arg);
   }
   else
   {
     /* 4. */
-    ecma_value_t regexp_arguments[1] = { arg };
+    ecma_value_t regexp_arguments[1] = { regexp_arg };
     ECMA_TRY_CATCH (new_regexp_value,
                     ecma_builtin_regexp_dispatch_construct (regexp_arguments, 1),
                     ret_value);
 
-    regexp_value = ecma_copy_value (new_regexp_value);
+    *regexp_value = ecma_copy_value (new_regexp_value);
 
     ECMA_FINALIZE (new_regexp_value);
   }
 
+  ECMA_FINALIZE (this_to_string_value);
+  ECMA_FINALIZE (this_check_coercible_value);
+
+  return ret_value;
+} /* ecma_builtin_string_prepare_search */
+
+/**
+ * The String.prototype object's 'match' routine
+ *
+ * See also:
+ *          ECMA-262 v5, 15.5.4.10
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_string_prototype_object_match (ecma_value_t this_arg, /**< this argument */
+                                            ecma_value_t regexp_arg) /**< routine's argument */
+{
+  ecma_value_t this_to_string_value = ECMA_VALUE_EMPTY;
+  ecma_value_t regexp_value = ECMA_VALUE_EMPTY;
+
+  ecma_value_t ret_value = ecma_builtin_string_prepare_search (this_arg, &this_to_string_value,
+                                                               regexp_arg, &regexp_value);
+
   if (ecma_is_value_empty (ret_value))
   {
     JERRY_ASSERT (!ecma_is_value_empty (regexp_value));
@@ -533,9 +540,7 @@ ecma_builtin_string_prototype_object_match (ecma_value_t this_arg, /**< this arg
             ecma_value_t completion = ecma_builtin_helper_def_prop (new_array_obj_p,
                                                                     current_index_str_p,
                                                                     match_string_value,
-                                                                    true, /* Writable */
-                                                                    true, /* Enumerable */
-                                                                    true, /* Configurable */
+                                                                    ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
                                                                     false); /* Failure handling */
 
             JERRY_ASSERT (ecma_is_value_true (completion));
@@ -580,9 +585,7 @@ ecma_builtin_string_prototype_object_match (ecma_value_t this_arg, /**< this arg
     ecma_free_value (regexp_value);
   }
 
-  ECMA_FINALIZE (this_to_string_value);
-
-  ECMA_FINALIZE (this_check_coercible_value);
+  ecma_free_value (this_to_string_value);
 
   return ret_value;
 } /* ecma_builtin_string_prototype_object_match */
@@ -605,7 +608,7 @@ typedef struct
   ecma_length_t match_end; /**< end position of the match */
 
   /* Replace value callable part. */
-  ecma_object_t *replace_function_p;
+  ecma_object_t *replace_function_p; /**< replace function */
 
   /* Replace value string part. */
   ecma_string_t *replace_string_p; /**< replace string */
@@ -1286,39 +1289,11 @@ static ecma_value_t
 ecma_builtin_string_prototype_object_search (ecma_value_t this_arg, /**< this argument */
                                              ecma_value_t regexp_arg) /**< routine's argument */
 {
-  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
-  /* 1. */
-  ECMA_TRY_CATCH (check_coercible_value,
-                  ecma_op_check_object_coercible (this_arg),
-                  ret_value);
-
-  /* 2. */
-  ECMA_TRY_CATCH (to_string_value,
-                  ecma_op_to_string (this_arg),
-                  ret_value);
-
+  ecma_value_t to_string_value = ECMA_VALUE_EMPTY;
   ecma_value_t regexp_value = ECMA_VALUE_EMPTY;
 
-  /* 3. */
-  if (ecma_is_value_object (regexp_arg)
-      && ecma_object_class_is (ecma_get_object_from_value (regexp_arg), LIT_MAGIC_STRING_REGEXP_UL))
-  {
-    regexp_value = ecma_copy_value (regexp_arg);
-  }
-  else
-  {
-    /* 4. */
-    ecma_value_t regexp_arguments[1] = { regexp_arg };
-
-    ECMA_TRY_CATCH (new_regexp_value,
-                    ecma_builtin_regexp_dispatch_construct (regexp_arguments, 1),
-                    ret_value);
-
-    regexp_value = ecma_copy_value (new_regexp_value);
-
-    ECMA_FINALIZE (new_regexp_value);
-  }
+  ecma_value_t ret_value = ecma_builtin_string_prepare_search (this_arg, &to_string_value,
+                                                               regexp_arg, &regexp_value);
 
   /* 5. */
   if (ecma_is_value_empty (ret_value))
@@ -1355,8 +1330,7 @@ ecma_builtin_string_prototype_object_search (ecma_value_t this_arg, /**< this ar
     ecma_free_value (regexp_value);
   }
 
-  ECMA_FINALIZE (to_string_value);
-  ECMA_FINALIZE (check_coercible_value);
+  ecma_free_value (to_string_value);
 
   /* 6. */
   return ret_value;
@@ -1496,10 +1470,8 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_arg, /**< this arg
       ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
                                                             zero_str_p,
                                                             this_to_string_val,
-                                                            true,
-                                                            true,
-                                                            true,
-                                                            false);
+                                                            ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+                                                            false); /* Failure handling */
 
       JERRY_ASSERT (ecma_is_value_true (put_comp));
 
@@ -1574,10 +1546,8 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_arg, /**< this arg
           ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
                                                                 zero_str_p,
                                                                 this_to_string_val,
-                                                                true,
-                                                                true,
-                                                                true,
-                                                                false);
+                                                                ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+                                                                false); /* Failure handling */
 
           JERRY_ASSERT (ecma_is_value_true (put_comp));
           ecma_deref_ecma_string (zero_str_p);
@@ -1666,10 +1636,9 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_arg, /**< this arg
               ecma_value_t put_comp = ecma_builtin_helper_def_prop (match_obj_p,
                                                                     zero_str_p,
                                                                     ecma_make_string_value (separator_str_p),
-                                                                    true,
-                                                                    true,
-                                                                    true,
-                                                                    true);
+                                                                    ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+                                                                    true); /* Failure handling */
+
               JERRY_ASSERT (ecma_is_value_true (put_comp));
 
               index_prop_value_p = ecma_create_named_data_property (match_obj_p,
@@ -1713,10 +1682,8 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_arg, /**< this arg
             ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
                                                                   array_length_str_p,
                                                                   ecma_make_string_value (substr_str_p),
-                                                                  true,
-                                                                  true,
-                                                                  true,
-                                                                  false);
+                                                                  ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+                                                                  false); /* Failure handling */
 
             JERRY_ASSERT (ecma_is_value_true (put_comp));
 
@@ -1760,10 +1727,8 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_arg, /**< this arg
               put_comp = ecma_builtin_helper_def_prop (new_array_p,
                                                        new_array_idx_str_p,
                                                        match_comp_value,
-                                                       true,
-                                                       true,
-                                                       true,
-                                                       false);
+                                                       ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+                                                       false); /* Failure handling */
 
               JERRY_ASSERT (ecma_is_value_true (put_comp));
 
@@ -1808,10 +1773,8 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_arg, /**< this arg
           ecma_value_t put_comp = ecma_builtin_helper_def_prop (new_array_p,
                                                                 array_length_string_p,
                                                                 ecma_make_string_value (substr_str_p),
-                                                                true,
-                                                                true,
-                                                                true,
-                                                                false);
+                                                                ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+                                                                false); /* Failure handling */
 
           JERRY_ASSERT (ecma_is_value_true (put_comp));
 
index c4ae8662ca574ebf9f00a57ab579ca96d75f77ce..a7091a02cdfa10c164c769822fa3aca2ab156cc1 100644 (file)
@@ -39,63 +39,83 @@ static void ecma_instantiate_builtin (ecma_builtin_id_t id);
  */
 typedef const ecma_builtin_property_descriptor_t *ecma_builtin_property_list_reference_t;
 
+/**
+ * Definition of built-in dispatch routine function pointer.
+ */
 typedef ecma_value_t (*ecma_builtin_dispatch_routine_t)(uint16_t builtin_routine_id,
                                                         ecma_value_t this_arg,
                                                         const ecma_value_t arguments_list[],
                                                         ecma_length_t arguments_number);
+/**
+ * Definition of built-in dispatch call function pointer.
+ */
 typedef ecma_value_t (*ecma_builtin_dispatch_call_t)(const ecma_value_t arguments_list[],
                                                      ecma_length_t arguments_number);
-
+/**
+ * List of the built-in routines.
+ */
 static const ecma_builtin_dispatch_routine_t ecma_builtin_routines[] =
 {
-  #define BUILTIN(a, b, c, d, e)
-  #define BUILTIN_ROUTINE(builtin_id, \
-                          object_type, \
-                          object_prototype_builtin_id, \
-                          is_extensible, \
-                          lowercase_name) \
-    ecma_builtin_ ## lowercase_name ## _dispatch_routine,
-  #include "ecma-builtins.inc.h"
-  #undef BUILTIN
-  #undef BUILTIN_ROUTINE
-  #define BUILTIN_ROUTINE(a, b, c, d, e)
-  #define BUILTIN(builtin_id, \
-                  object_type, \
-                  object_prototype_builtin_id, \
-                  is_extensible, \
-                  lowercase_name) \
-    ecma_builtin_ ## lowercase_name ## _dispatch_routine,
-  #include "ecma-builtins.inc.h"
-  #undef BUILTIN
-  #undef BUILTIN_ROUTINE
+/** @cond doxygen_suppress */
+#define BUILTIN(a, b, c, d, e)
+#define BUILTIN_ROUTINE(builtin_id, \
+                        object_type, \
+                        object_prototype_builtin_id, \
+                        is_extensible, \
+                        lowercase_name) \
+  ecma_builtin_ ## lowercase_name ## _dispatch_routine,
+#include "ecma-builtins.inc.h"
+#undef BUILTIN
+#undef BUILTIN_ROUTINE
+#define BUILTIN_ROUTINE(a, b, c, d, e)
+#define BUILTIN(builtin_id, \
+                object_type, \
+                object_prototype_builtin_id, \
+                is_extensible, \
+                lowercase_name) \
+  ecma_builtin_ ## lowercase_name ## _dispatch_routine,
+#include "ecma-builtins.inc.h"
+#undef BUILTIN
+#undef BUILTIN_ROUTINE
+/** @endcond */
 };
 
+/**
+ * List of the built-in call functions.
+ */
 static const ecma_builtin_dispatch_call_t ecma_builtin_call_functions[] =
 {
-  #define BUILTIN(a, b, c, d, e)
-  #define BUILTIN_ROUTINE(builtin_id, \
-                          object_type, \
-                          object_prototype_builtin_id, \
-                          is_extensible, \
-                          lowercase_name) \
-    ecma_builtin_ ## lowercase_name ## _dispatch_call,
-  #include "ecma-builtins.inc.h"
-  #undef BUILTIN_ROUTINE
-  #undef BUILTIN
+/** @cond doxygen_suppress */
+#define BUILTIN(a, b, c, d, e)
+#define BUILTIN_ROUTINE(builtin_id, \
+                        object_type, \
+                        object_prototype_builtin_id, \
+                        is_extensible, \
+                        lowercase_name) \
+  ecma_builtin_ ## lowercase_name ## _dispatch_call,
+#include "ecma-builtins.inc.h"
+#undef BUILTIN_ROUTINE
+#undef BUILTIN
+/** @endcond */
 };
 
+/**
+ * List of the built-in construct functions.
+ */
 static const ecma_builtin_dispatch_call_t ecma_builtin_construct_functions[] =
 {
-  #define BUILTIN(a, b, c, d, e)
-  #define BUILTIN_ROUTINE(builtin_id, \
-                          object_type, \
-                          object_prototype_builtin_id, \
-                          is_extensible, \
-                          lowercase_name) \
-    ecma_builtin_ ## lowercase_name ## _dispatch_construct,
-  #include "ecma-builtins.inc.h"
-  #undef BUILTIN_ROUTINE
-  #undef BUILTIN
+/** @cond doxygen_suppress */
+#define BUILTIN(a, b, c, d, e)
+#define BUILTIN_ROUTINE(builtin_id, \
+                        object_type, \
+                        object_prototype_builtin_id, \
+                        is_extensible, \
+                        lowercase_name) \
+  ecma_builtin_ ## lowercase_name ## _dispatch_construct,
+#include "ecma-builtins.inc.h"
+#undef BUILTIN_ROUTINE
+#undef BUILTIN
+/** @endcond */
 };
 
 /**
@@ -103,6 +123,7 @@ static const ecma_builtin_dispatch_call_t ecma_builtin_construct_functions[] =
  */
 static const ecma_builtin_property_list_reference_t ecma_builtin_property_list_references[] =
 {
+/** @cond doxygen_suppress */
 #define BUILTIN(a, b, c, d, e)
 #define BUILTIN_ROUTINE(builtin_id, \
                         object_type, \
@@ -123,6 +144,7 @@ static const ecma_builtin_property_list_reference_t ecma_builtin_property_list_r
 #include "ecma-builtins.inc.h"
 #undef BUILTIN_ROUTINE
 #undef BUILTIN
+/** @endcond */
 };
 
 /**
@@ -131,8 +153,9 @@ static const ecma_builtin_property_list_reference_t ecma_builtin_property_list_r
  * @return the number of properties
  */
 static size_t
-ecma_builtin_get_property_count (ecma_builtin_id_t builtin_id)
+ecma_builtin_get_property_count (ecma_builtin_id_t builtin_id) /**< built-in ID */
 {
+  JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT);
   const ecma_builtin_property_descriptor_t *property_list_p = ecma_builtin_property_list_references[builtin_id];
 
   const ecma_builtin_property_descriptor_t *curr_property_p = property_list_p;
@@ -147,6 +170,9 @@ ecma_builtin_get_property_count (ecma_builtin_id_t builtin_id)
 
 /**
  * Check if passed object is the instance of specified built-in.
+ *
+ * @return true  - if the object is instance of the specified built-in
+ *         false - otherwise
  */
 bool
 ecma_builtin_is (ecma_object_t *obj_p, /**< pointer to an object */
@@ -155,21 +181,17 @@ ecma_builtin_is (ecma_object_t *obj_p, /**< pointer to an object */
   JERRY_ASSERT (obj_p != NULL && !ecma_is_lexical_environment (obj_p));
   JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT);
 
-  if (JERRY_CONTEXT (ecma_builtin_objects)[builtin_id] == NULL)
-  {
-    /* If a built-in object is not instantiated,
-     * the specified object cannot be the built-in object */
-    return false;
-  }
-  else
-  {
-    return (obj_p == JERRY_CONTEXT (ecma_builtin_objects)[builtin_id]);
-  }
+  /* If a built-in object is not instantiated, its value is NULL,
+     hence it cannot be equal to a valid object. */
+  return (obj_p == JERRY_CONTEXT (ecma_builtin_objects)[builtin_id]);
 } /* ecma_builtin_is */
 
 /**
  * Get reference to specified built-in object
  *
+ * Note:
+ *   Does not increase the reference counter.
+ *
  * @return pointer to the object's instance
  */
 ecma_object_t *
@@ -177,23 +199,37 @@ ecma_builtin_get (ecma_builtin_id_t builtin_id) /**< id of built-in to check on
 {
   JERRY_ASSERT (builtin_id < ECMA_BUILTIN_ID__COUNT);
 
-  if (unlikely (JERRY_CONTEXT (ecma_builtin_objects)[builtin_id] == NULL))
+  if (JERRY_UNLIKELY (JERRY_CONTEXT (ecma_builtin_objects)[builtin_id] == NULL))
   {
     ecma_instantiate_builtin (builtin_id);
   }
 
-  ecma_ref_object (JERRY_CONTEXT (ecma_builtin_objects)[builtin_id]);
-
   return JERRY_CONTEXT (ecma_builtin_objects)[builtin_id];
 } /* ecma_builtin_get */
 
+/**
+ * Get reference to the global object
+ *
+ * Note:
+ *   Does not increase the reference counter.
+ *
+ * @return pointer to the global object
+ */
+inline ecma_object_t * JERRY_ATTR_ALWAYS_INLINE
+ecma_builtin_get_global (void)
+{
+  JERRY_ASSERT (JERRY_CONTEXT (ecma_builtin_objects)[ECMA_BUILTIN_ID_GLOBAL] != NULL);
+
+  return JERRY_CONTEXT (ecma_builtin_objects)[ECMA_BUILTIN_ID_GLOBAL];
+} /* ecma_builtin_get_global */
+
 /**
  * Checks whether the given function is a built-in routine
  *
  * @return true - if the function object is a built-in routine
  *         false - otherwise
  */
-inline bool __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_builtin_function_is_routine (ecma_object_t *func_obj_p) /**< function object */
 {
   JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION);
@@ -233,7 +269,7 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
 
   ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, ext_object_size, obj_type);
 
-  if (unlikely (!is_extensible))
+  if (JERRY_UNLIKELY (!is_extensible))
   {
     ecma_set_object_extensible (obj_p, false);
   }
@@ -256,8 +292,8 @@ ecma_builtin_init_object (ecma_builtin_id_t obj_builtin_id, /**< built-in ID */
     built_in_props_p = &((ecma_extended_object_t *) obj_p)->u.built_in;
   }
 
-  built_in_props_p->id = obj_builtin_id;
-  built_in_props_p->routine_id = obj_builtin_id;
+  built_in_props_p->id = (uint8_t) obj_builtin_id;
+  built_in_props_p->routine_id = (uint16_t) obj_builtin_id;
   built_in_props_p->instantiated_bitset[0] = 0;
 
   if (property_count > 32)
@@ -399,8 +435,10 @@ ecma_instantiate_builtin_helper (ecma_builtin_id_t builtin_id, /**< built-in id
 static void
 ecma_instantiate_builtin (ecma_builtin_id_t id) /**< built-in id */
 {
+  JERRY_ASSERT (id < ECMA_BUILTIN_ID__COUNT);
   switch (id)
   {
+/** @cond doxygen_suppress */
 #define BUILTIN(builtin_id, \
                 object_type, \
                 object_prototype_builtin_id, \
@@ -418,10 +456,9 @@ ecma_instantiate_builtin (ecma_builtin_id_t id) /**< built-in id */
 #include "ecma-builtins.inc.h"
 #undef BUILTIN
 #undef BUILTIN_ROUTINE
+/** @endcond */
     default:
     {
-      JERRY_ASSERT (id < ECMA_BUILTIN_ID__COUNT);
-
       JERRY_UNREACHABLE (); /* The built-in is not implemented. */
     }
   }
@@ -479,14 +516,12 @@ ecma_builtin_make_function_object_for_routine (ecma_builtin_id_t builtin_id, /**
                                                   ext_object_size,
                                                   ECMA_OBJECT_TYPE_FUNCTION);
 
-  ecma_deref_object (prototype_obj_p);
-
   ecma_set_object_is_builtin (func_obj_p);
 
   JERRY_ASSERT (routine_id >= ECMA_BUILTIN_ID__COUNT);
 
   ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
-  ext_func_obj_p->u.built_in.id = builtin_id;
+  ext_func_obj_p->u.built_in.id = (uint8_t) builtin_id;
   ext_func_obj_p->u.built_in.routine_id = routine_id;
   ext_func_obj_p->u.built_in.instantiated_bitset[0] = 0;
 
@@ -668,11 +703,6 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
       {
         switch (curr_property_p->value)
         {
-          case ECMA_BUILTIN_NUMBER_NAN:
-          {
-            num = ecma_number_make_nan ();
-            break;
-          }
           case ECMA_BUILTIN_NUMBER_POSITIVE_INFINITY:
           {
             num = ecma_number_make_infinity (false);
@@ -685,7 +715,9 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
           }
           default:
           {
-            JERRY_UNREACHABLE ();
+            JERRY_ASSERT (curr_property_p->value == ECMA_BUILTIN_NUMBER_NAN);
+
+            num = ecma_number_make_nan ();
             break;
           }
         }
@@ -696,12 +728,14 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
     }
     case ECMA_BUILTIN_PROPERTY_STRING:
     {
-      value = ecma_make_magic_string_value (curr_property_p->value);
+      value = ecma_make_magic_string_value ((lit_magic_string_id_t) curr_property_p->value);
       break;
     }
     case ECMA_BUILTIN_PROPERTY_OBJECT:
     {
-      value = ecma_make_object_value (ecma_builtin_get (curr_property_p->value));
+      ecma_object_t *builtin_object_p = ecma_builtin_get ((ecma_builtin_id_t) curr_property_p->value);
+      ecma_ref_object (builtin_object_p);
+      value = ecma_make_object_value (builtin_object_p);
       break;
     }
     case ECMA_BUILTIN_PROPERTY_ROUTINE:
@@ -722,18 +756,15 @@ ecma_builtin_try_to_instantiate_property (ecma_object_t *object_p, /**< object *
       setter_p = ecma_builtin_make_function_object_for_setter_accessor (builtin_id, setter_id);
       break;
     }
-    case ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_ONLY:
+    default:
     {
+      JERRY_ASSERT (curr_property_p->type == ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_ONLY);
+
       is_accessor = true;
       getter_p = ecma_builtin_make_function_object_for_getter_accessor (builtin_id,
                                                                         curr_property_p->value);
       break;
     }
-    default:
-    {
-      JERRY_UNREACHABLE ();
-      return NULL;
-    }
   }
 
   ecma_property_t *prop_p;
@@ -842,15 +873,15 @@ ecma_builtin_list_lazy_property_names (ecma_object_t *object_p, /**< a built-in
         index = 0;
       }
 
-      ecma_string_t *name_p = ecma_get_magic_string (curr_property_p->magic_string_id);
+      ecma_string_t *name_p = ecma_get_magic_string ((lit_magic_string_id_t) curr_property_p->magic_string_id);
 
       uint32_t bit_for_index = (uint32_t) 1u << index;
 
       if (!(*bitset_p & bit_for_index) || ecma_op_object_has_own_property (object_p, name_p))
       {
-        ecma_append_to_values_collection (for_non_enumerable_p,
-                                          ecma_make_magic_string_value (curr_property_p->magic_string_id),
-                                          0);
+        ecma_value_t name = ecma_make_magic_string_value ((lit_magic_string_id_t) curr_property_p->magic_string_id);
+
+        ecma_append_to_values_collection (for_non_enumerable_p, name, 0);
       }
 
       ecma_deref_ecma_string (name_p);
index 11ac1dc4763845dd7649a401f00897fcfb937165..8b2fbaec1bfe751fadacdc1768d6d16400fac555 100644 (file)
@@ -23,6 +23,7 @@
  */
 typedef enum
 {
+/** @cond doxygen_suppress */
 #define BUILTIN(a, b, c, d, e)
 #define BUILTIN_ROUTINE(builtin_id, \
                         object_type, \
@@ -43,6 +44,7 @@ typedef enum
 #include "ecma-builtins.inc.h"
 #undef BUILTIN
 #undef BUILTIN_ROUTINE
+/** @endcond */
   ECMA_BUILTIN_ID__COUNT /**< number of built-in objects */
 } ecma_builtin_id_t;
 
@@ -96,6 +98,8 @@ bool
 ecma_builtin_is (ecma_object_t *obj_p, ecma_builtin_id_t builtin_id);
 ecma_object_t *
 ecma_builtin_get (ecma_builtin_id_t builtin_id);
+ecma_object_t *
+ecma_builtin_get_global (void);
 bool
 ecma_builtin_function_is_routine (ecma_object_t *func_obj_p);
 
index d557f573b94ad8d796794128729337874b24646a..70561152f7a59a4aa12abbd3ed7b75e982b803c0 100644 (file)
@@ -423,6 +423,24 @@ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_PROMISE,
 
 #endif /* !CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */
 
+#ifndef CONFIG_DISABLE_ES2015_MAP_BUILTIN
+
+/* The Map prototype object (23.1.3) */
+BUILTIN (ECMA_BUILTIN_ID_MAP_PROTOTYPE,
+         ECMA_OBJECT_TYPE_GENERAL,
+         ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
+         true,
+         map_prototype)
+
+/* The Map routine (ECMA-262 v6, 23.1.1.1) */
+BUILTIN_ROUTINE (ECMA_BUILTIN_ID_MAP,
+                 ECMA_OBJECT_TYPE_FUNCTION,
+                 ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE,
+                 true,
+                 map)
+
+#endif /* !CONFIG_DISABLE_ES2015_MAP_BUILTIN */
+
 /* The Global object (15.1) */
 BUILTIN (ECMA_BUILTIN_ID_GLOBAL,
          ECMA_OBJECT_TYPE_GENERAL,
index 23149f33bda463fb10746d5339a05c27d3b0469a..e6cbe62bbf2417792d0f0cc4eca88bf01ec86f8b 100644 (file)
  * Float32Array prototype description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 
-/* ES2015 22.2.3.4 */
-OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
-              ECMA_BUILTIN_ID_FLOAT32ARRAY,
-              ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
-
-/* ES2015 22.2.6.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              4,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 4
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_FLOAT32ARRAY
+#include "ecma-builtin-typedarray-prototype-template.inc.h"
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index dca9a87a4fbc7699bb55370cc7cb13f08d2112b8..0e0978e4fef1ffb413d941d61ba412719fbf162f 100644 (file)
@@ -30,6 +30,8 @@
 #define BUILTIN_UNDERSCORED_ID float32array
 #include "ecma-builtin-internal-routines-template.inc.h"
 
+#include "ecma-builtin-typedarray-helpers.h"
+
 /** \addtogroup ecma ECMA
  * @{
  *
@@ -63,18 +65,8 @@ ecma_value_t
 ecma_builtin_float32array_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
                                               ecma_length_t arguments_list_len) /**< number of arguments */
 {
-  JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
-
-  ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FLOAT32ARRAY_PROTOTYPE);
-  ecma_value_t val = ecma_op_create_typedarray (arguments_list_p,
-                                                arguments_list_len,
-                                                prototype_obj_p,
-                                                2,
-                                                LIT_MAGIC_STRING_FLOAT32_ARRAY_UL);
-
-  ecma_deref_object (prototype_obj_p);
-
-  return val;
+  return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len,
+                                                    ECMA_BUILTIN_ID_FLOAT32ARRAY);
 } /* ecma_builtin_float32array_dispatch_construct */
 
 /**
index 259bf6afdef98990f7b8672ba00e1c9490f3d2b1..eb007ece20805e3c7e63e719805e73d0616f626d 100644 (file)
  * Float32Array description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              4,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-STRING_VALUE (LIT_MAGIC_STRING_NAME,
-              LIT_MAGIC_STRING_FLOAT32_ARRAY_UL,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.2 */
-OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
-              ECMA_BUILTIN_ID_FLOAT32ARRAY_PROTOTYPE,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 4
+#define TYPEDARRAY_MAGIC_STRING_ID LIT_MAGIC_STRING_FLOAT32_ARRAY_UL
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_FLOAT32ARRAY_PROTOTYPE
+#include "ecma-builtin-typedarray-template.inc.h"
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index fba6bd7c10e52a7137c64dabfee9c5612d80c8c8..268c355fc68783aa3e99f168768aa82a5c8bb768 100644 (file)
@@ -40,5 +40,6 @@
  * @}
  * @}
  */
+
 #endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
index 52fccbd2aa518a6c1aab77302b7669be69d879a9..0912c0a063e6f3ec12565c359408b7907b29f22a 100644 (file)
  * Float64Array prototype description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 #if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
 
-/* ES2015 22.2.3.4 */
-OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
-              ECMA_BUILTIN_ID_FLOAT64ARRAY,
-              ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
-
-/* ES2015 22.2.6.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              8,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 8
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_FLOAT64ARRAY
+#include "ecma-builtin-typedarray-prototype-template.inc.h"
 
 #endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index b825991c3fe3f971a316462b889a142e4992fa58..bb58d0a8380698fa891d410f0bc2a30b5a608589 100644 (file)
@@ -31,6 +31,8 @@
 #define BUILTIN_UNDERSCORED_ID float64array
 #include "ecma-builtin-internal-routines-template.inc.h"
 
+#include "ecma-builtin-typedarray-helpers.h"
+
 /** \addtogroup ecma ECMA
  * @{
  *
@@ -64,18 +66,8 @@ ecma_value_t
 ecma_builtin_float64array_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
                                               ecma_length_t arguments_list_len) /**< number of arguments */
 {
-  JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
-
-  ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FLOAT64ARRAY_PROTOTYPE);
-  ecma_value_t val = ecma_op_create_typedarray (arguments_list_p,
-                                                arguments_list_len,
-                                                prototype_obj_p,
-                                                3,
-                                                LIT_MAGIC_STRING_FLOAT64_ARRAY_UL);
-
-  ecma_deref_object (prototype_obj_p);
-
-  return val;
+  return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len,
+                                                    ECMA_BUILTIN_ID_FLOAT64ARRAY);
 } /* ecma_builtin_float64array_dispatch_construct */
 
 /**
index 4e4299790914c21bcfc4a6bd241fa04403f3ad36..8a90194b4827679a13f72b591643c35921330864 100644 (file)
  * Float64Array description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 #if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
 
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              8,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-STRING_VALUE (LIT_MAGIC_STRING_NAME,
-              LIT_MAGIC_STRING_FLOAT64_ARRAY_UL,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.2 */
-OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
-              ECMA_BUILTIN_ID_FLOAT64ARRAY_PROTOTYPE,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 8
+#define TYPEDARRAY_MAGIC_STRING_ID LIT_MAGIC_STRING_FLOAT64_ARRAY_UL
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_FLOAT64ARRAY_PROTOTYPE
+#include "ecma-builtin-typedarray-template.inc.h"
 
 #endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index 3455e12c4155aa206b7e5ae654dfadf16558195f..8cfcc2e9ee2b6b43eb535761d9b1f43038d308ac 100644 (file)
  * Int16Array prototype description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 
-/* ES2015 22.2.3.4 */
-OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
-              ECMA_BUILTIN_ID_INT16ARRAY,
-              ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
-
-/* ES2015 22.2.6.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              2,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 2
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_INT16ARRAY
+#include "ecma-builtin-typedarray-prototype-template.inc.h"
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index 302a759081b73af57fe69e8f18e6ec94c6467720..ddfad2733e745d4cac129b26f48645aa5a8b7178 100644 (file)
@@ -30,6 +30,8 @@
 #define BUILTIN_UNDERSCORED_ID int16array
 #include "ecma-builtin-internal-routines-template.inc.h"
 
+#include "ecma-builtin-typedarray-helpers.h"
+
 /** \addtogroup ecma ECMA
  * @{
  *
@@ -63,18 +65,8 @@ ecma_value_t
 ecma_builtin_int16array_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
                                             ecma_length_t arguments_list_len) /**< number of arguments */
 {
-  JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
-
-  ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_INT16ARRAY_PROTOTYPE);
-  ecma_value_t val = ecma_op_create_typedarray (arguments_list_p,
-                                                arguments_list_len,
-                                                prototype_obj_p,
-                                                1,
-                                                LIT_MAGIC_STRING_INT16_ARRAY_UL);
-
-  ecma_deref_object (prototype_obj_p);
-
-  return val;
+  return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len,
+                                                    ECMA_BUILTIN_ID_INT16ARRAY);
 } /* ecma_builtin_int16array_dispatch_construct */
 
 /**
index 887b446f60f833236b04f4cfc5222b9dd4bcaef9..e303f0fa64cbf0394d022d2e2569f3ee096dfd39 100644 (file)
  * Int16Array description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              2,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-STRING_VALUE (LIT_MAGIC_STRING_NAME,
-              LIT_MAGIC_STRING_INT16_ARRAY_UL,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.2 */
-OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
-              ECMA_BUILTIN_ID_INT16ARRAY_PROTOTYPE,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 2
+#define TYPEDARRAY_MAGIC_STRING_ID LIT_MAGIC_STRING_INT16_ARRAY_UL
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_INT16ARRAY_PROTOTYPE
+#include "ecma-builtin-typedarray-template.inc.h"
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index 5867495be0979a1a00f7677c4c9a9bd4e23263f9..d885bfb8de213a71f27d5583cc88d11e8dfc93f0 100644 (file)
  * Int32Array prototype description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 
-/* ES2015 22.2.3.4 */
-OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
-              ECMA_BUILTIN_ID_INT32ARRAY,
-              ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
-
-/* ES2015 22.2.6.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              4,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 4
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_INT32ARRAY
+#include "ecma-builtin-typedarray-prototype-template.inc.h"
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index af4b420dc04cea1dc45051f5f3367dbb1b9c6655..dbe045b5e048d130569423b349c6cab4c63c9792 100644 (file)
@@ -30,6 +30,8 @@
 #define BUILTIN_UNDERSCORED_ID int32array
 #include "ecma-builtin-internal-routines-template.inc.h"
 
+#include "ecma-builtin-typedarray-helpers.h"
+
 /** \addtogroup ecma ECMA
  * @{
  *
@@ -63,18 +65,8 @@ ecma_value_t
 ecma_builtin_int32array_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
                                             ecma_length_t arguments_list_len) /**< number of arguments */
 {
-  JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
-
-  ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_INT32ARRAY_PROTOTYPE);
-  ecma_value_t val = ecma_op_create_typedarray (arguments_list_p,
-                                                arguments_list_len,
-                                                prototype_obj_p,
-                                                2,
-                                                LIT_MAGIC_STRING_INT32_ARRAY_UL);
-
-  ecma_deref_object (prototype_obj_p);
-
-  return val;
+  return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len,
+                                                    ECMA_BUILTIN_ID_INT32ARRAY);
 } /* ecma_builtin_int32array_dispatch_construct */
 
 /**
index f45d486a407b9a5a11efde406593dd1b3f9a78be..37683ff7035352275c94b648cc7e033cbb18f4c2 100644 (file)
  * Int32Array description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              4,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-STRING_VALUE (LIT_MAGIC_STRING_NAME,
-              LIT_MAGIC_STRING_INT32_ARRAY_UL,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.2 */
-OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
-              ECMA_BUILTIN_ID_INT32ARRAY_PROTOTYPE,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 4
+#define TYPEDARRAY_MAGIC_STRING_ID LIT_MAGIC_STRING_INT32_ARRAY_UL
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_INT32ARRAY_PROTOTYPE
+#include "ecma-builtin-typedarray-template.inc.h"
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index 29a0842200828d7dd5a482b856d8cd12e075904f..63832d98cd41f82bf1d344f9d80f7df064d5e65c 100644 (file)
  * Int8Array prototype description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 
-/* ES2015 22.2.3.4 */
-OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
-              ECMA_BUILTIN_ID_INT8ARRAY,
-              ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
-
-/* ES2015 22.2.6.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              1,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 1
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_INT8ARRAY
+#include "ecma-builtin-typedarray-prototype-template.inc.h"
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index d076a15c03f7537363bef7a4c0f5e5a0b708037b..3a78a382af52b6a77e1aed66fb0af480346198bc 100644 (file)
@@ -30,6 +30,8 @@
 #define BUILTIN_UNDERSCORED_ID int8array
 #include "ecma-builtin-internal-routines-template.inc.h"
 
+#include "ecma-builtin-typedarray-helpers.h"
+
 /** \addtogroup ecma ECMA
  * @{
  *
@@ -63,18 +65,8 @@ ecma_value_t
 ecma_builtin_int8array_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
                                            ecma_length_t arguments_list_len) /**< number of arguments */
 {
-  JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
-
-  ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_INT8ARRAY_PROTOTYPE);
-  ecma_value_t val = ecma_op_create_typedarray (arguments_list_p,
-                                                arguments_list_len,
-                                                prototype_obj_p,
-                                                0,
-                                                LIT_MAGIC_STRING_INT8_ARRAY_UL);
-
-  ecma_deref_object (prototype_obj_p);
-
-  return val;
+  return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len,
+                                                    ECMA_BUILTIN_ID_INT8ARRAY);
 } /* ecma_builtin_int8array_dispatch_construct */
 
 /**
index d88bb0a32bd75e9358f1bb702d0d5dae8bcd72b4..ac204ba911eb55f98bea7df1fdc33fd36a76b2aa 100644 (file)
  * Int8Array description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              1,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-STRING_VALUE (LIT_MAGIC_STRING_NAME,
-              LIT_MAGIC_STRING_INT8_ARRAY_UL,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.2 */
-OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
-              ECMA_BUILTIN_ID_INT8ARRAY_PROTOTYPE,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 1
+#define TYPEDARRAY_MAGIC_STRING_ID LIT_MAGIC_STRING_INT8_ARRAY_UL
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_INT8ARRAY_PROTOTYPE
+#include "ecma-builtin-typedarray-template.inc.h"
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
diff --git a/deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-helpers.c b/deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-helpers.c
new file mode 100644 (file)
index 0000000..cc62348
--- /dev/null
@@ -0,0 +1,228 @@
+/* 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-typedarray-helpers.h"
+
+#ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
+
+#include "ecma-builtins.h"
+#include "ecma-gc.h"
+#include "ecma-objects.h"
+#include "ecma-typedarray-object.h"
+
+#define ECMA_BUILTINS_INTERNAL
+#include "ecma-builtins-internal.h"
+
+/**
+ * Returns true if the builtin is a TypedArray type.
+ *
+ * @return bool
+ */
+bool
+ecma_typedarray_helper_is_typedarray (uint8_t builtin_id) /**< the builtin id of a type **/
+{
+  switch (builtin_id)
+  {
+    case ECMA_BUILTIN_ID_INT8ARRAY:
+    case ECMA_BUILTIN_ID_UINT8ARRAY:
+    case ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY:
+    case ECMA_BUILTIN_ID_INT16ARRAY:
+    case ECMA_BUILTIN_ID_UINT16ARRAY:
+    case ECMA_BUILTIN_ID_INT32ARRAY:
+    case ECMA_BUILTIN_ID_UINT32ARRAY:
+    case ECMA_BUILTIN_ID_FLOAT32ARRAY:
+#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
+    case ECMA_BUILTIN_ID_FLOAT64ARRAY:
+#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */
+    {
+      return true;
+    }
+    default:
+    {
+      return false;
+    }
+  }
+} /* ecma_typedarray_helper_is_typedarray */
+
+/**
+ * Get the element shift size of a TypedArray type.
+ *
+ * @return uint8_t
+ */
+uint8_t
+ecma_typedarray_helper_get_shift_size (uint8_t builtin_id) /**< the builtin id of the typedarray **/
+{
+  switch (builtin_id)
+  {
+    case ECMA_BUILTIN_ID_INT8ARRAY:
+    case ECMA_BUILTIN_ID_UINT8ARRAY:
+    case ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY:
+    {
+      return 0;
+    }
+    case ECMA_BUILTIN_ID_INT16ARRAY:
+    case ECMA_BUILTIN_ID_UINT16ARRAY:
+    {
+      return 1;
+    }
+    case ECMA_BUILTIN_ID_INT32ARRAY:
+    case ECMA_BUILTIN_ID_UINT32ARRAY:
+    case ECMA_BUILTIN_ID_FLOAT32ARRAY:
+    {
+      return 2;
+    }
+#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
+    case ECMA_BUILTIN_ID_FLOAT64ARRAY:
+    {
+      return 3;
+    }
+#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */
+    default:
+    {
+      JERRY_UNREACHABLE ();
+    }
+  }
+} /* ecma_typedarray_helper_get_shift_size */
+
+/**
+ * Get the built-in TypedArray type from a magic string.
+ *
+ * @return uint8_t
+ */
+uint8_t
+ecma_typedarray_helper_get_builtin_id (ecma_object_t *obj_p) /**< typedarray object **/
+{
+#define TYPEDARRAY_ID_CASE(magic_id, builtin_id) \
+  case magic_id: \
+  { \
+    return builtin_id; \
+  }
+
+  switch (ecma_object_get_class_name (obj_p))
+  {
+    TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_INT8_ARRAY_UL, ECMA_BUILTIN_ID_INT8ARRAY)
+    TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_UINT8_ARRAY_UL, ECMA_BUILTIN_ID_UINT8ARRAY)
+    TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL, ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY)
+    TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_INT16_ARRAY_UL, ECMA_BUILTIN_ID_INT16ARRAY)
+    TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_UINT16_ARRAY_UL, ECMA_BUILTIN_ID_UINT16ARRAY)
+    TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_INT32_ARRAY_UL, ECMA_BUILTIN_ID_INT32ARRAY)
+    TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_UINT32_ARRAY_UL, ECMA_BUILTIN_ID_UINT32ARRAY)
+    TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_FLOAT32_ARRAY_UL, ECMA_BUILTIN_ID_FLOAT32ARRAY)
+#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
+    TYPEDARRAY_ID_CASE (LIT_MAGIC_STRING_FLOAT64_ARRAY_UL, ECMA_BUILTIN_ID_FLOAT64ARRAY)
+#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */
+    default:
+    {
+      JERRY_UNREACHABLE ();
+    }
+  }
+#undef TYPEDARRAY_ID_CASE
+} /* ecma_typedarray_helper_get_builtin_id */
+
+/**
+ * Get the magic string of a TypedArray type.
+ *
+ * @return uint8_t
+ */
+uint8_t
+ecma_typedarray_helper_get_magic_string (uint8_t builtin_id) /**< the builtin id of the typedarray **/
+{
+#define TYPEDARRAY_ID_CASE(builtin_id, magic_id) \
+  case builtin_id: \
+  { \
+    return magic_id; \
+  }
+
+  switch (builtin_id)
+  {
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT8ARRAY, LIT_MAGIC_STRING_INT8_ARRAY_UL)
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT8ARRAY, LIT_MAGIC_STRING_UINT8_ARRAY_UL)
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY, LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL)
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT16ARRAY, LIT_MAGIC_STRING_INT16_ARRAY_UL)
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT16ARRAY, LIT_MAGIC_STRING_UINT16_ARRAY_UL)
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT32ARRAY, LIT_MAGIC_STRING_INT32_ARRAY_UL)
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT32ARRAY, LIT_MAGIC_STRING_UINT32_ARRAY_UL)
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_FLOAT32ARRAY, LIT_MAGIC_STRING_FLOAT32_ARRAY_UL)
+#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_FLOAT64ARRAY, LIT_MAGIC_STRING_FLOAT64_ARRAY_UL)
+#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */
+    default:
+    {
+      JERRY_UNREACHABLE ();
+    }
+  }
+#undef TYPEDARRAY_ID_CASE
+} /* ecma_typedarray_helper_get_magic_string */
+
+/**
+ * Get the prototype ID of a TypedArray type.
+ *
+ * @return uint8_t
+ */
+uint8_t
+ecma_typedarray_helper_get_prototype_id (uint8_t builtin_id) /**< the builtin id of the typedarray **/
+{
+#define TYPEDARRAY_ID_CASE(builtin_id) \
+  case builtin_id: \
+  { \
+    return builtin_id ## _PROTOTYPE; \
+  }
+
+  switch (builtin_id)
+  {
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT8ARRAY)
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT8ARRAY)
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY)
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT16ARRAY)
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT16ARRAY)
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_INT32ARRAY)
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_UINT32ARRAY)
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_FLOAT32ARRAY)
+#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
+    TYPEDARRAY_ID_CASE (ECMA_BUILTIN_ID_FLOAT64ARRAY)
+#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */
+    default:
+    {
+      JERRY_UNREACHABLE ();
+    }
+  }
+#undef TYPEDARRAY_ID_CASE
+} /* ecma_typedarray_helper_get_prototype_id */
+
+/**
+ * Common implementation of the [[Construct]] call of TypedArrays.
+ *
+ * @return ecma value of the new TypedArray object
+ *         Returned value must be freed with ecma_free_value
+ */
+ecma_value_t
+ecma_typedarray_helper_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
+                                           ecma_length_t arguments_list_len, /**< number of arguments */
+                                           uint8_t builtin_id) /**< the builtin id of the typedarray */
+{
+  JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
+  JERRY_ASSERT (ecma_typedarray_helper_is_typedarray (builtin_id));
+
+  ecma_object_t *prototype_obj_p = ecma_builtin_get (ecma_typedarray_helper_get_prototype_id (builtin_id));
+  ecma_value_t val = ecma_op_create_typedarray (arguments_list_p,
+                                                arguments_list_len,
+                                                prototype_obj_p,
+                                                ecma_typedarray_helper_get_shift_size (builtin_id),
+                                                ecma_typedarray_helper_get_magic_string (builtin_id));
+
+  return val;
+} /* ecma_typedarray_helper_dispatch_construct */
+
+#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
diff --git a/deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-helpers.h b/deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-helpers.h
new file mode 100644 (file)
index 0000000..764208d
--- /dev/null
@@ -0,0 +1,46 @@
+/* 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_TYPEDARRAY_HELPERS_H
+#define ECMA_TYPEDARRAY_HELPERS_H
+#ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
+
+#include "ecma-globals.h"
+
+/** \addtogroup ecma ECMA
+ * @{
+ *
+ * \addtogroup ecmabuiltinhelpers ECMA builtin helper operations
+ * @{
+ */
+
+bool ecma_typedarray_helper_is_typedarray (uint8_t builtin_id);
+uint8_t ecma_typedarray_helper_get_shift_size (uint8_t builtin_id);
+uint8_t ecma_typedarray_helper_get_builtin_id (ecma_object_t *obj_p);
+uint8_t ecma_typedarray_helper_get_magic_string (uint8_t builtin_id);
+uint8_t ecma_typedarray_helper_get_prototype_id (uint8_t builtin_id);
+
+ecma_value_t
+ecma_typedarray_helper_dispatch_construct (const ecma_value_t *arguments_list_p,
+                                           ecma_length_t arguments_list_len,
+                                           uint8_t builtin_id);
+
+/**
+ * @}
+ * @}
+ */
+
+#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
+#endif /* !ECMA_TYPEDARRAY_HELPERS_H */
diff --git a/deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype-template.inc.h b/deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-prototype-template.inc.h
new file mode 100644 (file)
index 0000000..83527a9
--- /dev/null
@@ -0,0 +1,43 @@
+/* Copyright JS Foundation and other contributors, http://js.foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
+
+#ifndef TYPEDARRAY_BYTES_PER_ELEMENT
+# error "Please define TYPEDARRAY_BYTES_PER_ELEMENT"
+#endif /* !TYPEDARRAY_BYTES_PER_ELEMENT */
+
+#ifndef TYPEDARRAY_BUILTIN_ID
+# error "Please define TYPEDARRAY_BUILTIN_ID"
+#endif /* !TYPEDARRAY_BUILTIN_ID */
+
+#include "ecma-builtin-helpers-macro-defines.inc.h"
+
+/* ES2015 22.2.3.4 */
+OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
+              TYPEDARRAY_BUILTIN_ID,
+              ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
+
+/* ES2015 22.2.6.1 */
+NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
+              TYPEDARRAY_BYTES_PER_ELEMENT,
+              ECMA_PROPERTY_FIXED)
+
+#include "ecma-builtin-helpers-macro-undefs.inc.h"
+
+#undef TYPEDARRAY_BUILTIN_ID
+#undef TYPEDARRAY_BYTES_PER_ELEMENT
+
+#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
index 6b09a71e565a7e352188ee7dbabee3fd79412805..316e7cc475ed9af8ac9faff2c3add6521a9558fe 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include "ecma-builtin-helpers.h"
+#include "ecma-builtin-typedarray-helpers.h"
 #include "ecma-builtins.h"
 #include "ecma-exceptions.h"
 #include "ecma-globals.h"
@@ -198,12 +199,10 @@ ecma_builtin_typedarray_prototype_exec_routine (ecma_value_t this_arg, /**< this
         ret_value = ECMA_VALUE_FALSE;
       }
     }
-    else if (mode == TYPEDARRAY_ROUTINE_SOME)
+    else if (mode == TYPEDARRAY_ROUTINE_SOME
+             && ecma_op_to_boolean (call_value))
     {
-      if (ecma_op_to_boolean (call_value))
-      {
-        ret_value = ECMA_VALUE_TRUE;
-      }
+      ret_value = ECMA_VALUE_TRUE;
     }
 
     ECMA_FINALIZE (call_value);
@@ -554,6 +553,11 @@ ecma_builtin_typedarray_prototype_filter (ecma_value_t this_arg, /**< this argum
   ecma_object_t *func_object_p = ecma_get_object_from_value (cb_func_val);
   ecma_value_t ret_value = ECMA_VALUE_EMPTY;
 
+  if (len == 0)
+  {
+    return ecma_op_create_typedarray_with_type_and_length (obj_p, 0);
+  }
+
   JMEM_DEFINE_LOCAL_ARRAY (pass_value_list_p, len * element_size, lit_utf8_byte_t);
 
   lit_utf8_byte_t *pass_value_p = pass_value_list_p;
@@ -589,7 +593,6 @@ ecma_builtin_typedarray_prototype_filter (ecma_value_t this_arg, /**< this argum
 
     ret_value = ecma_op_create_typedarray_with_type_and_length (obj_p, pass_num);
 
-
     if (!ECMA_IS_VALUE_ERROR (ret_value))
     {
       obj_p = ecma_get_object_from_value (ret_value);
@@ -647,32 +650,148 @@ ecma_builtin_typedarray_prototype_reverse (ecma_value_t this_arg) /**< this argu
   return ecma_copy_value (this_arg);
 } /* ecma_builtin_typedarray_prototype_reverse */
 
+/**
+ * The %TypedArray%.prototype object's 'set' routine for a typedArray source
+ *
+ * See also:
+ *          ES2015, 22.2.3.22, 22.2.3.22.2
+ *
+ * @return ecma value of undefined if success, error otherwise.
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_op_typedarray_set_with_typedarray (ecma_value_t this_arg, /**< this argument */
+                                        ecma_value_t arr_val, /**< typedarray object */
+                                        ecma_value_t offset_val) /**< offset value */
+{
+  /* 6.~ 8. targetOffset */
+  ecma_number_t target_offset_num;
+  if (!ecma_is_value_empty (ecma_get_number (offset_val, &target_offset_num)))
+  {
+    return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid offset"));
+  }
+
+  if (ecma_number_is_nan (target_offset_num))
+  {
+    target_offset_num = 0;
+  }
+
+  if (target_offset_num <= -1.0 || target_offset_num >= (ecma_number_t) UINT32_MAX + 0.5)
+  {
+    return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid offset"));
+  }
+
+  ecma_object_t *target_typedarray_p = ecma_get_object_from_value (this_arg);
+  ecma_object_t *src_typedarray_p = ecma_get_object_from_value (arr_val);
+
+  /* 9. targetBuffer */
+  ecma_object_t *target_arraybuffer_p = ecma_typedarray_get_arraybuffer (target_typedarray_p);
+  lit_utf8_byte_t *target_buffer_p = ecma_typedarray_get_buffer (target_typedarray_p);
+
+  /* 11. targetLength */
+  ecma_length_t target_length = ecma_typedarray_get_length (target_typedarray_p);
+
+  /* 12. srcBuffer */
+  ecma_object_t *src_arraybuffer_p = ecma_typedarray_get_arraybuffer (src_typedarray_p);
+  lit_utf8_byte_t *src_buffer_p = ecma_typedarray_get_buffer (src_typedarray_p);
+
+  /* 15. targetType */
+  lit_magic_string_id_t target_class_id = ecma_object_get_class_name (target_typedarray_p);
+
+  /* 16. targetElementSize */
+  uint8_t target_shift = ecma_typedarray_get_element_size_shift (target_typedarray_p);
+  uint8_t target_element_size = (uint8_t) (1 << target_shift);
+
+  /* 17. targetByteOffset */
+  ecma_length_t target_byte_offset = ecma_typedarray_get_offset (target_typedarray_p);
+
+  /* 19. srcType */
+  lit_magic_string_id_t src_class_id = ecma_object_get_class_name (src_typedarray_p);
+
+  /* 20. srcElementSize */
+  uint8_t src_shift = ecma_typedarray_get_element_size_shift (src_typedarray_p);
+  uint8_t src_element_size = (uint8_t) (1 << src_shift);
+
+  /* 21. srcLength */
+  ecma_length_t src_length = ecma_typedarray_get_length (src_typedarray_p);
+  uint32_t src_length_uint32 = ecma_number_to_uint32 (src_length);
+
+  if ((ecma_number_t) src_length_uint32 != src_length)
+  {
+    return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid source length"));
+  }
+
+  /* 22. srcByteOffset */
+  ecma_length_t src_byte_offset = ecma_typedarray_get_offset (src_typedarray_p);
+
+  /* 23. */
+  uint32_t target_offset_uint32 = ecma_number_to_uint32 (target_offset_num);
+
+  if ((int64_t) src_length_uint32 + target_offset_uint32 > target_length)
+  {
+    return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid range of index"));
+  }
+
+  /* 24.d, 25. srcByteIndex */
+  ecma_length_t src_byte_index = 0;
+
+  if (src_arraybuffer_p != target_arraybuffer_p)
+  {
+    src_byte_index = src_byte_offset;
+  }
+
+  /* 26. targetByteIndex */
+  uint32_t target_byte_index = target_offset_uint32 * target_element_size + target_byte_offset;
+
+  /* 27. limit */
+  uint32_t limit = target_byte_index + target_element_size * src_length_uint32;
+
+  if (src_class_id == target_class_id)
+  {
+    memmove (target_buffer_p + target_byte_index, src_buffer_p + src_byte_index,
+             target_element_size * src_length_uint32);
+  }
+  else
+  {
+    while (target_byte_index < limit)
+    {
+      ecma_number_t elem_num = ecma_get_typedarray_element (src_buffer_p + src_byte_index, src_class_id);
+      ecma_set_typedarray_element (target_buffer_p + target_byte_index, elem_num, target_class_id);
+      src_byte_index += src_element_size;
+      target_byte_index += target_element_size;
+    }
+  }
+
+  return ECMA_VALUE_UNDEFINED;
+} /* ecma_op_typedarray_set_with_typedarray */
+
 /**
  * The %TypedArray%.prototype object's 'set' routine
  *
  * See also:
  *          ES2015, 22.2.3.22, 22.2.3.22.1
  *
- * @return ecma value of undefined.
+ * @return ecma value of undefined if success, error otherwise.
+ *         Returned value must be freed with ecma_free_value.
  */
 ecma_value_t
 ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument */
                                        ecma_value_t arr_val, /**< array object */
                                        ecma_value_t offset_val) /**< offset value */
 {
-  /* 1. */
-  if (ecma_is_typedarray (arr_val))
-  {
-    /* 22.2.3.22.2 %TypedArray%.prototype(typedArray [, offset ]) is not supported */
-    return ecma_raise_type_error (ECMA_ERR_MSG ("TypedArray.set(typedArray [,offset]) is not supported."));
-  }
-
   /* 2.~ 4. */
   if (!ecma_is_typedarray (this_arg))
   {
     return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a TypedArray."));
   }
 
+  /* 1. */
+  if (ecma_is_typedarray (arr_val))
+  {
+    /* 22.2.3.22.2 */
+    return ecma_op_typedarray_set_with_typedarray (this_arg, arr_val, offset_val);
+  }
+
   /* 6.~ 8. targetOffset */
   ecma_value_t ret_val = ECMA_VALUE_EMPTY;
   ECMA_OP_TO_NUMBER_TRY_CATCH (target_offset_num, offset_val, ret_val);
@@ -680,7 +799,7 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument
   {
     target_offset_num = 0;
   }
-  if (target_offset_num <= -1.0 || target_offset_num >= (double) UINT32_MAX + 0.5)
+  if (target_offset_num <= -1.0 || target_offset_num >= (ecma_number_t) UINT32_MAX + 0.5)
   {
     return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid offset"));
   }
@@ -767,6 +886,659 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument
   return ret_val;
 } /* ecma_builtin_typedarray_prototype_set */
 
+/**
+ * TypedArray.prototype's 'toString' single element operation routine based
+ * on the Array.prototype's 'toString' single element operation routine
+ *
+ * See also:
+ *          ECMA-262 v5.1, 15.4.4.2
+ *
+ * @return ecma_value_t value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_op_typedarray_get_to_string_at_index (ecma_object_t *obj_p, /**< this object */
+                                           uint32_t index) /**< array index */
+{
+  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
+  ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index);
+  ecma_value_t index_value = ecma_op_object_get (obj_p, index_string_p);
+  ecma_deref_ecma_string (index_string_p);
+
+  if (ECMA_IS_VALUE_ERROR (index_value))
+  {
+    return index_value;
+  }
+
+  if (ecma_is_value_undefined (index_value)
+      || ecma_is_value_null (index_value))
+  {
+    ret_value = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
+  }
+  else
+  {
+    ret_value = ecma_op_to_string (index_value);
+  }
+
+  ecma_free_value (index_value);
+  return ret_value;
+} /* ecma_op_typedarray_get_to_string_at_index */
+
+/**
+ * The TypedArray.prototype.toString's separator creation routine based on
+ * the Array.prototype.toString's separator routine
+ *
+ * See also:
+ *          ECMA-262 v5.1, 15.4.4.2 4th step
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_op_typedarray_get_separator_string (ecma_value_t separator) /**< possible separator */
+{
+  if (ecma_is_value_undefined (separator))
+  {
+    return ecma_make_magic_string_value (LIT_MAGIC_STRING_COMMA_CHAR);
+  }
+
+  return ecma_op_to_string (separator);
+} /* ecma_op_typedarray_get_separator_string */
+
+/**
+ * The TypedArray.prototype object's 'join' routine basen on
+ * the Array.porottype object's 'join'
+ *
+ * See also:
+ *          ECMA-262 v5, 15.4.4.5
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_typedarray_prototype_join (ecma_value_t this_arg, /**< this argument */
+                                        ecma_value_t separator_arg) /**< separator argument */
+{
+  /* 1. */
+  ecma_value_t obj_value = ecma_op_to_object (this_arg);
+
+  if (ECMA_IS_VALUE_ERROR (obj_value))
+  {
+    return obj_value;
+  }
+  ecma_object_t *obj_p = ecma_get_object_from_value (obj_value);
+
+  /* 2. */
+  ecma_value_t length_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_LENGTH);
+
+  if (ECMA_IS_VALUE_ERROR (length_value))
+  {
+    ecma_free_value (obj_value);
+    return length_value;
+  }
+
+  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
+
+  ECMA_OP_TO_NUMBER_TRY_CATCH (length_number,
+                               length_value,
+                               ret_value);
+
+  /* 3. */
+  uint32_t length = ecma_number_to_uint32 (length_number);
+  /* 4-5. */
+  ecma_value_t separator_value = ecma_op_typedarray_get_separator_string (separator_arg);
+  if (ECMA_IS_VALUE_ERROR (separator_value))
+  {
+    ecma_free_value (length_value);
+    ecma_free_value (obj_value);
+    return separator_value;
+  }
+
+  if (length == 0)
+  {
+    /* 6. */
+    ret_value = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
+  }
+  else
+  {
+    ecma_string_t *separator_string_p = ecma_get_string_from_value (separator_value);
+
+    /* 7-8. */
+    ecma_value_t first_value = ecma_op_typedarray_get_to_string_at_index (obj_p, 0);
+    if (ECMA_IS_VALUE_ERROR (first_value))
+    {
+      ecma_free_value (separator_value);
+      ecma_free_value (length_value);
+      ecma_free_value (obj_value);
+      return first_value;
+    }
+
+    ecma_string_t *return_string_p = ecma_get_string_from_value (first_value);
+    ecma_ref_ecma_string (return_string_p);
+    if (ecma_is_value_empty (ret_value))
+    {
+      /* 9-10. */
+      for (uint32_t k = 1; k < length; k++)
+      {
+        /* 10.a */
+        return_string_p = ecma_concat_ecma_strings (return_string_p, separator_string_p);
+
+       /* 10.b, 10.c */
+        ecma_value_t next_string_value = ecma_op_typedarray_get_to_string_at_index (obj_p, k);
+        if (ECMA_IS_VALUE_ERROR (next_string_value))
+        {
+          ecma_free_value (first_value);
+          ecma_free_value (separator_value);
+          ecma_free_value (length_value);
+          ecma_free_value (obj_value);
+          return next_string_value;
+        }
+
+        /* 10.d */
+        ecma_string_t *next_string_p = ecma_get_string_from_value (next_string_value);
+        return_string_p = ecma_concat_ecma_strings (return_string_p, next_string_p);
+
+        ecma_free_value (next_string_value);
+      }
+      ret_value = ecma_make_string_value (return_string_p);
+    }
+    else
+    {
+      ecma_deref_ecma_string (return_string_p);
+    }
+
+    ecma_free_value (first_value);
+  }
+  ecma_free_value (separator_value);
+
+  ecma_free_value (length_value);
+  ecma_free_value (obj_value);
+  ECMA_OP_TO_NUMBER_FINALIZE (length_number);
+  return ret_value;
+} /* ecma_builtin_typedarray_prototype_join */
+
+/**
+ * The TypedArray.prototype object's 'toString' routine basen on
+ * the Array.porottype object's 'toString'
+ *
+ * See also:
+ *          ECMA-262 v5, 15.4.4.2
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_typedarray_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */
+{
+  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
+
+  /* 1. */
+  ecma_value_t obj_this_value = ecma_op_to_object (this_arg);
+  if (ECMA_IS_VALUE_ERROR (obj_this_value))
+  {
+    return obj_this_value;
+  }
+  ecma_object_t *obj_p = ecma_get_object_from_value (obj_this_value);
+
+  /* 2. */
+  ecma_value_t join_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_JOIN);
+  if (ECMA_IS_VALUE_ERROR (join_value))
+  {
+    ecma_free_value (obj_this_value);
+    return join_value;
+  }
+
+  if (!ecma_op_is_callable (join_value))
+  {
+    /* 3. */
+    ret_value = ecma_builtin_helper_object_to_string (this_arg);
+  }
+  else
+  {
+    /* 4. */
+    ecma_object_t *join_func_obj_p = ecma_get_object_from_value (join_value);
+
+    ret_value = ecma_op_function_call (join_func_obj_p, this_arg, NULL, 0);
+  }
+
+  ecma_free_value (join_value);
+  ecma_free_value (obj_this_value);
+
+  return ret_value;
+} /* ecma_builtin_typedarray_prototype_object_to_string */
+
+/**
+ * The %TypedArray%.prototype object's 'subarray' routine.
+ *
+ * See also:
+ *          ES2015, 22.2.3.26
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_typedarray_prototype_subarray (ecma_value_t this_arg, /**< this argument */
+                                            ecma_value_t begin, /**< begin */
+                                            ecma_value_t end) /**< end */
+{
+  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
+
+  /* 2.~ 4. */
+  if (!ecma_is_typedarray (this_arg))
+  {
+    return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a TypedArray."));
+  }
+
+  ecma_object_t *src_typedarray_p = ecma_get_object_from_value (this_arg);
+
+  /* 5. buffer */
+  ecma_object_t *src_typedarray_arraybuffer_p = ecma_typedarray_get_arraybuffer (src_typedarray_p);
+
+  /* 6. srcLength */
+  ecma_length_t src_length = ecma_typedarray_get_length (src_typedarray_p);
+
+  /* 9. beginIndex, 12. endIndex */
+  uint32_t begin_index_uint32 = 0, end_index_uint32 = 0;
+
+  /* 7. relativeBegin */
+  ECMA_OP_TO_NUMBER_TRY_CATCH (relative_begin, begin, ret_value);
+  begin_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_begin, src_length);
+
+  if (ecma_is_value_undefined (end))
+  {
+    end_index_uint32 = (uint32_t) src_length;
+  }
+  else
+  {
+    /* 10. relativeEnd */
+    ECMA_OP_TO_NUMBER_TRY_CATCH (relative_end, end, ret_value);
+
+    end_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_end, src_length);
+
+    ECMA_OP_TO_NUMBER_FINALIZE (relative_end);
+  }
+
+  ECMA_OP_TO_NUMBER_FINALIZE (relative_begin);
+
+  if (!ecma_is_value_empty (ret_value))
+  {
+    return ret_value;
+  }
+
+  /* 13. newLength */
+  ecma_length_t subarray_length = 0;
+
+  if (end_index_uint32 > begin_index_uint32)
+  {
+    subarray_length = end_index_uint32 - begin_index_uint32;
+  }
+
+  /* 15. elementSize */
+  uint8_t shift = ecma_typedarray_get_element_size_shift (src_typedarray_p);
+  uint8_t element_size = (uint8_t) (1 << shift);
+
+  /* 16. srcByteOffset */
+  ecma_length_t src_byte_offset = ecma_typedarray_get_offset (src_typedarray_p);
+
+  /* 17. beginByteOffset */
+  ecma_length_t begin_byte_offset = src_byte_offset + begin_index_uint32 * element_size;
+
+  uint8_t src_builtin_id = ecma_typedarray_helper_get_builtin_id (src_typedarray_p);
+  ecma_value_t arguments_p[3] =
+  {
+    ecma_make_object_value (src_typedarray_arraybuffer_p),
+    ecma_make_uint32_value (begin_byte_offset),
+    ecma_make_uint32_value (subarray_length)
+  };
+
+  ret_value = ecma_typedarray_helper_dispatch_construct (arguments_p, 3, src_builtin_id);
+
+  ecma_free_value (arguments_p[1]);
+  ecma_free_value (arguments_p[2]);
+  return ret_value;
+} /* ecma_builtin_typedarray_prototype_subarray */
+
+/**
+ * The %TypedArray%.prototype object's 'fill' routine.
+ *
+ * See also:
+ *          ES2015, 22.2.3.8, 22.1.3.6
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_typedarray_prototype_fill (ecma_value_t this_arg, /**< this argument */
+                                        ecma_value_t value, /**< value */
+                                        ecma_value_t begin, /**< begin */
+                                        ecma_value_t end) /**< end */
+{
+  if (!ecma_is_typedarray (this_arg))
+  {
+    return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a TypedArray."));
+  }
+
+  ecma_number_t value_num;
+  ecma_value_t ret_value = ecma_get_number (value, &value_num);
+
+  if (!ecma_is_value_empty (ret_value))
+  {
+    return ret_value;
+  }
+
+  ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg);
+  ecma_object_t *typedarray_arraybuffer_p = ecma_typedarray_get_arraybuffer (typedarray_p);
+  lit_utf8_byte_t *buffer_p = ecma_arraybuffer_get_buffer (typedarray_arraybuffer_p);
+  ecma_length_t length = ecma_typedarray_get_length (typedarray_p);
+
+  uint32_t begin_index_uint32 = 0, end_index_uint32 = 0;
+
+  ECMA_OP_TO_NUMBER_TRY_CATCH (relative_begin, begin, ret_value);
+  begin_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_begin, length);
+
+  if (ecma_is_value_undefined (end))
+  {
+    end_index_uint32 = (uint32_t) length;
+  }
+  else
+  {
+    ECMA_OP_TO_NUMBER_TRY_CATCH (relative_end, end, ret_value);
+
+    end_index_uint32 = ecma_builtin_helper_array_index_normalize (relative_end, length);
+
+    ECMA_OP_TO_NUMBER_FINALIZE (relative_end);
+  }
+
+  ECMA_OP_TO_NUMBER_FINALIZE (relative_begin);
+
+  if (!ecma_is_value_empty (ret_value))
+  {
+    return ret_value;
+  }
+
+  ecma_length_t subarray_length = 0;
+
+  if (end_index_uint32 > begin_index_uint32)
+  {
+    subarray_length = end_index_uint32 - begin_index_uint32;
+  }
+
+  uint8_t shift = ecma_typedarray_get_element_size_shift (typedarray_p);
+  ecma_length_t byte_offset = ecma_typedarray_get_offset (typedarray_p);
+  lit_magic_string_id_t class_id = ecma_object_get_class_name (typedarray_p);
+
+  uint8_t element_size = (uint8_t) (1 << shift);
+  uint32_t byte_index = byte_offset + begin_index_uint32 * element_size;
+  uint32_t limit = byte_index + subarray_length * element_size;
+
+  while (byte_index < limit)
+  {
+    ecma_set_typedarray_element (buffer_p + byte_index, value_num, class_id);
+    byte_index += element_size;
+  }
+
+  return ecma_copy_value (this_arg);
+} /* ecma_builtin_typedarray_prototype_fill */
+
+/**
+ * SortCompare abstract method
+ *
+ * See also:
+ *          ECMA-262 v5, 15.4.4.11
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_typedarray_prototype_sort_compare_helper (ecma_value_t lhs, /**< left value */
+                                                       ecma_value_t rhs, /**< right value */
+                                                       ecma_value_t compare_func) /**< compare function */
+{
+  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
+  ecma_number_t result = ECMA_NUMBER_ZERO;
+
+  if (ecma_is_value_undefined (compare_func))
+  {
+    /* Default comparison when no comparefn is passed. */
+    double lhs_value = (double) ecma_get_number_from_value (lhs);
+    double rhs_value = (double) ecma_get_number_from_value (rhs);
+
+    if (ecma_number_is_nan (lhs_value))
+    {
+      // Keep NaNs at the end of the array.
+      result = ECMA_NUMBER_ONE;
+    }
+    else if (ecma_number_is_nan (rhs_value))
+    {
+      // Keep NaNs at the end of the array.
+      result = ECMA_NUMBER_MINUS_ONE;
+    }
+    else if (lhs_value < rhs_value)
+    {
+      result = ECMA_NUMBER_MINUS_ONE;
+    }
+    else if (lhs_value > rhs_value)
+    {
+      result = ECMA_NUMBER_ONE;
+    }
+    else
+    {
+      result = ECMA_NUMBER_ZERO;
+    }
+
+    return ecma_make_number_value (result);
+  }
+
+  /*
+   * compare_func, if not undefined, will always contain a callable function object.
+   * We checked this previously, before this function was called.
+   */
+  JERRY_ASSERT (ecma_op_is_callable (compare_func));
+  ecma_object_t *comparefn_obj_p = ecma_get_object_from_value (compare_func);
+
+  ecma_value_t compare_args[] = { lhs, rhs };
+
+  ECMA_TRY_CATCH (call_value,
+                  ecma_op_function_call (comparefn_obj_p,
+                                         ECMA_VALUE_UNDEFINED,
+                                         compare_args,
+                                         2),
+                  ret_value);
+
+  if (!ecma_is_value_number (call_value))
+  {
+    ECMA_OP_TO_NUMBER_TRY_CATCH (ret_num, call_value, ret_value);
+    result = ret_num;
+    ECMA_OP_TO_NUMBER_FINALIZE (ret_num);
+
+    // If the coerced value can't be represented as a Number, compare them as equals.
+    if (ecma_number_is_nan (result))
+    {
+      result = ECMA_NUMBER_ZERO;
+    }
+  }
+  else
+  {
+    result = ecma_get_number_from_value (call_value);
+  }
+
+  ECMA_FINALIZE (call_value);
+
+  if (ecma_is_value_empty (ret_value))
+  {
+    ret_value = ecma_make_number_value (result);
+  }
+
+  return ret_value;
+} /* ecma_builtin_typedarray_prototype_sort_compare_helper */
+
+/**
+ * The %TypedArray%.prototype object's 'sort' routine.
+ *
+ * See also:
+ *          ES2015, 22.2.3.25, 22.1.3.24
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_typedarray_prototype_sort (ecma_value_t this_arg, /**< this argument */
+                                        ecma_value_t compare_func) /**< comparator fn */
+{
+  if (!ecma_is_typedarray (this_arg))
+  {
+    return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a TypedArray."));
+  }
+
+  if (!ecma_is_value_undefined (compare_func) && !ecma_op_is_callable (compare_func))
+  {
+    return ecma_raise_type_error (ECMA_ERR_MSG ("Compare function is not callable."));
+  }
+
+  ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg);
+  ecma_length_t typedarray_length = ecma_typedarray_get_length (typedarray_p);
+
+  if (!typedarray_length)
+  {
+    return ecma_copy_value (this_arg);
+  }
+
+  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
+
+  JMEM_DEFINE_LOCAL_ARRAY (values_buffer, typedarray_length, ecma_value_t);
+
+  lit_magic_string_id_t class_id = ecma_object_get_class_name (typedarray_p);
+  lit_utf8_byte_t *typedarray_buffer_p = ecma_typedarray_get_buffer (typedarray_p);
+  uint8_t shift = ecma_typedarray_get_element_size_shift (typedarray_p);
+  uint8_t element_size = (uint8_t) (1 << shift);
+
+  uint32_t byte_index = 0, buffer_index = 0;
+  uint32_t limit = typedarray_length * element_size;
+
+  /* Copy unsorted array into a native c array. */
+  while (byte_index < limit)
+  {
+    JERRY_ASSERT (buffer_index < typedarray_length);
+    ecma_number_t element_num = ecma_get_typedarray_element (typedarray_buffer_p + byte_index,
+                                                             class_id);
+    ecma_value_t element_value = ecma_make_number_value (element_num);
+    values_buffer[buffer_index++] = element_value;
+    byte_index += element_size;
+  }
+
+  JERRY_ASSERT (buffer_index == typedarray_length);
+
+  const ecma_builtin_helper_sort_compare_fn_t sort_cb = &ecma_builtin_typedarray_prototype_sort_compare_helper;
+  ECMA_TRY_CATCH (sort_value,
+                  ecma_builtin_helper_array_heap_sort_helper (values_buffer,
+                                                              (uint32_t) (typedarray_length - 1),
+                                                              compare_func,
+                                                              sort_cb),
+                  ret_value);
+  ECMA_FINALIZE (sort_value);
+
+  if (ecma_is_value_empty (ret_value))
+  {
+    byte_index = 0;
+    buffer_index = 0;
+    limit = typedarray_length * element_size;
+    /* Put sorted values from the native array back into the typedarray buffer. */
+    while (byte_index < limit)
+    {
+      JERRY_ASSERT (buffer_index < typedarray_length);
+      ecma_value_t element_value = values_buffer[buffer_index++];
+      ecma_number_t element_num = ecma_get_number_from_value (element_value);
+      ecma_set_typedarray_element (typedarray_buffer_p + byte_index, element_num, class_id);
+      byte_index += element_size;
+    }
+
+    JERRY_ASSERT (buffer_index == typedarray_length);
+  }
+
+  /* Free values that were copied to the local array. */
+  for (uint32_t index = 0; index < typedarray_length; index++)
+  {
+    ecma_free_value (values_buffer[index]);
+  }
+
+  JMEM_FINALIZE_LOCAL_ARRAY (values_buffer);
+
+  if (ecma_is_value_empty (ret_value))
+  {
+    ret_value = ecma_copy_value (this_arg);
+  }
+
+  return ret_value;
+} /* ecma_builtin_typedarray_prototype_sort */
+
+/**
+ * The %TypedArray%.prototype object's 'find' routine
+ *
+ * See also:
+ *          ECMA-262 v6, 22.2.3.10
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+static ecma_value_t
+ecma_builtin_typedarray_prototype_find (ecma_value_t this_arg, /**< this argument */
+                                        ecma_value_t predicate, /**< callback function */
+                                        ecma_value_t predicate_this_arg) /**< this argument for
+                                                                          *   invoke predicate */
+{
+  if (!ecma_is_typedarray (this_arg))
+  {
+    return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a TypedArray."));
+  }
+
+  if (!ecma_op_is_callable (predicate))
+  {
+    return ecma_raise_type_error (ECMA_ERR_MSG ("Callback function is not callable."));
+  }
+
+  JERRY_ASSERT (ecma_is_value_object (predicate));
+  ecma_object_t *func_object_p = ecma_get_object_from_value (predicate);
+
+  ecma_object_t *typedarray_p = ecma_get_object_from_value (this_arg);
+  uint32_t typedarray_length = ecma_typedarray_get_length (typedarray_p);
+  lit_magic_string_id_t class_id = ecma_object_get_class_name (typedarray_p);
+  lit_utf8_byte_t *typedarray_buffer_p = ecma_typedarray_get_buffer (typedarray_p);
+  uint8_t shift = ecma_typedarray_get_element_size_shift (typedarray_p);
+  uint8_t element_size = (uint8_t) (1 << shift);
+
+  uint32_t buffer_index = 0;
+  uint32_t limit = typedarray_length * element_size;
+
+  for (uint32_t byte_index = 0;  byte_index < limit; byte_index += element_size)
+  {
+    JERRY_ASSERT (buffer_index < typedarray_length);
+    ecma_number_t element_num = ecma_get_typedarray_element (typedarray_buffer_p + byte_index, class_id);
+    ecma_value_t element_value = ecma_make_number_value (element_num);
+
+    ecma_value_t call_args[] = { element_value, ecma_make_uint32_value (buffer_index++), this_arg };
+
+    ecma_value_t call_value = ecma_op_function_call (func_object_p, predicate_this_arg, call_args, 3);
+
+    if (ECMA_IS_VALUE_ERROR (call_value))
+    {
+      ecma_free_value (element_value);
+      return call_value;
+    }
+
+    bool call_result = ecma_op_to_boolean (call_value);
+    ecma_free_value (call_value);
+
+    if (call_result)
+    {
+      return element_value;
+    }
+
+    ecma_free_value (element_value);
+  }
+
+  return ECMA_VALUE_UNDEFINED;
+} /* ecma_builtin_typedarray_prototype_find */
+
 /**
  * @}
  * @}
index 60dffd9c0665c0ad59bd6161d645fdf68dbebc83..59047b80d7d01ab0f6cd1c2b16c084890526e2aa 100644 (file)
@@ -45,6 +45,10 @@ ACCESSOR_READ_ONLY (LIT_MAGIC_STRING_LENGTH,
                     ecma_builtin_typedarray_prototype_length_getter,
                     ECMA_PROPERTY_FIXED)
 
+/* 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_builtin_typedarray_prototype_object_to_string, 0, 0)
+ROUTINE (LIT_MAGIC_STRING_JOIN,  ecma_builtin_typedarray_prototype_join, 1, 1)
 ROUTINE (LIT_MAGIC_STRING_EVERY, ecma_builtin_typedarray_prototype_every, 2, 1)
 ROUTINE (LIT_MAGIC_STRING_SOME, ecma_builtin_typedarray_prototype_some, 2, 1)
 ROUTINE (LIT_MAGIC_STRING_FOR_EACH_UL, ecma_builtin_typedarray_prototype_for_each, 2, 1)
@@ -54,6 +58,10 @@ ROUTINE (LIT_MAGIC_STRING_REDUCE_RIGHT_UL, ecma_builtin_typedarray_prototype_red
 ROUTINE (LIT_MAGIC_STRING_FILTER, ecma_builtin_typedarray_prototype_filter, 2, 1)
 ROUTINE (LIT_MAGIC_STRING_REVERSE, ecma_builtin_typedarray_prototype_reverse, 0, 0)
 ROUTINE (LIT_MAGIC_STRING_SET, ecma_builtin_typedarray_prototype_set, 2, 1)
+ROUTINE (LIT_MAGIC_STRING_SUBARRAY, ecma_builtin_typedarray_prototype_subarray, 2, 2)
+ROUTINE (LIT_MAGIC_STRING_FILL, ecma_builtin_typedarray_prototype_fill, 3, 1)
+ROUTINE (LIT_MAGIC_STRING_SORT, ecma_builtin_typedarray_prototype_sort, 1, 1)
+ROUTINE (LIT_MAGIC_STRING_FIND, ecma_builtin_typedarray_prototype_find, 2, 1)
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
 
diff --git a/deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-template.inc.h b/deps/jerry/jerry-core/ecma/builtin-objects/typedarray/ecma-builtin-typedarray-template.inc.h
new file mode 100644 (file)
index 0000000..d81a0c0
--- /dev/null
@@ -0,0 +1,63 @@
+/* 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 CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
+
+#ifndef TYPEDARRAY_BYTES_PER_ELEMENT
+# error "Please define TYPEDARRAY_BYTES_PER_ELEMENT"
+#endif /* !TYPEDARRAY_BYTES_PER_ELEMENT */
+
+#ifndef TYPEDARRAY_MAGIC_STRING_ID
+# error "Please define TYPEDARRAY_MAGIC_STRING_ID"
+#endif /* !TYPEDARRAY_MAGIC_STRING_ID */
+
+#ifndef TYPEDARRAY_BUILTIN_ID
+# error "Please define TYPEDARRAY_BUILTIN_ID"
+#endif /* !TYPEDARRAY_BUILTIN_ID */
+
+#include "ecma-builtin-helpers-macro-defines.inc.h"
+
+/* ES2015 22.2.5 */
+NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
+              3,
+              ECMA_PROPERTY_FIXED)
+
+/* ES2015 22.2.5.1 */
+NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
+              TYPEDARRAY_BYTES_PER_ELEMENT,
+              ECMA_PROPERTY_FIXED)
+
+/* ES2015 22.2.5 */
+NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
+              3,
+              ECMA_PROPERTY_FIXED)
+
+/* ES2015 22.2.5 */
+STRING_VALUE (LIT_MAGIC_STRING_NAME,
+              TYPEDARRAY_MAGIC_STRING_ID,
+              ECMA_PROPERTY_FIXED)
+
+/* ES2015 22.2.5.2 */
+OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
+              TYPEDARRAY_BUILTIN_ID,
+              ECMA_PROPERTY_FIXED)
+
+#include "ecma-builtin-helpers-macro-undefs.inc.h"
+
+#undef TYPEDARRAY_BUILTIN_ID
+#undef TYPEDARRAY_MAGIC_STRING_ID
+#undef TYPEDARRAY_BYTES_PER_ELEMENT
+
+#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
index 5485a341fc22a0f97646b3efcbcbfd1e4232d0f0..0b1c7e96e59d1679e2d38e1db714f51330737040 100644 (file)
@@ -32,6 +32,8 @@
 #define BUILTIN_UNDERSCORED_ID typedarray
 #include "ecma-builtin-internal-routines-template.inc.h"
 
+#include "ecma-builtin-typedarray-helpers.h"
+
 /** \addtogroup ecma ECMA
  * @{
  *
@@ -91,85 +93,16 @@ ecma_builtin_typedarray_from (ecma_value_t this_arg, /**< 'this' argument */
 
   ecma_object_t *obj_p = ecma_get_object_from_value (this_arg);
 
-  uint8_t builtin_id = ecma_get_object_builtin_id (obj_p);
-  ecma_object_t *proto_p;
-  uint8_t element_size_shift;
-  lit_magic_string_id_t class_id;
-
-  switch (builtin_id)
+  const uint8_t builtin_id = ecma_get_object_builtin_id (obj_p);
+  if (!ecma_typedarray_helper_is_typedarray (builtin_id))
   {
-    case ECMA_BUILTIN_ID_INT8ARRAY:
-    {
-      proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_INT8ARRAY_PROTOTYPE);
-      element_size_shift = 0;
-      class_id = LIT_MAGIC_STRING_INT8_ARRAY_UL;
-      break;
-    }
-    case ECMA_BUILTIN_ID_UINT8ARRAY:
-    {
-      proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_UINT8ARRAY_PROTOTYPE);
-      element_size_shift = 0;
-      class_id = LIT_MAGIC_STRING_UINT8_ARRAY_UL;
-      break;
-    }
-    case ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY:
-    {
-      proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY_PROTOTYPE);
-      element_size_shift = 0;
-      class_id = LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL;
-      break;
-    }
-    case ECMA_BUILTIN_ID_INT16ARRAY:
-    {
-      proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_INT16ARRAY_PROTOTYPE);
-      element_size_shift = 1;
-      class_id = LIT_MAGIC_STRING_INT16_ARRAY_UL;
-      break;
-    }
-    case ECMA_BUILTIN_ID_UINT16ARRAY:
-    {
-      proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_UINT16ARRAY_PROTOTYPE);
-      element_size_shift = 1;
-      class_id = LIT_MAGIC_STRING_UINT16_ARRAY_UL;
-      break;
-    }
-    case ECMA_BUILTIN_ID_INT32ARRAY:
-    {
-      proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_INT32ARRAY_PROTOTYPE);
-      element_size_shift = 2;
-      class_id = LIT_MAGIC_STRING_INT32_ARRAY_UL;
-      break;
-    }
-    case ECMA_BUILTIN_ID_UINT32ARRAY:
-    {
-      proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_UINT32ARRAY_PROTOTYPE);
-      element_size_shift = 2;
-      class_id = LIT_MAGIC_STRING_UINT32_ARRAY_UL;
-      break;
-    }
-    case ECMA_BUILTIN_ID_FLOAT32ARRAY:
-    {
-      proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_FLOAT32ARRAY_PROTOTYPE);
-      element_size_shift = 2;
-      class_id = LIT_MAGIC_STRING_FLOAT32_ARRAY_UL;
-      break;
-    }
-#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64
-    case ECMA_BUILTIN_ID_FLOAT64ARRAY:
-    {
-      proto_p = ecma_builtin_get (ECMA_BUILTIN_ID_FLOAT64ARRAY_PROTOTYPE);
-      element_size_shift = 3;
-      class_id = LIT_MAGIC_STRING_FLOAT64_ARRAY_UL;
-      break;
-    }
-#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */
-    default:
-    {
-      return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not a typedarray constructor"));
-    }
+    return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not a typedarray constructor"));
   }
 
-  ecma_deref_object (proto_p);
+  ecma_object_t *proto_p = ecma_builtin_get (ecma_typedarray_helper_get_prototype_id (builtin_id));
+  const uint8_t element_size_shift = ecma_typedarray_helper_get_shift_size (builtin_id);
+  const lit_magic_string_id_t class_id = ecma_typedarray_helper_get_magic_string (builtin_id);
+
 
   return ecma_op_typedarray_from (source,
                                   map_fn,
index f77cbfd8d92f2b17247b206c59d6516791af90bd..a93b54d798f18e9d62563459518825fb432aecfb 100644 (file)
  * Uint16Array prototype description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 
-/* ES2015 22.2.3.4 */
-OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
-              ECMA_BUILTIN_ID_UINT16ARRAY,
-              ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
-
-/* ES2015 22.2.6.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              2,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 2
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_UINT16ARRAY
+#include "ecma-builtin-typedarray-prototype-template.inc.h"
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index 5f29a4e1f324e387a2b3778ee7eb85abc63d0336..62c17a41ed68bbec0ab6d45353ef2703269df646 100644 (file)
@@ -30,6 +30,8 @@
 #define BUILTIN_UNDERSCORED_ID uint16array
 #include "ecma-builtin-internal-routines-template.inc.h"
 
+#include "ecma-builtin-typedarray-helpers.h"
+
 /** \addtogroup ecma ECMA
  * @{
  *
@@ -63,18 +65,8 @@ ecma_value_t
 ecma_builtin_uint16array_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
                                              ecma_length_t arguments_list_len) /**< number of arguments */
 {
-  JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
-
-  ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_UINT16ARRAY_PROTOTYPE);
-  ecma_value_t val = ecma_op_create_typedarray (arguments_list_p,
-                                                arguments_list_len,
-                                                prototype_obj_p,
-                                                1,
-                                                LIT_MAGIC_STRING_UINT16_ARRAY_UL);
-
-  ecma_deref_object (prototype_obj_p);
-
-  return val;
+  return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len,
+                                                    ECMA_BUILTIN_ID_UINT16ARRAY);
 } /* ecma_builtin_uint16array_dispatch_construct */
 
 /**
index d25cc9cc1c1b2853ad87d6a915df30404215793c..ae96f95b7d188ad18ebe7a0bce2720635be8a111 100644 (file)
  * Uint16Array description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              2,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-STRING_VALUE (LIT_MAGIC_STRING_NAME,
-              LIT_MAGIC_STRING_UINT16_ARRAY_UL,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.2 */
-OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
-              ECMA_BUILTIN_ID_UINT16ARRAY_PROTOTYPE,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 2
+#define TYPEDARRAY_MAGIC_STRING_ID LIT_MAGIC_STRING_UINT16_ARRAY_UL
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_UINT16ARRAY_PROTOTYPE
+#include "ecma-builtin-typedarray-template.inc.h"
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index 9d730d2860a1432c573e69f5359a8594bbf0ec40..ea217de7914ee4ffddf0af770e5db96ce7afedcd 100644 (file)
  * Uint32Array prototype description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 
-/* ES2015 22.2.3.4 */
-OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
-              ECMA_BUILTIN_ID_UINT32ARRAY,
-              ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
-
-/* ES2015 22.2.6.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              4,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 4
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_UINT32ARRAY
+#include "ecma-builtin-typedarray-prototype-template.inc.h"
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index f8f702d3e8ce3b962fc63e487d559ff809bc5670..ee2e398a0df7a1b4b34d21c45135e351c4b92820 100644 (file)
@@ -72,8 +72,6 @@ ecma_builtin_uint32array_dispatch_construct (const ecma_value_t *arguments_list_
                                                 2,
                                                 LIT_MAGIC_STRING_UINT32_ARRAY_UL);
 
-  ecma_deref_object (prototype_obj_p);
-
   return val;
 } /* ecma_builtin_uint32array_dispatch_construct */
 
index ba1eab907b257d7a449047d625a15a9659a20e7d..cf9d466772c931619741f9b505257157a08ba7b4 100644 (file)
  * Uint32Array description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              4,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-STRING_VALUE (LIT_MAGIC_STRING_NAME,
-              LIT_MAGIC_STRING_UINT32_ARRAY_UL,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.2 */
-OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
-              ECMA_BUILTIN_ID_UINT32ARRAY_PROTOTYPE,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 4
+#define TYPEDARRAY_MAGIC_STRING_ID LIT_MAGIC_STRING_UINT32_ARRAY_UL
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_UINT32ARRAY_PROTOTYPE
+#include "ecma-builtin-typedarray-template.inc.h"
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index d55b4506117aea9a254eac3a51c585dac7adb8f0..30543dc687d2464c3f728d9809e6ba9e8760765f 100644 (file)
  * Uint8Array prototype description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 
-/* ES2015 22.2.3.4 */
-OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
-              ECMA_BUILTIN_ID_UINT8ARRAY,
-              ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
-
-/* ES2015 22.2.6.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              1,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 1
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_UINT8ARRAY
+#include "ecma-builtin-typedarray-prototype-template.inc.h"
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index 71c89cdab0e05332d1caa794ea18f5a5de839576..0c42cee4620f4d410d8b078925477355cb87442c 100644 (file)
@@ -30,6 +30,8 @@
 #define BUILTIN_UNDERSCORED_ID uint8array
 #include "ecma-builtin-internal-routines-template.inc.h"
 
+#include "ecma-builtin-typedarray-helpers.h"
+
 /** \addtogroup ecma ECMA
  * @{
  *
@@ -63,18 +65,8 @@ ecma_value_t
 ecma_builtin_uint8array_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
                                             ecma_length_t arguments_list_len) /**< number of arguments */
 {
-  JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
-
-  ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_UINT8ARRAY_PROTOTYPE);
-  ecma_value_t val = ecma_op_create_typedarray (arguments_list_p,
-                                                arguments_list_len,
-                                                prototype_obj_p,
-                                                0,
-                                                LIT_MAGIC_STRING_UINT8_ARRAY_UL);
-
-  ecma_deref_object (prototype_obj_p);
-
-  return val;
+  return ecma_typedarray_helper_dispatch_construct (arguments_list_p, arguments_list_len,
+                                                    ECMA_BUILTIN_ID_UINT8ARRAY);
 } /* ecma_builtin_uint8array_dispatch_construct */
 
 /**
index ed36f15bfbdfa44e4d056c6cc75fc7622c7c8103..1555f891041609860f076fa92a0ee72c6128748c 100644 (file)
  * Uint8Array description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              1,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-STRING_VALUE (LIT_MAGIC_STRING_NAME,
-              LIT_MAGIC_STRING_UINT8_ARRAY_UL,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.2 */
-OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
-              ECMA_BUILTIN_ID_UINT8ARRAY_PROTOTYPE,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 1
+#define TYPEDARRAY_MAGIC_STRING_ID LIT_MAGIC_STRING_UINT8_ARRAY_UL
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_UINT8ARRAY_PROTOTYPE
+#include "ecma-builtin-typedarray-template.inc.h"
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index 014922b006dc34ef3021605f644f690af5081075..3dc17c455c209d22b2b8cf55be52e9dde63baa2f 100644 (file)
  * Uint8ClampedArray prototype description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 
-/* ES2015 22.2.3.4 */
-OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
-              ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY,
-              ECMA_PROPERTY_CONFIGURABLE_WRITABLE)
-
-/* ES2015 22.2.6.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              1,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 1
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY
+#include "ecma-builtin-typedarray-prototype-template.inc.h"
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index e5f7a8b3dab47ae39387aee54927133ac445d2a3..a199b430a1adb01645befcaaf0cd2d1514b252de 100644 (file)
@@ -72,7 +72,6 @@ ecma_builtin_uint8clampedarray_dispatch_construct (const ecma_value_t *arguments
                                                 0,
                                                 LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL);
 
-  ecma_deref_object (prototype_obj_p);
 
   return val;
 } /* ecma_builtin_uint8clampedarray_dispatch_construct */
index fe02d87fd27dd13c3b27803f8194949555f0931d..5cb9c6ccae426178667de483e549d8a85ef186d8 100644 (file)
  * Uint8ClampedArray description
  */
 
-#include "ecma-builtin-helpers-macro-defines.inc.h"
-
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.1 */
-NUMBER_VALUE (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U,
-              1,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
-              3,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5 */
-STRING_VALUE (LIT_MAGIC_STRING_NAME,
-              LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL,
-              ECMA_PROPERTY_FIXED)
-
-/* ES2015 22.2.5.2 */
-OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
-              ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY_PROTOTYPE,
-              ECMA_PROPERTY_FIXED)
+#define TYPEDARRAY_BYTES_PER_ELEMENT 1
+#define TYPEDARRAY_MAGIC_STRING_ID LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL
+#define TYPEDARRAY_BUILTIN_ID ECMA_BUILTIN_ID_UINT8CLAMPEDARRAY_PROTOTYPE
+#include "ecma-builtin-typedarray-template.inc.h"
 
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
-
-#include "ecma-builtin-helpers-macro-undefs.inc.h"
index 6fe922273aba6907b545d18d32feed626cbd6f0d..abc7acd4450efece5e8924d1e8d806cdf45ed908 100644 (file)
@@ -24,6 +24,7 @@
 #include "ecma-number-arithmetic.h"
 #include "ecma-objects.h"
 #include "ecma-objects-general.h"
+#include "ecma-function-object.h"
 
 /** \addtogroup ecma ECMA
  * @{
  */
 ecma_value_t
 ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of arguments that
-                                                                        are passed to Array constructor */
+                                                                    *   are passed to Array constructor */
                              ecma_length_t arguments_list_len, /**< length of the arguments' list */
                              bool is_treat_single_arg_as_length) /**< if the value is true,
-                                                                      arguments_list_len is 1
-                                                                      and single argument is Number,
-                                                                      then treat the single argument
-                                                                      as new Array's length rather
-                                                                      than as single item of the Array */
+                                                                  *   arguments_list_len is 1
+                                                                  *   and single argument is Number,
+                                                                  *   then treat the single argument
+                                                                  *   as new Array's length rather
+                                                                  *   than as single item of the Array */
 {
   JERRY_ASSERT (arguments_list_len == 0
                 || arguments_list_p != NULL);
@@ -94,8 +95,6 @@ ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of
                                                 sizeof (ecma_extended_object_t),
                                                 ECMA_OBJECT_TYPE_ARRAY);
 
-  ecma_deref_object (array_prototype_object_p);
-
   /*
    * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_ARRAY type.
    *
@@ -120,9 +119,7 @@ ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of
     ecma_builtin_helper_def_prop (object_p,
                                   item_name_string_p,
                                   array_items_p[index],
-                                  true, /* Writable */
-                                  true, /* Enumerable */
-                                  true, /* Configurable */
+                                  ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
                                   false); /* Failure handling */
 
     ecma_deref_ecma_string (item_name_string_p);
@@ -131,6 +128,39 @@ ecma_op_create_array_object (const ecma_value_t *arguments_list_p, /**< list of
   return ecma_make_object_value (object_p);
 } /* ecma_op_create_array_object */
 
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+/**
+ * Array object creation with custom prototype.
+ *
+ * See also: ECMA-262 v6, 9.4.2.3
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value
+ */
+ecma_value_t
+ecma_op_create_array_object_by_constructor (const ecma_value_t *arguments_list_p, /**< list of arguments that
+                                                                                   *   are passed to
+                                                                                   *   Array constructor */
+                                            ecma_length_t arguments_list_len, /**< length of the arguments' list */
+                                            bool is_treat_single_arg_as_length, /**< if the value is true,
+                                                                                 *   arguments_list_len is 1
+                                                                                 *   and single argument is Number,
+                                                                                 *   then treat the single argument
+                                                                                 *   as new Array's length rather
+                                                                                 *   than as single item of the
+                                                                                 *   Array */
+                                            ecma_object_t *object_p) /**< The object from whom the new array object
+                                                                      *   is being created */
+{
+  /* TODO: Use @@species after Symbol has been implemented */
+  JERRY_UNUSED (object_p);
+
+  return ecma_op_create_array_object (arguments_list_p,
+                                      arguments_list_len,
+                                      is_treat_single_arg_as_length);
+} /* ecma_op_create_array_object_by_constructor */
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
 /**
  * Update the length of an array to a new length
  *
index f32c6cfc17e28dd195b50d310b69451625a9e963..7f4c934b1404aafc17259c383220d7c7e1bef591 100644 (file)
@@ -43,6 +43,12 @@ ecma_value_t
 ecma_op_create_array_object (const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len,
                              bool is_treat_single_arg_as_length);
 
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+ecma_value_t
+ecma_op_create_array_object_by_constructor (const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len,
+                                            bool is_treat_single_arg_as_length, ecma_object_t *object_p);
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
 ecma_value_t
 ecma_op_array_object_set_length (ecma_object_t *object_p, ecma_value_t new_value, uint32_t flags);
 
index 1840791f095872adf6dea7812e1010544dc34b3a..c828ded3f0bc63eed1297e8eaa10b43a91b5fa2e 100644 (file)
@@ -49,7 +49,7 @@ ecma_arraybuffer_new_object (ecma_length_t length) /**< length of the arraybuffe
   ecma_object_t *object_p = ecma_create_object (prototype_obj_p,
                                                 sizeof (ecma_extended_object_t) + length,
                                                 ECMA_OBJECT_TYPE_CLASS);
-  ecma_deref_object (prototype_obj_p);
+
   ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
   ext_object_p->u.class_prop.extra_info = ECMA_ARRAYBUFFER_INTERNAL_MEMORY;
   ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_ARRAY_BUFFER_UL;
@@ -80,7 +80,7 @@ ecma_arraybuffer_new_object_external (ecma_length_t length, /**< length of the b
   ecma_object_t *object_p = ecma_create_object (prototype_obj_p,
                                                 sizeof (ecma_arraybuffer_external_info),
                                                 ECMA_OBJECT_TYPE_CLASS);
-  ecma_deref_object (prototype_obj_p);
+
   ecma_arraybuffer_external_info *array_object_p = (ecma_arraybuffer_external_info *) object_p;
   array_object_p->extended_object.u.class_prop.extra_info = ECMA_ARRAYBUFFER_EXTERNAL_MEMORY;
   array_object_p->extended_object.u.class_prop.class_id = LIT_MAGIC_STRING_ARRAY_BUFFER_UL;
@@ -138,7 +138,7 @@ ecma_op_create_arraybuffer_object (const ecma_value_t *arguments_list_p, /**< li
 
     const uint32_t maximum_size_in_byte = UINT32_MAX - sizeof (ecma_extended_object_t) - JMEM_ALIGNMENT + 1;
 
-    if (length_num <= -1.0 || length_num > (double) maximum_size_in_byte + 0.5)
+    if (length_num <= -1.0 || length_num > (ecma_number_t) maximum_size_in_byte + 0.5)
     {
       return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid ArrayBuffer length."));
     }
@@ -171,7 +171,7 @@ ecma_is_arraybuffer (ecma_value_t target) /**< the target value */
  *
  * @return ecma_length_t, the length of the arraybuffer
  */
-ecma_length_t __attr_pure___
+ecma_length_t JERRY_ATTR_PURE
 ecma_arraybuffer_get_length (ecma_object_t *object_p) /**< pointer to the ArrayBuffer object */
 {
   JERRY_ASSERT (ecma_object_class_is (object_p, LIT_MAGIC_STRING_ARRAY_BUFFER_UL));
@@ -185,7 +185,7 @@ ecma_arraybuffer_get_length (ecma_object_t *object_p) /**< pointer to the ArrayB
  *
  * @return pointer to the data buffer
  */
-inline lit_utf8_byte_t * __attr_pure___ __attr_always_inline___
+inline lit_utf8_byte_t * JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
 ecma_arraybuffer_get_buffer (ecma_object_t *object_p) /**< pointer to the ArrayBuffer object */
 {
   JERRY_ASSERT (ecma_object_class_is (object_p, LIT_MAGIC_STRING_ARRAY_BUFFER_UL));
index 0fe3f5c9df4f09a94350a5b0ad58fc520e58d718..e5597d7736d13c2b2bd9b464caa1a51565081194 100644 (file)
@@ -38,10 +38,10 @@ ecma_object_t *
 ecma_arraybuffer_new_object_external (ecma_length_t length,
                                       void *buffer_p,
                                       ecma_object_native_free_callback_t free_cb);
-lit_utf8_byte_t *
-ecma_arraybuffer_get_buffer (ecma_object_t *obj_p) __attr_pure___;
-ecma_length_t
-ecma_arraybuffer_get_length (ecma_object_t *obj_p) __attr_pure___;
+lit_utf8_byte_t * JERRY_ATTR_PURE
+ecma_arraybuffer_get_buffer (ecma_object_t *obj_p);
+ecma_length_t JERRY_ATTR_PURE
+ecma_arraybuffer_get_length (ecma_object_t *obj_p);
 bool
 ecma_is_arraybuffer (ecma_value_t val);
 
index fdadfbcf8b1ff70919b695fc144e639ca396eb78..f8a8c26b780ff8a797ddbdc7acc81d7788b7d7f5 100644 (file)
@@ -53,8 +53,6 @@ ecma_op_create_boolean_object (ecma_value_t arg) /**< argument passed to the Boo
                                                 sizeof (ecma_extended_object_t),
                                                 ECMA_OBJECT_TYPE_CLASS);
 
-  ecma_deref_object (prototype_obj_p);
-
   ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
   ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_BOOLEAN_UL;
   ext_object_p->u.class_prop.u.value = ecma_make_boolean_value (boolean_value);
index e1fe51694e19fb0f7924dcc810f367eab7d9a58e..4a5dbf5f7ec46b7790c0e23e6659ef63860594dc 100644 (file)
@@ -305,7 +305,8 @@ ecma_op_to_number (ecma_value_t value) /**< ecma value */
  *         Returned value must be freed with ecma_free_value
  */
 ecma_value_t
-ecma_get_number (ecma_value_t value, ecma_number_t *number_p)
+ecma_get_number (ecma_value_t value, /**< ecma value*/
+                 ecma_number_t *number_p) /**< [out] ecma number */
 {
   if (ecma_is_value_integer_number (value))
   {
@@ -372,7 +373,7 @@ ecma_op_to_string (ecma_value_t value) /**< ecma value */
 {
   ecma_check_value_type_is_spec_defined (value);
 
-  if (unlikely (ecma_is_value_object (value)))
+  if (JERRY_UNLIKELY (ecma_is_value_object (value)))
   {
     ecma_value_t ret_value = ECMA_VALUE_EMPTY;
 
@@ -774,14 +775,10 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */
       JERRY_ASSERT (ecma_is_value_empty (ret_value));
 
       /* 9. */
-      if (prop_desc.is_get_defined
-          || prop_desc.is_set_defined)
+      if ((prop_desc.is_get_defined || prop_desc.is_set_defined)
+          && (prop_desc.is_value_defined || prop_desc.is_writable_defined))
       {
-        if (prop_desc.is_value_defined
-            || prop_desc.is_writable_defined)
-        {
-          ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Accessors cannot be writable."));
-        }
+        ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Accessors cannot be writable."));
       }
     }
 
index 994d39861d39bce0474c17317c5d58425d943b0f..a149c244f3b99eebd4a4c87e621f62b69d8e0b1d 100644 (file)
 #include "ecma-lex-env.h"
 #include "js-parser.h"
 #include "vm.h"
-
-#ifdef JERRY_ENABLE_LINE_INFO
 #include "jcontext.h"
-#endif /* JERRY_ENABLE_LINE_INFO */
 
 /** \addtogroup ecma ECMA
  * @{
@@ -45,8 +42,7 @@
  */
 ecma_value_t
 ecma_op_eval (ecma_string_t *code_p, /**< code string */
-              bool is_direct, /**< is eval called directly (ECMA-262 v5, 15.1.2.1.1) */
-              bool is_called_from_strict_mode_code) /**< is eval is called from strict mode code */
+              uint32_t parse_opts) /**< ecma_parse_opts_t option bits */
 {
   ecma_value_t ret_value;
 
@@ -61,8 +57,7 @@ ecma_op_eval (ecma_string_t *code_p, /**< code string */
 
     ret_value = ecma_op_eval_chars_buffer (code_utf8_buffer_p,
                                            chars_num,
-                                           is_direct,
-                                           is_called_from_strict_mode_code);
+                                           parse_opts);
 
     ECMA_FINALIZE_UTF8_STRING (code_utf8_buffer_p, code_utf8_buffer_size);
   }
@@ -82,25 +77,35 @@ ecma_op_eval (ecma_string_t *code_p, /**< code string */
 ecma_value_t
 ecma_op_eval_chars_buffer (const lit_utf8_byte_t *code_p, /**< code characters buffer */
                            size_t code_buffer_size, /**< size of the buffer */
-                           bool is_direct, /**< is eval called directly (ECMA-262 v5, 15.1.2.1.1) */
-                           bool is_called_from_strict_mode_code) /**< is eval is called from strict mode code */
+                           uint32_t parse_opts) /**< ecma_parse_opts_t option bits */
 {
 #ifndef JERRY_DISABLE_JS_PARSER
   JERRY_ASSERT (code_p != NULL);
 
   ecma_compiled_code_t *bytecode_data_p;
 
-  bool is_strict_call = (is_direct && is_called_from_strict_mode_code);
+  uint32_t is_strict_call = ECMA_PARSE_STRICT_MODE | ECMA_PARSE_DIRECT_EVAL;
+
+  if ((parse_opts & is_strict_call) != is_strict_call)
+  {
+    parse_opts &= (uint32_t) ~ECMA_PARSE_STRICT_MODE;
+  }
 
 #ifdef JERRY_ENABLE_LINE_INFO
   JERRY_CONTEXT (resource_name) = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
 #endif /* JERRY_ENABLE_LINE_INFO */
 
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  parse_opts |= ECMA_GET_SUPER_EVAL_PARSER_OPTS ();
+
+  ECMA_CLEAR_SUPER_EVAL_PARSER_OPTS ();
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
   ecma_value_t parse_status = parser_parse_script (NULL,
                                                    0,
                                                    code_p,
                                                    code_buffer_size,
-                                                   is_strict_call,
+                                                   parse_opts,
                                                    &bytecode_data_p);
 
   if (ECMA_IS_VALUE_ERROR (parse_status))
@@ -108,12 +113,11 @@ ecma_op_eval_chars_buffer (const lit_utf8_byte_t *code_p, /**< code characters b
     return parse_status;
   }
 
-  return vm_run_eval (bytecode_data_p, is_direct);
+  return vm_run_eval (bytecode_data_p, parse_opts);
 #else /* JERRY_DISABLE_JS_PARSER */
   JERRY_UNUSED (code_p);
   JERRY_UNUSED (code_buffer_size);
-  JERRY_UNUSED (is_direct);
-  JERRY_UNUSED (is_called_from_strict_mode_code);
+  JERRY_UNUSED (parse_opts);
 
   return ecma_raise_syntax_error (ECMA_ERR_MSG ("The parser has been disabled."));
 #endif /* !JERRY_DISABLE_JS_PARSER */
index 500bd611b520e1ffc804189b471a3f2372e57cff..057c4d2fab9596e2069a7ec9e0667e727117f1e0 100644 (file)
  */
 
 ecma_value_t
-ecma_op_eval (ecma_string_t *code_p, bool is_direct, bool is_called_from_strict_mode_code);
+ecma_op_eval (ecma_string_t *code_p, uint32_t parse_opts);
 
 ecma_value_t
-ecma_op_eval_chars_buffer (const lit_utf8_byte_t *code_p, size_t code_buffer_size, bool is_direct,
-                           bool is_called_from_strict_mode_code);
+ecma_op_eval_chars_buffer (const lit_utf8_byte_t *code_p, size_t code_buffer_size, uint32_t parse_opts);
 
 /**
  * @}
index f3e782b6be279c1cf765880a9ecc9cd3576345cc..33d04cd0d5536302ff2e36922791bdf4e1939166 100644 (file)
  * \addtogroup exceptions Exceptions
  * @{
  */
+
+/**
+ * Map error type to error prototype.
+ */
 typedef struct
 {
-  ecma_standard_error_t error_type;
-  ecma_builtin_id_t error_prototype_id;
+  ecma_standard_error_t error_type; /**< Native error type */
+  ecma_builtin_id_t error_prototype_id; /**< ID of the error prototype */
 } ecma_error_mapping_t;
 
+/**
+ * List of error type mappings
+ */
 const ecma_error_mapping_t ecma_error_mappings[] =
 {
 #define ERROR_ELEMENT(TYPE, ID) { TYPE, ID }
@@ -75,12 +82,6 @@ ecma_new_standard_error (ecma_standard_error_t error_type) /**< native error typ
 
   switch (error_type)
   {
-    case ECMA_ERROR_COMMON:
-    {
-      prototype_id = ECMA_BUILTIN_ID_ERROR_PROTOTYPE;
-      break;
-    }
-
     case ECMA_ERROR_EVAL:
     {
       prototype_id = ECMA_BUILTIN_ID_EVAL_ERROR_PROTOTYPE;
@@ -117,9 +118,11 @@ ecma_new_standard_error (ecma_standard_error_t error_type) /**< native error typ
       break;
     }
 
-    case ECMA_ERROR_NONE:
+    default:
     {
-      JERRY_UNREACHABLE ();
+      JERRY_ASSERT (error_type == ECMA_ERROR_COMMON);
+
+      prototype_id = ECMA_BUILTIN_ID_ERROR_PROTOTYPE;
       break;
     }
   }
@@ -134,13 +137,11 @@ ecma_new_standard_error (ecma_standard_error_t error_type) /**< native error typ
                                                        sizeof (ecma_extended_object_t),
                                                        ECMA_OBJECT_TYPE_CLASS);
 
-  ecma_deref_object (prototype_obj_p);
-
   ((ecma_extended_object_t *) new_error_obj_p)->u.class_prop.class_id = LIT_MAGIC_STRING_ERROR_UL;
 
 #ifdef JERRY_ENABLE_LINE_INFO
   /* The "stack" identifier is not a magic string. */
-  const char *stack_id_p = "stack";
+  const char * const stack_id_p = "stack";
 
   ecma_string_t *stack_str_p = ecma_new_ecma_string_from_utf8 ((const lit_utf8_byte_t *) stack_id_p, 5);
 
@@ -215,7 +216,7 @@ ecma_new_standard_error_with_message (ecma_standard_error_t error_type, /**< nat
  * @return ecma value
  *         Returned value must be freed with ecma_free_value
  */
-ecma_value_t
+static ecma_value_t
 ecma_raise_standard_error (ecma_standard_error_t error_type, /**< error type */
                            const lit_utf8_byte_t *msg_p) /**< error message */
 {
@@ -282,7 +283,7 @@ ecma_raise_standard_error_with_format (ecma_standard_error_t error_type, /**< er
       ecma_string_t *arg_string_p;
       const ecma_value_t arg_val = va_arg (args, ecma_value_t);
 
-      if (unlikely (ecma_is_value_object (arg_val)))
+      if (JERRY_UNLIKELY (ecma_is_value_object (arg_val)))
       {
         ecma_object_t *arg_object_p = ecma_get_object_from_value (arg_val);
         lit_magic_string_id_t class_name = ecma_object_get_class_name (arg_object_p);
@@ -340,20 +341,6 @@ ecma_raise_common_error (const char *msg_p) /**< error message */
   return ecma_raise_standard_error (ECMA_ERROR_COMMON, (const lit_utf8_byte_t *) msg_p);
 } /* ecma_raise_common_error */
 
-/**
- * Raise an EvalError with the given message.
- *
- * See also: ECMA-262 v5, 15.11.6.1
- *
- * @return ecma value
- *         Returned value must be freed with ecma_free_value
- */
-ecma_value_t
-ecma_raise_eval_error (const char *msg_p) /**< error message */
-{
-  return ecma_raise_standard_error (ECMA_ERROR_EVAL, (const lit_utf8_byte_t *) msg_p);
-} /* ecma_raise_eval_error */
-
 /**
  * Raise a RangeError with the given message.
  *
index c11c53a691333522a84ba2c1fc5366ad4d95f9fd..11ae8caba741f4f7c9a57cc36e6dce83e7675e15 100644 (file)
@@ -53,12 +53,10 @@ typedef enum
 ecma_standard_error_t ecma_get_error_type (ecma_object_t *error_object);
 ecma_object_t *ecma_new_standard_error (ecma_standard_error_t error_type);
 ecma_object_t *ecma_new_standard_error_with_message (ecma_standard_error_t error_type, ecma_string_t *message_string_p);
-ecma_value_t ecma_raise_standard_error (ecma_standard_error_t error_type, const lit_utf8_byte_t *msg_p);
 #ifdef JERRY_ENABLE_ERROR_MESSAGES
 ecma_value_t ecma_raise_standard_error_with_format (ecma_standard_error_t error_type, const char *msg_p, ...);
 #endif /* JERRY_ENABLE_ERROR_MESSAGES */
 ecma_value_t ecma_raise_common_error (const char *msg_p);
-ecma_value_t ecma_raise_eval_error (const char *msg_p);
 ecma_value_t ecma_raise_range_error (const char *msg_p);
 ecma_value_t ecma_raise_reference_error (const char *msg_p);
 ecma_value_t ecma_raise_syntax_error (const char *msg_p);
index 30e47583768424f6824a6395aa62d86abe1ec4cb..f5a11ed1176b3b6ae2a523e7a2e8a2fef886865c 100644 (file)
@@ -40,8 +40,8 @@
  * @return true - if the type is a normal or arrow function;
  *         false - otherwise
  */
-inline bool __attr_always_inline___
-ecma_is_normal_or_arrow_function (ecma_object_type_t type)
+inline bool JERRY_ATTR_ALWAYS_INLINE
+ecma_is_normal_or_arrow_function (ecma_object_type_t type) /**< object type */
 {
 #ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
   return (type == ECMA_OBJECT_TYPE_FUNCTION || type == ECMA_OBJECT_TYPE_ARROW_FUNCTION);
@@ -121,6 +121,8 @@ ecma_object_t *
 ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
                                 const ecma_compiled_code_t *bytecode_data_p) /**< byte-code array */
 {
+  JERRY_ASSERT (ecma_is_lexical_environment (scope_p));
+
   /* 1., 4., 13. */
   ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
 
@@ -137,8 +139,6 @@ ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
                                               function_object_size,
                                               ECMA_OBJECT_TYPE_FUNCTION);
 
-  ecma_deref_object (prototype_obj_p);
-
   /* 2., 6., 7., 8. */
   /*
    * We don't setup [[Get]], [[Call]], [[Construct]], [[HasInstance]] for each function object.
@@ -215,9 +215,6 @@ ecma_op_create_arrow_function_object (ecma_object_t *scope_p, /**< function's sc
                                               arrow_function_object_size,
                                               ECMA_OBJECT_TYPE_ARROW_FUNCTION);
 
-  ecma_deref_object (prototype_obj_p);
-
-
   ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_p;
 
   ECMA_SET_NON_NULL_POINTER (arrow_func_p->scope_cp, scope_p);
@@ -263,8 +260,6 @@ ecma_op_create_external_function_object (ecma_external_handler_t handler_cb) /**
                                        sizeof (ecma_extended_object_t),
                                        ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
 
-  ecma_deref_object (prototype_obj_p);
-
   /*
    * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION type.
    *
@@ -282,7 +277,7 @@ ecma_op_create_external_function_object (ecma_external_handler_t handler_cb) /**
  *
  * @return compiled code
  */
-inline const ecma_compiled_code_t * __attr_always_inline___
+inline const ecma_compiled_code_t * JERRY_ATTR_ALWAYS_INLINE
 ecma_op_function_get_compiled_code (ecma_extended_object_t *function_p) /**< function pointer */
 {
 #ifdef JERRY_ENABLE_SNAPSHOT_EXEC
@@ -308,7 +303,7 @@ ecma_op_function_get_compiled_code (ecma_extended_object_t *function_p) /**< fun
  *
  * @return compiled code
  */
-inline const ecma_compiled_code_t * __attr_always_inline___
+inline const ecma_compiled_code_t * JERRY_ATTR_ALWAYS_INLINE
 ecma_op_arrow_function_get_compiled_code (ecma_arrow_function_t *arrow_function_p) /**< arrow function pointer */
 {
 #ifdef JERRY_ENABLE_SNAPSHOT_EXEC
@@ -330,11 +325,7 @@ ecma_op_arrow_function_get_compiled_code (ecma_arrow_function_t *arrow_function_
 #endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
 
 /**
- * [[Call]] implementation for Function objects,
- * created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION)
- * or 15.3.4.5 (ECMA_OBJECT_TYPE_BOUND_FUNCTION),
- * and for built-in Function objects
- * from section 15 (ECMA_OBJECT_TYPE_FUNCTION).
+ * 15.3.5.3 implementation of [[HasInstance]] for Function objects
  *
  * @return ecma value
  *         Returned value must be freed with ecma_free_value
@@ -346,19 +337,15 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object *
   JERRY_ASSERT (func_obj_p != NULL
                 && !ecma_is_lexical_environment (func_obj_p));
 
-  if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION)
+  while (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION)
   {
     JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
 
-    /* 1. */
+    /* 1. 3. */
     ecma_extended_object_t *ext_function_p = (ecma_extended_object_t *) func_obj_p;
 
-    ecma_object_t *target_func_obj_p;
-    target_func_obj_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
-                                                         ext_function_p->u.bound_function.target_function);
-
-    /* 3. */
-    return ecma_op_object_has_instance (target_func_obj_p, value);
+    func_obj_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
+                                                  ext_function_p->u.bound_function.target_function);
   }
 
   JERRY_ASSERT (ecma_is_normal_or_arrow_function (ecma_get_object_type (func_obj_p))
@@ -388,7 +375,7 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object *
   ecma_object_t *prototype_obj_p = ecma_get_object_from_value (prototype_obj_value);
   JERRY_ASSERT (prototype_obj_p != NULL);
 
-  bool result = false;
+  ecma_value_t result = ECMA_VALUE_FALSE;
 
   while (true)
   {
@@ -401,15 +388,225 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object *
 
     if (v_obj_p == prototype_obj_p)
     {
-      result = true;
+      result = ECMA_VALUE_TRUE;
       break;
     }
   }
 
   ecma_deref_object (prototype_obj_p);
-  return ecma_make_boolean_value (result);
+  return result;
 } /* ecma_op_function_has_instance */
 
+
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+/**
+ * Indicates whether the class has been invoked with 'new'.
+ */
+#define ECMA_CLASS_CONSTRUCT_FLAG ((uintptr_t) 0x01u)
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
+/**
+ * Sets the construct flag in the arguments list pointer.
+ *
+ * @return arguments list pointer with the construct flag
+ */
+static inline const ecma_value_t * JERRY_ATTR_ALWAYS_INLINE
+ecma_op_function_set_construct_flag (const ecma_value_t *arguments_list_p) /**< original arguments list pointer */
+{
+  /* Any ecma value list must be aligned to 4 byte. */
+  JERRY_ASSERT ((((uintptr_t) arguments_list_p) & 0x3) == 0);
+
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  arguments_list_p = (const ecma_value_t *)(((uintptr_t) arguments_list_p) | ECMA_CLASS_CONSTRUCT_FLAG);
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
+  return arguments_list_p;
+} /* ecma_op_function_set_construct_flag */
+
+/**
+ * Clears the construct flag in the arguments list pointer.
+ *
+ * @return arguments list pointer without the construct flag
+ */
+static inline const ecma_value_t * JERRY_ATTR_ALWAYS_INLINE
+ecma_op_function_clear_construct_flag (const ecma_value_t *arguments_list_p) /**< modified arguments list pointer */
+{
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  arguments_list_p = (const ecma_value_t *)(((uintptr_t) arguments_list_p) & ~ECMA_CLASS_CONSTRUCT_FLAG);
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
+  return arguments_list_p;
+} /* ecma_op_function_clear_construct_flag */
+
+/**
+ * Returns true if the construct flag is set.
+ *
+ * @return true, if construct flag is set, false otherwise
+ */
+static inline bool JERRY_ATTR_ALWAYS_INLINE
+ecma_op_function_has_construct_flag (const ecma_value_t *arguments_list_p) /**< modified arguments list pointer */
+{
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  return (((uintptr_t) arguments_list_p) & ECMA_CLASS_CONSTRUCT_FLAG);
+#else /* CONFIG_DISABLE_ES2015_CLASS */
+  JERRY_UNUSED (arguments_list_p);
+  return false;
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+} /* ecma_op_function_has_construct_flag */
+
+#ifndef CONFIG_DISABLE_ES2015
+/**
+ * Returns the closest declarative lexical enviroment to the super object bound lexical enviroment.
+ *
+ * @return the found lexical enviroment
+ */
+static ecma_object_t *
+ecma_op_find_super_declerative_lex_env (ecma_object_t *lex_env_p) /**< starting lexical enviroment */
+{
+  JERRY_ASSERT (lex_env_p);
+  JERRY_ASSERT (ecma_op_resolve_super_reference_value (lex_env_p));
+  JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) != ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND);
+
+  while (true)
+  {
+    ecma_object_t *lex_env_outer_p = ecma_get_lex_env_outer_reference (lex_env_p);
+
+    JERRY_ASSERT (lex_env_outer_p);
+
+    if (ecma_get_lex_env_type (lex_env_outer_p) == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND)
+    {
+      JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE);
+      return lex_env_p;
+    }
+
+    lex_env_p = lex_env_outer_p;
+  }
+} /* ecma_op_find_super_declerative_lex_env */
+
+/**
+ * Returns with the current class this_binding property
+ *
+ * @return NULL - if the property was not found
+ *         the found property - otherwise
+ */
+static ecma_property_t *
+ecma_op_get_class_this_binding_property (ecma_object_t *lex_env_p) /**< starting lexical enviroment */
+{
+  JERRY_ASSERT (lex_env_p);
+  JERRY_ASSERT (ecma_is_lexical_environment (lex_env_p));
+
+  lex_env_p = ecma_op_find_super_declerative_lex_env (lex_env_p);
+  ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_CLASS_THIS_BINDING);
+  return ecma_find_named_property (lex_env_p, name_p);
+} /* ecma_op_get_class_this_binding_property */
+
+/**
+ * Checks whether the 'super(...)' has been called.
+ *
+ * @return true  - if the 'super (...)' has been called
+ *         false - otherwise
+ */
+inline bool JERRY_ATTR_PURE
+ecma_op_is_super_called (ecma_object_t *lex_env_p) /**< starting lexical enviroment */
+{
+  ecma_property_t *property_p = ecma_op_get_class_this_binding_property (lex_env_p);
+
+  JERRY_ASSERT (property_p);
+  return (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
+} /* ecma_op_is_super_called */
+
+/**
+ * Sets the value of 'super(...)' has been called.
+ */
+inline void
+ecma_op_set_super_called (ecma_object_t *lex_env_p) /**< starting lexical enviroment */
+{
+  ecma_property_t *property_p = ecma_op_get_class_this_binding_property (lex_env_p);
+
+  JERRY_ASSERT (property_p);
+
+  JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_INTERNAL);
+  ECMA_CONVERT_INTERNAL_PROPERTY_TO_DATA_PROPERTY (property_p);
+} /* ecma_op_set_super_called */
+
+/**
+ * Sets the class context this_binding value.
+ */
+void
+ecma_op_set_class_this_binding (ecma_object_t *lex_env_p, /**< starting lexical enviroment */
+                                ecma_value_t this_binding) /**< 'this' argument's value */
+{
+  JERRY_ASSERT (ecma_is_value_object (this_binding));
+  ecma_property_t *property_p = ecma_op_get_class_this_binding_property (lex_env_p);
+
+  ecma_property_value_t *value_p;
+
+  if (property_p)
+  {
+    JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (*property_p) == ECMA_PROPERTY_TYPE_NAMEDDATA);
+    value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
+  }
+  else
+  {
+    ecma_string_t *name_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_CLASS_THIS_BINDING);
+    value_p = ecma_create_named_data_property (lex_env_p, name_p, ECMA_PROPERTY_FLAG_WRITABLE, &property_p);
+    ECMA_CONVERT_DATA_PROPERTY_TO_INTERNAL_PROPERTY (property_p);
+  }
+
+  value_p->value = this_binding;
+} /* ecma_op_set_class_this_binding */
+
+/**
+ * Gets the class context this binding value.
+ *
+ * @return the class context this binding value
+ */
+ecma_value_t
+ecma_op_get_class_this_binding (ecma_object_t *lex_env_p) /**< starting lexical enviroment */
+{
+  ecma_property_t *property_p = ecma_op_get_class_this_binding_property (lex_env_p);
+
+  JERRY_ASSERT (property_p);
+
+  ecma_property_value_t *value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
+
+  JERRY_ASSERT (ecma_is_value_object (value_p->value));
+  return value_p->value;
+} /* ecma_op_get_class_this_binding */
+
+/**
+ * Dummy external function for implicit constructor call.
+ *
+ * @return ECMA_VALUE_ERROR - TypeError
+ */
+ecma_value_t
+ecma_op_function_implicit_constructor_handler_cb (const ecma_value_t function_obj, /**< the function itself */
+                                                  const ecma_value_t this_val, /**< this_arg of the function */
+                                                  const ecma_value_t args_p[], /**< argument list */
+                                                  const ecma_length_t args_count) /**< argument number */
+{
+  JERRY_UNUSED_4 (function_obj, this_val, args_p, args_count);
+  return ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor cannot be invoked without 'new'."));
+} /* ecma_op_function_implicit_constructor_handler_cb */
+
+/**
+ * Sets the completion value [[Prototype]] based on the this_arg value
+ */
+void
+ecma_op_set_class_prototype (ecma_value_t completion_value, /**< completion_value */
+                             ecma_value_t this_arg) /**< this argument*/
+{
+  JERRY_ASSERT (ecma_is_value_object (completion_value));
+  JERRY_ASSERT (ecma_is_value_object (this_arg));
+
+  ecma_object_t *completion_obj_p = ecma_get_object_from_value (completion_value);
+  ecma_object_t *prototype_obj_p = ecma_get_object_prototype (ecma_get_object_from_value (this_arg));
+
+  JERRY_ASSERT (prototype_obj_p);
+  ECMA_SET_POINTER (completion_obj_p->prototype_or_outer_reference_cp, prototype_obj_p);
+} /* ecma_op_set_class_prototype */
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
 /**
  * [[Call]] implementation for Function objects,
  * created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION)
@@ -430,19 +627,27 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
                 && !ecma_is_lexical_environment (func_obj_p));
   JERRY_ASSERT (ecma_op_is_callable (ecma_make_object_value (func_obj_p)));
 
-  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-
-  if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION)
+  while (true)
   {
-    if (unlikely (ecma_get_object_is_builtin (func_obj_p)))
-    {
-      ret_value = ecma_builtin_dispatch_call (func_obj_p,
-                                              this_arg_value,
-                                              arguments_list_p,
-                                              arguments_list_len);
-    }
-    else
+    ecma_object_type_t func_type = ecma_get_object_type (func_obj_p);
+
+    JERRY_ASSERT (func_type == ECMA_OBJECT_TYPE_FUNCTION
+                  || func_type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION
+                  || func_type == ECMA_OBJECT_TYPE_BOUND_FUNCTION
+                  || !ecma_op_function_has_construct_flag (arguments_list_p));
+
+    if (func_type == ECMA_OBJECT_TYPE_FUNCTION)
     {
+      if (JERRY_UNLIKELY (ecma_get_object_is_builtin (func_obj_p)))
+      {
+        JERRY_ASSERT (!ecma_op_function_has_construct_flag (arguments_list_p));
+
+        return ecma_builtin_dispatch_call (func_obj_p,
+                                           this_arg_value,
+                                           arguments_list_p,
+                                           arguments_list_len);
+      }
+
       /* Entering Function Code (ECMA-262 v5, 10.4.3) */
       ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_obj_p;
 
@@ -450,34 +655,44 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
                                                                 ext_func_p->u.function.scope_cp);
 
       /* 8. */
-      ecma_value_t this_binding;
-      bool is_strict;
-      bool is_no_lex_env;
+      ecma_value_t this_binding = this_arg_value;
+      bool free_this_binding = false;
 
       const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
 
-      is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) ? true : false;
-      is_no_lex_env = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED) ? true : false;
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+      bool is_class_constructor = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_CONSTRUCTOR) != 0;
 
-      /* 1. */
-      if (is_strict)
-      {
-        this_binding = ecma_copy_value (this_arg_value);
-      }
-      else if (ecma_is_value_undefined (this_arg_value)
-               || ecma_is_value_null (this_arg_value))
+      if (is_class_constructor && !ecma_op_function_has_construct_flag (arguments_list_p))
       {
-        /* 2. */
-        this_binding = ecma_make_object_value (ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL));
+        return ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor cannot be invoked without 'new'."));
       }
-      else
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
+      bool is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0;
+      bool is_no_lex_env = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED) != 0;
+
+      /* 1. */
+      if (!is_strict)
       {
-        /* 3., 4. */
-        this_binding = ecma_op_to_object (this_arg_value);
+        if (ecma_is_value_undefined (this_binding)
+            || ecma_is_value_null (this_binding))
+        {
+          /* 2. */
+          this_binding = ecma_make_object_value (ecma_builtin_get_global ());
+        }
+        else if (!ecma_is_value_object (this_binding))
+        {
+          /* 3., 4. */
+          this_binding = ecma_op_to_object (this_binding);
+          free_this_binding = true;
 
-        JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (this_binding));
+          JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (this_binding));
+        }
       }
 
+      arguments_list_p = ecma_op_function_clear_construct_flag (arguments_list_p);
+
       /* 5. */
       ecma_object_t *local_env_p;
       if (is_no_lex_env)
@@ -495,86 +710,93 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
                                            arguments_list_len,
                                            bytecode_data_p);
         }
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+        if (JERRY_UNLIKELY (is_class_constructor))
+        {
+          ecma_op_set_class_this_binding (local_env_p, this_binding);
+        }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
       }
 
-      ret_value = vm_run (bytecode_data_p,
-                          this_binding,
-                          local_env_p,
-                          false,
-                          arguments_list_p,
-                          arguments_list_len);
+      ecma_value_t ret_value = vm_run (bytecode_data_p,
+                                       this_binding,
+                                       local_env_p,
+                                       ECMA_PARSE_NO_OPTS,
+                                       arguments_list_p,
+                                       arguments_list_len);
 
       if (!is_no_lex_env)
       {
         ecma_deref_object (local_env_p);
       }
 
-      ecma_free_value (this_binding);
+      if (JERRY_UNLIKELY (free_this_binding))
+      {
+        ecma_free_value (this_binding);
+      }
+
+      return ret_value;
+    }
+    else if (func_type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
+    {
+      ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
+
+      ecma_value_t ret_value = ext_func_obj_p->u.external_handler_cb (ecma_make_object_value (func_obj_p),
+                                                                      this_arg_value,
+                                                                      arguments_list_p,
+                                                                      arguments_list_len);
+
+      if (JERRY_UNLIKELY (ecma_is_value_error_reference (ret_value)))
+      {
+        JERRY_CONTEXT (error_value) = ecma_clear_error_reference (ret_value, true);
+        return ECMA_VALUE_ERROR;
+      }
+
+#ifdef JERRY_DEBUGGER
+      JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_EXCEPTION_THROWN);
+#endif /* JERRY_DEBUGGER */
+      return ret_value;
     }
-  }
 #ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
-  else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_ARROW_FUNCTION)
-  {
-    /* Entering Function Code (ES2015, 9.2.1) */
-    ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_obj_p;
+    else if (func_type == ECMA_OBJECT_TYPE_ARROW_FUNCTION)
+    {
+      /* Entering Function Code (ES2015, 9.2.1) */
+      ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_obj_p;
 
-    ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t,
-                                                        arrow_func_p->scope_cp);
+      ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t,
+                                                          arrow_func_p->scope_cp);
 
-    bool is_no_lex_env;
+      bool is_no_lex_env;
 
-    const ecma_compiled_code_t *bytecode_data_p = ecma_op_arrow_function_get_compiled_code (arrow_func_p);
+      const ecma_compiled_code_t *bytecode_data_p = ecma_op_arrow_function_get_compiled_code (arrow_func_p);
 
-    is_no_lex_env = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED) ? true : false;
+      is_no_lex_env = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED) != 0;
 
-    ecma_object_t *local_env_p;
-    if (is_no_lex_env)
-    {
-      local_env_p = scope_p;
-    }
-    else
-    {
-      local_env_p = ecma_create_decl_lex_env (scope_p);
+      ecma_object_t *local_env_p = scope_p;
 
-      JERRY_ASSERT (!(bytecode_data_p->status_flags & CBC_CODE_FLAGS_ARGUMENTS_NEEDED));
-    }
+      if (!is_no_lex_env)
+      {
+        local_env_p = ecma_create_decl_lex_env (scope_p);
 
-    ret_value = vm_run (bytecode_data_p,
-                        arrow_func_p->this_binding,
-                        local_env_p,
-                        false,
-                        arguments_list_p,
-                        arguments_list_len);
+        JERRY_ASSERT (!(bytecode_data_p->status_flags & CBC_CODE_FLAGS_ARGUMENTS_NEEDED));
+      }
 
-    if (!is_no_lex_env)
-    {
-      ecma_deref_object (local_env_p);
-    }
-  }
-#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
-  else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
-  {
-    ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
+      ecma_value_t ret_value = vm_run (bytecode_data_p,
+                                       arrow_func_p->this_binding,
+                                       local_env_p,
+                                       ECMA_PARSE_NO_OPTS,
+                                       arguments_list_p,
+                                       arguments_list_len);
 
-    ret_value = ext_func_obj_p->u.external_handler_cb (ecma_make_object_value (func_obj_p),
-                                                       this_arg_value,
-                                                       arguments_list_p,
-                                                       arguments_list_len);
+      if (!is_no_lex_env)
+      {
+        ecma_deref_object (local_env_p);
+      }
 
-    if (unlikely (ecma_is_value_error_reference (ret_value)))
-    {
-      JERRY_CONTEXT (error_value) = ecma_clear_error_reference (ret_value, true);
-      ret_value = ECMA_VALUE_ERROR;
+      return ret_value;
     }
-    else
-    {
-#ifdef JERRY_DEBUGGER
-      JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_EXCEPTION_THROWN);
-#endif /* JERRY_DEBUGGER */
-    }
-  }
-  else
-  {
+#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
+
     JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
     JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_DIRECT_EVAL;
 
@@ -587,137 +809,74 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
 
     /* 4. */
     ecma_value_t args_len_or_this = ext_function_p->u.bound_function.args_len_or_this;
-    ecma_value_t bound_this_value;
     ecma_length_t args_length;
 
     if (!ecma_is_value_integer_number (args_len_or_this))
     {
-      bound_this_value = args_len_or_this;
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+      if (JERRY_UNLIKELY (args_len_or_this == ECMA_VALUE_IMPLICIT_CONSTRUCTOR))
+      {
+        if (!ecma_op_function_has_construct_flag (arguments_list_p))
+        {
+          return ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor cannot be invoked without 'new'."));
+        }
+        if (ecma_get_object_is_builtin (target_func_obj_p))
+        {
+          arguments_list_p = ecma_op_function_clear_construct_flag (arguments_list_p);
+        }
+      }
+      else
+      {
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+        this_arg_value = args_len_or_this;
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+      }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
       args_length = 1;
     }
     else
     {
-      bound_this_value = *(ecma_value_t *) (ext_function_p + 1);
+      this_arg_value = *(ecma_value_t *) (ext_function_p + 1);
       args_length = (ecma_length_t) ecma_get_integer_from_value (args_len_or_this);
     }
 
     JERRY_ASSERT (args_length > 0);
 
-    if (args_length > 1)
+    if (args_length == 1)
     {
-      args_length--;
-      ecma_length_t merged_args_list_len = args_length + arguments_list_len;
-
-      JMEM_DEFINE_LOCAL_ARRAY (merged_args_list_p, merged_args_list_len, ecma_value_t);
-
-      ecma_value_t *args_p = (ecma_value_t *) (ext_function_p + 1);
-
-      memcpy (merged_args_list_p, args_p + 1, args_length * sizeof (ecma_value_t));
-      memcpy (merged_args_list_p + args_length, arguments_list_p, arguments_list_len * sizeof (ecma_value_t));
-
-      /* 5. */
-      ret_value = ecma_op_function_call (target_func_obj_p,
-                                         bound_this_value,
-                                         merged_args_list_p,
-                                         merged_args_list_len);
-
-      JMEM_FINALIZE_LOCAL_ARRAY (merged_args_list_p);
-    }
-    else
-    {
-      /* 5. */
-      ret_value = ecma_op_function_call (target_func_obj_p,
-                                         bound_this_value,
-                                         arguments_list_p,
-                                         arguments_list_len);
+      func_obj_p = target_func_obj_p;
+      continue;
     }
-  }
 
-  JERRY_ASSERT (!ecma_is_value_empty (ret_value));
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+    arguments_list_p = ecma_op_function_clear_construct_flag (arguments_list_p);
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
 
-  return ret_value;
-} /* ecma_op_function_call */
+    JERRY_ASSERT (!ecma_op_function_has_construct_flag (arguments_list_p));
+    args_length--;
 
-/**
- * [[Construct]] implementation for Function objects (13.2.2),
- * created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION) and
- * externally defined (host) functions (ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION).
- *
- * @return ecma value
- *         Returned value must be freed with ecma_free_value
- */
-static ecma_value_t
-ecma_op_function_construct_simple_or_external (ecma_object_t *func_obj_p, /**< Function object */
-                                               const ecma_value_t *arguments_list_p, /**< arguments list */
-                                               ecma_length_t arguments_list_len) /**< length of arguments list */
-{
-  JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION
-                || ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
+    ecma_length_t merged_args_list_len = args_length + arguments_list_len;
+    ecma_value_t ret_value;
 
-  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
+    JMEM_DEFINE_LOCAL_ARRAY (merged_args_list_p, merged_args_list_len, ecma_value_t);
 
-  /* 5. */
-  ECMA_TRY_CATCH (func_obj_prototype_prop_value,
-                  ecma_op_object_get_by_magic_id (func_obj_p,
-                                                  LIT_MAGIC_STRING_PROTOTYPE),
-                  ret_value);
+    ecma_value_t *args_p = (ecma_value_t *) (ext_function_p + 1);
 
-  /* 1., 2., 4. */
-  ecma_object_t *obj_p;
-  if (ecma_is_value_object (func_obj_prototype_prop_value))
-  {
-    /* 6. */
-    obj_p = ecma_create_object (ecma_get_object_from_value (func_obj_prototype_prop_value),
-                                0,
-                                ECMA_OBJECT_TYPE_GENERAL);
-  }
-  else
-  {
-    /* 7. */
-    ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
+    memcpy (merged_args_list_p, args_p + 1, args_length * sizeof (ecma_value_t));
+    memcpy (merged_args_list_p + args_length, arguments_list_p, arguments_list_len * sizeof (ecma_value_t));
 
-    obj_p = ecma_create_object (prototype_p, 0, ECMA_OBJECT_TYPE_GENERAL);
+    /* 5. */
+    ret_value = ecma_op_function_call (target_func_obj_p,
+                                       this_arg_value,
+                                       merged_args_list_p,
+                                       merged_args_list_len);
 
-    ecma_deref_object (prototype_p);
-  }
+    JMEM_FINALIZE_LOCAL_ARRAY (merged_args_list_p);
 
-  /* 3. */
-  /*
-   * [[Class]] property of ECMA_OBJECT_TYPE_GENERAL type objects
-   * without ECMA_INTERNAL_PROPERTY_CLASS internal property
-   * is "Object".
-   *
-   * See also: ecma_object_get_class_name.
-   */
-
-  /* 8. */
-  ECMA_TRY_CATCH (call_completion,
-                  ecma_op_function_call (func_obj_p,
-                                         ecma_make_object_value (obj_p),
-                                         arguments_list_p,
-                                         arguments_list_len),
-                  ret_value);
-
-  /* 9. */
-  if (ecma_is_value_object (call_completion))
-  {
-    ret_value = ecma_copy_value (call_completion);
+    return ret_value;
   }
-  else
-  {
-    /* 10. */
-    ecma_ref_object (obj_p);
-    ret_value = ecma_make_object_value (obj_p);
-  }
-
-  ECMA_FINALIZE (call_completion);
-
-  ecma_deref_object (obj_p);
-
-  ECMA_FINALIZE (func_obj_prototype_prop_value);
-
-  return ret_value;
-} /* ecma_op_function_construct_simple_or_external */
+} /* ecma_op_function_call */
 
 /**
  * [[Construct]] implementation:
@@ -730,97 +889,206 @@ ecma_op_function_construct_simple_or_external (ecma_object_t *func_obj_p, /**< F
  */
 ecma_value_t
 ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
+                            ecma_value_t this_arg_value, /**< optional 'this' object value
+                                                          *   or ECMA_VALUE_UNDEFINED */
                             const ecma_value_t *arguments_list_p, /**< arguments list */
                             ecma_length_t arguments_list_len) /**< length of arguments list */
 {
   JERRY_ASSERT (func_obj_p != NULL
                 && !ecma_is_lexical_environment (func_obj_p));
-  JERRY_ASSERT (ecma_is_constructor (ecma_make_object_value (func_obj_p)));
 
-  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
+  JERRY_ASSERT (ecma_is_value_object (this_arg_value)
+                || this_arg_value == ECMA_VALUE_UNDEFINED);
 
-  if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION)
+  ecma_object_t *target_func_obj_p = NULL;
+
+  while (JERRY_UNLIKELY (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION))
   {
-    if (unlikely (ecma_get_object_is_builtin (func_obj_p)
-                  && !ecma_builtin_function_is_routine (func_obj_p)))
+    /* 1-3. */
+    ecma_extended_object_t *ext_function_p = (ecma_extended_object_t *) func_obj_p;
+
+    target_func_obj_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
+                                                         ext_function_p->u.bound_function.target_function);
+
+    /* 4. */
+    ecma_value_t args_len_or_this = ext_function_p->u.bound_function.args_len_or_this;
+
+    ecma_length_t args_length = 1;
+
+    if (ecma_is_value_integer_number (args_len_or_this))
     {
-      ret_value = ecma_builtin_dispatch_construct (func_obj_p,
-                                                   arguments_list_p,
-                                                   arguments_list_len);
+      args_length = (ecma_length_t) ecma_get_integer_from_value (args_len_or_this);
     }
-    else
+
+    JERRY_ASSERT (args_length > 0);
+
+    /* 5. */
+    if (args_length == 1)
     {
-      ret_value = ecma_op_function_construct_simple_or_external (func_obj_p,
-                                                                 arguments_list_p,
-                                                                 arguments_list_len);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+      if (args_len_or_this == ECMA_VALUE_IMPLICIT_CONSTRUCTOR && ecma_is_value_undefined (this_arg_value))
+      {
+        break;
+      }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+      func_obj_p = target_func_obj_p;
+      continue;
     }
+
+    ecma_value_t *args_p = (ecma_value_t *) (ext_function_p + 1);
+    ecma_value_t ret_value;
+
+    args_length--;
+    ecma_length_t merged_args_list_len = args_length + arguments_list_len;
+
+    JMEM_DEFINE_LOCAL_ARRAY (merged_args_list_p, merged_args_list_len, ecma_value_t);
+
+    memcpy (merged_args_list_p, args_p + 1, args_length * sizeof (ecma_value_t));
+    memcpy (merged_args_list_p + args_length, arguments_list_p, arguments_list_len * sizeof (ecma_value_t));
+
+    /* 5. */
+    ret_value = ecma_op_function_construct (target_func_obj_p,
+                                            this_arg_value,
+                                            merged_args_list_p,
+                                            merged_args_list_len);
+
+    JMEM_FINALIZE_LOCAL_ARRAY (merged_args_list_p);
+
+    return ret_value;
   }
-  else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
+
+  ecma_object_type_t type = ecma_get_object_type (func_obj_p);
+
+#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
+  if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_ARROW_FUNCTION))
   {
-    ret_value = ecma_op_function_construct_simple_or_external (func_obj_p,
-                                                               arguments_list_p,
-                                                               arguments_list_len);
+    return ecma_raise_type_error (ECMA_ERR_MSG ("Arrow functions have no constructor."));
   }
-  else
+#endif /* CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
+
+  if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_FUNCTION && ecma_get_object_is_builtin (func_obj_p)))
   {
-    JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
+    if (ecma_builtin_function_is_routine (func_obj_p))
+    {
+      return ecma_raise_type_error (ECMA_ERR_MSG ("Built-in routines have no constructor."));
+    }
 
-    /* 1. */
-    ecma_extended_object_t *ext_function_p = (ecma_extended_object_t *) func_obj_p;
+    ecma_value_t ret_value = ecma_builtin_dispatch_construct (func_obj_p,
+                                                              arguments_list_p,
+                                                              arguments_list_len);
 
-    ecma_object_t *target_func_obj_p;
-    target_func_obj_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
-                                                         ext_function_p->u.bound_function.target_function);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+    if (!ecma_is_value_undefined (this_arg_value) && !ECMA_IS_VALUE_ERROR (ret_value))
+    {
+      ecma_op_set_class_prototype (ret_value, this_arg_value);
+    }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
+    return ret_value;
+  }
+
+  ecma_object_t *new_this_obj_p = NULL;
+
+  if (JERRY_LIKELY (this_arg_value == ECMA_VALUE_UNDEFINED))
+  {
+    /* 5. */
+    ecma_value_t prototype_prop_value = ecma_op_object_get_by_magic_id (func_obj_p,
+                                                                        LIT_MAGIC_STRING_PROTOTYPE);
 
-    /* 2. */
-    if (!ecma_is_constructor (ecma_make_object_value (target_func_obj_p)))
+    if (ECMA_IS_VALUE_ERROR (prototype_prop_value))
     {
-      ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected a constructor."));
+      return prototype_prop_value;
+    }
+
+    /* 1., 2., 4. */
+    if (ecma_is_value_object (prototype_prop_value))
+    {
+      /* 6. */
+      new_this_obj_p = ecma_create_object (ecma_get_object_from_value (prototype_prop_value),
+                                           0,
+                                           ECMA_OBJECT_TYPE_GENERAL);
     }
     else
     {
-      /* 4. */
-      ecma_value_t args_len_or_this = ext_function_p->u.bound_function.args_len_or_this;
+      /* 7. */
+      ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
 
-      ecma_length_t args_length = 1;
+      new_this_obj_p = ecma_create_object (prototype_p, 0, ECMA_OBJECT_TYPE_GENERAL);
+    }
 
-      if (ecma_is_value_integer_number (args_len_or_this))
-      {
-        args_length = (ecma_length_t) ecma_get_integer_from_value (args_len_or_this);
-      }
+    ecma_free_value (prototype_prop_value);
 
-      JERRY_ASSERT (args_length > 0);
+    this_arg_value = ecma_make_object_value (new_this_obj_p);
+  }
 
-      if (args_length > 1)
-      {
-        ecma_value_t *args_p = (ecma_value_t *) (ext_function_p + 1);
+  /* 8. */
+  ecma_value_t ret_value;
 
-        args_length--;
-        ecma_length_t merged_args_list_len = args_length + arguments_list_len;
+  switch (type)
+  {
+    case ECMA_OBJECT_TYPE_FUNCTION:
+    {
+      arguments_list_p = ecma_op_function_set_construct_flag (arguments_list_p);
 
-        JMEM_DEFINE_LOCAL_ARRAY (merged_args_list_p, merged_args_list_len, ecma_value_t);
+      ret_value = ecma_op_function_call (func_obj_p,
+                                         this_arg_value,
+                                         arguments_list_p,
+                                         arguments_list_len);
+      break;
+    }
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+    case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
+    {
+      JERRY_ASSERT (!ecma_op_function_has_construct_flag (arguments_list_p));
+      JERRY_ASSERT (target_func_obj_p != NULL);
 
-        memcpy (merged_args_list_p, args_p + 1, args_length * sizeof (ecma_value_t));
-        memcpy (merged_args_list_p + args_length, arguments_list_p, arguments_list_len * sizeof (ecma_value_t));
+      ret_value = ecma_op_function_construct (target_func_obj_p,
+                                              this_arg_value,
+                                              arguments_list_p,
+                                              arguments_list_len);
+      break;
+    }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+    default:
+    {
+      JERRY_ASSERT (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
 
-        /* 5. */
-        ret_value = ecma_op_function_construct (target_func_obj_p,
-                                                merged_args_list_p,
-                                                merged_args_list_len);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+      ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
 
-        JMEM_FINALIZE_LOCAL_ARRAY (merged_args_list_p);
-      }
-      else
+      if (ext_func_obj_p->u.external_handler_cb == ecma_op_function_implicit_constructor_handler_cb)
       {
-        /* 5. */
-        ret_value = ecma_op_function_construct (target_func_obj_p,
-                                                arguments_list_p,
-                                                arguments_list_len);
+        ret_value = ECMA_VALUE_UNDEFINED;
+        break;
       }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
+      ret_value = ecma_op_function_call (func_obj_p,
+                                         this_arg_value,
+                                         arguments_list_p,
+                                         arguments_list_len);
+      break;
     }
   }
 
-  return ret_value;
+  /* 9. */
+  if (ECMA_IS_VALUE_ERROR (ret_value) || ecma_is_value_object (ret_value))
+  {
+    if (new_this_obj_p != NULL)
+    {
+      ecma_deref_object (new_this_obj_p);
+    }
+    return ret_value;
+  }
+
+  ecma_fast_free_value (ret_value);
+
+  if (JERRY_UNLIKELY (new_this_obj_p == NULL))
+  {
+    ecma_ref_object (ecma_get_object_from_value (this_arg_value));
+  }
+
+  return this_arg_value;
 } /* ecma_op_function_construct */
 
 /**
@@ -904,8 +1172,6 @@ ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**<
                                            thrower_p,
                                            ECMA_PROPERTY_FIXED,
                                            &caller_prop_p);
-
-      ecma_deref_object (thrower_p);
       return caller_prop_p;
     }
   }
@@ -1015,8 +1281,6 @@ ecma_op_bound_function_try_to_lazy_instantiate_property (ecma_object_t *object_p
                                          thrower_p,
                                          ECMA_PROPERTY_FIXED,
                                          &caller_prop_p);
-
-    ecma_deref_object (thrower_p);
     return caller_prop_p;
   }
 
@@ -1059,7 +1323,19 @@ ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, /**< functio
                                     0);
 
   const ecma_compiled_code_t *bytecode_data_p;
+
+#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
+  if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_ARROW_FUNCTION)
+  {
+    bytecode_data_p = ecma_op_arrow_function_get_compiled_code ((ecma_arrow_function_t *) object_p);
+  }
+  else
+  {
+    bytecode_data_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
+  }
+#else /* CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
   bytecode_data_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
+#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
 
   if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE)
   {
index a047b6ad0f4baa6fc19532d05ddc055b87edf7a5..00377766caf697637c5948dadb08493d5b57e190 100644 (file)
@@ -46,6 +46,29 @@ ecma_op_create_external_function_object (ecma_external_handler_t handler_cb);
 const ecma_compiled_code_t *
 ecma_op_function_get_compiled_code (ecma_extended_object_t *function_p);
 
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+void
+ecma_op_set_super_called (ecma_object_t *lex_env_p);
+
+bool
+ecma_op_is_super_called (ecma_object_t *lex_env_p);
+
+void
+ecma_op_set_class_this_binding (ecma_object_t *lex_env_p, ecma_value_t this_binding);
+
+ecma_value_t
+ecma_op_get_class_this_binding (ecma_object_t *lex_env_p);
+
+ecma_value_t
+ecma_op_function_implicit_constructor_handler_cb (const ecma_value_t function_obj,
+                                                  const ecma_value_t this_val,
+                                                  const ecma_value_t args_p[],
+                                                  const ecma_length_t args_count);
+
+void
+ecma_op_set_class_prototype (ecma_value_t completion_value, ecma_value_t this_arg);
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
 #ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
 const ecma_compiled_code_t *
 ecma_op_arrow_function_get_compiled_code (ecma_arrow_function_t *arrow_function_p);
@@ -59,8 +82,8 @@ ecma_op_function_call (ecma_object_t *func_obj_p, ecma_value_t this_arg_value,
                        const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len);
 
 ecma_value_t
-ecma_op_function_construct (ecma_object_t *func_obj_p, const ecma_value_t *arguments_list_p,
-                            ecma_length_t arguments_list_len);
+ecma_op_function_construct (ecma_object_t *func_obj_p, ecma_value_t this_arg_value,
+                            const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len);
 
 ecma_property_t *
 ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
index 7d5873aadd18f2aba17cb35f03f3f478182a1764..4f4604d758947502a438fc11705613cd903b67c6 100644 (file)
@@ -50,7 +50,7 @@ ecma_op_get_value_lex_env_base (ecma_object_t *ref_base_lex_env_p, /**< referenc
   const bool is_unresolvable_reference = (ref_base_lex_env_p == NULL);
 
   /* 3. */
-  if (unlikely (is_unresolvable_reference))
+  if (JERRY_UNLIKELY (is_unresolvable_reference))
   {
 #ifdef JERRY_ENABLE_ERROR_MESSAGES
     ecma_value_t var_name_val = ecma_make_string_value (var_name_string_p);
@@ -151,7 +151,7 @@ ecma_op_put_value_lex_env_base (ecma_object_t *ref_base_lex_env_p, /**< referenc
   const bool is_unresolvable_reference = (ref_base_lex_env_p == NULL);
 
   /* 3. */
-  if (unlikely (is_unresolvable_reference))
+  if (JERRY_UNLIKELY (is_unresolvable_reference))
   {
     /* 3.a. */
     if (is_strict)
@@ -169,15 +169,13 @@ ecma_op_put_value_lex_env_base (ecma_object_t *ref_base_lex_env_p, /**< referenc
     else
     {
       /* 3.b. */
-      ecma_object_t *global_object_p = ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL);
+      ecma_object_t *global_object_p = ecma_builtin_get_global ();
 
       ecma_value_t completion = ecma_op_object_put (global_object_p,
                                                     var_name_string_p,
                                                     value,
                                                     false);
 
-      ecma_deref_object (global_object_p);
-
       JERRY_ASSERT (ecma_is_value_boolean (completion));
 
       return ECMA_VALUE_EMPTY;
index 59b5c8ac732015f5fa6226c2d54e76c9a2c3d853..901052759dceba240c541cb3a9e76ed016902a7d 100644 (file)
@@ -46,7 +46,7 @@ typedef struct
 {
   ecma_value_t promise; /**< promise to be resolved */
   ecma_value_t thenable; /**< thenbale object */
-  ecma_value_t then; /** 'then' function */
+  ecma_value_t then; /**< 'then' function */
 } ecma_job_promise_resolve_thenable_t;
 
 /**
@@ -145,10 +145,10 @@ ecma_process_promise_reaction_job (void *obj_p) /**< the job to be operated */
   ecma_job_promise_reaction_t *job_p = (ecma_job_promise_reaction_t *) obj_p;
   ecma_object_t *reaction_p = ecma_get_object_from_value (job_p->reaction);
 
-  ecma_string_t *capability_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_CAPABILITY);
-  ecma_string_t *handler_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_HANDLER);
-  ecma_string_t *resolve_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_RESOLVE);
-  ecma_string_t *reject_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT);
+  ecma_string_t *capability_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_CAPABILITY);
+  ecma_string_t *handler_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_HANDLER);
+  ecma_string_t *resolve_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_RESOLVE);
+  ecma_string_t *reject_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REJECT);
 
   /* 2. */
   ecma_value_t capability = ecma_op_object_get (reaction_p, capability_str_p);
index 2af3ce31aa5d551f7833191be4222ffd6f76f281..d000fa4f2ef3ea6f4292e9ab3693ee6c93145775 100644 (file)
 void
 ecma_init_global_lex_env (void)
 {
-#ifdef CONFIG_ECMA_GLOBAL_ENVIRONMENT_DECLARATIVE
-  JERRY_CONTEXT (ecma_global_lex_env_p) = ecma_create_decl_lex_env (NULL);
-#else /* !CONFIG_ECMA_GLOBAL_ENVIRONMENT_DECLARATIVE */
   ecma_object_t *glob_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL);
 
-  JERRY_CONTEXT (ecma_global_lex_env_p) = ecma_create_object_lex_env (NULL, glob_obj_p, false);
-
-  ecma_deref_object (glob_obj_p);
-#endif /* CONFIG_ECMA_GLOBAL_ENVIRONMENT_DECLARATIVE */
+  JERRY_CONTEXT (ecma_global_lex_env_p) = ecma_create_object_lex_env (NULL,
+                                                                      glob_obj_p,
+                                                                      ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
 } /* ecma_init_global_lex_env */
 
 /**
@@ -90,7 +86,9 @@ ecma_op_has_binding (ecma_object_t *lex_env_p, /**< lexical environment */
   JERRY_ASSERT (lex_env_p != NULL
                 && ecma_is_lexical_environment (lex_env_p));
 
-  if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
+  ecma_lexical_environment_type_t lex_env_type = ecma_get_lex_env_type (lex_env_p);
+
+  if (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
   {
     ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
 
@@ -98,8 +96,12 @@ ecma_op_has_binding (ecma_object_t *lex_env_p, /**< lexical environment */
   }
   else
   {
-    JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND
-                  || ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+    JERRY_ASSERT (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND
+                  || lex_env_type == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND);
+#else /* CONFIG_DISABLE_ES2015_CLASS */
+    JERRY_ASSERT (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
 
     ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
 
@@ -140,8 +142,7 @@ ecma_op_create_mutable_binding (ecma_object_t *lex_env_p, /**< lexical environme
   }
   else
   {
-    JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND
-                  || ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
+    JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
 
     ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
 
@@ -154,9 +155,8 @@ ecma_op_create_mutable_binding (ecma_object_t *lex_env_p, /**< lexical environme
     completion = ecma_builtin_helper_def_prop (binding_obj_p,
                                                name_p,
                                                ECMA_VALUE_UNDEFINED,
-                                               true, /* Writable */
-                                               true, /* Enumerable */
-                                               is_deletable, /* Configurable */
+                                               is_deletable ? ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE
+                                                            : ECMA_PROPERTY_ENUMERABLE_WRITABLE,
                                                true); /* Failure handling */
 
     if (ECMA_IS_VALUE_ERROR (completion))
@@ -208,8 +208,7 @@ ecma_op_set_mutable_binding (ecma_object_t *lex_env_p, /**< lexical environment
   }
   else
   {
-    JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND
-                  || ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
+    JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
 
     ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
 
@@ -222,10 +221,8 @@ ecma_op_set_mutable_binding (ecma_object_t *lex_env_p, /**< lexical environment
     {
       return completion;
     }
-    else
-    {
-      JERRY_ASSERT (ecma_is_value_boolean (completion));
-    }
+
+    JERRY_ASSERT (ecma_is_value_boolean (completion));
   }
 
   return ECMA_VALUE_EMPTY;
@@ -256,8 +253,7 @@ ecma_op_get_binding_value (ecma_object_t *lex_env_p, /**< lexical environment */
   }
   else
   {
-    JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND
-                  || ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
+    JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
 
     ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
 
@@ -326,8 +322,7 @@ ecma_op_delete_binding (ecma_object_t *lex_env_p, /**< lexical environment */
   }
   else
   {
-    JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND
-                  || ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
+    JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
 
     ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
 
@@ -355,20 +350,12 @@ ecma_op_implicit_this_value (ecma_object_t *lex_env_p) /**< lexical environment
   }
   else
   {
-    JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND
-                  || ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
+    JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
 
-    if (ecma_get_lex_env_provide_this (lex_env_p))
-    {
-      ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
-      ecma_ref_object (binding_obj_p);
+    ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
+    ecma_ref_object (binding_obj_p);
 
-      return ecma_make_object_value (binding_obj_p);
-    }
-    else
-    {
-      return ECMA_VALUE_UNDEFINED;
-    }
+    return ecma_make_object_value (binding_obj_p);
   }
 } /* ecma_op_implicit_this_value */
 
index 4b0c6055fa3fc7ffb7bb8191a14e7b14cc648545..c0808cbf015c4f12fc4ab23d867585bc4b5dbef4 100644 (file)
@@ -57,8 +57,6 @@ ecma_value_t ecma_op_implicit_this_value (ecma_object_t *lex_env_p);
 /* ECMA-262 v5, Table 18. Additional methods of Declarative Environment Records */
 void ecma_op_create_immutable_binding (ecma_object_t *lex_env_p, ecma_string_t *name_p, ecma_value_t value);
 
-ecma_object_t *ecma_op_create_global_environment (ecma_object_t *);
-
 /**
  * @}
  * @}
diff --git a/deps/jerry/jerry-core/ecma/operations/ecma-map-object.c b/deps/jerry/jerry-core/ecma/operations/ecma-map-object.c
new file mode 100644 (file)
index 0000000..403e867
--- /dev/null
@@ -0,0 +1,584 @@
+/* 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-helpers.h"
+#include "ecma-map-object.h"
+#include "ecma-objects.h"
+
+#ifndef CONFIG_DISABLE_ES2015_MAP_BUILTIN
+
+/** \addtogroup ecma ECMA
+ * @{
+ *
+ * \addtogroup \addtogroup ecmamaphelpers ECMA builtin map helper functions
+ * @{
+ */
+
+JERRY_STATIC_ASSERT (ECMA_MAP_OBJECT_ITEM_COUNT == 3,
+                     ecma_map_object_item_count_must_be_3);
+
+/**
+ * Handle calling [[Construct]] of built-in map like objects
+ *
+ * @return ecma value
+ */
+ecma_value_t
+ecma_op_map_create (const ecma_value_t *arguments_list_p, /**< arguments list */
+                    ecma_length_t arguments_list_len) /**< number of arguments */
+{
+  JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
+
+  ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_MAP_PROTOTYPE);
+  ecma_object_t *object_p = ecma_create_object (prototype_obj_p,
+                                                sizeof (ecma_map_object_t),
+                                                ECMA_OBJECT_TYPE_CLASS);
+
+  ecma_map_object_t *map_object_p = (ecma_map_object_t *) object_p;
+  map_object_p->header.u.class_prop.class_id = LIT_MAGIC_STRING_MAP_UL;
+  map_object_p->header.u.class_prop.extra_info = 0;
+  map_object_p->header.u.class_prop.u.length = 0;
+  map_object_p->first_chunk_cp = ECMA_NULL_POINTER;
+  map_object_p->last_chunk_cp = ECMA_NULL_POINTER;
+
+  return ecma_make_object_value (object_p);
+} /* ecma_op_map_create */
+
+/**
+ * Get map object pointer
+ *
+ * Note:
+ *   If the function returns with NULL, the error object has
+ *   already set, and the caller must return with ECMA_VALUE_ERROR
+ *
+ * @return pointer to the map if this_arg is a valid map object
+ *         NULL otherwise
+ */
+static ecma_map_object_t *
+ecma_op_map_get_object (ecma_value_t this_arg) /**< this argument */
+{
+  if (ecma_is_value_object (this_arg))
+  {
+    ecma_map_object_t *map_object_p = (ecma_map_object_t *) ecma_get_object_from_value (this_arg);
+
+    if (ecma_get_object_type (&map_object_p->header.object) == ECMA_OBJECT_TYPE_CLASS
+        && map_object_p->header.u.class_prop.class_id == LIT_MAGIC_STRING_MAP_UL)
+    {
+      return map_object_p;
+    }
+  }
+
+  ecma_raise_type_error (ECMA_ERR_MSG ("Expected a Map object."));
+  return NULL;
+} /* ecma_op_map_get_object */
+
+/**
+ * Returns with the size of the map object.
+ *
+ * @return size of the map object as ecma-value.
+ */
+ecma_value_t
+ecma_op_map_size (ecma_value_t this_arg) /**< this argument */
+{
+  ecma_map_object_t *map_object_p = ecma_op_map_get_object (this_arg);
+  if (map_object_p == NULL)
+  {
+    return ECMA_VALUE_ERROR;
+  }
+
+  return ecma_make_uint32_value (map_object_p->header.u.class_prop.u.length);
+} /* ecma_op_map_size */
+
+/**
+ * Linear search for the value in the map storage
+ *
+ * @return pointer to value if key is found
+ *         NULL otherwise
+ */
+static ecma_value_t *
+ecma_builtin_map_search (jmem_cpointer_t first_chunk_cp, /**< first chunk */
+                         ecma_value_t key) /**< key to search */
+{
+  if (JERRY_UNLIKELY (first_chunk_cp == ECMA_NULL_POINTER))
+  {
+    return NULL;
+  }
+
+  ecma_map_object_chunk_t *chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_map_object_chunk_t,
+                                                                first_chunk_cp);
+
+  bool is_direct = true;
+  const ecma_string_t *key_str_p = NULL;
+  ecma_number_t key_float = 0;
+
+  if (ecma_is_value_non_direct_string (key))
+  {
+    key_str_p = ecma_get_string_from_value (key);
+    is_direct = false;
+  }
+  else if (ecma_is_value_float_number (key))
+  {
+    key_float = ecma_get_float_from_value (key);
+    is_direct = false;
+  }
+
+  ecma_value_t *item_p = chunk_p->items;
+  ecma_value_t last_key = ECMA_VALUE_ARRAY_HOLE;
+
+  while (true)
+  {
+    ecma_value_t item = *item_p++;
+
+    if (JERRY_UNLIKELY (item == ECMA_VALUE_ARRAY_HOLE))
+    {
+      JERRY_ASSERT (last_key == ECMA_VALUE_ARRAY_HOLE);
+      continue;
+    }
+
+    if (JERRY_UNLIKELY (ecma_is_value_pointer (item)))
+    {
+      item_p = (ecma_value_t *) ecma_get_pointer_from_value (item);
+
+      if (item_p == NULL)
+      {
+        JERRY_ASSERT (last_key == ECMA_VALUE_ARRAY_HOLE);
+        return NULL;
+      }
+
+      JERRY_ASSERT (!ecma_is_value_pointer (*item_p));
+      continue;
+    }
+
+    if (last_key == ECMA_VALUE_ARRAY_HOLE)
+    {
+      last_key = item;
+    }
+    else
+    {
+      if (JERRY_LIKELY (is_direct))
+      {
+        if (key == last_key)
+        {
+          return item_p - 1;
+        }
+      }
+      else if (key_str_p != NULL)
+      {
+        if (ecma_is_value_non_direct_string (last_key)
+            && ecma_compare_ecma_non_direct_strings (key_str_p, ecma_get_string_from_value (last_key)))
+        {
+          return item_p - 1;
+        }
+      }
+      else if (ecma_is_value_float_number (last_key)
+               && ecma_get_float_from_value (last_key) == key_float)
+      {
+        return item_p - 1;
+      }
+
+      last_key = ECMA_VALUE_ARRAY_HOLE;
+    }
+  }
+} /* ecma_builtin_map_search */
+
+/**
+ * The generic map prototype object's 'get' routine
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+ecma_value_t
+ecma_op_map_get (ecma_value_t this_arg, /**< this argument */
+                 ecma_value_t key_arg) /**< key argument */
+{
+  ecma_map_object_t *map_object_p = ecma_op_map_get_object (this_arg);
+  if (map_object_p == NULL)
+  {
+    return ECMA_VALUE_ERROR;
+  }
+
+  ecma_value_t *value_p = ecma_builtin_map_search (map_object_p->first_chunk_cp, key_arg);
+
+  if (value_p == NULL)
+  {
+    return ECMA_VALUE_UNDEFINED;
+  }
+
+  return ecma_copy_value (*value_p);
+} /* ecma_op_map_get */
+
+/**
+ * The generic map prototype object's 'has' routine
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+ecma_value_t
+ecma_op_map_has (ecma_value_t this_arg, /**< this argument */
+                 ecma_value_t key_arg) /**< key argument */
+{
+  ecma_map_object_t *map_object_p = ecma_op_map_get_object (this_arg);
+  if (map_object_p == NULL)
+  {
+    return ECMA_VALUE_ERROR;
+  }
+
+  return ecma_make_boolean_value (ecma_builtin_map_search (map_object_p->first_chunk_cp, key_arg) != NULL);
+} /* ecma_op_map_has */
+
+/**
+ * The generic map prototype object's 'set' routine
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+ecma_value_t
+ecma_op_map_set (ecma_value_t this_arg, /**< this argument */
+                 ecma_value_t key_arg, /**< key argument */
+                 ecma_value_t value_arg) /**< value argument */
+{
+  ecma_map_object_t *map_object_p = ecma_op_map_get_object (this_arg);
+  if (map_object_p == NULL)
+  {
+    return ECMA_VALUE_ERROR;
+  }
+
+  ecma_value_t *value_p = ecma_builtin_map_search (map_object_p->first_chunk_cp, key_arg);
+
+  if (value_p == NULL)
+  {
+    ecma_value_t *key_p = NULL;
+    ecma_map_object_chunk_t *last_chunk_p = ECMA_GET_POINTER (ecma_map_object_chunk_t,
+                                                              map_object_p->last_chunk_cp);
+
+    if (last_chunk_p != NULL)
+    {
+      if (last_chunk_p->items[2] == ECMA_VALUE_ARRAY_HOLE)
+      {
+        key_p = last_chunk_p->items + 2;
+
+        if (last_chunk_p->items[1] == ECMA_VALUE_ARRAY_HOLE)
+        {
+          key_p = last_chunk_p->items + 1;
+          value_p = last_chunk_p->items + 2;
+        }
+      }
+    }
+
+    if (key_p == NULL || value_p == NULL)
+    {
+      size_t size = sizeof (ecma_map_object_chunk_t);
+      ecma_map_object_chunk_t *new_chunk_p = (ecma_map_object_chunk_t *) jmem_heap_alloc_block (size);
+
+      new_chunk_p->items[ECMA_MAP_OBJECT_ITEM_COUNT] = ecma_make_pointer_value (NULL);
+
+      for (int i = 0; i < ECMA_MAP_OBJECT_ITEM_COUNT; i++)
+      {
+        new_chunk_p->items[i] = ECMA_VALUE_ARRAY_HOLE;
+      }
+
+      ECMA_SET_NON_NULL_POINTER (map_object_p->last_chunk_cp, new_chunk_p);
+
+      if (last_chunk_p == NULL)
+      {
+        map_object_p->first_chunk_cp = map_object_p->last_chunk_cp;
+      }
+      else
+      {
+        last_chunk_p->items[ECMA_MAP_OBJECT_ITEM_COUNT] = ecma_make_pointer_value (new_chunk_p);
+      }
+
+      if (key_p == NULL)
+      {
+        JERRY_ASSERT (value_p == NULL);
+        key_p = new_chunk_p->items + 0;
+        value_p = new_chunk_p->items + 1;
+      }
+      else
+      {
+        value_p = new_chunk_p->items + 0;
+      }
+    }
+
+    *key_p = ecma_copy_value_if_not_object (key_arg);
+    map_object_p->header.u.class_prop.u.length++;
+  }
+  else
+  {
+    ecma_free_value_if_not_object (*value_p);
+  }
+
+  *value_p = ecma_copy_value_if_not_object (value_arg);
+
+  ecma_ref_object (&map_object_p->header.object);
+  return this_arg;
+} /* ecma_op_map_set */
+
+/**
+ * Low-level function to clear all items from a map
+ */
+void
+ecma_op_map_clear_map (ecma_map_object_t *map_object_p) /**< map object */
+{
+  JERRY_ASSERT (ecma_get_object_type (&map_object_p->header.object) == ECMA_OBJECT_TYPE_CLASS
+                && (map_object_p->header.u.class_prop.class_id == LIT_MAGIC_STRING_MAP_UL));
+
+  jmem_cpointer_t first_chunk_cp = map_object_p->first_chunk_cp;
+
+  if (JERRY_UNLIKELY (first_chunk_cp == ECMA_NULL_POINTER))
+  {
+    return;
+  }
+
+  ecma_map_object_chunk_t *chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_map_object_chunk_t,
+                                                                first_chunk_cp);
+
+  do
+  {
+    ecma_value_t *current_p = chunk_p->items;
+    ecma_value_t *last_p = current_p + ECMA_MAP_OBJECT_ITEM_COUNT;
+
+    do
+    {
+      ecma_free_value_if_not_object (*current_p++);
+    }
+    while (current_p < last_p);
+
+    ecma_value_t next = *current_p;
+
+    jmem_heap_free_block (chunk_p, sizeof (ecma_map_object_chunk_t));
+
+    chunk_p = (ecma_map_object_chunk_t *) ecma_get_pointer_from_value (next);
+  }
+  while (chunk_p != NULL);
+
+  map_object_p->header.u.class_prop.u.length = 0;
+  map_object_p->first_chunk_cp = ECMA_NULL_POINTER;
+  map_object_p->last_chunk_cp = ECMA_NULL_POINTER;
+} /* ecma_op_map_clear_map */
+
+/**
+ * The Map prototype object's 'clear' routine
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+ecma_value_t
+ecma_op_map_clear (ecma_value_t this_arg) /**< this argument */
+{
+  /* WeakMap does not have a clear method. */
+  ecma_map_object_t *map_object_p = ecma_op_map_get_object (this_arg);
+  if (map_object_p == NULL)
+  {
+    return ECMA_VALUE_ERROR;
+  }
+
+  ecma_op_map_clear_map (map_object_p);
+  return ECMA_VALUE_UNDEFINED;
+} /* ecma_op_map_clear */
+
+/**
+ * Deletes the current chunk if it is filled with ECMA_VALUE_ARRAY_HOLE.
+ *
+ * @return next chunk if the chunk is deleted, NULL otherwise
+ */
+static ecma_map_object_chunk_t *
+ecma_op_map_delete_chunk (ecma_map_object_t *map_object_p, /**< map object */
+                          ecma_map_object_chunk_t *chunk_p, /**< current chunk */
+                          ecma_map_object_chunk_t *prev_chunk_p) /**< previous chunk */
+{
+  for (int i = 0; i < ECMA_MAP_OBJECT_ITEM_COUNT; i++)
+  {
+    JERRY_ASSERT (!ecma_is_value_pointer (chunk_p->items[i]));
+
+    if (chunk_p->items[i] != ECMA_VALUE_ARRAY_HOLE)
+    {
+      return NULL;
+    }
+  }
+
+  ecma_value_t next_chunk = chunk_p->items[ECMA_MAP_OBJECT_ITEM_COUNT];
+  ecma_map_object_chunk_t *next_chunk_p = (ecma_map_object_chunk_t *) ecma_get_pointer_from_value (next_chunk);
+
+  jmem_heap_free_block (chunk_p, sizeof (ecma_map_object_chunk_t));
+
+  if (prev_chunk_p != NULL)
+  {
+    prev_chunk_p->items[ECMA_MAP_OBJECT_ITEM_COUNT] = ecma_make_pointer_value (next_chunk_p);
+
+    if (next_chunk_p == NULL)
+    {
+      JERRY_ASSERT (map_object_p->first_chunk_cp != map_object_p->last_chunk_cp);
+      JERRY_ASSERT (ECMA_GET_NON_NULL_POINTER (ecma_map_object_chunk_t, map_object_p->last_chunk_cp) == chunk_p);
+
+      ECMA_SET_POINTER (map_object_p->last_chunk_cp, prev_chunk_p);
+    }
+    return next_chunk_p;
+  }
+
+  if (next_chunk_p == NULL)
+  {
+    JERRY_ASSERT (map_object_p->first_chunk_cp == map_object_p->last_chunk_cp);
+    JERRY_ASSERT (ECMA_GET_NON_NULL_POINTER (ecma_map_object_chunk_t, map_object_p->last_chunk_cp) == chunk_p);
+
+    map_object_p->first_chunk_cp = ECMA_NULL_POINTER;
+    map_object_p->last_chunk_cp = ECMA_NULL_POINTER;
+    return next_chunk_p;
+  }
+
+  ECMA_SET_POINTER (map_object_p->first_chunk_cp, next_chunk_p);
+  return next_chunk_p;
+} /* ecma_op_map_delete_chunk */
+
+/**
+ * The generic map prototype object's 'delete' routine
+ *
+ * @return ecma value
+ *         Returned value must be freed with ecma_free_value.
+ */
+ecma_value_t
+ecma_op_map_delete (ecma_value_t this_arg, /**< this argument */
+                    ecma_value_t key_arg) /**< key argument */
+{
+  ecma_map_object_t *map_object_p = ecma_op_map_get_object (this_arg);
+  if (map_object_p == NULL)
+  {
+    return ECMA_VALUE_ERROR;
+  }
+
+  if (JERRY_UNLIKELY (map_object_p->first_chunk_cp == ECMA_NULL_POINTER))
+  {
+    return ECMA_VALUE_FALSE;
+  }
+
+  ecma_map_object_chunk_t *chunk_p = ECMA_GET_NON_NULL_POINTER (ecma_map_object_chunk_t,
+                                                                map_object_p->first_chunk_cp);
+
+  bool is_direct = true;
+  const ecma_string_t *key_str_p = NULL;
+  ecma_number_t key_float = 0;
+
+  if (ecma_is_value_non_direct_string (key_arg))
+  {
+    key_str_p = ecma_get_string_from_value (key_arg);
+    is_direct = false;
+  }
+  else if (ecma_is_value_float_number (key_arg))
+  {
+    key_float = ecma_get_float_from_value (key_arg);
+    is_direct = false;
+  }
+
+  ecma_map_object_chunk_t *prev_chunk_p = NULL;
+  ecma_value_t *item_p = chunk_p->items;
+  bool is_key = true;
+
+  while (true)
+  {
+    ecma_value_t item = *item_p++;
+
+    if (JERRY_UNLIKELY (item == ECMA_VALUE_ARRAY_HOLE))
+    {
+      JERRY_ASSERT (is_key);
+      continue;
+    }
+
+    if (JERRY_UNLIKELY (ecma_is_value_pointer (item)))
+    {
+      prev_chunk_p = chunk_p;
+      chunk_p = (ecma_map_object_chunk_t *) ecma_get_pointer_from_value (item);
+
+      if (chunk_p == NULL)
+      {
+        JERRY_ASSERT (is_key);
+        return ECMA_VALUE_FALSE;
+      }
+
+      item_p = chunk_p->items;
+
+      JERRY_ASSERT (!ecma_is_value_pointer (*item_p));
+      continue;
+    }
+
+    if (is_key)
+    {
+      if (JERRY_LIKELY (is_direct))
+      {
+        if (key_arg == item)
+        {
+          break;
+        }
+      }
+      else if (key_str_p != NULL)
+      {
+        if (ecma_is_value_non_direct_string (item)
+            && ecma_compare_ecma_non_direct_strings (key_str_p, ecma_get_string_from_value (item)))
+        {
+          break;
+        }
+      }
+      else if (ecma_is_value_float_number (item)
+               && ecma_get_float_from_value (item) == key_float)
+      {
+        break;
+      }
+    }
+
+    is_key = !is_key;
+  }
+
+  map_object_p->header.u.class_prop.u.length--;
+
+  item_p -= 1;
+  ecma_free_value_if_not_object (item_p[0]);
+  item_p[0] = ECMA_VALUE_ARRAY_HOLE;
+
+  if ((item_p - chunk_p->items) < ECMA_MAP_OBJECT_ITEM_COUNT - 1)
+  {
+    JERRY_ASSERT (!ecma_is_value_pointer (item_p[1]));
+
+    ecma_free_value_if_not_object (item_p[1]);
+    item_p[1] = ECMA_VALUE_ARRAY_HOLE;
+
+    ecma_op_map_delete_chunk (map_object_p, chunk_p, prev_chunk_p);
+    return ECMA_VALUE_TRUE;
+  }
+
+  ecma_map_object_chunk_t *next_chunk_p = ecma_op_map_delete_chunk (map_object_p, chunk_p, prev_chunk_p);
+
+  if (next_chunk_p == NULL)
+  {
+    prev_chunk_p = chunk_p;
+
+    ecma_value_t next_chunk = chunk_p->items[ECMA_MAP_OBJECT_ITEM_COUNT];
+    next_chunk_p = (ecma_map_object_chunk_t *) ecma_get_pointer_from_value (next_chunk);
+  }
+
+  ecma_free_value_if_not_object (next_chunk_p->items[0]);
+  next_chunk_p->items[0] = ECMA_VALUE_ARRAY_HOLE;
+
+  ecma_op_map_delete_chunk (map_object_p, next_chunk_p, prev_chunk_p);
+
+  return ECMA_VALUE_TRUE;
+} /* ecma_op_map_delete */
+
+/**
+ * @}
+ * @}
+ */
+
+#endif /* !CONFIG_DISABLE_ES2015_MAP_BUILTIN */
diff --git a/deps/jerry/jerry-core/ecma/operations/ecma-map-object.h b/deps/jerry/jerry-core/ecma/operations/ecma-map-object.h
new file mode 100644 (file)
index 0000000..fd3ddba
--- /dev/null
@@ -0,0 +1,46 @@
+/* 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_MAP_OBJECT_H
+#define ECMA_MAP_OBJECT_H
+
+#include "ecma-globals.h"
+
+#ifndef CONFIG_DISABLE_ES2015_MAP_BUILTIN
+
+/** \addtogroup ecma ECMA
+ * @{
+ *
+ * \addtogroup ecmamaphelpers ECMA builtin map helper functions
+ * @{
+ */
+
+ecma_value_t ecma_op_map_create (const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len);
+ecma_value_t ecma_op_map_size (ecma_value_t this_arg);
+ecma_value_t ecma_op_map_get (ecma_value_t this_arg, ecma_value_t key_arg);
+ecma_value_t ecma_op_map_has (ecma_value_t this_arg, ecma_value_t key_arg);
+ecma_value_t ecma_op_map_set (ecma_value_t this_arg, ecma_value_t key_arg, ecma_value_t value_arg);
+void ecma_op_map_clear_map (ecma_map_object_t *map_object_p);
+ecma_value_t ecma_op_map_clear (ecma_value_t this_arg);
+ecma_value_t ecma_op_map_delete (ecma_value_t this_arg, ecma_value_t key_arg);
+
+/**
+ * @}
+ * @}
+ */
+
+#endif /* !CONFIG_DISABLE_ES2015_MAP_BUILTIN */
+
+#endif /* !ECMA_MAP_OBJECT_H */
index bb09f0f158de41bc8fa8496e20126d5a41d7c25b..346f69f3089a199e7dc294040090bfa2907e6710 100644 (file)
@@ -58,8 +58,6 @@ ecma_op_create_number_object (ecma_value_t arg) /**< argument passed to the Numb
                                                 sizeof (ecma_extended_object_t),
                                                 ECMA_OBJECT_TYPE_CLASS);
 
-  ecma_deref_object (prototype_obj_p);
-
   ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
   ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_NUMBER_UL;
 
index 031862603522f01bd6b8283227a903b34c766c55..b87724c78fce88d3fea67e9dab17eb4a3cd08d39 100644 (file)
@@ -20,7 +20,6 @@
 #include "ecma-gc.h"
 #include "ecma-globals.h"
 #include "ecma-helpers.h"
-#include "ecma-lcache.h"
 #include "ecma-lex-env.h"
 #include "ecma-objects.h"
 #include "ecma-objects-arguments.h"
@@ -110,8 +109,6 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
     ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_ARGUMENTS_UL;
   }
 
-  ecma_deref_object (prototype_p);
-
   ecma_property_value_t *prop_value_p;
 
   /* 11.a, 11.b */
@@ -183,8 +180,6 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
                                                      &prop_desc,
                                                      false);
     JERRY_ASSERT (ecma_is_value_true (completion));
-
-    ecma_deref_object (thrower_p);
   }
 
   ecma_string_t *arguments_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ARGUMENTS);
index 3f90af41cbad4ccd9b17ca2ad966877cb7d52959..7ebe6b2fd9f6813e7087100ae2042768a968816b 100644 (file)
@@ -62,11 +62,7 @@ ecma_op_create_object_object_noarg (void)
   ecma_object_t *object_prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
 
   /* 3., 4., 6., 7. */
-  ecma_object_t *obj_p = ecma_op_create_object_object_noarg_and_set_prototype (object_prototype_p);
-
-  ecma_deref_object (object_prototype_p);
-
-  return obj_p;
+  return ecma_op_create_object_object_noarg_and_set_prototype (object_prototype_p);
 } /* ecma_op_create_object_object_noarg */
 
 /**
@@ -169,18 +165,15 @@ ecma_op_general_object_delete (ecma_object_t *obj_p, /**< the object */
     /* b. */
     return ECMA_VALUE_TRUE;
   }
-  else if (is_throw)
+
+  /* 4. */
+  if (is_throw)
   {
-    /* 4. */
     return ecma_raise_type_error (ECMA_ERR_MSG ("Expected a configurable property."));
   }
-  else
-  {
-    /* 5. */
-    return ECMA_VALUE_FALSE;
-  }
 
-  JERRY_UNREACHABLE ();
+  /* 5. */
+  return ECMA_VALUE_FALSE;
 } /* ecma_op_general_object_delete */
 
 /**
@@ -431,10 +424,10 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
   {
     /* No action required. */
   }
-  else if (likely (property_desc_type == current_property_type))
+  else if (JERRY_LIKELY (property_desc_type == current_property_type))
   {
     /* If property is configurable, there is no need for checks. */
-    if (unlikely (!is_current_configurable))
+    if (JERRY_UNLIKELY (!is_current_configurable))
     {
       if (property_desc_type == ECMA_PROPERTY_TYPE_NAMEDDATA)
       {
index d535d4b6a20d98a34fc1cb1711915ca3ce5c5167..5e30fe04989ca85f68fe8ebb7c380a5dc93cedc5 100644 (file)
@@ -20,7 +20,6 @@
 #include "ecma-gc.h"
 #include "ecma-globals.h"
 #include "ecma-function-object.h"
-#include "ecma-lcache.h"
 #include "ecma-lex-env.h"
 #include "ecma-string-object.h"
 #include "ecma-objects-arguments.h"
@@ -264,29 +263,27 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
     {
       uint32_t index = ecma_string_get_array_index (property_name_p);
 
-      if (index != ECMA_STRING_NOT_ARRAY_INDEX)
+      if (index != ECMA_STRING_NOT_ARRAY_INDEX
+          && index < ext_object_p->u.pseudo_array.u1.length)
       {
-        if (index < ext_object_p->u.pseudo_array.u1.length)
-        {
-          ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1);
+        ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1);
 
-          if (arg_Literal_p[index] != ECMA_VALUE_EMPTY)
-          {
-            ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_Literal_p[index]);
+        if (arg_Literal_p[index] != ECMA_VALUE_EMPTY)
+        {
+          ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_Literal_p[index]);
 
-            ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
-                                                                        ext_object_p->u.pseudo_array.u2.lex_env_cp);
+          ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
+                                                                      ext_object_p->u.pseudo_array.u2.lex_env_cp);
 
-            JERRY_ASSERT (lex_env_p != NULL
-                          && ecma_is_lexical_environment (lex_env_p));
+          JERRY_ASSERT (lex_env_p != NULL
+                        && ecma_is_lexical_environment (lex_env_p));
 
-            ecma_value_t binding_value = ecma_op_get_binding_value (lex_env_p, arg_name_p, true);
+          ecma_value_t binding_value = ecma_op_get_binding_value (lex_env_p, arg_name_p, true);
 
-            ecma_named_data_property_assign_value (object_p,
-                                                   ECMA_PROPERTY_VALUE_PTR (property_p),
-                                                   binding_value);
-            ecma_free_value (binding_value);
-          }
+          ecma_named_data_property_assign_value (object_p,
+                                                 ECMA_PROPERTY_VALUE_PTR (property_p),
+                                                 binding_value);
+          ecma_free_value (binding_value);
         }
       }
     }
@@ -314,7 +311,7 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
  * @return pointer to a property - if it exists,
  *         NULL (i.e. ecma-undefined) - otherwise.
  */
-ecma_property_t
+static ecma_property_t
 ecma_op_object_get_property (ecma_object_t *object_p, /**< the object */
                              ecma_string_t *property_name_p, /**< property name */
                              ecma_property_ref_t *property_ref_p, /**< property reference */
@@ -353,7 +350,7 @@ ecma_op_object_get_property (ecma_object_t *object_p, /**< the object */
  * @return true - if property is found
  *         false - otherwise
  */
-inline bool __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_op_object_has_own_property (ecma_object_t *object_p, /**< the object */
                                  ecma_string_t *property_name_p) /**< property name */
 {
@@ -371,7 +368,7 @@ ecma_op_object_has_own_property (ecma_object_t *object_p, /**< the object */
  * @return true - if property is found
  *         false - otherwise
  */
-inline bool __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_op_object_has_property (ecma_object_t *object_p, /**< the object */
                              ecma_string_t *property_name_p) /**< property name */
 {
@@ -456,24 +453,22 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */
       {
         uint32_t index = ecma_string_get_array_index (property_name_p);
 
-        if (index != ECMA_STRING_NOT_ARRAY_INDEX)
+        if (index != ECMA_STRING_NOT_ARRAY_INDEX
+            && index < ext_object_p->u.pseudo_array.u1.length)
         {
-          if (index < ext_object_p->u.pseudo_array.u1.length)
-          {
-            ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1);
+          ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1);
 
-            if (arg_Literal_p[index] != ECMA_VALUE_EMPTY)
-            {
-              ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_Literal_p[index]);
+          if (arg_Literal_p[index] != ECMA_VALUE_EMPTY)
+          {
+            ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_Literal_p[index]);
 
-              ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
-                                                                          ext_object_p->u.pseudo_array.u2.lex_env_cp);
+            ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
+                                                                        ext_object_p->u.pseudo_array.u2.lex_env_cp);
 
-              JERRY_ASSERT (lex_env_p != NULL
-                            && ecma_is_lexical_environment (lex_env_p));
+            JERRY_ASSERT (lex_env_p != NULL
+                          && ecma_is_lexical_environment (lex_env_p));
 
-              return ecma_op_get_binding_value (lex_env_p, arg_name_p, true);
-            }
+            return ecma_op_get_binding_value (lex_env_p, arg_name_p, true);
           }
         }
       }
@@ -639,7 +634,7 @@ ecma_op_object_find (ecma_object_t *object_p, /**< the object */
  * @return ecma value
  *         Returned value must be freed with ecma_free_value
  */
-inline ecma_value_t __attr_always_inline___
+inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
 ecma_op_object_get_own_data_prop (ecma_object_t *object_p, /**< the object */
                                   ecma_string_t *property_name_p) /**< property name */
 {
@@ -718,7 +713,7 @@ ecma_op_object_get (ecma_object_t *object_p, /**< the object */
  * @return ecma value
  *         Returned value must be freed with ecma_free_value
  */
-inline ecma_value_t __attr_always_inline___
+inline ecma_value_t JERRY_ATTR_ALWAYS_INLINE
 ecma_op_object_get_by_magic_id (ecma_object_t *object_p, /**< the object */
                                 lit_magic_string_id_t property_id) /**< property magic string id */
 {
@@ -781,25 +776,23 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */
       {
         uint32_t index = ecma_string_get_array_index (property_name_p);
 
-        if (index != ECMA_STRING_NOT_ARRAY_INDEX)
+        if (index != ECMA_STRING_NOT_ARRAY_INDEX
+            && index < ext_object_p->u.pseudo_array.u1.length)
         {
-          if (index < ext_object_p->u.pseudo_array.u1.length)
-          {
-            ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1);
+          ecma_value_t *arg_Literal_p = (ecma_value_t *) (ext_object_p + 1);
 
-            if (arg_Literal_p[index] != ECMA_VALUE_EMPTY)
-            {
-              ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_Literal_p[index]);
+          if (arg_Literal_p[index] != ECMA_VALUE_EMPTY)
+          {
+            ecma_string_t *arg_name_p = ecma_get_string_from_value (arg_Literal_p[index]);
 
-              ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
-                                                                          ext_object_p->u.pseudo_array.u2.lex_env_cp);
+            ecma_object_t *lex_env_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
+                                                                        ext_object_p->u.pseudo_array.u2.lex_env_cp);
 
-              JERRY_ASSERT (lex_env_p != NULL
-                            && ecma_is_lexical_environment (lex_env_p));
+            JERRY_ASSERT (lex_env_p != NULL
+                          && ecma_is_lexical_environment (lex_env_p));
 
-              ecma_op_set_mutable_binding (lex_env_p, arg_name_p, value, true);
-              return ECMA_VALUE_TRUE;
-            }
+            ecma_op_set_mutable_binding (lex_env_p, arg_name_p, value, true);
+            return ECMA_VALUE_TRUE;
           }
         }
       }
@@ -954,10 +947,8 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */
           return ecma_builtin_helper_def_prop (object_p,
                                                property_name_p,
                                                value,
-                                               true, /* Writable */
-                                               true, /* Enumerable */
-                                               true, /* Configurable */
-                                               is_throw); /* Failure handling */
+                                               ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
+                                               true); /* Failure handling */
         }
       }
 
@@ -1136,18 +1127,24 @@ ecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */
                                                        is_throw);
     }
 
-    case ECMA_OBJECT_TYPE_PSEUDO_ARRAY:
+    default:
     {
+      JERRY_ASSERT (type == ECMA_OBJECT_TYPE_PSEUDO_ARRAY);
+
       ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
 
+#ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
       if (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS)
       {
+#else /* CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
+        JERRY_ASSERT (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS);
+#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
         return ecma_op_arguments_object_define_own_property (obj_p,
                                                              property_name_p,
                                                              property_desc_p,
                                                              is_throw);
-      }
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
+      }
       /* ES2015 9.4.5.3 */
       if (ecma_is_typedarray (ecma_make_object_value (obj_p)))
       {
@@ -1184,19 +1181,10 @@ ecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */
                                                          property_name_p,
                                                          property_desc_p,
                                                          is_throw);
-
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
       break;
     }
-    default:
-    {
-      JERRY_ASSERT (false);
-    }
   }
-
-  JERRY_UNREACHABLE ();
-
-  return ecma_reject (is_throw);
 } /* ecma_op_object_define_own_property */
 
 /**
@@ -1281,6 +1269,9 @@ ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, /**< the ob
  *
  * See also:
  *          ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 9
+ *
+ * @return ecma value containing a boolean value or an error
+ *         Returned value must be freed with ecma_free_value
  */
 ecma_value_t
 ecma_op_object_has_instance (ecma_object_t *obj_p, /**< the object */
@@ -1346,11 +1337,7 @@ ecma_op_object_is_prototype_of (ecma_object_t *base_p, /**< base object */
  */
 ecma_collection_header_t *
 ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
-                                   bool is_array_indices_only, /**< true - exclude properties with names
-                                                                *          that are not indices */
-                                   bool is_enumerable_only, /**< true - exclude non-enumerable properties */
-                                   bool is_with_prototype_chain) /**< true - list properties from prototype chain,
-                                                                  *   false - list only own properties */
+                                   uint32_t opts) /**< any combination of ecma_list_properties_options_t values  */
 {
   JERRY_ASSERT (obj_p != NULL
                 && !ecma_is_lexical_environment (obj_p));
@@ -1360,11 +1347,15 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
 
   const ecma_object_type_t type = ecma_get_object_type (obj_p);
   const bool obj_is_builtin = ecma_get_object_is_builtin (obj_p);
+  const bool is_enumerable_only = (const bool) (opts & ECMA_LIST_ENUMERABLE);
+  const bool is_array_indices_only = (const bool) (opts & ECMA_LIST_ARRAY_INDICES);
+  const bool is_with_prototype_chain = (const bool) (opts & ECMA_LIST_PROTOTYPE);
 
   const size_t bitmap_row_size = sizeof (uint32_t) * JERRY_BITSINBYTE;
-  uint32_t names_hashes_bitmap[ECMA_OBJECT_HASH_BITMAP_SIZE / bitmap_row_size];
+  const size_t names_hashes_bitmap_size = ECMA_OBJECT_HASH_BITMAP_SIZE / bitmap_row_size;
+  JERRY_VLA (uint32_t, names_hashes_bitmap, names_hashes_bitmap_size);
 
-  memset (names_hashes_bitmap, 0, sizeof (names_hashes_bitmap));
+  memset (names_hashes_bitmap, 0, names_hashes_bitmap_size * sizeof (names_hashes_bitmap[0]));
 
   for (ecma_object_t *prototype_chain_iter_p = obj_p;
        prototype_chain_iter_p != NULL;
@@ -1387,10 +1378,6 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
     {
       switch (type)
       {
-        case ECMA_OBJECT_TYPE_GENERAL:
-        {
-          break;
-        }
         case ECMA_OBJECT_TYPE_PSEUDO_ARRAY:
         {
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
@@ -1450,7 +1437,8 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
         }
         default:
         {
-          JERRY_UNREACHABLE ();
+          JERRY_ASSERT (type == ECMA_OBJECT_TYPE_GENERAL);
+
           break;
         }
       }
@@ -1458,8 +1446,9 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
 
     ecma_value_t *ecma_value_p = ecma_collection_iterator_init (prop_names_p);
 
-    uint32_t own_names_hashes_bitmap[ECMA_OBJECT_HASH_BITMAP_SIZE / bitmap_row_size];
-    memset (own_names_hashes_bitmap, 0, sizeof (own_names_hashes_bitmap));
+    const size_t own_names_hashes_bitmap_size = ECMA_OBJECT_HASH_BITMAP_SIZE / bitmap_row_size;
+    JERRY_VLA (uint32_t, own_names_hashes_bitmap, own_names_hashes_bitmap_size);
+    memset (own_names_hashes_bitmap, 0, own_names_hashes_bitmap_size * sizeof (own_names_hashes_bitmap[0]));
 
     while (ecma_value_p != NULL)
     {
@@ -1729,6 +1718,9 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
 
 /**
  * The function is used in the assert of ecma_object_get_class_name
+ *
+ * @return true  - if class name is an object
+ *         false - otherwise
  */
 inline static bool
 ecma_object_check_class_name_is_object (ecma_object_t *obj_p) /**< object */
@@ -1779,7 +1771,7 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */
     case ECMA_OBJECT_TYPE_CLASS:
     {
       ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
-      return ext_object_p->u.class_prop.class_id;
+      return (lit_magic_string_id_t) ext_object_p->u.class_prop.class_id;
     }
     case ECMA_OBJECT_TYPE_PSEUDO_ARRAY:
     {
@@ -1787,24 +1779,21 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */
 
       switch (ext_obj_p->u.pseudo_array.type)
       {
-        case ECMA_PSEUDO_ARRAY_ARGUMENTS:
-        {
-          return LIT_MAGIC_STRING_ARGUMENTS_UL;
-        }
 #ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
         case ECMA_PSEUDO_ARRAY_TYPEDARRAY:
         case ECMA_PSEUDO_ARRAY_TYPEDARRAY_WITH_INFO:
         {
-          return ext_obj_p->u.pseudo_array.u1.class_id;
+          return (lit_magic_string_id_t) ext_obj_p->u.pseudo_array.u1.class_id;
         }
 #endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
         default:
         {
-          JERRY_UNREACHABLE ();
+          JERRY_ASSERT (ext_obj_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS);
+
+          return LIT_MAGIC_STRING_ARGUMENTS_UL;
         }
       }
 
-      JERRY_UNREACHABLE ();
       break;
     }
     case ECMA_OBJECT_TYPE_FUNCTION:
@@ -1872,7 +1861,7 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */
  * @return value of the object if the class matches
  *         ECMA_VALUE_NOT_FOUND otherwise
  */
-inline bool __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_object_class_is (ecma_object_t *object_p, /**< object */
                       uint32_t class_id) /**< class id */
 {
index 92e932ebae9666976823d4f2686cc55e8330d744..76ca231712ed781a83abfcdd00723daa0b9c8188 100644 (file)
@@ -28,8 +28,6 @@
 
 ecma_property_t ecma_op_object_get_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p,
                                                  ecma_property_ref_t *property_ref_p, uint32_t options);
-ecma_property_t ecma_op_object_get_property (ecma_object_t *object_p, ecma_string_t *property_name_p,
-                                             ecma_property_ref_t *property_ref_p, uint32_t options);
 bool ecma_op_object_has_own_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
 bool ecma_op_object_has_property (ecma_object_t *object_p, ecma_string_t *property_name_p);
 ecma_value_t ecma_op_object_find_own (ecma_value_t base_value, ecma_object_t *object_p, ecma_string_t *property_name_p);
@@ -47,8 +45,7 @@ bool ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, ecma_s
                                                  ecma_property_descriptor_t *prop_desc_p);
 ecma_value_t ecma_op_object_has_instance (ecma_object_t *obj_p, ecma_value_t value);
 bool ecma_op_object_is_prototype_of (ecma_object_t *base_p, ecma_object_t *target_p);
-ecma_collection_header_t * ecma_op_object_get_property_names (ecma_object_t *obj_p, bool is_array_indices_only,
-                                                              bool is_enumerable_only, bool is_with_prototype_chain);
+ecma_collection_header_t * ecma_op_object_get_property_names (ecma_object_t *obj_p, uint32_t opts);
 
 lit_magic_string_id_t ecma_object_get_class_name (ecma_object_t *obj_p);
 bool ecma_object_class_is (ecma_object_t *object_p, uint32_t class_id);
index f6415d543ed7ca6110847f6810a9a6ce01a01e9a..1ae1c109fef6d97cf2be731e4b3aea7203194626 100644 (file)
@@ -41,7 +41,7 @@
  * @return true - if the object is a promise.
  *         false - otherwise.
  */
-inline bool __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 ecma_is_promise (ecma_object_t *obj_p) /**< points to object */
 {
   return ecma_object_class_is (obj_p, LIT_MAGIC_STRING_PROMISE_UL);
@@ -53,7 +53,7 @@ ecma_is_promise (ecma_object_t *obj_p) /**< points to object */
  * @return ecma value of the promise result.
  *         Returned value must be freed with ecma_free_value
  */
-inline ecma_value_t
+static inline ecma_value_t
 ecma_promise_get_result (ecma_object_t *obj_p) /**< points to promise object */
 {
   JERRY_ASSERT (ecma_is_promise (obj_p));
@@ -66,7 +66,7 @@ ecma_promise_get_result (ecma_object_t *obj_p) /**< points to promise object */
 /**
  * Set the PromiseResult of promise.
  */
-inline void __attr_always_inline___
+static inline void JERRY_ATTR_ALWAYS_INLINE
 ecma_promise_set_result (ecma_object_t *obj_p, /**< points to promise object */
                          ecma_value_t result) /**< the result value */
 {
@@ -84,7 +84,7 @@ ecma_promise_set_result (ecma_object_t *obj_p, /**< points to promise object */
  *
  * @return the state's enum value
  */
-inline uint8_t __attr_always_inline___
+static inline uint8_t JERRY_ATTR_ALWAYS_INLINE
 ecma_promise_get_state (ecma_object_t *obj_p) /**< points to promise object */
 {
   JERRY_ASSERT (ecma_is_promise (obj_p));
@@ -95,7 +95,7 @@ ecma_promise_get_state (ecma_object_t *obj_p) /**< points to promise object */
 /**
  * Set the PromiseState of promise.
  */
-inline void __attr_always_inline___
+static inline void JERRY_ATTR_ALWAYS_INLINE
 ecma_promise_set_state (ecma_object_t *obj_p, /**< points to promise object */
                         uint8_t state) /**< the state */
 {
@@ -119,7 +119,7 @@ ecma_get_already_resolved_bool_value (ecma_value_t already_resolved) /**< the al
 
   JERRY_ASSERT (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_BOOLEAN_UL);
 
-  return ext_object_p->u.class_prop.u.value == ecma_make_boolean_value (true);
+  return ext_object_p->u.class_prop.u.value == ECMA_VALUE_TRUE;
 } /* ecma_get_already_resolved_bool_value */
 
 /**
@@ -155,8 +155,6 @@ ecma_promise_trigger_reactions (ecma_collection_header_t *reactions, /**< lists
     ecma_enqueue_promise_reaction_job (*ecma_value_p, value);
     ecma_value_p = ecma_collection_iterator_next (ecma_value_p);
   }
-
-  ecma_free_values_collection (reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
 } /* ecma_promise_trigger_reactions */
 
 /**
@@ -180,12 +178,15 @@ ecma_reject_promise (ecma_value_t promise, /**< promise */
      first and creating a new one might cause a heap after use event. */
   ecma_collection_header_t *reject_reactions = promise_p->reject_reactions;
   ecma_collection_header_t *fulfill_reactions = promise_p->fulfill_reactions;
+
+  /* Fulfill reactions will never be triggered. */
+  ecma_promise_trigger_reactions (reject_reactions, reason);
+
   promise_p->reject_reactions = ecma_new_values_collection ();
   promise_p->fulfill_reactions = ecma_new_values_collection ();
 
-  /* Fulfill reactions will never be triggered. */
+  ecma_free_values_collection (reject_reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
   ecma_free_values_collection (fulfill_reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
-  ecma_promise_trigger_reactions (reject_reactions, reason);
 } /* ecma_reject_promise */
 
 /**
@@ -209,12 +210,15 @@ ecma_fulfill_promise (ecma_value_t promise, /**< promise */
      first and creating a new one might cause a heap after use event. */
   ecma_collection_header_t *reject_reactions = promise_p->reject_reactions;
   ecma_collection_header_t *fulfill_reactions = promise_p->fulfill_reactions;
+
+  /* Reject reactions will never be triggered. */
+  ecma_promise_trigger_reactions (fulfill_reactions, value);
+
   promise_p->reject_reactions = ecma_new_values_collection ();
   promise_p->fulfill_reactions = ecma_new_values_collection ();
 
-  /* Reject reactions will never be triggered. */
   ecma_free_values_collection (reject_reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
-  ecma_promise_trigger_reactions (fulfill_reactions, value);
+  ecma_free_values_collection (fulfill_reactions, ECMA_COLLECTION_NO_REF_OBJECTS);
 } /* ecma_fulfill_promise */
 
 /**
@@ -362,9 +366,9 @@ ecma_call_builtin_executor (ecma_object_t *executor_p, /**< the executor object
                             ecma_value_t resolve_func, /**< the resolve function */
                             ecma_value_t reject_func) /**< the reject function */
 {
-  ecma_string_t *capability_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_CAPABILITY);
-  ecma_string_t *resolve_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_RESOLVE);
-  ecma_string_t *reject_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT);
+  ecma_string_t *capability_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_CAPABILITY);
+  ecma_string_t *resolve_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_RESOLVE);
+  ecma_string_t *reject_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REJECT);
 
   /* 2. */
   ecma_value_t capability = ecma_op_object_get (executor_p, capability_str_p);
@@ -417,7 +421,7 @@ ecma_promise_resolving_functions_t *
 ecma_promise_create_resolving_functions (ecma_object_t *object_p) /**< the promise object */
 {
   /* 1. */
-  ecma_value_t already_resolved = ecma_op_create_boolean_object (ecma_make_boolean_value (false));
+  ecma_value_t already_resolved = ecma_op_create_boolean_object (ECMA_VALUE_FALSE);
 
   ecma_string_t *str_promise_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE);
   ecma_string_t *str_already_resolved_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED);
@@ -488,7 +492,6 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
   ecma_object_t *object_p = ecma_create_object (prototype_obj_p,
                                                 sizeof (ecma_promise_object_t),
                                                 ECMA_OBJECT_TYPE_CLASS);
-  ecma_deref_object (prototype_obj_p);
   ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
   ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_PROMISE_UL;
   ext_object_p->u.class_prop.u.value = ECMA_VALUE_UNDEFINED;
@@ -585,8 +588,8 @@ ecma_promise_new_capability (void)
   /* 3. */
   ecma_object_t *capability_p = ecma_op_create_object_object_noarg ();
 
-  ecma_string_t *capability_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_CAPABILITY);
-  ecma_string_t *promise_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_PROMISE);
+  ecma_string_t *capability_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_CAPABILITY);
+  ecma_string_t *promise_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_PROMISE);
   /* 4. */
   ecma_object_t *executor_p;
   executor_p = ecma_op_create_object_object_noarg ();
@@ -618,7 +621,7 @@ ecma_promise_new_capability (void)
 
   ecma_free_value (promise);
   /* 8. */
-  ecma_string_t *resolve_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_RESOLVE);
+  ecma_string_t *resolve_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_RESOLVE);
   ecma_value_t resolve = ecma_op_object_get (capability_p, resolve_str_p);
 
   if (!ecma_op_is_callable (resolve))
@@ -630,7 +633,7 @@ ecma_promise_new_capability (void)
 
   ecma_free_value (resolve);
   /* 9. */
-  ecma_string_t *reject_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT);
+  ecma_string_t *reject_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REJECT);
   ecma_value_t reject = ecma_op_object_get (capability_p, reject_str_p);
 
   if (!ecma_op_is_callable (reject))
@@ -660,20 +663,20 @@ ecma_promise_do_then (ecma_value_t promise, /**< the promise which call 'then' *
                       ecma_value_t on_rejected, /**< on_rejected function */
                       ecma_value_t result_capability) /**< promise capability */
 {
-  ecma_string_t *capability_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_CAPABILITY);
-  ecma_string_t *handler_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_HANDLER);
-  ecma_string_t *promise_str_p = ecma_get_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_PROMISE);
+  ecma_string_t *capability_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_CAPABILITY);
+  ecma_string_t *handler_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_HANDLER);
+  ecma_string_t *promise_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_PROMISE);
 
   /* 3. boolean true indicates "indentity" */
   if (!ecma_op_is_callable (on_fulfilled))
   {
-    on_fulfilled = ecma_make_boolean_value (true);
+    on_fulfilled = ECMA_VALUE_TRUE;
   }
 
   /* 4. boolean false indicates "thrower" */
   if (!ecma_op_is_callable (on_rejected))
   {
-    on_rejected = ecma_make_boolean_value (false);
+    on_rejected = ECMA_VALUE_FALSE;
   }
 
   /* 5-6. */
index d688be1dc1402847f1550c12191bc33e75f88d67..ce82abe3c2fcf8b5ea6351f77670e8e3d3aa92a4 100644 (file)
@@ -68,28 +68,7 @@ typedef struct
   ecma_collection_header_t *reject_reactions; /**< list of PromiseRejectReactions */
 } ecma_promise_object_t;
 
-/**
- * Use symbolic constant to represent the internal property name of
- * promise related structures.
- */
-typedef enum
-{
-  ECMA_PROMISE_PROPERTY_PROMISE, /**< [[Promise]] property */
-  ECMA_PROMISE_PROPERTY_RESOLVE, /**< [[Resolve]] property */
-  ECMA_PROMISE_PROPERTY_REJECT, /**< [[Reject]] property */
-  ECMA_PROMISE_PROPERTY_CAPABILITY, /**< [[Capability]] property */
-  ECMA_PROMISE_PROPERTY_HANDLER, /**< [[Handler]] property */
-  ECMA_PROMISE_PROPERTY_ALREADY_CALLED, /**< [[AlreadyCalled]] property */
-  ECMA_PROMISE_PROPERTY_INDEX, /**< [[Index]] property */
-  ECMA_PROMISE_PROPERTY_VALUE, /**< [[Values]] property */
-  ECMA_PROMISE_PROPERTY_REMAINING_ELEMENT /**< [[RemainingElement]] property */
-} ecma_promise_property_symbolic_constant_t;
-
 bool ecma_is_promise (ecma_object_t *obj_p);
-ecma_value_t ecma_promise_get_result (ecma_object_t *obj_p);
-void ecma_promise_set_result (ecma_object_t *obj_p, ecma_value_t result);
-uint8_t ecma_promise_get_state (ecma_object_t *obj_p);
-void ecma_promise_set_state (ecma_object_t *obj_p, uint8_t state);
 ecma_value_t
 ecma_op_create_promise_object (ecma_value_t executor, ecma_promise_executor_type_t type);
 ecma_value_t ecma_promise_new_capability (void);
index b64070e22da87bcf7406628adb90a9f3fc624275..a2efd32e6aa6076089ee2382accf0b775bc03d5d 100644 (file)
@@ -59,6 +59,29 @@ ecma_op_resolve_reference_base (ecma_object_t *lex_env_p, /**< starting lexical
   return NULL;
 } /* ecma_op_resolve_reference_base */
 
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+/**
+ * Resolve super reference.
+ *
+ * @return value of the reference
+ */
+ecma_object_t *
+ecma_op_resolve_super_reference_value (ecma_object_t *lex_env_p) /**< starting lexical environment */
+{
+  while (true)
+  {
+    JERRY_ASSERT (lex_env_p != NULL);
+
+    if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND)
+    {
+      return ecma_get_lex_env_binding_object (lex_env_p);
+    }
+
+    lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
+  }
+} /* ecma_op_resolve_super_reference_value */
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
 /**
  * Resolve value corresponding to reference.
  *
@@ -72,7 +95,9 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical
 
   while (lex_env_p != NULL)
   {
-    if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
+    ecma_lexical_environment_type_t lex_env_type = ecma_get_lex_env_type (lex_env_p);
+
+    if (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
     {
       ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
 
@@ -81,13 +106,11 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical
         return ecma_fast_copy_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
       }
     }
-    else
+    else if (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND)
     {
-      JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECT_BOUND
-                    || ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
-
       ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
 
+#ifndef CONFIG_ECMA_LCACHE_DISABLE
       ecma_property_t *property_p = ecma_lcache_lookup (binding_obj_p, name_p);
 
       if (property_p != NULL)
@@ -111,6 +134,7 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical
         ecma_value_t base_value = ecma_make_object_value (binding_obj_p);
         return ecma_op_function_call (getter_p, base_value, NULL, 0);
       }
+#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
 
       ecma_value_t prop_value = ecma_op_object_find (binding_obj_p, name_p);
 
@@ -119,6 +143,14 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical
         return prop_value;
       }
     }
+    else
+    {
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+      JERRY_ASSERT (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND);
+#else /* CONFIG_DISABLE_ES2015_CLASS */
+      JERRY_UNREACHABLE ();
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+    }
 
     lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
   }
index e05934117c4575af816ea6d0dfea72147beac09d..3ffefcadfea99fc251c7d55f5e51c35602ddd754 100644 (file)
@@ -28,6 +28,9 @@
 
 ecma_object_t *ecma_op_resolve_reference_base (ecma_object_t *lex_env_p, ecma_string_t *name_p);
 ecma_value_t ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, ecma_string_t *name_p);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+ecma_object_t *ecma_op_resolve_super_reference_value (ecma_object_t *lex_env_p);
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
 
 /**
  * @}
index 6ab090927b581f28c9a5615aceee519b13689d31..225837987ae3f380cb7954fe3fc586743785af0c 100644 (file)
  *   [n+1] n/2 th group end
  */
 #define RE_GLOBAL_START_IDX 0
+
+/**
+ * @copydoc RE_GLOBAL_START_IDX
+ */
 #define RE_GLOBAL_END_IDX   1
 
 /**
@@ -214,8 +218,6 @@ ecma_op_create_regexp_object_from_bytecode (re_compiled_code_t *bytecode_p) /**<
                                                 sizeof (ecma_extended_object_t),
                                                 ECMA_OBJECT_TYPE_CLASS);
 
-  ecma_deref_object (re_prototype_obj_p);
-
   ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
 
   /* Set the internal [[Class]] property */
@@ -245,31 +247,16 @@ ecma_op_create_regexp_object_from_bytecode (re_compiled_code_t *bytecode_p) /**<
  */
 ecma_value_t
 ecma_op_create_regexp_object (ecma_string_t *pattern_p, /**< input pattern */
-                              ecma_string_t *flags_str_p) /**< flags */
+                              uint16_t flags) /**< flags */
 {
   JERRY_ASSERT (pattern_p != NULL);
   ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-  uint16_t flags = 0;
-
-  if (flags_str_p != NULL)
-  {
-    ECMA_TRY_CATCH (empty, re_parse_regexp_flags (flags_str_p, &flags), ret_value);
-    ECMA_FINALIZE (empty);
-
-    if (!ecma_is_value_empty (ret_value))
-    {
-      return ret_value;
-    }
-  }
 
   ecma_object_t *re_prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE);
 
   ecma_object_t *object_p = ecma_create_object (re_prototype_obj_p,
                                                 sizeof (ecma_extended_object_t),
                                                 ECMA_OBJECT_TYPE_CLASS);
-
-  ecma_deref_object (re_prototype_obj_p);
-
   ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
   ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_UNDEFINED;
 
@@ -302,7 +289,7 @@ ecma_op_create_regexp_object (ecma_string_t *pattern_p, /**< input pattern */
  *
  * @return ecma_char_t canonicalized character
  */
-inline ecma_char_t __attr_always_inline___
+inline ecma_char_t JERRY_ATTR_ALWAYS_INLINE
 re_canonicalize (ecma_char_t ch, /**< character */
                  bool is_ignorecase) /**< IgnoreCase flag */
 {
@@ -360,21 +347,19 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
                  const lit_utf8_byte_t *str_p, /**< input string pointer */
                  const lit_utf8_byte_t **out_str_p) /**< [out] matching substring iterator */
 {
-  ecma_value_t ret_value = ECMA_VALUE_EMPTY;
-  re_opcode_t op;
-
   const lit_utf8_byte_t *str_curr_p = str_p;
 
-  while ((op = re_get_opcode (&bc_p)))
+  while (true)
   {
+    re_opcode_t op = re_get_opcode (&bc_p);
+
     switch (op)
     {
       case RE_OP_MATCH:
       {
         JERRY_TRACE_MSG ("Execute RE_OP_MATCH: match\n");
         *out_str_p = str_curr_p;
-        ret_value = ECMA_VALUE_TRUE;
-        return ret_value; /* match */
+        return ECMA_VALUE_TRUE; /* match */
       }
       case RE_OP_CHAR:
       {
@@ -1082,8 +1067,10 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
         }
         return ECMA_VALUE_FALSE; /* fail */
       }
-      case RE_OP_GREEDY_ITERATOR:
+      default:
       {
+        JERRY_ASSERT (op == RE_OP_GREEDY_ITERATOR);
+
         uint32_t min, max, offset, num_of_iter;
         const lit_utf8_byte_t *sub_str_p = NULL;
 
@@ -1138,16 +1125,8 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
         }
         return ECMA_VALUE_FALSE; /* fail */
       }
-      default:
-      {
-        JERRY_TRACE_MSG ("UNKNOWN opcode (%u)!\n", (unsigned int) op);
-        return ecma_raise_common_error (ECMA_ERR_MSG ("Unknown RegExp opcode."));
-      }
     }
   }
-
-  JERRY_UNREACHABLE ();
-  return ECMA_VALUE_FALSE; /* fail */
 } /* re_match_regexp */
 
 /**
@@ -1163,18 +1142,14 @@ re_set_result_array_properties (ecma_object_t *array_obj_p, /**< result array */
   ecma_builtin_helper_def_prop (array_obj_p,
                                 ecma_get_magic_string (LIT_MAGIC_STRING_INDEX),
                                 ecma_make_int32_value (index),
-                                true, /* Writable */
-                                true, /* Enumerable */
-                                true, /* Configurable */
+                                ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
                                 true); /* Failure handling */
 
   /* Set input property of the result array */
   ecma_builtin_helper_def_prop (array_obj_p,
                                 ecma_get_magic_string (LIT_MAGIC_STRING_INPUT),
                                 ecma_make_string_value (input_str_p),
-                                true, /* Writable */
-                                true, /* Enumerable */
-                                true, /* Configurable */
+                                ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE,
                                 true); /* Failure handling */
 
   /* Set length property of the result array */
@@ -1427,6 +1402,44 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */
   return ret_value;
 } /* ecma_regexp_exec_helper */
 
+/**
+ * Helper function for converting a RegExp pattern parameter to string.
+ *
+ * See also:
+ *         RegExp.compile
+ *         RegExp dispatch call
+ *
+ * @return empty value if success, error value otherwise
+ *         Returned value must be freed with ecma_free_value.
+ */
+ecma_value_t
+ecma_regexp_read_pattern_str_helper (ecma_value_t pattern_arg, /**< the RegExp pattern */
+                                     ecma_string_t **pattern_string_p) /**< [out] ptr to the pattern string ptr */
+{
+  if (!ecma_is_value_undefined (pattern_arg))
+  {
+    ecma_value_t regexp_str_value = ecma_op_to_string (pattern_arg);
+    if (ECMA_IS_VALUE_ERROR (regexp_str_value))
+    {
+      return regexp_str_value;
+    }
+
+    *pattern_string_p = ecma_get_string_from_value (regexp_str_value);
+    if (!ecma_string_is_empty (*pattern_string_p))
+    {
+      ecma_ref_ecma_string (*pattern_string_p);
+    }
+
+    ecma_free_value (regexp_str_value); // must be freed *after* ecma_ref_ecma_string
+  }
+
+  if (!*pattern_string_p || ecma_string_is_empty (*pattern_string_p))
+  {
+    *pattern_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_EMPTY_NON_CAPTURE_GROUP);
+  }
+  return ECMA_VALUE_EMPTY;
+} /* ecma_regexp_read_pattern_str_helper */
+
 /**
  * @}
  * @}
index ccefe993b701f7ee363db9073240437e868f12bc..2035d4dbec294d8da11f044313f9c7fae415d672 100644 (file)
@@ -30,6 +30,8 @@
 
 /**
  * RegExp flags
+ * Note:
+ *      This enum has to be kept in sync with jerry_regexp_flags_t.
  */
 typedef enum
 {
@@ -53,8 +55,9 @@ typedef struct
 } re_matcher_ctx_t;
 
 ecma_value_t ecma_op_create_regexp_object_from_bytecode (re_compiled_code_t *bytecode_p);
-ecma_value_t ecma_op_create_regexp_object (ecma_string_t *pattern_p, ecma_string_t *flags_str_p);
+ecma_value_t ecma_op_create_regexp_object (ecma_string_t *pattern_p, uint16_t flags);
 ecma_value_t ecma_regexp_exec_helper (ecma_value_t regexp_value, ecma_value_t input_string, bool ignore_global);
+ecma_value_t ecma_regexp_read_pattern_str_helper (ecma_value_t pattern_arg, ecma_string_t **pattern_string_p);
 ecma_char_t re_canonicalize (ecma_char_t ch, bool is_ignorecase);
 void re_set_result_array_properties (ecma_object_t *array_obj_p, ecma_string_t *input_str_p, uint32_t num_of_elements,
                                      int32_t index);
index a4a18df1866811e726f9179c225835c6ae6a7448..2384d8a69aece1da38807b2593a8bc28f9c2266a 100644 (file)
@@ -70,8 +70,6 @@ ecma_op_create_string_object (const ecma_value_t *arguments_list_p, /**< list of
                                                 sizeof (ecma_extended_object_t),
                                                 ECMA_OBJECT_TYPE_CLASS);
 
-  ecma_deref_object (prototype_obj_p);
-
   ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
   ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_STRING_UL;
   ext_object_p->u.class_prop.u.value = prim_value;
index b97f1e907d4b21aaafce314538f5624fe7104981..8d01ac089cf5a65ca3c59a0cafeb2fc405c239d4 100644 (file)
@@ -69,7 +69,7 @@
   ecma_number_t num_var; \
   return_value = ecma_get_number (value, &num_var); \
   \
-  if (likely (ecma_is_value_empty (return_value))) \
+  if (JERRY_LIKELY (ecma_is_value_empty (return_value))) \
   {
 
 /**
index 0dce329b44bcd6ea82caa6b7b8bd8b54c3b29cf3..6062555a82aa7e9c0462d52223552c82c5d00c85 100644 (file)
@@ -94,7 +94,6 @@ ecma_get_typedarray_element (lit_utf8_byte_t *src, /**< the location in the inte
     default:
     {
       JERRY_UNREACHABLE ();
-      return 0;
     }
   }
 } /* ecma_get_typedarray_element */
@@ -250,7 +249,7 @@ ecma_typedarray_create_object_with_length (ecma_length_t array_length, /**< leng
                                                 ECMA_OBJECT_TYPE_PSEUDO_ARRAY);
 
   ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
-  ext_object_p->u.pseudo_array.u1.class_id = class_id;
+  ext_object_p->u.pseudo_array.u1.class_id = (uint16_t) class_id;
   ext_object_p->u.pseudo_array.type = ECMA_PSEUDO_ARRAY_TYPEDARRAY;
   ext_object_p->u.pseudo_array.extra_info = element_size_shift;
   ext_object_p->u.pseudo_array.u2.arraybuffer = new_arraybuffer_p;
@@ -258,7 +257,7 @@ ecma_typedarray_create_object_with_length (ecma_length_t array_length, /**< leng
   ecma_free_value (new_arraybuffer_p);
 
   return ecma_make_object_value (object_p);
-} /* !ecma_typedarray_create_object_with_length */
+} /* ecma_typedarray_create_object_with_length */
 
 /**
  * Create a TypedArray object by given buffer, offset, and array_length
@@ -286,7 +285,7 @@ ecma_typedarray_create_object_with_buffer (ecma_object_t *arraybuffer_p, /**< th
   ecma_object_t *object_p = ecma_create_object (proto_p, object_size, ECMA_OBJECT_TYPE_PSEUDO_ARRAY);
 
   ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
-  ext_object_p->u.pseudo_array.u1.class_id = class_id;
+  ext_object_p->u.pseudo_array.u1.class_id = (uint16_t) class_id;
   ext_object_p->u.pseudo_array.type = ECMA_PSEUDO_ARRAY_TYPEDARRAY;
   ext_object_p->u.pseudo_array.extra_info = element_size_shift;
   ext_object_p->u.pseudo_array.u2.arraybuffer = ecma_make_object_value (arraybuffer_p);
@@ -490,7 +489,7 @@ ecma_op_typedarray_from (ecma_value_t items_val, /**< the source array-like obje
  *
  * @return the pointer to the internal arraybuffer
  */
-inline ecma_object_t * __attr_always_inline___
+inline ecma_object_t * JERRY_ATTR_ALWAYS_INLINE
 ecma_typedarray_get_arraybuffer (ecma_object_t *typedarray_p) /**< the pointer to the typedarray object */
 {
   JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (typedarray_p)));
@@ -917,7 +916,7 @@ ecma_op_create_typedarray_with_type_and_length (ecma_object_t *obj_p, /**< Typed
   JERRY_ASSERT (ecma_is_typedarray (ecma_make_object_value (obj_p)));
 
   ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
-  lit_magic_string_id_t class_id = ext_object_p->u.pseudo_array.u1.class_id;
+  lit_magic_string_id_t class_id = (lit_magic_string_id_t) ext_object_p->u.pseudo_array.u1.class_id;
   ecma_object_t *proto_p;
   uint8_t element_size_shift = 0;
 
@@ -985,12 +984,41 @@ ecma_op_create_typedarray_with_type_and_length (ecma_object_t *obj_p, /**< Typed
     }
   }
 
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  ecma_value_t constructor_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_CONSTRUCTOR);
+
+  if (ECMA_IS_VALUE_ERROR (constructor_value)
+      || !ecma_is_value_object (constructor_value)
+      || !ecma_is_constructor (constructor_value))
+  {
+    ecma_free_value (constructor_value);
+    return ecma_raise_type_error (ECMA_ERR_MSG ("object.constructor is not a constructor."));
+  }
+
+  ecma_object_t *constructor_object_p = ecma_get_object_from_value (constructor_value);
+  ecma_value_t constructor_prototype = ecma_op_object_get_by_magic_id (constructor_object_p,
+                                                                       LIT_MAGIC_STRING_PROTOTYPE);
+
+  ecma_deref_object (constructor_object_p);
+
+  if (ECMA_IS_VALUE_ERROR (constructor_prototype))
+  {
+    return constructor_prototype;
+  }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
   ecma_value_t new_obj = ecma_typedarray_create_object_with_length (array_length,
                                                                     proto_p,
                                                                     element_size_shift,
                                                                     class_id);
 
-  ecma_deref_object (proto_p);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  ecma_object_t *constructor_prototype_object_p = ecma_get_object_from_value (constructor_prototype);
+  ecma_object_t *new_obj_p = ecma_get_object_from_value (new_obj);
+  ECMA_SET_POINTER (new_obj_p->prototype_or_outer_reference_cp, constructor_prototype_object_p);
+
+  ecma_deref_object (constructor_prototype_object_p);
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
 
   return new_obj;
 } /* ecma_op_create_typedarray_with_type_and_length */
diff --git a/deps/jerry/jerry-core/include/jerry-api.h b/deps/jerry/jerry-core/include/jerry-api.h
deleted file mode 100644 (file)
index 65b8335..0000000
+++ /dev/null
@@ -1,23 +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_API_H
-#define JERRY_API_H
-
-#pragma message ("using jerry-api.h directly is deprecated, please use jerryscript.h")
-
-#include "jerryscript.h"
-
-#endif /* !JERRY_API_H */
diff --git a/deps/jerry/jerry-core/include/jerry-port.h b/deps/jerry/jerry-core/include/jerry-port.h
deleted file mode 100644 (file)
index fe6bc37..0000000
+++ /dev/null
@@ -1,23 +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_PORT_H
-#define JERRY_PORT_H
-
-#pragma message ("using jerry-port.h directly is deprecated, please use jerryscript-port.h")
-
-#include "jerryscript-port.h"
-
-#endif /* !JERRY_PORT_H */
diff --git a/deps/jerry/jerry-core/include/jerryscript-compiler.h b/deps/jerry/jerry-core/include/jerryscript-compiler.h
new file mode 100644 (file)
index 0000000..726d986
--- /dev/null
@@ -0,0 +1,183 @@
+/* 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 JERRYSCRIPT_COMPILER_H
+#define JERRYSCRIPT_COMPILER_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/** \addtogroup jerry-compiler Jerry compiler compatibility components
+ * @{
+ */
+
+#ifdef __GNUC__
+
+/*
+ * Compiler-specific macros relevant for GCC.
+ */
+#define JERRY_ATTR_ALIGNED(ALIGNMENT) __attribute__((aligned(ALIGNMENT)))
+#define JERRY_ATTR_ALWAYS_INLINE __attribute__((always_inline))
+#define JERRY_ATTR_CONST __attribute__((const))
+#define JERRY_ATTR_DEPRECATED __attribute__((deprecated))
+#define JERRY_ATTR_FORMAT(...) __attribute__((format(__VA_ARGS__)))
+#define JERRY_ATTR_HOT __attribute__((hot))
+#define JERRY_ATTR_NOINLINE __attribute__((noinline))
+#define JERRY_ATTR_NORETURN __attribute__((noreturn))
+#define JERRY_ATTR_PURE __attribute__((pure))
+#define JERRY_ATTR_SECTION(SECTION) __attribute__((section(SECTION)))
+#define JERRY_ATTR_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+
+#define JERRY_LIKELY(x) __builtin_expect(!!(x), 1)
+#define JERRY_UNLIKELY(x) __builtin_expect(!!(x), 0)
+
+#endif /* __GNUC__ */
+
+#ifdef _MSC_VER
+
+/*
+ * Compiler-specific macros relevant for Microsoft Visual C/C++ Compiler.
+ */
+#define JERRY_ATTR_DEPRECATED __declspec(deprecated)
+#define JERRY_ATTR_NOINLINE __declspec(noinline)
+#define JERRY_ATTR_NORETURN __declspec(noreturn)
+
+/*
+ * Microsoft Visual C/C++ Compiler doesn't support for VLA, using _alloca
+ * instead.
+ */
+void * __cdecl _alloca (size_t _Size);
+#define JERRY_VLA(type, name, size) type *name = (type *) (_alloca (sizeof (type) * size))
+
+#endif /* _MSC_VER */
+
+/*
+ * Default empty definitions for all compiler-specific macros. Define any of
+ * these in a guarded block above (e.g., as for GCC) to fine tune compilation
+ * for your own compiler. */
+
+/**
+ * Function attribute to align function to given number of bytes.
+ */
+#ifndef JERRY_ATTR_ALIGNED
+#define JERRY_ATTR_ALIGNED(ALIGNMENT)
+#endif /* !JERRY_ATTR_ALIGNED */
+
+/**
+ * Function attribute to inline function to all call sites.
+ */
+#ifndef JERRY_ATTR_ALWAYS_INLINE
+#define JERRY_ATTR_ALWAYS_INLINE
+#endif /* !JERRY_ATTR_ALWAYS_INLINE */
+
+/**
+ * Function attribute to declare that function has no effect except the return
+ * value and it only depends on parameters.
+ */
+#ifndef JERRY_ATTR_CONST
+#define JERRY_ATTR_CONST
+#endif /* !JERRY_ATTR_CONST */
+
+/**
+ * Function attribute to trigger warning if deprecated function is called.
+ */
+#ifndef JERRY_ATTR_DEPRECATED
+#define JERRY_ATTR_DEPRECATED
+#endif /* !JERRY_ATTR_DEPRECATED */
+
+/**
+ * Function attribute to declare that function is variadic and takes a format
+ * string and some arguments as parameters.
+ */
+#ifndef JERRY_ATTR_FORMAT
+#define JERRY_ATTR_FORMAT(...)
+#endif /* !JERRY_ATTR_FORMAT */
+
+/**
+ * Function attribute to predict that function is a hot spot, and therefore
+ * should be optimized aggressively.
+ */
+#ifndef JERRY_ATTR_HOT
+#define JERRY_ATTR_HOT
+#endif /* !JERRY_ATTR_HOT */
+
+/**
+ * Function attribute not to inline function ever.
+ */
+#ifndef JERRY_ATTR_NOINLINE
+#define JERRY_ATTR_NOINLINE
+#endif /* !JERRY_ATTR_NOINLINE */
+
+/**
+ * Function attribute to declare that function never returns.
+ */
+#ifndef JERRY_ATTR_NORETURN
+#define JERRY_ATTR_NORETURN
+#endif /* !JERRY_ATTR_NORETURN */
+
+/**
+ * Function attribute to declare that function has no effect except the return
+ * value and it only depends on parameters and global variables.
+ */
+#ifndef JERRY_ATTR_PURE
+#define JERRY_ATTR_PURE
+#endif /* !JERRY_ATTR_PURE */
+
+/**
+ * Function attribute to place function in given section.
+ */
+#ifndef JERRY_ATTR_SECTION
+#define JERRY_ATTR_SECTION(SECTION)
+#endif /* !JERRY_ATTR_SECTION */
+
+/**
+ * Function attribute to trigger warning if function's caller doesn't use (e.g.,
+ * check) the return value.
+ */
+#ifndef JERRY_ATTR_WARN_UNUSED_RESULT
+#define JERRY_ATTR_WARN_UNUSED_RESULT
+#endif /* !JERRY_ATTR_WARN_UNUSED_RESULT */
+
+/**
+ * Helper to predict that a condition is likely.
+ */
+#ifndef JERRY_LIKELY
+#define JERRY_LIKELY(x) (x)
+#endif /* !JERRY_LIKELY */
+
+/**
+ * Helper to predict that a condition is unlikely.
+ */
+#ifndef JERRY_UNLIKELY
+#define JERRY_UNLIKELY(x) (x)
+#endif /* !JERRY_UNLIKELY */
+
+/**
+ * Helper to declare (or mimic) a C99 variable-length array.
+ */
+#ifndef JERRY_VLA
+#define JERRY_VLA(type, name, size) type name[size]
+#endif /* !JERRY_VLA */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* !JERRYSCRIPT_COMPILER_H */
index bba7861f7cd2c9cb9b19a6cba53d0c55926852c9..4584db9f148d3453af2b8cea419fb23fe2a0e8fe 100644 (file)
 #include <stddef.h>
 #include <stdint.h>
 
+#include "jerryscript-compiler.h"
+
 #ifdef __cplusplus
 extern "C"
 {
 #endif /* __cplusplus */
 
-#ifdef __GNUC__
-#define JERRY_DEPRECATED_API __attribute__((deprecated))
-#else /* !__GNUC__ */
-/* TODO: for other compilers */
-#define JERRY_DEPRECATED_API
-#endif /* __GNUC__ */
-
 /** \addtogroup jerry Jerry engine interface
  * @{
  */
@@ -96,6 +91,7 @@ typedef enum
   JERRY_FEATURE_DATE, /**< Date support */
   JERRY_FEATURE_REGEXP, /**< Regexp support */
   JERRY_FEATURE_LINE_INFO, /**< line info available */
+  JERRY_FEATURE_LOGGING, /**< logging */
   JERRY_FEATURE__COUNT /**< number of features. NOTE: must be at the end of the list */
 } jerry_feature_t;
 
@@ -105,18 +101,34 @@ typedef enum
 typedef enum
 {
   JERRY_PARSE_NO_OPTS = 0, /**< no options passed */
-  JERRY_PARSE_STRICT_MODE = (1 << 0), /**< enable strict mode */
+  JERRY_PARSE_STRICT_MODE = (1 << 0) /**< enable strict mode */
 } jerry_parse_opts_t;
 
 /**
- * Character type of JerryScript.
+ * GC operational modes.
  */
-typedef uint8_t jerry_char_t;
+typedef enum
+{
+  JERRY_GC_SEVERITY_LOW, /**< free unused objects, but keep memory
+                          *   allocated for performance improvements
+                          *   such as property hash tables for large objects */
+  JERRY_GC_SEVERITY_HIGH /**< free as much memory as possible */
+} jerry_gc_mode_t;
+
+/**
+ * Jerry regexp flags.
+ */
+typedef enum
+{
+  JERRY_REGEXP_FLAG_GLOBAL = (1u << 1),      /**< Globally scan string */
+  JERRY_REGEXP_FLAG_IGNORE_CASE = (1u << 2), /**< Ignore case */
+  JERRY_REGEXP_FLAG_MULTILINE = (1u << 3)    /**< Multiline string scan */
+} jerry_regexp_flags_t;
 
 /**
- * Pointer to an array of character values.
+ * Character type of JerryScript.
  */
-typedef jerry_char_t *jerry_char_ptr_t;
+typedef uint8_t jerry_char_t;
 
 /**
  * Size type of JerryScript.
@@ -196,11 +208,6 @@ typedef jerry_value_t (*jerry_external_handler_t) (const jerry_value_t function_
                                                    const jerry_value_t args_p[],
                                                    const jerry_length_t args_count);
 
-/**
- * Native free callback of an object (deprecated).
- */
-typedef void (*jerry_object_free_callback_t) (const uintptr_t native_p);
-
 /**
  * Native free callback of an object.
  */
@@ -284,9 +291,9 @@ typedef struct
 } jerry_context_data_manager_t;
 
 /**
- * Function type for allocating buffer for JerryScript instance.
+ * Function type for allocating buffer for JerryScript context.
  */
-typedef void *(*jerry_instance_alloc_t) (size_t size, void *cb_data_p);
+typedef void *(*jerry_context_alloc_t) (size_t size, void *cb_data_p);
 
 /**
  * Type information of a native pointer.
@@ -297,19 +304,19 @@ typedef struct
 } jerry_object_native_info_t;
 
 /**
- * A forward declaration of the JerryScript instance structure.
+ * An opaque declaration of the JerryScript context structure.
  */
-typedef struct jerry_instance_t jerry_instance_t;
+typedef struct jerry_context_t jerry_context_t;
 
 /**
  * General engine functions.
  */
 void jerry_init (jerry_init_flag_t flags);
 void jerry_cleanup (void);
-void jerry_register_magic_strings (const jerry_char_ptr_t *ex_str_items_p, uint32_t count,
+void jerry_register_magic_strings (const jerry_char_t * const *ex_str_items_p,
+                                   uint32_t count,
                                    const jerry_length_t *str_lengths_p);
-void jerry_get_memory_limits (size_t *out_data_bss_brk_limit_p, size_t *out_stack_limit_p);
-void jerry_gc (void);
+void jerry_gc (jerry_gc_mode_t mode);
 void *jerry_get_context_data (const jerry_context_data_manager_t *manager_p);
 
 bool jerry_get_memory_stats (jerry_heap_stats_t *out_stats_p);
@@ -324,7 +331,7 @@ jerry_value_t jerry_parse_function (const jerry_char_t *resource_name_p, size_t
                                     const jerry_char_t *arg_list_p, size_t arg_list_size,
                                     const jerry_char_t *source_p, size_t source_size, uint32_t parse_opts);
 jerry_value_t jerry_run (const jerry_value_t func_val);
-jerry_value_t jerry_eval (const jerry_char_t *source_p, size_t source_size, bool is_strict);
+jerry_value_t jerry_eval (const jerry_char_t *source_p, size_t source_size, uint32_t parse_opts);
 
 jerry_value_t jerry_run_all_enqueued_jobs (void);
 
@@ -336,9 +343,11 @@ jerry_value_t jerry_get_global_object (void);
 /**
  * Checker functions of 'jerry_value_t'.
  */
+bool jerry_value_is_abort (const jerry_value_t value);
 bool jerry_value_is_array (const jerry_value_t value);
 bool jerry_value_is_boolean (const jerry_value_t value);
 bool jerry_value_is_constructor (const jerry_value_t value);
+bool jerry_value_is_error (const jerry_value_t value);
 bool jerry_value_is_function (const jerry_value_t value);
 bool jerry_value_is_number (const jerry_value_t value);
 bool jerry_value_is_null (const jerry_value_t value);
@@ -360,6 +369,7 @@ typedef enum
   JERRY_TYPE_STRING,    /**< string type */
   JERRY_TYPE_OBJECT,    /**< object type */
   JERRY_TYPE_FUNCTION,  /**< function type */
+  JERRY_TYPE_ERROR,     /**< error/abort type */
 } jerry_type_t;
 
 jerry_type_t jerry_value_get_type (const jerry_value_t value);
@@ -370,19 +380,16 @@ jerry_type_t jerry_value_get_type (const jerry_value_t value);
 bool jerry_is_feature_enabled (const jerry_feature_t feature);
 
 /**
- * Error flag manipulation functions.
+ * Error manipulation functions.
  */
-bool jerry_value_has_error_flag (const jerry_value_t value);
-bool jerry_value_has_abort_flag (const jerry_value_t value);
-void jerry_value_clear_error_flag (jerry_value_t *value_p);
-void jerry_value_set_error_flag (jerry_value_t *value_p);
-void jerry_value_set_abort_flag (jerry_value_t *value_p);
-jerry_value_t jerry_get_value_without_error_flag (jerry_value_t value);
+jerry_value_t jerry_create_abort_from_value (jerry_value_t value, bool release);
+jerry_value_t jerry_create_error_from_value (jerry_value_t value, bool release);
+jerry_value_t jerry_get_value_from_error (jerry_value_t value, bool release);
 
 /**
  * Error object function(s).
  */
-jerry_error_t jerry_get_error_type (const jerry_value_t value);
+jerry_error_t jerry_get_error_type (jerry_value_t value);
 
 /**
  * Getter functions of 'jerry_value_t'.
@@ -451,6 +458,9 @@ jerry_value_t jerry_create_number_nan (void);
 jerry_value_t jerry_create_null (void);
 jerry_value_t jerry_create_object (void);
 jerry_value_t jerry_create_promise (void);
+jerry_value_t jerry_create_regexp (const jerry_char_t *pattern, jerry_regexp_flags_t flags);
+jerry_value_t jerry_create_regexp_sz (const jerry_char_t *pattern, jerry_size_t pattern_size,
+                                      jerry_regexp_flags_t flags);
 jerry_value_t jerry_create_string_from_utf8 (const jerry_char_t *str_p);
 jerry_value_t jerry_create_string_sz_from_utf8 (const jerry_char_t *str_p, jerry_size_t str_size);
 jerry_value_t jerry_create_string (const jerry_char_t *str_p);
@@ -491,23 +501,18 @@ jerry_value_t jerry_get_object_keys (const jerry_value_t obj_val);
 jerry_value_t jerry_get_prototype (const jerry_value_t obj_val);
 jerry_value_t jerry_set_prototype (const jerry_value_t obj_val, const jerry_value_t proto_obj_val);
 
-JERRY_DEPRECATED_API
-bool jerry_get_object_native_handle (const jerry_value_t obj_val, uintptr_t *out_handle_p);
-JERRY_DEPRECATED_API
-void jerry_set_object_native_handle (const jerry_value_t obj_val, uintptr_t handle_p,
-                                     jerry_object_free_callback_t freecb_p);
-
 bool jerry_get_object_native_pointer (const jerry_value_t obj_val,
                                       void **out_native_pointer_p,
                                       const jerry_object_native_info_t **out_pointer_info_p);
+void jerry_set_object_native_pointer (const jerry_value_t obj_val,
+                                      void *native_pointer_p,
+                                      const jerry_object_native_info_t *native_info_p);
+
 bool jerry_objects_foreach (jerry_objects_foreach_t foreach_p,
                             void *user_data);
 bool jerry_objects_foreach_by_native_info (const jerry_object_native_info_t *native_info_p,
                                            jerry_objects_foreach_by_native_info_t foreach_p,
                                            void *user_data_p);
-void jerry_set_object_native_pointer (const jerry_value_t obj_val,
-                                      void *native_pointer_p,
-                                      const jerry_object_native_info_t *native_info_p);
 
 bool jerry_foreach_object_property (const jerry_value_t obj_val, jerry_object_property_foreach_t foreach_p,
                                     void *user_data_p);
@@ -523,10 +528,16 @@ jerry_value_t jerry_resolve_or_reject_promise (jerry_value_t promise, jerry_valu
 bool jerry_is_valid_utf8_string (const jerry_char_t *utf8_buf_p, jerry_size_t buf_size);
 bool jerry_is_valid_cesu8_string (const jerry_char_t *cesu8_buf_p, jerry_size_t buf_size);
 
+/*
+ * Dynamic memory management functions.
+ */
+void *jerry_heap_alloc (size_t size);
+void jerry_heap_free (void *mem_p, size_t size);
+
 /*
  * External context functions.
  */
-jerry_instance_t *jerry_create_instance (uint32_t heap_size, jerry_instance_alloc_t alloc, void *cb_data_p);
+jerry_context_t *jerry_create_context (uint32_t heap_size, jerry_context_alloc_t alloc, void *cb_data_p);
 
 /**
  * Miscellaneous functions.
@@ -590,7 +601,7 @@ jerry_value_t jerry_get_typedarray_buffer (jerry_value_t value,
                                            jerry_length_t *byte_offset,
                                            jerry_length_t *byte_length);
 jerry_value_t jerry_json_parse (const jerry_char_t *string_p, jerry_size_t string_size);
-jerry_value_t jerry_json_stringfy (const jerry_value_t object_to_stringify);
+jerry_value_t jerry_json_stringify (const jerry_value_t object_to_stringify);
 
 /**
  * @}
diff --git a/deps/jerry/jerry-core/include/jerryscript-debugger-transport.h b/deps/jerry/jerry-core/include/jerryscript-debugger-transport.h
new file mode 100644 (file)
index 0000000..f6f9aca
--- /dev/null
@@ -0,0 +1,107 @@
+/* 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 JERRYSCRIPT_DEBUGGER_TRANSPORT_H
+#define JERRYSCRIPT_DEBUGGER_TRANSPORT_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/** \addtogroup jerry-debugger-transport Jerry engine debugger interface - transport control
+ * @{
+ */
+
+/**
+ * Maximum number of bytes transmitted or received.
+ */
+#define JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE 128
+
+/**
+ * Receive message context.
+ */
+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;
+
+/**
+ * Forward definition of jerry_debugger_transport_header_t.
+ */
+struct jerry_debugger_transport_interface_t;
+
+/**
+ * Close connection callback.
+ */
+typedef void (*jerry_debugger_transport_close_t) (struct jerry_debugger_transport_interface_t *header_p);
+
+/**
+ * Send data callback.
+ */
+typedef bool (*jerry_debugger_transport_send_t) (struct jerry_debugger_transport_interface_t *header_p,
+                                                 uint8_t *message_p, size_t message_length);
+
+/**
+ * Receive data callback.
+ */
+typedef bool (*jerry_debugger_transport_receive_t) (struct jerry_debugger_transport_interface_t *header_p,
+                                                    jerry_debugger_transport_receive_context_t *context_p);
+
+/**
+ * Transport layer header.
+ */
+typedef struct jerry_debugger_transport_interface_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_interface_t *next_p; /**< next transport layer */
+} jerry_debugger_transport_header_t;
+
+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);
+void jerry_debugger_transport_start (void);
+
+bool jerry_debugger_transport_is_connected (void);
+void jerry_debugger_transport_close (void);
+
+bool jerry_debugger_transport_send (const uint8_t *message_p, size_t message_length);
+bool jerry_debugger_transport_receive (jerry_debugger_transport_receive_context_t *context_p);
+void jerry_debugger_transport_receive_completed (jerry_debugger_transport_receive_context_t *context_p);
+
+void jerry_debugger_transport_sleep (void);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* !JERRYSCRIPT_DEBUGGER_TRANSPORT_H */
index c6e73a79a778ceb405e2ee02055b419126c80322..735d61e16e95513b93a7fa61e67bd5a36d5b86ff 100644 (file)
@@ -16,7 +16,8 @@
 #ifndef JERRYSCRIPT_DEBUGGER_H
 #define JERRYSCRIPT_DEBUGGER_H
 
-#include <stdbool.h>
+#include "jerryscript-core.h"
+#include "jerryscript-port.h"
 
 #ifdef __cplusplus
 extern "C"
@@ -27,6 +28,11 @@ extern "C"
  * @{
  */
 
+/**
+ * JerryScript debugger protocol version.
+ */
+#define JERRY_DEBUGGER_VERSION (8)
+
 /**
  * Types for the client source wait and run method.
  */
@@ -53,7 +59,6 @@ typedef jerry_value_t (*jerry_debugger_wait_for_source_callback_t) (const jerry_
 /**
  * Engine debugger functions.
  */
-void jerry_debugger_init (uint16_t port);
 bool jerry_debugger_is_connected (void);
 void jerry_debugger_stop (void);
 void jerry_debugger_continue (void);
@@ -61,7 +66,8 @@ void jerry_debugger_stop_at_breakpoint (bool enable_stop_at_breakpoint);
 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);
-void jerry_debugger_send_output (jerry_char_t buffer[], jerry_size_t str_size, uint8_t type);
+void jerry_debugger_send_output (const jerry_char_t *buffer, jerry_size_t str_size);
+void jerry_debugger_send_log (jerry_log_level_t level, const jerry_char_t *buffer, jerry_size_t str_size);
 
 /**
  * @}
index 95a976343d8646a8f362f460444d7e739106f686..cc6eca8ce09a7e2a270072023eb0046947649c5d 100644 (file)
@@ -20,6 +20,8 @@
 #include <stdint.h>
 #include <stdio.h>
 
+#include "jerryscript-compiler.h"
+
 #ifdef __cplusplus
 extern "C"
 {
@@ -48,6 +50,7 @@ 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;
 
@@ -62,7 +65,7 @@ typedef enum
  *
  * Example: a libc-based port may implement this with exit() or abort(), or both.
  */
-void jerry_port_fatal (jerry_fatal_code_t code) __attribute__((noreturn));
+void JERRY_ATTR_NORETURN jerry_port_fatal (jerry_fatal_code_t code);
 
 /*
  *  I/O Port API
@@ -95,55 +98,87 @@ typedef enum
  *
  * 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_ENABLE_LOGGING is
+ *      defined. It is also common practice though to use this function in
+ *      application code.
  */
-void jerry_port_log (jerry_log_level_t level, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
+void JERRY_ATTR_FORMAT (printf, 2, 3) jerry_port_log (jerry_log_level_t level, const char *format, ...);
 
 /*
  * Date Port API
  */
 
 /**
- * Jerry time zone structure
- */
-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
+ * 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
  *
- * @return true  - if success
- *         false - otherwise
+ * Note:
+ *      This port function is called by jerry-core when
+ *      CONFIG_DISABLE_DATE_BUILTIN is _not_ defined. 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.
  */
-bool jerry_port_get_time_zone (jerry_time_zone_t *tz_p);
+double jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc);
 
 /**
  * Get system time
  *
+ * Note:
+ *      This port function is called by jerry-core when
+ *      CONFIG_DISABLE_DATE_BUILTIN is _not_ defined. 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);
 
 /**
- * Get the current instance which contains the current context, heap and other
- * structures. Each port should provide its own implementation of this interface.
+ * 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_ENABLE_EXTERNAL_CONTEXT
- *    is defined. Otherwise this function is not used.
+ * Note:
+ *      This port function is called by jerry-core when
+ *      JERRY_ENABLE_EXTERNAL_CONTEXT is defined. Otherwise this function is not
+ *      used.
  *
- * @return the pointer to the jerry instance.
+ * @return the pointer to the engine context.
  */
-struct jerry_instance_t *jerry_port_get_current_instance (void);
+struct jerry_context_t *jerry_port_get_current_context (void);
 
 /**
  * Makes the process sleep for a given time.
+ *
+ * Note:
+ *      This port function is called by jerry-core when JERRY_DEBUGGER is
+ *      defined. Otherwise this function is not used.
+ *
+ * @param sleep_time milliseconds to sleep.
  */
-#ifdef JERRY_DEBUGGER
 void jerry_port_sleep (uint32_t sleep_time);
-#endif /* JERRY_DEBUGGER */
 
 /**
  * @}
index 8da3f4898194723d89ac04ff71f0399bff50f4e7..29b6b9080f33b9ad7ff6f1f228753797414a28d2 100644 (file)
@@ -27,6 +27,11 @@ extern "C"
  * @{
  */
 
+/**
+ * Jerry snapshot format version.
+ */
+#define JERRY_SNAPSHOT_VERSION (20u)
+
 /**
  * Flags for jerry_generate_snapshot and jerry_generate_function_snapshot.
  */
@@ -65,8 +70,8 @@ jerry_value_t jerry_load_function_snapshot (const uint32_t *function_snapshot_p,
 
 size_t jerry_merge_snapshots (const uint32_t **inp_buffers_p, size_t *inp_buffer_sizes_p, size_t number_of_snapshots,
                               uint32_t *out_buffer_p, size_t out_buffer_size, const char **error_p);
-size_t jerry_parse_and_save_literals (const jerry_char_t *source_p, size_t source_size, bool is_strict,
-                                      uint32_t *buffer_p, size_t buffer_size, bool is_c_format);
+size_t jerry_get_literals_from_snapshot (const uint32_t *snapshot_p, size_t snapshot_size,
+                                         jerry_char_t *lit_buf_p, size_t lit_buf_size, bool is_c_format);
 /**
  * @}
  */
index a89f2aa8f48da87d41e2fcdae85a9b4d1c602c63..199b871df34603819233789c65ea2358d8d4785a 100644 (file)
  */
 
 #ifndef JERRY_ENABLE_EXTERNAL_CONTEXT
+
 /**
  * Global context.
  */
 jerry_context_t jerry_global_context;
 
+#ifndef JERRY_SYSTEM_ALLOCATOR
+
+/**
+ * Check size of heap is corresponding to configuration
+ */
+JERRY_STATIC_ASSERT (sizeof (jmem_heap_t) <= JMEM_HEAP_SIZE,
+                     size_of_mem_heap_must_be_less_than_or_equal_to_JMEM_HEAP_SIZE);
+
 /**
  * Jerry global heap section attribute.
  */
 #ifndef JERRY_HEAP_SECTION_ATTR
 #define JERRY_GLOBAL_HEAP_SECTION
 #else /* JERRY_HEAP_SECTION_ATTR */
-#define JERRY_GLOBAL_HEAP_SECTION __attribute__ ((section (JERRY_HEAP_SECTION_ATTR)))
+#define JERRY_GLOBAL_HEAP_SECTION JERRY_ATTR_SECTION (JERRY_HEAP_SECTION_ATTR)
 #endif /* !JERRY_HEAP_SECTION_ATTR */
 
-#ifndef JERRY_SYSTEM_ALLOCATOR
 /**
  * Global heap.
  */
-jmem_heap_t jerry_global_heap __attribute__ ((aligned (JMEM_ALIGNMENT))) JERRY_GLOBAL_HEAP_SECTION;
-#endif /* !JERRY_SYSTEM_ALLOCATOR */
-
-#ifndef CONFIG_ECMA_LCACHE_DISABLE
+jmem_heap_t jerry_global_heap JERRY_ATTR_ALIGNED (JMEM_ALIGNMENT) JERRY_GLOBAL_HEAP_SECTION;
 
-/**
- * Global hash table.
- */
-jerry_hash_table_t jerry_global_hash_table;
+#endif /* !JERRY_SYSTEM_ALLOCATOR */
 
-#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
 #endif /* !JERRY_ENABLE_EXTERNAL_CONTEXT */
 
 /**
index 917c5e9c1980fd986d15ca325702c250b0207f37..baa866b53561758955bf01044ba40965f79d5036 100644 (file)
@@ -13,8 +13,8 @@
  * limitations under the License.
  */
 
-/**
- * Memory context for JerryScript
+/*
+ * Engine context for JerryScript
  */
 #ifndef JCONTEXT_H
 #define JCONTEXT_H
 #include "re-bytecode.h"
 #include "vm-defines.h"
 #include "jerryscript.h"
+#include "jerryscript-debugger-transport.h"
 
 /** \addtogroup context Context
  * @{
  */
 
+#ifndef JERRY_SYSTEM_ALLOCATOR
 /**
- * First member of the jerry context
+ * Heap structure
+ *
+ * Memory blocks returned by the allocator must not start from the
+ * beginning of the heap area because offset 0 is reserved for
+ * JMEM_CP_NULL. This special constant is used in several places,
+ * e.g. it marks the end of the property chain list, so it cannot
+ * be eliminated from the project. Although the allocator cannot
+ * use the first 8 bytes of the heap, nothing prevents to use it
+ * for other purposes. Currently the free region start is stored
+ * there.
  */
-#define JERRY_CONTEXT_FIRST_MEMBER ecma_builtin_objects
+typedef struct jmem_heap_t jmem_heap_t;
+#endif /* !JERRY_SYSTEM_ALLOCATOR */
 
 /**
  * User context item
@@ -49,15 +61,28 @@ typedef struct jerry_context_data_header
 #define JERRY_CONTEXT_DATA_HEADER_USER_DATA(item_p) \
   ((uint8_t *) (item_p + 1))
 
+/**
+ * First non-external member of the jerry context
+ */
+#define JERRY_CONTEXT_FIRST_MEMBER ecma_builtin_objects
+
 /**
  * JerryScript context
  *
  * The purpose of this header is storing
  * all global variables for Jerry
  */
-typedef struct
+struct jerry_context_t
 {
-  /* Update JERRY_CONTEXT_FIRST_MEMBER if the first member changes */
+  /* The value of external context members must be preserved across initializations and cleanups. */
+#ifdef JERRY_ENABLE_EXTERNAL_CONTEXT
+#ifndef JERRY_SYSTEM_ALLOCATOR
+  jmem_heap_t *heap_p; /**< point to the heap aligned to JMEM_ALIGNMENT. */
+  uint32_t heap_size; /**< size of the heap */
+#endif /* !JERRY_SYSTEM_ALLOCATOR */
+#endif /* JERRY_ENABLE_EXTERNAL_CONTEXT */
+
+  /* Update JERRY_CONTEXT_FIRST_MEMBER if the first non-external member changes */
   ecma_object_t *ecma_builtin_objects[ECMA_BUILTIN_ID__COUNT]; /**< pointer to instances of built-in objects */
 #ifndef CONFIG_DISABLE_REGEXP_BUILTIN
   const re_compiled_code_t *re_cache[RE_CACHE_SIZE]; /**< regex cache */
@@ -69,7 +94,7 @@ typedef struct
   jmem_pools_chunk_t *jmem_free_16_byte_chunk_p; /**< list of free sixteen byte pool chunks */
 #endif /* JERRY_CPOINTER_32_BIT */
   jmem_free_unused_memory_callback_t jmem_free_unused_memory_callback; /**< Callback for freeing up memory. */
-  const lit_utf8_byte_t **lit_magic_string_ex_array; /**< array of external magic strings */
+  const lit_utf8_byte_t * const *lit_magic_string_ex_array; /**< array of external magic strings */
   const lit_utf8_size_t *lit_magic_string_ex_sizes; /**< external magic string lengths */
   ecma_lit_storage_item_t *string_list_first_p; /**< first item of the literal string list */
   ecma_lit_storage_item_t *number_list_first_p; /**< first item of the literal number list */
@@ -84,7 +109,7 @@ typedef struct
   ecma_value_t error_value; /**< currently thrown error value */
   uint32_t lit_magic_string_ex_count; /**< external magic strings count */
   uint32_t jerry_init_flags; /**< run-time configuration flags */
-  uint32_t status_flags; /**< run-time flags */
+  uint32_t status_flags; /**< run-time flags (the top 8 bits are used for passing class parsing options) */
 
 #ifndef CONFIG_ECMA_PROPERTY_HASHMAP_DISABLE
   uint8_t ecma_prop_hashmap_alloc_state; /**< property hashmap allocation state: 0-4,
@@ -109,19 +134,20 @@ typedef struct
 #endif /* JERRY_VM_EXEC_STOP */
 
 #ifdef JERRY_DEBUGGER
-  uint8_t debugger_send_buffer[JERRY_DEBUGGER_MAX_BUFFER_SIZE]; /**< buffer for sending messages */
-  uint8_t debugger_receive_buffer[JERRY_DEBUGGER_MAX_BUFFER_SIZE]; /**< buffer for receiving messages */
+  uint8_t debugger_send_buffer[JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE]; /**< buffer for sending messages */
+  uint8_t debugger_receive_buffer[JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE]; /**< buffer for receiving messages */
+  jerry_debugger_transport_header_t *debugger_transport_header_p; /**< head of transport protocol chain */
   uint8_t *debugger_send_buffer_payload_p; /**< start where the outgoing message can be written */
   vm_frame_ctx_t *debugger_stop_context; /**< stop only if the current context is equal to this context */
+  uint8_t *debugger_exception_byte_code_p; /**< Location of the currently executed byte code if an
+                                            *   error occours while the vm_loop is suspended */
   jmem_cpointer_t debugger_byte_code_free_head; /**< head of byte code free linked list */
   jmem_cpointer_t debugger_byte_code_free_tail; /**< tail of byte code free linked list */
   uint32_t debugger_flags; /**< debugger flags */
-  uint16_t debugger_receive_buffer_offset; /**< receive buffer offset */
-  uint16_t debugger_port; /**< debugger socket communication port */
+  uint16_t debugger_received_length; /**< length of currently received bytes */
   uint8_t debugger_message_delay; /**< call receive message when reaches zero */
-  uint8_t debugger_max_send_size; /**< maximum amount of data that can be written */
+  uint8_t debugger_max_send_size; /**< maximum amount of data that can be sent */
   uint8_t debugger_max_receive_size; /**< maximum amount of data that can be received */
-  int debugger_connection; /**< holds the file descriptor of the socket communication */
 #endif /* JERRY_DEBUGGER */
 
 #ifdef JERRY_ENABLE_LINE_INFO
@@ -132,163 +158,84 @@ typedef struct
   jmem_heap_stats_t jmem_heap_stats; /**< heap's memory usage statistics */
 #endif /* JMEM_STATS */
 
-#ifdef JERRY_VALGRIND_FREYA
-  uint8_t valgrind_freya_mempool_request; /**< Tells whether a pool manager
-                                           *   allocator request is in progress */
-#endif /* JERRY_VALGRIND_FREYA */
-} jerry_context_t;
-
+  /* This must be at the end of the context for performance reasons */
 #ifndef CONFIG_ECMA_LCACHE_DISABLE
-/**
- * Hash table for caching the last access of properties.
- */
-typedef struct
-{
-  ecma_lcache_hash_entry_t table[ECMA_LCACHE_HASH_ROWS_COUNT][ECMA_LCACHE_HASH_ROW_LENGTH];
-} jerry_hash_table_t;
+  /** hash table for caching the last access of properties */
+  ecma_lcache_hash_entry_t lcache[ECMA_LCACHE_HASH_ROWS_COUNT][ECMA_LCACHE_HASH_ROW_LENGTH];
 #endif /* !CONFIG_ECMA_LCACHE_DISABLE */
+};
 
-#ifdef JERRY_ENABLE_EXTERNAL_CONTEXT
 
-#ifndef JERRY_GET_CURRENT_INSTANCE
+#ifdef JERRY_ENABLE_EXTERNAL_CONTEXT
 
-/**
- * Default function if JERRY_GET_CURRENT_INSTANCE is not defined.
+/*
+ * This part is for JerryScript which uses external context.
  */
-#define JERRY_GET_CURRENT_INSTANCE() (jerry_port_get_current_instance ())
-
-#endif /* !JERRY_GET_CURRENT_INSTANCE */
 
-/**
- * This part is for Jerry which enable external context.
- */
-typedef struct
-{
-  jmem_heap_free_t first; /**< first node in free region list */
-  uint8_t area[]; /**< heap area */
-} jmem_heap_t;
+#define JERRY_CONTEXT(field) (jerry_port_get_current_context ()->field)
 
-/**
- * Description of jerry instance which is the header of the context space.
- */
-struct jerry_instance_t
-{
-  jerry_context_t context; /**< the context of the instance */
 #ifndef JERRY_SYSTEM_ALLOCATOR
-  jmem_heap_t *heap_p; /**< point to the heap aligned to JMEM_ALIGNMENT. */
-  uint32_t heap_size; /**< size of the heap */
-#endif /* !JERRY_SYSTEM_ALLOCATOR */
-#ifndef CONFIG_ECMA_LCACHE_DISABLE
-  uint8_t *lcache_p; /**< point to the entrance of the lcache in buffer */
-#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
-};
 
-#define JERRY_CONTEXT(field) (JERRY_GET_CURRENT_INSTANCE ()->context.field)
+#define JMEM_HEAP_SIZE (JERRY_CONTEXT (heap_size))
 
-#ifndef JERRY_SYSTEM_ALLOCATOR
+#define JMEM_HEAP_AREA_SIZE (JMEM_HEAP_SIZE - JMEM_ALIGNMENT)
 
-static inline jmem_heap_t * __attr_always_inline___
-jerry_context_get_current_heap (void)
+struct jmem_heap_t
 {
-  return JERRY_GET_CURRENT_INSTANCE ()->heap_p;
-} /* jerry_context_get_current_heap */
-
-#define JERRY_HEAP_CONTEXT(field) (jerry_context_get_current_heap ()->field)
-
-#ifdef JMEM_HEAP_SIZE
-#error "JMEM_HEAP_SIZE must not be defined if JERRY_ENABLE_EXTERNAL_CONTEXT is defined"
-#endif /* JMEM_HEAP_SIZE */
-
-#define JMEM_HEAP_SIZE (JERRY_GET_CURRENT_INSTANCE ()->heap_size)
+  jmem_heap_free_t first; /**< first node in free region list */
+  uint8_t area[]; /**< heap area */
+};
 
-#define JMEM_HEAP_AREA_SIZE (JERRY_GET_CURRENT_INSTANCE ()->heap_size - JMEM_ALIGNMENT)
+#define JERRY_HEAP_CONTEXT(field) (JERRY_CONTEXT (heap_p)->field)
 
 #endif /* !JERRY_SYSTEM_ALLOCATOR */
 
-#ifndef CONFIG_ECMA_LCACHE_DISABLE
+#else /* !JERRY_ENABLE_EXTERNAL_CONTEXT */
 
-static inline jerry_hash_table_t * __attr_always_inline___
-jerry_context_get_current_lcache (void)
-{
-  return (jerry_hash_table_t *) (JERRY_GET_CURRENT_INSTANCE ()->lcache_p);
-} /* jerry_context_get_current_lcache */
+/*
+ * This part is for JerryScript which uses default context.
+ */
 
-#define JERRY_HASH_TABLE_CONTEXT(field) (jerry_context_get_current_lcache ()->field)
+/**
+ * Global context.
+ */
+extern jerry_context_t jerry_global_context;
 
-#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
+/**
+ * Provides a reference to a field in the current context.
+ */
+#define JERRY_CONTEXT(field) (jerry_global_context.field)
 
-#else /* !JERRY_ENABLE_EXTERNAL_CONTEXT */
+#ifndef JERRY_SYSTEM_ALLOCATOR
 
 /**
- * This part is for Jerry which use default context.
- */
+* Size of heap
+*/
+#define JMEM_HEAP_SIZE ((size_t) (CONFIG_MEM_HEAP_AREA_SIZE))
 
 /**
  * Calculate heap area size, leaving space for a pointer to the free list
  */
 #define JMEM_HEAP_AREA_SIZE (JMEM_HEAP_SIZE - JMEM_ALIGNMENT)
 
-/**
- * Heap structure
- *
- * Memory blocks returned by the allocator must not start from the
- * beginning of the heap area because offset 0 is reserved for
- * JMEM_CP_NULL. This special constant is used in several places,
- * e.g. it marks the end of the property chain list, so it cannot
- * be eliminated from the project. Although the allocator cannot
- * use the first 8 bytes of the heap, nothing prevents to use it
- * for other purposes. Currently the free region start is stored
- * there.
- */
-typedef struct
+struct jmem_heap_t
 {
   jmem_heap_free_t first; /**< first node in free region list */
   uint8_t area[JMEM_HEAP_AREA_SIZE]; /**< heap area */
-} jmem_heap_t;
-
-/**
- * Global context.
- */
-extern jerry_context_t jerry_global_context;
+};
 
-#ifndef JERRY_SYSTEM_ALLOCATOR
 /**
  * Global heap.
  */
 extern jmem_heap_t jerry_global_heap;
-#endif /* !JERRY_SYSTEM_ALLOCATOR */
-
-#ifndef CONFIG_ECMA_LCACHE_DISABLE
-
-/**
- * Global hash table.
- */
-extern jerry_hash_table_t jerry_global_hash_table;
-
-#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
 
 /**
- * Provides a reference to a field in the current context.
- */
-#define JERRY_CONTEXT(field) (jerry_global_context.field)
-
-#ifndef JERRY_SYSTEM_ALLOCATOR
-/**
- * Provides a reference to the area field of the heap.
+ * Provides a reference to a field of the heap.
  */
 #define JERRY_HEAP_CONTEXT(field) (jerry_global_heap.field)
 
 #endif /* !JERRY_SYSTEM_ALLOCATOR */
 
-#ifndef CONFIG_ECMA_LCACHE_DISABLE
-
-/**
- * Provides a reference to the global hash table.
- */
-#define JERRY_HASH_TABLE_CONTEXT(field) (jerry_global_hash_table.field)
-
-#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
-
 #endif /* JERRY_ENABLE_EXTERNAL_CONTEXT */
 
 /**
index 41029cd4b359f6614e3bf8f08fe1236fe468b2de..77cb0c4b6a3ccaa4f0455c8972427a47a06dfa93 100644 (file)
  * @{
  */
 
+/**
+ * @{
+ * Valgrind-related options and headers
+ */
+#ifdef JERRY_VALGRIND
+# include "memcheck.h"
+
+# define JMEM_VALGRIND_NOACCESS_SPACE(p, s)   VALGRIND_MAKE_MEM_NOACCESS((p), (s))
+# define JMEM_VALGRIND_UNDEFINED_SPACE(p, s)  VALGRIND_MAKE_MEM_UNDEFINED((p), (s))
+# define JMEM_VALGRIND_DEFINED_SPACE(p, s)    VALGRIND_MAKE_MEM_DEFINED((p), (s))
+# define JMEM_VALGRIND_MALLOCLIKE_SPACE(p, s) VALGRIND_MALLOCLIKE_BLOCK((p), (s), 0, 0)
+# define JMEM_VALGRIND_FREELIKE_SPACE(p)      VALGRIND_FREELIKE_BLOCK((p), 0)
+#else /* !JERRY_VALGRIND */
+# define JMEM_VALGRIND_NOACCESS_SPACE(p, s)
+# define JMEM_VALGRIND_UNDEFINED_SPACE(p, s)
+# define JMEM_VALGRIND_DEFINED_SPACE(p, s)
+# define JMEM_VALGRIND_MALLOCLIKE_SPACE(p, s)
+# define JMEM_VALGRIND_FREELIKE_SPACE(p)
+#endif /* JERRY_VALGRIND */
+/** @} */
+
 #ifdef JMEM_STATS
 void jmem_heap_stats_reset_peak (void);
 void jmem_heap_stats_print (void);
@@ -39,9 +60,6 @@ void jmem_run_free_unused_memory_callbacks (jmem_free_unused_memory_severity_t s
  * \addtogroup poolman Memory pool manager
  * @{
  */
-#ifdef JMEM_STATS
-void jmem_pools_stats_print (void);
-#endif /* JMEM_STATS */
 
 void jmem_pools_finalize (void);
 void jmem_pools_collect_empty (void);
index db3bb8fbe744404330831e74301141fb346c0430..8c42d39523c8a86a35b8c70e556f113d4ba9c42d 100644 (file)
 #define JMEM_ALLOCATOR_INTERNAL
 #include "jmem-allocator-internal.h"
 
+#ifdef JMEM_STATS
+/**
+ * Register byte code allocation.
+ */
+void
+jmem_stats_allocate_byte_code_bytes (size_t byte_code_size)
+{
+  jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
+
+  heap_stats->byte_code_bytes += byte_code_size;
+
+  if (heap_stats->byte_code_bytes >= heap_stats->peak_byte_code_bytes)
+  {
+    heap_stats->peak_byte_code_bytes = heap_stats->byte_code_bytes;
+  }
+} /* jmem_stats_allocate_byte_code_bytes */
+
+/**
+ * Register byte code free.
+ */
+void
+jmem_stats_free_byte_code_bytes (size_t byte_code_size)
+{
+  jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
+
+  JERRY_ASSERT (heap_stats->byte_code_bytes >= byte_code_size);
+
+  heap_stats->byte_code_bytes -= byte_code_size;
+} /* jmem_stats_free_byte_code_bytes */
+
+/**
+ * Register string allocation.
+ */
+void
+jmem_stats_allocate_string_bytes (size_t string_size)
+{
+  jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
+
+  heap_stats->string_bytes += string_size;
+
+  if (heap_stats->string_bytes >= heap_stats->peak_string_bytes)
+  {
+    heap_stats->peak_string_bytes = heap_stats->string_bytes;
+  }
+} /* jmem_stats_allocate_string_bytes */
+
+/**
+ * Register string free.
+ */
+void
+jmem_stats_free_string_bytes (size_t string_size)
+{
+  jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
+
+  JERRY_ASSERT (heap_stats->string_bytes >= string_size);
+
+  heap_stats->string_bytes -= string_size;
+} /* jmem_stats_free_string_bytes */
+
+/**
+ * Register object allocation.
+ */
+void
+jmem_stats_allocate_object_bytes (size_t object_size)
+{
+  jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
+
+  heap_stats->object_bytes += object_size;
+
+  if (heap_stats->object_bytes >= heap_stats->peak_object_bytes)
+  {
+    heap_stats->peak_object_bytes = heap_stats->object_bytes;
+  }
+} /* jmem_stats_allocate_object_bytes */
+
+/**
+ * Register object free.
+ */
+void
+jmem_stats_free_object_bytes (size_t object_size)
+{
+  jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
+
+  JERRY_ASSERT (heap_stats->object_bytes >= object_size);
+
+  heap_stats->object_bytes -= object_size;
+} /* jmem_stats_free_object_bytes */
+
+/**
+ * Register property allocation.
+ */
+void
+jmem_stats_allocate_property_bytes (size_t property_size)
+{
+  jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
+
+  heap_stats->property_bytes += property_size;
+
+  if (heap_stats->property_bytes >= heap_stats->peak_property_bytes)
+  {
+    heap_stats->peak_property_bytes = heap_stats->property_bytes;
+  }
+} /* jmem_stats_allocate_property_bytes */
+
+/**
+ * Register property free.
+ */
+void
+jmem_stats_free_property_bytes (size_t property_size)
+{
+  jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
+
+  JERRY_ASSERT (heap_stats->property_bytes >= property_size);
+
+  heap_stats->property_bytes -= property_size;
+} /* jmem_stats_free_property_bytes */
+
+#endif /* JMEM_STATS */
+
 /**
  * Initialize memory allocators.
  */
@@ -44,7 +163,7 @@ jmem_finalize (void)
 #ifdef JMEM_STATS
   if (JERRY_CONTEXT (jerry_init_flags) & ECMA_INIT_MEM_STATS)
   {
-    jmem_stats_print ();
+    jmem_heap_stats_print ();
   }
 #endif /* JMEM_STATS */
 
@@ -56,7 +175,7 @@ jmem_finalize (void)
  *
  * @return packed pointer
  */
-inline jmem_cpointer_t __attr_pure___ __attr_always_inline___
+inline jmem_cpointer_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
 jmem_compress_pointer (const void *pointer_p) /**< pointer to compress */
 {
   JERRY_ASSERT (pointer_p != NULL);
@@ -90,7 +209,7 @@ jmem_compress_pointer (const void *pointer_p) /**< pointer to compress */
  *
  * @return unpacked pointer
  */
-inline void * __attr_pure___ __attr_always_inline___
+inline void * JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
 jmem_decompress_pointer (uintptr_t compressed_pointer) /**< pointer to decompress */
 {
   JERRY_ASSERT (compressed_pointer != JMEM_CP_NULL);
@@ -150,131 +269,3 @@ jmem_run_free_unused_memory_callbacks (jmem_free_unused_memory_severity_t severi
 
   jmem_pools_collect_empty ();
 } /* jmem_run_free_unused_memory_callbacks */
-
-#ifdef JMEM_STATS
-/**
- * Print memory usage statistics
- */
-void
-jmem_stats_print (void)
-{
-  jmem_heap_stats_print ();
-} /* jmem_stats_print */
-
-/**
- * Register byte code allocation.
- */
-void
-jmem_stats_allocate_byte_code_bytes (size_t byte_code_size)
-{
-  jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
-
-  heap_stats->byte_code_bytes += byte_code_size;
-
-  if (heap_stats->byte_code_bytes >= heap_stats->peak_byte_code_bytes)
-  {
-    heap_stats->peak_byte_code_bytes = heap_stats->byte_code_bytes;
-  }
-} /* jmem_stats_allocate_byte_code_bytes */
-
-/**
- * Register byte code free.
- */
-void
-jmem_stats_free_byte_code_bytes (size_t byte_code_size)
-{
-  jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
-
-  JERRY_ASSERT (heap_stats->byte_code_bytes >= byte_code_size);
-
-  heap_stats->byte_code_bytes -= byte_code_size;
-} /* jmem_stats_free_byte_code_bytes */
-
-/**
- * Register string allocation.
- */
-void
-jmem_stats_allocate_string_bytes (size_t string_size)
-{
-  jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
-
-  heap_stats->string_bytes += string_size;
-
-  if (heap_stats->string_bytes >= heap_stats->peak_string_bytes)
-  {
-    heap_stats->peak_string_bytes = heap_stats->string_bytes;
-  }
-} /* jmem_stats_allocate_string_bytes */
-
-/**
- * Register string free.
- */
-void
-jmem_stats_free_string_bytes (size_t string_size)
-{
-  jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
-
-  JERRY_ASSERT (heap_stats->string_bytes >= string_size);
-
-  heap_stats->string_bytes -= string_size;
-} /* jmem_stats_free_string_bytes */
-
-/**
- * Register object allocation.
- */
-void
-jmem_stats_allocate_object_bytes (size_t object_size)
-{
-  jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
-
-  heap_stats->object_bytes += object_size;
-
-  if (heap_stats->object_bytes >= heap_stats->peak_object_bytes)
-  {
-    heap_stats->peak_object_bytes = heap_stats->object_bytes;
-  }
-} /* jmem_stats_allocate_object_bytes */
-
-/**
- * Register object free.
- */
-void
-jmem_stats_free_object_bytes (size_t object_size)
-{
-  jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
-
-  JERRY_ASSERT (heap_stats->object_bytes >= object_size);
-
-  heap_stats->object_bytes -= object_size;
-} /* jmem_stats_free_object_bytes */
-
-/**
- * Register property allocation.
- */
-void
-jmem_stats_allocate_property_bytes (size_t property_size)
-{
-  jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
-
-  heap_stats->property_bytes += property_size;
-
-  if (heap_stats->property_bytes >= heap_stats->peak_property_bytes)
-  {
-    heap_stats->peak_property_bytes = heap_stats->property_bytes;
-  }
-} /* jmem_stats_allocate_property_bytes */
-
-/**
- * Register property free.
- */
-void
-jmem_stats_free_property_bytes (size_t property_size)
-{
-  jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
-
-  JERRY_ASSERT (heap_stats->property_bytes >= property_size);
-
-  heap_stats->property_bytes -= property_size;
-} /* jmem_stats_free_property_bytes */
-
-#endif /* JMEM_STATS */
index f15ba904412af02febad12e2108fcaf33e8a2589..e7e9906d6f10f050f57e7349ababe1dcfb71e543 100644 (file)
  * @{
  */
 
-/*
- * Valgrind-related options and headers
- */
-#ifdef JERRY_VALGRIND
-# include "memcheck.h"
-
-# define VALGRIND_NOACCESS_SPACE(p, s)   VALGRIND_MAKE_MEM_NOACCESS((p), (s))
-# define VALGRIND_UNDEFINED_SPACE(p, s)  VALGRIND_MAKE_MEM_UNDEFINED((p), (s))
-# define VALGRIND_DEFINED_SPACE(p, s)    VALGRIND_MAKE_MEM_DEFINED((p), (s))
-
-#else /* !JERRY_VALGRIND */
-# define VALGRIND_NOACCESS_SPACE(p, s)
-# define VALGRIND_UNDEFINED_SPACE(p, s)
-# define VALGRIND_DEFINED_SPACE(p, s)
-#endif /* JERRY_VALGRIND */
-
-#ifdef JERRY_VALGRIND_FREYA
-
-#ifdef JERRY_VALGRIND
-#error Valgrind and valgrind-freya modes are not compatible.
-#endif /* JERRY_VALGRIND */
-
-#include "memcheck.h"
-
-# define VALGRIND_FREYA_CHECK_MEMPOOL_REQUEST \
-  bool mempool_request = JERRY_CONTEXT (valgrind_freya_mempool_request); \
-  JERRY_CONTEXT (valgrind_freya_mempool_request) = false
-
-# define VALGRIND_FREYA_MALLOCLIKE_SPACE(p, s) \
-  if (!mempool_request) \
-  { \
-    VALGRIND_MALLOCLIKE_BLOCK((p), (s), 0, 0); \
-  }
-
-# define VALGRIND_FREYA_FREELIKE_SPACE(p) \
-  if (!mempool_request) \
-  { \
-    VALGRIND_FREELIKE_BLOCK((p), 0); \
-  }
-
-#else /* !JERRY_VALGRIND_FREYA */
-# define VALGRIND_FREYA_CHECK_MEMPOOL_REQUEST
-# define VALGRIND_FREYA_MALLOCLIKE_SPACE(p, s)
-# define VALGRIND_FREYA_FREELIKE_SPACE(p)
-#endif /* JERRY_VALGRIND_FREYA */
-
+#ifndef JERRY_SYSTEM_ALLOCATOR
 /**
  * End of list marker.
  */
 #define JMEM_HEAP_END_OF_LIST ((uint32_t) 0xffffffff)
 
+/**
+ * @{
+ */
 #ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
 /* In this case we simply store the pointer, since it fits anyway. */
 #define JMEM_HEAP_GET_OFFSET_FROM_ADDR(p) ((uint32_t) (p))
 #define JMEM_HEAP_GET_OFFSET_FROM_ADDR(p) ((uint32_t) ((uint8_t *) (p) - JERRY_HEAP_CONTEXT (area)))
 #define JMEM_HEAP_GET_ADDR_FROM_OFFSET(u) ((jmem_heap_free_t *) (JERRY_HEAP_CONTEXT (area) + (u)))
 #endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
+/**
+ * @}
+ */
 
-#ifndef JERRY_SYSTEM_ALLOCATOR
 /**
  * Get end of region
+ *
+ * @return pointer to the end of the region
  */
-static inline jmem_heap_free_t *  __attr_always_inline___ __attr_pure___
+static inline jmem_heap_free_t *  JERRY_ATTR_ALWAYS_INLINE JERRY_ATTR_PURE
 jmem_heap_get_region_end (jmem_heap_free_t *curr_p) /**< current region */
 {
   return (jmem_heap_free_t *)((uint8_t *) curr_p + curr_p->size);
 } /* jmem_heap_get_region_end */
 #endif /* !JERRY_SYSTEM_ALLOCATOR */
 
-#ifndef JERRY_ENABLE_EXTERNAL_CONTEXT
 /**
- * Check size of heap is corresponding to configuration
+ * @{
+ * JMEM_HEAP_STAT_xxx definitions
  */
-JERRY_STATIC_ASSERT (sizeof (jmem_heap_t) <= JMEM_HEAP_SIZE,
-                     size_of_mem_heap_must_be_less_than_or_equal_to_MEM_HEAP_SIZE);
-#endif /* !JERRY_ENABLE_EXTERNAL_CONTEXT */
-
 #ifdef JMEM_STATS
 static void jmem_heap_stat_init (void);
 static void jmem_heap_stat_alloc (size_t num);
 static void jmem_heap_stat_free (size_t num);
 
+#define JMEM_HEAP_STAT_INIT() jmem_heap_stat_init ()
+#define JMEM_HEAP_STAT_ALLOC(v1) jmem_heap_stat_alloc (v1)
+#define JMEM_HEAP_STAT_FREE(v1) jmem_heap_stat_free (v1)
+
 #ifndef JERRY_SYSTEM_ALLOCATOR
 static void jmem_heap_stat_skip (void);
 static void jmem_heap_stat_nonskip (void);
 static void jmem_heap_stat_alloc_iter (void);
 static void jmem_heap_stat_free_iter (void);
-#endif /* !JERRY_SYSTEM_ALLOCATOR */
 
-#  define JMEM_HEAP_STAT_INIT() jmem_heap_stat_init ()
-#  define JMEM_HEAP_STAT_ALLOC(v1) jmem_heap_stat_alloc (v1)
-#  define JMEM_HEAP_STAT_FREE(v1) jmem_heap_stat_free (v1)
-#  define JMEM_HEAP_STAT_SKIP() jmem_heap_stat_skip ()
-#  define JMEM_HEAP_STAT_NONSKIP() jmem_heap_stat_nonskip ()
-#  define JMEM_HEAP_STAT_ALLOC_ITER() jmem_heap_stat_alloc_iter ()
-#  define JMEM_HEAP_STAT_FREE_ITER() jmem_heap_stat_free_iter ()
+#define JMEM_HEAP_STAT_SKIP() jmem_heap_stat_skip ()
+#define JMEM_HEAP_STAT_NONSKIP() jmem_heap_stat_nonskip ()
+#define JMEM_HEAP_STAT_ALLOC_ITER() jmem_heap_stat_alloc_iter ()
+#define JMEM_HEAP_STAT_FREE_ITER() jmem_heap_stat_free_iter ()
+#endif /* !JERRY_SYSTEM_ALLOCATOR */
 #else /* !JMEM_STATS */
-#  define JMEM_HEAP_STAT_INIT()
-#  define JMEM_HEAP_STAT_ALLOC(v1)
-#  define JMEM_HEAP_STAT_FREE(v1)
-#  define JMEM_HEAP_STAT_SKIP()
-#  define JMEM_HEAP_STAT_NONSKIP()
-#  define JMEM_HEAP_STAT_ALLOC_ITER()
-#  define JMEM_HEAP_STAT_FREE_ITER()
+#define JMEM_HEAP_STAT_INIT()
+#define JMEM_HEAP_STAT_ALLOC(v1) JERRY_UNUSED (v1)
+#define JMEM_HEAP_STAT_FREE(v1) JERRY_UNUSED (v1)
+
+#ifndef JERRY_SYSTEM_ALLOCATOR
+#define JMEM_HEAP_STAT_SKIP()
+#define JMEM_HEAP_STAT_NONSKIP()
+#define JMEM_HEAP_STAT_ALLOC_ITER()
+#define JMEM_HEAP_STAT_FREE_ITER()
+#endif /* !JERRY_SYSTEM_ALLOCATOR */
 #endif /* JMEM_STATS */
+/** @} */
 
 /**
  * Startup initialization of heap
@@ -146,12 +109,11 @@ static void jmem_heap_stat_free_iter (void);
 void
 jmem_heap_init (void)
 {
+#ifndef JERRY_SYSTEM_ALLOCATOR
 #ifndef JERRY_CPOINTER_32_BIT
   /* the maximum heap size for 16bit compressed pointers should be 512K */
   JERRY_ASSERT (((UINT16_MAX + 1) << JMEM_ALIGNMENT_LOG) >= JMEM_HEAP_SIZE);
 #endif /* !JERRY_CPOINTER_32_BIT */
-
-#ifndef JERRY_SYSTEM_ALLOCATOR
   JERRY_ASSERT ((uintptr_t) JERRY_HEAP_CONTEXT (area) % JMEM_ALIGNMENT == 0);
 
   JERRY_CONTEXT (jmem_heap_limit) = CONFIG_MEM_HEAP_DESIRED_LIMIT;
@@ -166,7 +128,7 @@ jmem_heap_init (void)
 
   JERRY_CONTEXT (jmem_heap_list_skip_p) = &JERRY_HEAP_CONTEXT (first);
 
-  VALGRIND_NOACCESS_SPACE (JERRY_HEAP_CONTEXT (area), JMEM_HEAP_AREA_SIZE);
+  JMEM_VALGRIND_NOACCESS_SPACE (JERRY_HEAP_CONTEXT (area), JMEM_HEAP_AREA_SIZE);
 
 #endif /* !JERRY_SYSTEM_ALLOCATOR */
   JMEM_HEAP_STAT_INIT ();
@@ -180,7 +142,7 @@ jmem_heap_finalize (void)
 {
   JERRY_ASSERT (JERRY_CONTEXT (jmem_heap_allocated_size) == 0);
 #ifndef JERRY_SYSTEM_ALLOCATOR
-  VALGRIND_NOACCESS_SPACE (&JERRY_HEAP_CONTEXT (first), JMEM_HEAP_SIZE);
+  JMEM_VALGRIND_NOACCESS_SPACE (&JERRY_HEAP_CONTEXT (first), JMEM_HEAP_SIZE);
 #endif /* !JERRY_SYSTEM_ALLOCATOR */
 } /* jmem_heap_finalize */
 
@@ -193,24 +155,24 @@ jmem_heap_finalize (void)
  * @return pointer to allocated memory block - if allocation is successful,
  *         NULL - if there is not enough memory.
  */
-static __attr_hot___ void *
-jmem_heap_alloc_block_internal (const size_t size)
+static void * JERRY_ATTR_HOT
+jmem_heap_alloc_block_internal (const size_t size) /**< size of requested block */
 {
 #ifndef JERRY_SYSTEM_ALLOCATOR
   /* Align size. */
   const size_t required_size = ((size + JMEM_ALIGNMENT - 1) / JMEM_ALIGNMENT) * JMEM_ALIGNMENT;
   jmem_heap_free_t *data_space_p = NULL;
 
-  VALGRIND_DEFINED_SPACE (&JERRY_HEAP_CONTEXT (first), sizeof (jmem_heap_free_t));
+  JMEM_VALGRIND_DEFINED_SPACE (&JERRY_HEAP_CONTEXT (first), sizeof (jmem_heap_free_t));
 
   /* Fast path for 8 byte chunks, first region is guaranteed to be sufficient. */
   if (required_size == JMEM_ALIGNMENT
-      && likely (JERRY_HEAP_CONTEXT (first).next_offset != JMEM_HEAP_END_OF_LIST))
+      && JERRY_LIKELY (JERRY_HEAP_CONTEXT (first).next_offset != JMEM_HEAP_END_OF_LIST))
   {
     data_space_p = JMEM_HEAP_GET_ADDR_FROM_OFFSET (JERRY_HEAP_CONTEXT (first).next_offset);
     JERRY_ASSERT (jmem_is_heap_pointer (data_space_p));
 
-    VALGRIND_DEFINED_SPACE (data_space_p, sizeof (jmem_heap_free_t));
+    JMEM_VALGRIND_DEFINED_SPACE (data_space_p, sizeof (jmem_heap_free_t));
     JERRY_CONTEXT (jmem_heap_allocated_size) += JMEM_ALIGNMENT;
     JMEM_HEAP_STAT_ALLOC_ITER ();
 
@@ -225,17 +187,17 @@ jmem_heap_alloc_block_internal (const size_t size)
       jmem_heap_free_t *remaining_p;
       remaining_p = JMEM_HEAP_GET_ADDR_FROM_OFFSET (JERRY_HEAP_CONTEXT (first).next_offset) + 1;
 
-      VALGRIND_DEFINED_SPACE (remaining_p, sizeof (jmem_heap_free_t));
+      JMEM_VALGRIND_DEFINED_SPACE (remaining_p, sizeof (jmem_heap_free_t));
       remaining_p->size = data_space_p->size - JMEM_ALIGNMENT;
       remaining_p->next_offset = data_space_p->next_offset;
-      VALGRIND_NOACCESS_SPACE (remaining_p, sizeof (jmem_heap_free_t));
+      JMEM_VALGRIND_NOACCESS_SPACE (remaining_p, sizeof (jmem_heap_free_t));
 
       JERRY_HEAP_CONTEXT (first).next_offset = JMEM_HEAP_GET_OFFSET_FROM_ADDR (remaining_p);
     }
 
-    VALGRIND_UNDEFINED_SPACE (data_space_p, sizeof (jmem_heap_free_t));
+    JMEM_VALGRIND_UNDEFINED_SPACE (data_space_p, sizeof (jmem_heap_free_t));
 
-    if (unlikely (data_space_p == JERRY_CONTEXT (jmem_heap_list_skip_p)))
+    if (JERRY_UNLIKELY (data_space_p == JERRY_CONTEXT (jmem_heap_list_skip_p)))
     {
       JERRY_CONTEXT (jmem_heap_list_skip_p) = JMEM_HEAP_GET_ADDR_FROM_OFFSET (JERRY_HEAP_CONTEXT (first).next_offset);
     }
@@ -250,7 +212,7 @@ jmem_heap_alloc_block_internal (const size_t size)
     {
       jmem_heap_free_t *current_p = JMEM_HEAP_GET_ADDR_FROM_OFFSET (current_offset);
       JERRY_ASSERT (jmem_is_heap_pointer (current_p));
-      VALGRIND_DEFINED_SPACE (current_p, sizeof (jmem_heap_free_t));
+      JMEM_VALGRIND_DEFINED_SPACE (current_p, sizeof (jmem_heap_free_t));
       JMEM_HEAP_STAT_ALLOC_ITER ();
 
       const uint32_t next_offset = current_p->next_offset;
@@ -270,23 +232,23 @@ jmem_heap_alloc_block_internal (const size_t size)
           jmem_heap_free_t *const remaining_p = (jmem_heap_free_t *) ((uint8_t *) current_p + required_size);
 
           /* Update metadata. */
-          VALGRIND_DEFINED_SPACE (remaining_p, sizeof (jmem_heap_free_t));
+          JMEM_VALGRIND_DEFINED_SPACE (remaining_p, sizeof (jmem_heap_free_t));
           remaining_p->size = current_p->size - (uint32_t) required_size;
           remaining_p->next_offset = next_offset;
-          VALGRIND_NOACCESS_SPACE (remaining_p, sizeof (jmem_heap_free_t));
+          JMEM_VALGRIND_NOACCESS_SPACE (remaining_p, sizeof (jmem_heap_free_t));
 
           /* Update list. */
-          VALGRIND_DEFINED_SPACE (prev_p, sizeof (jmem_heap_free_t));
+          JMEM_VALGRIND_DEFINED_SPACE (prev_p, sizeof (jmem_heap_free_t));
           prev_p->next_offset = JMEM_HEAP_GET_OFFSET_FROM_ADDR (remaining_p);
-          VALGRIND_NOACCESS_SPACE (prev_p, sizeof (jmem_heap_free_t));
+          JMEM_VALGRIND_NOACCESS_SPACE (prev_p, sizeof (jmem_heap_free_t));
         }
         /* Block is an exact fit. */
         else
         {
           /* Remove the region from the list. */
-          VALGRIND_DEFINED_SPACE (prev_p, sizeof (jmem_heap_free_t));
+          JMEM_VALGRIND_DEFINED_SPACE (prev_p, sizeof (jmem_heap_free_t));
           prev_p->next_offset = next_offset;
-          VALGRIND_NOACCESS_SPACE (prev_p, sizeof (jmem_heap_free_t));
+          JMEM_VALGRIND_NOACCESS_SPACE (prev_p, sizeof (jmem_heap_free_t));
         }
 
         JERRY_CONTEXT (jmem_heap_list_skip_p) = prev_p;
@@ -295,7 +257,7 @@ jmem_heap_alloc_block_internal (const size_t size)
         break;
       }
 
-      VALGRIND_NOACCESS_SPACE (current_p, sizeof (jmem_heap_free_t));
+      JMEM_VALGRIND_NOACCESS_SPACE (current_p, sizeof (jmem_heap_free_t));
       /* Next in list. */
       prev_p = current_p;
       current_offset = next_offset;
@@ -307,15 +269,15 @@ jmem_heap_alloc_block_internal (const size_t size)
     JERRY_CONTEXT (jmem_heap_limit) += CONFIG_MEM_HEAP_DESIRED_LIMIT;
   }
 
-  VALGRIND_NOACCESS_SPACE (&JERRY_HEAP_CONTEXT (first), sizeof (jmem_heap_free_t));
+  JMEM_VALGRIND_NOACCESS_SPACE (&JERRY_HEAP_CONTEXT (first), sizeof (jmem_heap_free_t));
 
-  if (unlikely (!data_space_p))
+  if (JERRY_UNLIKELY (!data_space_p))
   {
     return NULL;
   }
 
   JERRY_ASSERT ((uintptr_t) data_space_p % JMEM_ALIGNMENT == 0);
-  VALGRIND_UNDEFINED_SPACE (data_space_p, size);
+  JMEM_VALGRIND_UNDEFINED_SPACE (data_space_p, size);
   JMEM_HEAP_STAT_ALLOC (size);
 
   return (void *) data_space_p;
@@ -341,13 +303,11 @@ jmem_heap_gc_and_alloc_block (const size_t size,      /**< required memory size
                               bool ret_null_on_error) /**< indicates whether return null or terminate
                                                            with ERR_OUT_OF_MEMORY on out of memory */
 {
-  if (unlikely (size == 0))
+  if (JERRY_UNLIKELY (size == 0))
   {
     return NULL;
   }
 
-  VALGRIND_FREYA_CHECK_MEMPOOL_REQUEST;
-
 #ifdef JMEM_GC_BEFORE_EACH_ALLOC
   jmem_run_free_unused_memory_callbacks (JMEM_FREE_UNUSED_MEMORY_SEVERITY_HIGH);
 #endif /* JMEM_GC_BEFORE_EACH_ALLOC */
@@ -359,9 +319,9 @@ jmem_heap_gc_and_alloc_block (const size_t size,      /**< required memory size
 
   void *data_space_p = jmem_heap_alloc_block_internal (size);
 
-  if (likely (data_space_p != NULL))
+  if (JERRY_LIKELY (data_space_p != NULL))
   {
-    VALGRIND_FREYA_MALLOCLIKE_SPACE (data_space_p, size);
+    JMEM_VALGRIND_MALLOCLIKE_SPACE (data_space_p, size);
     return data_space_p;
   }
 
@@ -373,9 +333,9 @@ jmem_heap_gc_and_alloc_block (const size_t size,      /**< required memory size
 
     data_space_p = jmem_heap_alloc_block_internal (size);
 
-    if (likely (data_space_p != NULL))
+    if (JERRY_LIKELY (data_space_p != NULL))
     {
-      VALGRIND_FREYA_MALLOCLIKE_SPACE (data_space_p, size);
+      JMEM_VALGRIND_MALLOCLIKE_SPACE (data_space_p, size);
       return data_space_p;
     }
   }
@@ -400,7 +360,7 @@ jmem_heap_gc_and_alloc_block (const size_t size,      /**< required memory size
  * @return NULL, if the required memory is 0
  *         pointer to allocated memory block, otherwise
  */
-inline void * __attr_hot___ __attr_always_inline___
+inline void * JERRY_ATTR_HOT JERRY_ATTR_ALWAYS_INLINE
 jmem_heap_alloc_block (const size_t size)  /**< required memory size */
 {
   return jmem_heap_gc_and_alloc_block (size, false);
@@ -416,7 +376,7 @@ jmem_heap_alloc_block (const size_t size)  /**< required memory size */
  *         also NULL, if the allocation has failed
  *         pointer to the allocated memory block, otherwise
  */
-inline void * __attr_hot___ __attr_always_inline___
+inline void * JERRY_ATTR_HOT JERRY_ATTR_ALWAYS_INLINE
 jmem_heap_alloc_block_null_on_error (const size_t size) /**< required memory size */
 {
   return jmem_heap_gc_and_alloc_block (size, true);
@@ -425,27 +385,25 @@ jmem_heap_alloc_block_null_on_error (const size_t size) /**< required memory siz
 /**
  * Free the memory block.
  */
-void __attr_hot___
+void JERRY_ATTR_HOT
 jmem_heap_free_block (void *ptr, /**< pointer to beginning of data space of the block */
                       const size_t size) /**< size of allocated region */
 {
 #ifndef JERRY_SYSTEM_ALLOCATOR
-  VALGRIND_FREYA_CHECK_MEMPOOL_REQUEST;
-
   /* checking that ptr points to the heap */
   JERRY_ASSERT (jmem_is_heap_pointer (ptr));
   JERRY_ASSERT (size > 0);
   JERRY_ASSERT (JERRY_CONTEXT (jmem_heap_limit) >= JERRY_CONTEXT (jmem_heap_allocated_size));
 
-  VALGRIND_FREYA_FREELIKE_SPACE (ptr);
-  VALGRIND_NOACCESS_SPACE (ptr, size);
+  JMEM_VALGRIND_FREELIKE_SPACE (ptr);
+  JMEM_VALGRIND_NOACCESS_SPACE (ptr, size);
   JMEM_HEAP_STAT_FREE_ITER ();
 
   jmem_heap_free_t *block_p = (jmem_heap_free_t *) ptr;
   jmem_heap_free_t *prev_p;
   jmem_heap_free_t *next_p;
 
-  VALGRIND_DEFINED_SPACE (&JERRY_HEAP_CONTEXT (first), sizeof (jmem_heap_free_t));
+  JMEM_VALGRIND_DEFINED_SPACE (&JERRY_HEAP_CONTEXT (first), sizeof (jmem_heap_free_t));
 
   if (block_p > JERRY_CONTEXT (jmem_heap_list_skip_p))
   {
@@ -461,34 +419,34 @@ jmem_heap_free_block (void *ptr, /**< pointer to beginning of data space of the
   JERRY_ASSERT (jmem_is_heap_pointer (block_p));
   const uint32_t block_offset = JMEM_HEAP_GET_OFFSET_FROM_ADDR (block_p);
 
-  VALGRIND_DEFINED_SPACE (prev_p, sizeof (jmem_heap_free_t));
+  JMEM_VALGRIND_DEFINED_SPACE (prev_p, sizeof (jmem_heap_free_t));
   /* Find position of region in the list. */
   while (prev_p->next_offset < block_offset)
   {
     next_p = JMEM_HEAP_GET_ADDR_FROM_OFFSET (prev_p->next_offset);
     JERRY_ASSERT (jmem_is_heap_pointer (next_p));
 
-    VALGRIND_DEFINED_SPACE (next_p, sizeof (jmem_heap_free_t));
-    VALGRIND_NOACCESS_SPACE (prev_p, sizeof (jmem_heap_free_t));
+    JMEM_VALGRIND_DEFINED_SPACE (next_p, sizeof (jmem_heap_free_t));
+    JMEM_VALGRIND_NOACCESS_SPACE (prev_p, sizeof (jmem_heap_free_t));
     prev_p = next_p;
 
     JMEM_HEAP_STAT_FREE_ITER ();
   }
 
   next_p = JMEM_HEAP_GET_ADDR_FROM_OFFSET (prev_p->next_offset);
-  VALGRIND_DEFINED_SPACE (next_p, sizeof (jmem_heap_free_t));
+  JMEM_VALGRIND_DEFINED_SPACE (next_p, sizeof (jmem_heap_free_t));
 
   /* Realign size */
   const size_t aligned_size = (size + JMEM_ALIGNMENT - 1) / JMEM_ALIGNMENT * JMEM_ALIGNMENT;
 
-  VALGRIND_DEFINED_SPACE (block_p, sizeof (jmem_heap_free_t));
-  VALGRIND_DEFINED_SPACE (prev_p, sizeof (jmem_heap_free_t));
+  JMEM_VALGRIND_DEFINED_SPACE (block_p, sizeof (jmem_heap_free_t));
+  JMEM_VALGRIND_DEFINED_SPACE (prev_p, sizeof (jmem_heap_free_t));
   /* Update prev. */
   if (jmem_heap_get_region_end (prev_p) == block_p)
   {
     /* Can be merged. */
     prev_p->size += (uint32_t) aligned_size;
-    VALGRIND_NOACCESS_SPACE (block_p, sizeof (jmem_heap_free_t));
+    JMEM_VALGRIND_NOACCESS_SPACE (block_p, sizeof (jmem_heap_free_t));
     block_p = prev_p;
   }
   else
@@ -497,7 +455,7 @@ jmem_heap_free_block (void *ptr, /**< pointer to beginning of data space of the
     prev_p->next_offset = block_offset;
   }
 
-  VALGRIND_DEFINED_SPACE (next_p, sizeof (jmem_heap_free_t));
+  JMEM_VALGRIND_DEFINED_SPACE (next_p, sizeof (jmem_heap_free_t));
   /* Update next. */
   if (jmem_heap_get_region_end (block_p) == next_p)
   {
@@ -512,9 +470,9 @@ jmem_heap_free_block (void *ptr, /**< pointer to beginning of data space of the
 
   JERRY_CONTEXT (jmem_heap_list_skip_p) = prev_p;
 
-  VALGRIND_NOACCESS_SPACE (prev_p, sizeof (jmem_heap_free_t));
-  VALGRIND_NOACCESS_SPACE (block_p, size);
-  VALGRIND_NOACCESS_SPACE (next_p, sizeof (jmem_heap_free_t));
+  JMEM_VALGRIND_NOACCESS_SPACE (prev_p, sizeof (jmem_heap_free_t));
+  JMEM_VALGRIND_NOACCESS_SPACE (block_p, size);
+  JMEM_VALGRIND_NOACCESS_SPACE (next_p, sizeof (jmem_heap_free_t));
 
   JERRY_ASSERT (JERRY_CONTEXT (jmem_heap_allocated_size) > 0);
   JERRY_CONTEXT (jmem_heap_allocated_size) -= aligned_size;
@@ -524,15 +482,11 @@ jmem_heap_free_block (void *ptr, /**< pointer to beginning of data space of the
     JERRY_CONTEXT (jmem_heap_limit) -= CONFIG_MEM_HEAP_DESIRED_LIMIT;
   }
 
-  VALGRIND_NOACCESS_SPACE (&JERRY_HEAP_CONTEXT (first), sizeof (jmem_heap_free_t));
+  JMEM_VALGRIND_NOACCESS_SPACE (&JERRY_HEAP_CONTEXT (first), sizeof (jmem_heap_free_t));
   JERRY_ASSERT (JERRY_CONTEXT (jmem_heap_limit) >= JERRY_CONTEXT (jmem_heap_allocated_size));
   JMEM_HEAP_STAT_FREE (size);
 #else /* JERRY_SYSTEM_ALLOCATOR */
-#ifdef JMEM_STATS
   JMEM_HEAP_STAT_FREE (size);
-#else /* !JMEM_STATS */
-  JERRY_UNUSED (size);
-#endif /* JMEM_STATS */
   free (ptr);
 #endif /* !JERRY_SYSTEM_ALLOCATOR */
 } /* jmem_heap_free_block */
@@ -580,9 +534,12 @@ jmem_heap_stats_print (void)
 {
   jmem_heap_stats_t *heap_stats = &JERRY_CONTEXT (jmem_heap_stats);
 
-  JERRY_DEBUG_MSG ("Heap stats:\n"
-                   "  Heap size = %zu bytes\n"
-                   "  Allocated = %zu bytes\n"
+  JERRY_DEBUG_MSG ("Heap stats:\n");
+#ifndef JERRY_SYSTEM_ALLOCATOR
+  JERRY_DEBUG_MSG ("  Heap size = %zu bytes\n",
+                   heap_stats->size);
+#endif /* !JERRY_SYSTEM_ALLOCATOR */
+  JERRY_DEBUG_MSG ("  Allocated = %zu bytes\n"
                    "  Peak allocated = %zu bytes\n"
                    "  Waste = %zu bytes\n"
                    "  Peak waste = %zu bytes\n"
@@ -594,7 +551,6 @@ jmem_heap_stats_print (void)
                    "  Peak allocated object data = %zu bytes\n"
                    "  Allocated property data = %zu bytes\n"
                    "  Peak allocated property data = %zu bytes\n",
-                   heap_stats->size,
                    heap_stats->allocated_bytes,
                    heap_stats->peak_allocated_bytes,
                    heap_stats->waste_bytes,
@@ -626,7 +582,9 @@ jmem_heap_stats_print (void)
 static void
 jmem_heap_stat_init (void)
 {
+#ifndef JERRY_SYSTEM_ALLOCATOR
   JERRY_CONTEXT (jmem_heap_stats).size = JMEM_HEAP_AREA_SIZE;
+#endif /* !JERRY_SYSTEM_ALLOCATOR */
 } /* jmem_heap_stat_init */
 
 /**
@@ -710,13 +668,6 @@ jmem_heap_stat_free_iter (void)
 #endif /* !JERRY_SYSTEM_ALLOCATOR */
 #endif /* JMEM_STATS */
 
-#undef VALGRIND_NOACCESS_SPACE
-#undef VALGRIND_UNDEFINED_SPACE
-#undef VALGRIND_DEFINED_SPACE
-#undef VALGRIND_FREYA_CHECK_MEMPOOL_REQUEST
-#undef VALGRIND_FREYA_MALLOCLIKE_SPACE
-#undef VALGRIND_FREYA_FREELIKE_SPACE
-
 /**
  * @}
  * @}
index e9092b247b7f53b7a602f9c6c28337feb9cef2c5..d34e94eeb06ca493a54c727d3d52be019ff37c74 100644 (file)
  * @{
  */
 
-/*
- * Valgrind-related options and headers
- */
-#ifdef JERRY_VALGRIND
-# include "memcheck.h"
-
-# define VALGRIND_NOACCESS_SPACE(p, s)   VALGRIND_MAKE_MEM_NOACCESS((p), (s))
-# define VALGRIND_UNDEFINED_SPACE(p, s)  VALGRIND_MAKE_MEM_UNDEFINED((p), (s))
-# define VALGRIND_DEFINED_SPACE(p, s)    VALGRIND_MAKE_MEM_DEFINED((p), (s))
-#else /* !JERRY_VALGRIND */
-# define VALGRIND_NOACCESS_SPACE(p, s)
-# define VALGRIND_UNDEFINED_SPACE(p, s)
-# define VALGRIND_DEFINED_SPACE(p, s)
-#endif /* JERRY_VALGRIND */
-
-#ifdef JERRY_VALGRIND_FREYA
-# include "memcheck.h"
-
-# define VALGRIND_FREYA_MALLOCLIKE_SPACE(p, s) VALGRIND_MALLOCLIKE_BLOCK((p), (s), 0, 0)
-# define VALGRIND_FREYA_FREELIKE_SPACE(p)      VALGRIND_FREELIKE_BLOCK((p), 0)
-#else /* !JERRY_VALGRIND_FREYA */
-# define VALGRIND_FREYA_MALLOCLIKE_SPACE(p, s)
-# define VALGRIND_FREYA_FREELIKE_SPACE(p)
-#endif /* JERRY_VALGRIND_FREYA */
-
 /**
  * Finalize pool manager
  */
@@ -76,24 +51,29 @@ jmem_pools_finalize (void)
  * @return pointer to allocated chunk, if allocation was successful,
  *         or NULL - if not enough memory.
  */
-inline void * __attr_hot___ __attr_always_inline___
+inline void * JERRY_ATTR_HOT JERRY_ATTR_ALWAYS_INLINE
 jmem_pools_alloc (size_t size) /**< size of the chunk */
 {
 #ifdef JMEM_GC_BEFORE_EACH_ALLOC
   jmem_run_free_unused_memory_callbacks (JMEM_FREE_UNUSED_MEMORY_SEVERITY_HIGH);
 #endif /* JMEM_GC_BEFORE_EACH_ALLOC */
 
+#ifdef JERRY_CPOINTER_32_BIT
   if (size <= 8)
   {
+#else /* !JERRY_CPOINTER_32_BIT */
+    JERRY_ASSERT (size <= 8);
+#endif /* JERRY_CPOINTER_32_BIT */
+
     if (JERRY_CONTEXT (jmem_free_8_byte_chunk_p) != NULL)
     {
       const jmem_pools_chunk_t *const chunk_p = JERRY_CONTEXT (jmem_free_8_byte_chunk_p);
 
-      VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
+      JMEM_VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
 
       JERRY_CONTEXT (jmem_free_8_byte_chunk_p) = chunk_p->next_p;
 
-      VALGRIND_UNDEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
+      JMEM_VALGRIND_UNDEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
 
       return (void *) chunk_p;
     }
@@ -101,20 +81,21 @@ jmem_pools_alloc (size_t size) /**< size of the chunk */
     {
       return (void *) jmem_heap_alloc_block (8);
     }
-  }
 
 #ifdef JERRY_CPOINTER_32_BIT
+  }
+
   JERRY_ASSERT (size <= 16);
 
   if (JERRY_CONTEXT (jmem_free_16_byte_chunk_p) != NULL)
   {
     const jmem_pools_chunk_t *const chunk_p = JERRY_CONTEXT (jmem_free_16_byte_chunk_p);
 
-    VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
+    JMEM_VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
 
     JERRY_CONTEXT (jmem_free_16_byte_chunk_p) = chunk_p->next_p;
 
-    VALGRIND_UNDEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
+    JMEM_VALGRIND_UNDEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
 
     return (void *) chunk_p;
   }
@@ -122,16 +103,13 @@ jmem_pools_alloc (size_t size) /**< size of the chunk */
   {
     return (void *) jmem_heap_alloc_block (16);
   }
-#else /* !JERRY_CPOINTER_32_BIT */
-  JERRY_UNREACHABLE ();
-  return NULL;
-#endif
+#endif /* JERRY_CPOINTER_32_BIT */
 } /* jmem_pools_alloc */
 
 /**
  * Free the chunk
  */
-inline void __attr_hot___ __attr_always_inline___
+inline void JERRY_ATTR_HOT JERRY_ATTR_ALWAYS_INLINE
 jmem_pools_free (void *chunk_p, /**< pointer to the chunk */
                  size_t size) /**< size of the chunk */
 {
@@ -139,26 +117,30 @@ jmem_pools_free (void *chunk_p, /**< pointer to the chunk */
 
   jmem_pools_chunk_t *const chunk_to_free_p = (jmem_pools_chunk_t *) chunk_p;
 
-  VALGRIND_DEFINED_SPACE (chunk_to_free_p, size);
+  JMEM_VALGRIND_DEFINED_SPACE (chunk_to_free_p, size);
 
+#ifdef JERRY_CPOINTER_32_BIT
   if (size <= 8)
   {
+#else /* !JERRY_CPOINTER_32_BIT */
+    JERRY_ASSERT (size <= 8);
+#endif /* JERRY_CPOINTER_32_BIT */
+
     chunk_to_free_p->next_p = JERRY_CONTEXT (jmem_free_8_byte_chunk_p);
     JERRY_CONTEXT (jmem_free_8_byte_chunk_p) = chunk_to_free_p;
+
+#ifdef JERRY_CPOINTER_32_BIT
   }
   else
   {
-#ifdef JERRY_CPOINTER_32_BIT
     JERRY_ASSERT (size <= 16);
 
     chunk_to_free_p->next_p = JERRY_CONTEXT (jmem_free_16_byte_chunk_p);
     JERRY_CONTEXT (jmem_free_16_byte_chunk_p) = chunk_to_free_p;
-#else /* !JERRY_CPOINTER_32_BIT */
-    JERRY_UNREACHABLE ();
-#endif /* JERRY_CPOINTER_32_BIT */
   }
+#endif /* JERRY_CPOINTER_32_BIT */
 
-  VALGRIND_NOACCESS_SPACE (chunk_to_free_p, size);
+  JMEM_VALGRIND_NOACCESS_SPACE (chunk_to_free_p, size);
 } /* jmem_pools_free */
 
 /**
@@ -172,9 +154,9 @@ jmem_pools_collect_empty (void)
 
   while (chunk_p)
   {
-    VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
+    JMEM_VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
     jmem_pools_chunk_t *const next_p = chunk_p->next_p;
-    VALGRIND_NOACCESS_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
+    JMEM_VALGRIND_NOACCESS_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
 
     jmem_heap_free_block (chunk_p, 8);
     chunk_p = next_p;
@@ -186,9 +168,9 @@ jmem_pools_collect_empty (void)
 
   while (chunk_p)
   {
-    VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
+    JMEM_VALGRIND_DEFINED_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
     jmem_pools_chunk_t *const next_p = chunk_p->next_p;
-    VALGRIND_NOACCESS_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
+    JMEM_VALGRIND_NOACCESS_SPACE (chunk_p, sizeof (jmem_pools_chunk_t));
 
     jmem_heap_free_block (chunk_p, 16);
     chunk_p = next_p;
@@ -196,12 +178,6 @@ jmem_pools_collect_empty (void)
 #endif /* JERRY_CPOINTER_32_BIT */
 } /* jmem_pools_collect_empty */
 
-#undef VALGRIND_NOACCESS_SPACE
-#undef VALGRIND_UNDEFINED_SPACE
-#undef VALGRIND_DEFINED_SPACE
-#undef VALGRIND_FREYA_MALLOCLIKE_SPACE
-#undef VALGRIND_FREYA_FREELIKE_SPACE
-
 /**
  * @}
  * @}
index c2620b596887f1a030f58239dc513bdfa4903c28..8665e52fc8f94cd41860a20d842c7996303552d4 100644 (file)
  * @{
  */
 
-#ifndef JERRY_ENABLE_EXTERNAL_CONTEXT
-/**
- * Size of heap
- */
-#define JMEM_HEAP_SIZE ((size_t) (CONFIG_MEM_HEAP_AREA_SIZE))
-#endif /* !JERRY_ENABLE_EXTERNAL_CONTEXT */
-
 /**
  * Logarithm of required alignment for allocated units/blocks
  */
@@ -151,7 +144,6 @@ typedef struct
   size_t free_iter_count; /**< Number of iterations required for inserting free blocks */
 } jmem_heap_stats_t;
 
-void jmem_stats_print (void);
 void jmem_stats_allocate_byte_code_bytes (size_t property_size);
 void jmem_stats_free_byte_code_bytes (size_t property_size);
 void jmem_stats_allocate_string_bytes (size_t string_size);
@@ -164,8 +156,8 @@ void jmem_stats_free_property_bytes (size_t property_size);
 void jmem_heap_get_stats (jmem_heap_stats_t *);
 #endif /* JMEM_STATS */
 
-jmem_cpointer_t jmem_compress_pointer (const void *pointer_p) __attr_pure___;
-void *jmem_decompress_pointer (uintptr_t compressed_pointer) __attr_pure___;
+jmem_cpointer_t JERRY_ATTR_PURE jmem_compress_pointer (const void *pointer_p);
+void * JERRY_ATTR_PURE jmem_decompress_pointer (uintptr_t compressed_pointer);
 
 /**
  * A free memory callback routine type.
@@ -217,7 +209,7 @@ void jmem_run_free_unused_memory_callbacks (jmem_free_unused_memory_severity_t s
  * Get value of pointer from specified compressed pointer value
  */
 #define JMEM_CP_GET_POINTER(type, cp_value) \
-  (((unlikely ((cp_value) == JMEM_CP_NULL)) ? NULL : JMEM_CP_GET_NON_NULL_POINTER (type, cp_value)))
+  (((JERRY_UNLIKELY ((cp_value) == JMEM_CP_NULL)) ? NULL : JMEM_CP_GET_NON_NULL_POINTER (type, cp_value)))
 
 /**
  * Set value of non-null compressed pointer so that it will correspond
@@ -235,7 +227,7 @@ void jmem_run_free_unused_memory_callbacks (jmem_free_unused_memory_severity_t s
   { \
     void *ptr_value = (void *) non_compressed_pointer; \
     \
-    if (unlikely ((ptr_value) == NULL)) \
+    if (JERRY_UNLIKELY ((ptr_value) == NULL)) \
     { \
       (cp_value) = JMEM_CP_NULL; \
     } \
index d5d81706fa97a9c953c4861abcb5d1cf85762a98..838cbc92548d42d4ccda1d2eea16bb9b2564a46d 100644 (file)
@@ -26,7 +26,7 @@
  * If !JERRY_NDEBUG and code != 0, print status code with description
  * and call assertion fail handler.
  */
-void __noreturn
+void JERRY_ATTR_NORETURN
 jerry_fatal (jerry_fatal_code_t code) /**< status code */
 {
 #ifndef JERRY_NDEBUG
@@ -47,6 +47,11 @@ jerry_fatal (jerry_fatal_code_t code) /**< status code */
       JERRY_ERROR_MSG ("Error: ERR_REF_COUNT_LIMIT\n");
       break;
     }
+    case ERR_DISABLED_BYTE_CODE:
+    {
+      JERRY_ERROR_MSG ("Error: ERR_DISABLED_BYTE_CODE\n");
+      break;
+    }
     case ERR_FAILED_INTERNAL_ASSERTION:
     {
       JERRY_ERROR_MSG ("Error: ERR_FAILED_INTERNAL_ASSERTION\n");
@@ -67,7 +72,7 @@ jerry_fatal (jerry_fatal_code_t code) /**< status code */
 /**
  * Handle failed assertion
  */
-void __noreturn
+void JERRY_ATTR_NORETURN
 jerry_assert_fail (const char *assertion, /**< assertion condition string */
                    const char *file, /**< file name */
                    const char *function, /**< function name */
@@ -85,7 +90,7 @@ jerry_assert_fail (const char *assertion, /**< assertion condition string */
 /**
  * Handle execution of control path that should be unreachable
  */
-void __noreturn
+void JERRY_ATTR_NORETURN
 jerry_unreachable (const char *file, /**< file name */
                    const char *function, /**< function name */
                    const uint32_t line) /**< line */
index 46ab6b203ebe77b9a38b0159801d3941c21cd165..12e3d908fadf96c304d037bfbfc7dfad7b7bfe3d 100644 (file)
 #ifndef JRT_H
 #define JRT_H
 
-#if !defined (_XOPEN_SOURCE) || _XOPEN_SOURCE < 500
-#undef _XOPEN_SOURCE
-/* Required macro for sleep functions (nanosleep or usleep) */
-#define _XOPEN_SOURCE 500
-#endif
-
 #include <stdio.h>
 #include <string.h>
 
 #include "jerryscript-port.h"
 #include "jrt-types.h"
 
-/*
- * Attributes
- */
-#define __noreturn __attribute__((noreturn))
-#define __attr_noinline___ __attribute__((noinline))
-#define __attr_return_value_should_be_checked___ __attribute__((warn_unused_result))
-#define __attr_hot___ __attribute__((hot))
-#ifndef __attr_always_inline___
-#define __attr_always_inline___ __attribute__((always_inline))
-#endif /* !__attr_always_inline___ */
-#ifndef __attr_const___
-#define __attr_const___ __attribute__((const))
-#endif /* !__attr_const___ */
-#ifndef __attr_pure___
-#define __attr_pure___ __attribute__((pure))
-#endif /* !__attr_pure___ */
-
-/*
- * Conditions' likeliness, unlikeliness.
- */
-#ifdef __GNUC__
-#define likely(x)       __builtin_expect(!!(x), 1)
-#define unlikely(x)     __builtin_expect(!!(x), 0)
-#else /* !__GNUC__ */
-#define likely(x)       (x)
-#define unlikely(x)     (x)
-#endif /* __GNUC__ */
-
 /*
  * 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.
  */
 #define JERRY_UNUSED(x) ((void) (x))
 
+#define JERRY_UNUSED_1(_1)                 JERRY_UNUSED (_1)
+#define JERRY_UNUSED_2(_1, _2)             JERRY_UNUSED (_1), JERRY_UNUSED_1 (_2)
+#define JERRY_UNUSED_3(_1, _2, _3)         JERRY_UNUSED (_1), JERRY_UNUSED_2 (_2, _3)
+#define JERRY_UNUSED_4(_1, _2, _3, _4)     JERRY_UNUSED (_1), JERRY_UNUSED_3 (_2, _3, _4)
+#define JERRY_UNUSED_5(_1, _2, _3, _4, _5) JERRY_UNUSED (_1), JERRY_UNUSED_4 (_2, _3, _4, _5)
+
+#define JERRY_VA_ARGS_NUM_IMPL(_1, _2, _3, _4, _5, N, ...) N
+#define JERRY_VA_ARGS_NUM(...) JERRY_VA_ARGS_NUM_IMPL (__VA_ARGS__, 5, 4, 3, 2, 1, 0)
+
+#define JERRY_UNUSED_ALL_IMPL_(nargs) JERRY_UNUSED_ ## nargs
+#define JERRY_UNUSED_ALL_IMPL(nargs) JERRY_UNUSED_ALL_IMPL_ (nargs)
+#define JERRY_UNUSED_ALL(...) JERRY_UNUSED_ALL_IMPL (JERRY_VA_ARGS_NUM (__VA_ARGS__)) (__VA_ARGS__)
+
 /*
  * Asserts
  *
   enum { JERRY_STATIC_ASSERT_GLUE (static_assertion_failed_, __LINE__, msg) = 1 / (!!(x)) }
 
 #ifndef JERRY_NDEBUG
-void __noreturn jerry_assert_fail (const char *assertion, const char *file, const char *function, const uint32_t line);
-void __noreturn jerry_unreachable (const char *file, const char *function, const uint32_t line);
+void JERRY_ATTR_NORETURN
+jerry_assert_fail (const char *assertion, const char *file, const char *function, const uint32_t line);
+void JERRY_ATTR_NORETURN
+jerry_unreachable (const char *file, const char *function, const uint32_t line);
 
 #define JERRY_ASSERT(x) \
   do \
   { \
-    if (unlikely (!(x))) \
+    if (JERRY_UNLIKELY (!(x))) \
     { \
       jerry_assert_fail (#x, __FILE__, __func__, __LINE__); \
     } \
@@ -120,23 +101,37 @@ void __noreturn jerry_unreachable (const char *file, const char *function, const
 
 #ifdef __GNUC__
 #define JERRY_UNREACHABLE() __builtin_unreachable ()
-#else /* !__GNUC__ */
-#define JERRY_UNREACHABLE()
 #endif /* __GNUC__ */
+
+#ifdef _MSC_VER
+#define JERRY_UNREACHABLE()  _assume (0)
+#endif /* _MSC_VER */
+
+#ifndef JERRY_UNREACHABLE
+#define JERRY_UNREACHABLE()
+#endif /* !JERRY_UNREACHABLE */
+
 #endif /* !JERRY_NDEBUG */
 
 /**
  * Exit on fatal error
  */
-void __noreturn jerry_fatal (jerry_fatal_code_t code);
+void JERRY_ATTR_NORETURN jerry_fatal (jerry_fatal_code_t code);
 
 /*
  * Logging
  */
+#ifdef JERRY_ENABLE_LOGGING
 #define JERRY_ERROR_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_ERROR, __VA_ARGS__)
 #define JERRY_WARNING_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_WARNING, __VA_ARGS__)
 #define JERRY_DEBUG_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_DEBUG, __VA_ARGS__)
 #define JERRY_TRACE_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_TRACE, __VA_ARGS__)
+#else /* !JERRY_ENABLE_LOGGING */
+#define JERRY_ERROR_MSG(...) do { if (false) { JERRY_UNUSED_ALL (__VA_ARGS__); } } while (0)
+#define JERRY_WARNING_MSG(...) do { if (false) { JERRY_UNUSED_ALL (__VA_ARGS__); } } while (0)
+#define JERRY_DEBUG_MSG(...) do { if (false) { JERRY_UNUSED_ALL (__VA_ARGS__); } } while (0)
+#define JERRY_TRACE_MSG(...) do { if (false) { JERRY_UNUSED_ALL (__VA_ARGS__); } } while (0)
+#endif /* JERRY_ENABLE_LOGGING */
 
 /**
  * Size of struct member
@@ -156,4 +151,13 @@ void __noreturn jerry_fatal (jerry_fatal_code_t code);
 #define JERRY_MIN(v1, v2) (((v1) < (v2)) ? (v1) : (v2))
 #define JERRY_MAX(v1, v2) (((v1) < (v2)) ? (v2) : (v1))
 
+/**
+ * Calculate the index of the first non-zero bit of a 32 bit integer value
+ */
+#define JERRY__LOG2_1(n) (((n) >= 2) ? 1 : 0)
+#define JERRY__LOG2_2(n) (((n) >= 1 << 2) ? (2 + JERRY__LOG2_1 ((n) >> 2)) : JERRY__LOG2_1 (n))
+#define JERRY__LOG2_4(n) (((n) >= 1 << 4) ? (4 + JERRY__LOG2_2 ((n) >> 4)) : JERRY__LOG2_2 (n))
+#define JERRY__LOG2_8(n) (((n) >= 1 << 8) ? (8 + JERRY__LOG2_4 ((n) >> 8)) : JERRY__LOG2_4 (n))
+#define JERRY_LOG2(n) (((n) >= 1 << 16) ? (16 + JERRY__LOG2_8 ((n) >> 16)) : JERRY__LOG2_8 (n))
+
 #endif /* !JRT_H */
index cb790fc5db2a0dc8c797e22e0af9f7c30c6e714a..ac25d9e18d3c8b8eef26b68f5e5d4491d56d9583 100644 (file)
@@ -14,7 +14,7 @@
  */
 
 #include "lit-char-helpers.h"
-#include "lit/lit-unicode-ranges.inc.h"
+#include "lit-unicode-ranges.inc.h"
 #include "lit-strings.h"
 
 #ifndef CONFIG_DISABLE_UNICODE_CASE_CONVERSION
@@ -101,20 +101,6 @@ search_char_in_interval_array (ecma_char_t c,               /**< code unit */
   return false;
 } /* search_char_in_interval_array */
 
-/**
- * Check if specified character is one of the Format-Control characters
- *
- * @return true - if the character is one of characters, listed in ECMA-262 v5, Table 1,
- *         false - otherwise
- */
-bool
-lit_char_is_format_control (ecma_char_t c) /**< code unit */
-{
-  return (c == LIT_CHAR_ZWNJ
-          || c == LIT_CHAR_ZWJ
-          || c == LIT_CHAR_BOM);
-} /* lit_char_is_format_control */
-
 /**
  * Check if specified character is one of the Whitespace characters including those
  * that fall into "Space, Separator" ("Zs") Unicode character category.
@@ -428,7 +414,7 @@ lit_char_get_utf8_length (ecma_char_t chr) /**< EcmaScript character */
 bool
 lit_read_code_unit_from_hex (const lit_utf8_byte_t *buf_p, /**< buffer with characters */
                              lit_utf8_size_t number_of_characters, /**< number of characters to be read */
-                             ecma_char_ptr_t out_code_unit_p) /**< [out] decoded result */
+                             ecma_char_t *out_code_unit_p) /**< [out] decoded result */
 {
   ecma_char_t code_unit = LIT_CHAR_NULL;
 
index ae018c916ac7c81440ec1f15b0288e603d0661d9..08c0439a0e8f59a52c99f6c5dfc4d50662ffd025 100644 (file)
@@ -27,8 +27,6 @@
 #define LIT_CHAR_ZWJ  ((ecma_char_t) 0x200D) /* zero width joiner */
 #define LIT_CHAR_BOM  ((ecma_char_t) 0xFEFF) /* byte order mark */
 
-bool lit_char_is_format_control (ecma_char_t c);
-
 /*
  * Whitespace characters (ECMA-262 v5, Table 2)
  */
@@ -222,7 +220,7 @@ size_t lit_char_get_utf8_length (ecma_char_t chr);
 
 /* read a hex encoded code point from a zero terminated buffer */
 bool lit_read_code_unit_from_hex (const lit_utf8_byte_t *buf_p, lit_utf8_size_t number_of_characters,
-                                  ecma_char_ptr_t out_code_unit_p);
+                                  ecma_char_t *out_code_unit_p);
 
 /**
  * Null character
index df4716d2357747d491cfcf8fb428b59758904551..8cfe6aeb1f14c1e9b404c73378d82e08bc5fe674 100644 (file)
@@ -78,11 +78,6 @@ typedef uint16_t ecma_char_t;
  */
 typedef uint32_t ecma_length_t;
 
-/**
- * Description of an ecma-character pointer
- */
-typedef ecma_char_t *ecma_char_ptr_t;
-
 /**
  * Max bytes needed to represent a code unit (utf-16 char) via utf-8 encoding
  */
index ce220de389909293dfc3e3e59f19caf556097d62..b316ebf68efc551951c206d1676e43bcd30b41d1 100644 (file)
@@ -23,7 +23,7 @@
  * @return number of the strings, if there were registered,
  *         zero - otherwise.
  */
-inline uint32_t __attr_always_inline___
+inline uint32_t JERRY_ATTR_ALWAYS_INLINE
 lit_get_magic_string_ex_count (void)
 {
   return JERRY_CONTEXT (lit_magic_string_ex_count);
@@ -39,12 +39,14 @@ lit_get_magic_string_utf8 (lit_magic_string_id_t id) /**< magic string id */
 {
   static const lit_utf8_byte_t * const lit_magic_strings[] JERRY_CONST_DATA =
   {
+/** @cond doxygen_suppress */
 #define LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE(size, id)
 #define LIT_MAGIC_STRING_DEF(id, utf8_string) \
     (const lit_utf8_byte_t *) utf8_string,
 #include "lit-magic-strings.inc.h"
 #undef LIT_MAGIC_STRING_DEF
 #undef LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE
+/** @endcond */
   };
 
   JERRY_ASSERT (id < LIT_NON_INTERNAL_MAGIC_STRING__COUNT);
@@ -62,12 +64,14 @@ lit_get_magic_string_size (lit_magic_string_id_t id) /**< magic string id */
 {
   static const lit_magic_size_t lit_magic_string_sizes[] JERRY_CONST_DATA =
   {
+/** @cond doxygen_suppress */
 #define LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE(size, id)
 #define LIT_MAGIC_STRING_DEF(id, utf8_string) \
     sizeof(utf8_string) - 1,
 #include "lit-magic-strings.inc.h"
 #undef LIT_MAGIC_STRING_DEF
 #undef LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE
+/** @endcond */
   };
 
   JERRY_ASSERT (id < LIT_NON_INTERNAL_MAGIC_STRING__COUNT);
@@ -81,11 +85,12 @@ lit_get_magic_string_size (lit_magic_string_id_t id) /**< magic string id */
  *
  * @return magic string id
  */
-lit_magic_string_id_t
+static lit_magic_string_id_t
 lit_get_magic_string_size_block_start (lit_utf8_size_t size) /**< magic string size */
 {
   static const lit_magic_string_id_t lit_magic_string_size_block_starts[] JERRY_CONST_DATA =
   {
+/** @cond doxygen_suppress */
 #define LIT_MAGIC_STRING_DEF(id, utf8_string)
 #define LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE(size, id) \
     id,
@@ -93,6 +98,7 @@ lit_get_magic_string_size_block_start (lit_utf8_size_t size) /**< magic string s
     LIT_NON_INTERNAL_MAGIC_STRING__COUNT
 #undef LIT_MAGIC_STRING_DEF
 #undef LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE
+/** @endcond */
   };
 
   JERRY_ASSERT (size <= (sizeof (lit_magic_string_size_block_starts) / sizeof (lit_magic_string_id_t)));
@@ -108,12 +114,9 @@ lit_get_magic_string_size_block_start (lit_utf8_size_t size) /**< magic string s
 const lit_utf8_byte_t *
 lit_get_magic_string_ex_utf8 (lit_magic_string_ex_id_t id) /**< extern magic string id */
 {
-  if (JERRY_CONTEXT (lit_magic_string_ex_array) && id < JERRY_CONTEXT (lit_magic_string_ex_count))
-  {
-    return JERRY_CONTEXT (lit_magic_string_ex_array)[id];
-  }
+  JERRY_ASSERT (JERRY_CONTEXT (lit_magic_string_ex_array) && id < JERRY_CONTEXT (lit_magic_string_ex_count));
 
-  JERRY_UNREACHABLE ();
+  return JERRY_CONTEXT (lit_magic_string_ex_array)[id];
 } /* lit_get_magic_string_ex_utf8 */
 
 /**
@@ -131,8 +134,8 @@ lit_get_magic_string_ex_size (lit_magic_string_ex_id_t id) /**< external magic s
  * Register external magic strings
  */
 void
-lit_magic_strings_ex_set (const lit_utf8_byte_t **ex_str_items, /**< character arrays, representing
-                                                                 *   external magic strings' contents */
+lit_magic_strings_ex_set (const lit_utf8_byte_t * const *ex_str_items, /**< character arrays, representing
+                                                                        *   external magic strings' contents */
                           uint32_t count,                       /**< number of the strings */
                           const lit_utf8_size_t *ex_str_sizes)  /**< sizes of the strings */
 {
@@ -154,9 +157,7 @@ lit_magic_strings_ex_set (const lit_utf8_byte_t **ex_str_items, /**< character a
        id < JERRY_CONTEXT (lit_magic_string_ex_count);
        id = (lit_magic_string_ex_id_t) (id + 1))
   {
-    lit_utf8_size_t string_size = lit_zt_utf8_string_size (lit_get_magic_string_ex_utf8 (id));
-    JERRY_ASSERT (JERRY_CONTEXT (lit_magic_string_ex_sizes)[id] == string_size);
-    JERRY_ASSERT (JERRY_CONTEXT (lit_magic_string_ex_sizes)[id] <= LIT_MAGIC_STRING_LENGTH_LIMIT);
+    lit_utf8_size_t string_size = JERRY_CONTEXT (lit_magic_string_ex_sizes)[id];
 
     /**
      * Check whether the strings are sorted by size and lexicographically,
@@ -166,6 +167,8 @@ lit_magic_strings_ex_set (const lit_utf8_byte_t **ex_str_items, /**< character a
     {
       const lit_magic_string_ex_id_t prev_id = id - 1;
       const lit_utf8_size_t prev_string_size = lit_get_magic_string_ex_size (prev_id);
+      JERRY_ASSERT (lit_is_valid_cesu8_string (lit_get_magic_string_ex_utf8 (id),
+                                               string_size));
       JERRY_ASSERT (prev_string_size <= string_size);
 
       if (prev_string_size == string_size)
@@ -201,7 +204,7 @@ lit_is_utf8_string_magic (const lit_utf8_byte_t *string_p, /**< utf-8 string */
   while (first < last)
   {
     lit_utf8_size_t middle = ((first + last) / 2); /**< mid point of search */
-    int compare = memcmp (lit_get_magic_string_utf8 (middle), string_p, string_size);
+    int compare = memcmp (lit_get_magic_string_utf8 ((lit_magic_string_id_t) middle), string_p, string_size);
 
     if (compare == 0)
     {
@@ -246,7 +249,7 @@ lit_is_utf8_string_pair_magic (const lit_utf8_byte_t *string1_p, /**< first utf-
   while (first < last)
   {
     lit_utf8_size_t middle = ((first + last) / 2); /**< mid point of search */
-    const lit_utf8_byte_t *middle_string_p = lit_get_magic_string_utf8 (middle);
+    const lit_utf8_byte_t *middle_string_p = lit_get_magic_string_utf8 ((lit_magic_string_id_t) middle);
 
     int compare = memcmp (middle_string_p, string1_p, string1_size);
 
index 940330e1d5c9db5802073697bfec7b9a5975eb6c..1e40636a398f3258d23502e4aba46fe40fa283e3 100644 (file)
 
 #include "lit-globals.h"
 
-/**
- * Limit for magic string length
- */
-#define LIT_MAGIC_STRING_LENGTH_LIMIT 32
-
 /**
  * Identifiers of ECMA and implementation-defined magic string constants
  */
 typedef enum
 {
+/** @cond doxygen_suppress */
 #define LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE(size, id)
 #define LIT_MAGIC_STRING_DEF(id, ascii_zt_string) \
      id,
 #include "lit-magic-strings.inc.h"
 #undef LIT_MAGIC_STRING_DEF
 #undef LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE
+/** @endcond */
   LIT_NON_INTERNAL_MAGIC_STRING__COUNT, /**< number of non-internal magic strings */
   LIT_INTERNAL_MAGIC_STRING_PROMISE = LIT_NON_INTERNAL_MAGIC_STRING__COUNT, /**<  [[Promise]] of promise
                                                                              *    reject or resolve functions */
   LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED, /**< [[AlreadyResolved]] of promise reject or resolve functions */
   LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION, /**< the resolve funtion of the promise object */
   LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION, /**< the reject function of the promise object */
-  LIT_NEED_MARK_MAGIC_STRING__COUNT,  /**< number of internal magic strings which will be used as properties' names,
-                                       *   and the properties need to be marked during gc. */
-  LIT_INTERNAL_MAGIC_STRING_NATIVE_HANDLE = LIT_NEED_MARK_MAGIC_STRING__COUNT, /**< native handle package
-                                                                                *   associated with an object */
-  LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER, /**< native pointer package associated with an object */
+  LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_PROMISE, /**< [[Promise]] property */
+  LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_RESOLVE, /**< [[Resolve]] property */
+  LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REJECT, /**< [[Reject]] property */
+  LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_CAPABILITY, /**< [[Capability]] property */
+  LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_HANDLER, /**< [[Handler]] property */
+  LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_ALREADY_CALLED, /**< [[AlreadyCalled]] property */
+  LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_INDEX, /**< [[Index]] property */
+  LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_VALUE, /**< [[Values]] property */
+  LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REMAINING_ELEMENT, /**< [[RemainingElement]] property */
+  LIT_GC_MARK_REQUIRED_MAGIC_STRING__COUNT,  /**< number of internal magic strings which will be used as
+                                              *   property names, and their values need to be marked during gc. */
+  LIT_INTERNAL_MAGIC_STRING_DELETED = LIT_GC_MARK_REQUIRED_MAGIC_STRING__COUNT, /**< special value for
+                                                                                 *   deleted properties */
+
+  LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER, /**< native pointer info associated with an object */
+  LIT_FIRST_INTERNAL_MAGIC_STRING = LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER,  /**< first index of internal
+                                                                                *   magic strings */
+  LIT_INTERNAL_MAGIC_STRING_CLASS_THIS_BINDING, /**< the this binding of the class constructor */
   LIT_MAGIC_STRING__COUNT /**< number of magic strings */
 } lit_magic_string_id_t;
 
@@ -57,12 +67,12 @@ uint32_t lit_get_magic_string_ex_count (void);
 
 const lit_utf8_byte_t *lit_get_magic_string_utf8 (lit_magic_string_id_t id);
 lit_utf8_size_t lit_get_magic_string_size (lit_magic_string_id_t id);
-lit_magic_string_id_t lit_get_magic_string_size_block_start (lit_utf8_size_t size);
 
 const lit_utf8_byte_t *lit_get_magic_string_ex_utf8 (lit_magic_string_ex_id_t id);
 lit_utf8_size_t lit_get_magic_string_ex_size (lit_magic_string_ex_id_t id);
 
-void lit_magic_strings_ex_set (const lit_utf8_byte_t **ex_str_items, uint32_t count,
+void lit_magic_strings_ex_set (const lit_utf8_byte_t * const *ex_str_items,
+                               uint32_t count,
                                const lit_utf8_size_t *ex_str_sizes);
 
 lit_magic_string_id_t lit_is_utf8_string_magic (const lit_utf8_byte_t *string_p, lit_utf8_size_t string_size);
index 6ac2eb05465e93e0e9cab5acefd6405f872a248f..59e325311d1cb52b84480d3762c8e85f82a0943a 100644 (file)
@@ -19,9 +19,6 @@
 
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING__EMPTY, "")
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SPACE_CHAR, " ")
-#if !defined (CONFIG_DISABLE_JSON_BUILTIN)
-LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_DOUBLE_QUOTE_CHAR, "\"")
-#endif
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_COMMA_CHAR, ",")
 #if !defined (CONFIG_DISABLE_REGEXP_BUILTIN)
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SLASH_CHAR, "/")
@@ -41,6 +38,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_OF, "of")
 #if !defined (CONFIG_DISABLE_MATH_BUILTIN)
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_LN2_U, "LN2")
 #endif
+#if !defined (CONFIG_DISABLE_ES2015_MAP_BUILTIN)
+LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_MAP_UL, "Map")
+#endif
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_NAN, "NaN")
 #if !defined (CONFIG_DISABLE_DATE_BUILTIN)
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_UTC_U, "UTC")
@@ -56,6 +56,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_COS, "cos")
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_EXP, "exp")
 #endif
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_GET, "get")
+#if !defined (CONFIG_DISABLE_ES2015_MAP_BUILTIN)
+LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_HAS, "has")
+#endif
 #if !defined (CONFIG_DISABLE_MATH_BUILTIN)
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_LOG, "log")
 #endif
@@ -108,9 +111,17 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_EVAL, "eval")
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_EXEC, "exec")
 #endif
 #if !defined (CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN)
+LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_FILL, "fill")
+#endif
+#if !defined (CONFIG_DISABLE_ARRAY_BUILTIN) && !defined (CONFIG_DISABLE_ES2015_BUILTIN) \
+|| !defined (CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN)
+LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_FIND, "find")
+#endif
+#if !defined (CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN)
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_FROM, "from")
 #endif
-#if !defined (CONFIG_DISABLE_ARRAY_BUILTIN)
+#if !defined (CONFIG_DISABLE_ARRAY_BUILTIN) \
+|| !defined (CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN)
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_JOIN, "join")
 #endif
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_KEYS, "keys")
@@ -123,11 +134,12 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_PUSH, "push")
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_RACE, "race")
 #endif
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SEAL, "seal")
+#if !defined (CONFIG_DISABLE_ES2015_MAP_BUILTIN)
+LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SIZE, "size")
+#endif
 #if !defined (CONFIG_DISABLE_ARRAY_BUILTIN) \
 || !defined (CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN)
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SOME, "some")
-#endif
-#if !defined (CONFIG_DISABLE_ARRAY_BUILTIN)
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SORT, "sort")
 #endif
 #if !defined (CONFIG_DISABLE_MATH_BUILTIN)
@@ -156,6 +168,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ATAN2, "atan2")
 #if !defined (CONFIG_DISABLE_ES2015_PROMISE_BUILTIN)
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_CATCH, "catch")
 #endif
+#if !defined (CONFIG_DISABLE_ES2015_MAP_BUILTIN)
+LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_CLEAR, "clear")
+#endif
 #if !defined (CONFIG_DISABLE_ARRAY_BUILTIN) \
 || !defined (CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN)
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_EVERY, "every")
@@ -214,6 +229,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_CHAR_AT_UL, "charAt")
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_CONCAT, "concat")
 #endif
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_CREATE, "create")
+#if !defined (CONFIG_DISABLE_ES2015_MAP_BUILTIN)
+LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_DELETE, "delete")
+#endif
 #if !defined (CONFIG_DISABLE_ANNEXB_BUILTIN)
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ESCAPE, "escape")
 #endif
@@ -333,6 +351,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_PARSE_INT, "parseInt")
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SET_HOURS_UL, "setHours")
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SET_MONTH_UL, "setMonth")
 #endif
+#if !defined (CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN)
+LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SUBARRAY, "subarray")
+#endif
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TO_STRING_UL, "toString")
 #if !defined (CONFIG_DISABLE_ANNEXB_BUILTIN)
 LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_UNESCAPE, "unescape")
@@ -541,11 +562,15 @@ LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (2, LIT_MAGIC_STRING_PI_U)
 LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (2, LIT_MAGIC_STRING_OF)
 #elif !defined (CONFIG_DISABLE_MATH_BUILTIN)
 LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (2, LIT_MAGIC_STRING_LN2_U)
+#elif !defined (CONFIG_DISABLE_ES2015_MAP_BUILTIN)
+LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (2, LIT_MAGIC_STRING_MAP_UL)
 #else
 LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (2, LIT_MAGIC_STRING_NAN)
 #endif
 #if !defined (CONFIG_DISABLE_MATH_BUILTIN)
 LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (3, LIT_MAGIC_STRING_LN2_U)
+#elif !defined (CONFIG_DISABLE_ES2015_MAP_BUILTIN)
+LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (3, LIT_MAGIC_STRING_MAP_UL)
 #else
 LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (3, LIT_MAGIC_STRING_NAN)
 #endif
index 905dade69665a8f22bcbd54d481274a4ecc83d84..7e9e34bc9a5800e17e9c7e771198e0e0f9ecc801 100644 (file)
@@ -24,7 +24,6 @@
 
 LIT_MAGIC_STRING__EMPTY = ""
 LIT_MAGIC_STRING_SPACE_CHAR = " "
-LIT_MAGIC_STRING_DOUBLE_QUOTE_CHAR = "\""
 LIT_MAGIC_STRING_COMMA_CHAR = ","
 LIT_MAGIC_STRING_SLASH_CHAR = "/"
 LIT_MAGIC_STRING_COLON_CHAR = ":"
@@ -34,6 +33,7 @@ LIT_MAGIC_STRING_RIGHT_SQUARE_CHAR = "]"
 LIT_MAGIC_STRING_PI_U = "PI"
 LIT_MAGIC_STRING_OF = "of"
 LIT_MAGIC_STRING_LN2_U = "LN2"
+LIT_MAGIC_STRING_MAP_UL = "Map"
 LIT_MAGIC_STRING_NAN = "NaN"
 LIT_MAGIC_STRING_UTC_U = "UTC"
 LIT_MAGIC_STRING_ABS = "abs"
@@ -41,6 +41,7 @@ LIT_MAGIC_STRING_ALL = "all"
 LIT_MAGIC_STRING_COS = "cos"
 LIT_MAGIC_STRING_EXP = "exp"
 LIT_MAGIC_STRING_GET = "get"
+LIT_MAGIC_STRING_HAS = "has"
 LIT_MAGIC_STRING_LOG = "log"
 LIT_MAGIC_STRING_MAP = "map"
 LIT_MAGIC_STRING_MAX = "max"
@@ -65,6 +66,8 @@ LIT_MAGIC_STRING_CALL = "call"
 LIT_MAGIC_STRING_CEIL = "ceil"
 LIT_MAGIC_STRING_EVAL = "eval"
 LIT_MAGIC_STRING_EXEC = "exec"
+LIT_MAGIC_STRING_FILL = "fill"
+LIT_MAGIC_STRING_FIND = "find"
 LIT_MAGIC_STRING_FROM = "from"
 LIT_MAGIC_STRING_JOIN = "join"
 LIT_MAGIC_STRING_KEYS = "keys"
@@ -73,6 +76,7 @@ LIT_MAGIC_STRING_NULL = "null"
 LIT_MAGIC_STRING_PUSH = "push"
 LIT_MAGIC_STRING_RACE = "race"
 LIT_MAGIC_STRING_SEAL = "seal"
+LIT_MAGIC_STRING_SIZE = "size"
 LIT_MAGIC_STRING_SOME = "some"
 LIT_MAGIC_STRING_SORT = "sort"
 LIT_MAGIC_STRING_SQRT = "sqrt"
@@ -87,6 +91,7 @@ LIT_MAGIC_STRING_SQRT2_U = "SQRT2"
 LIT_MAGIC_STRING_APPLY = "apply"
 LIT_MAGIC_STRING_ATAN2 = "atan2"
 LIT_MAGIC_STRING_CATCH = "catch"
+LIT_MAGIC_STRING_CLEAR = "clear"
 LIT_MAGIC_STRING_EVERY = "every"
 LIT_MAGIC_STRING_FALSE = "false"
 LIT_MAGIC_STRING_FLOOR = "floor"
@@ -111,6 +116,7 @@ LIT_MAGIC_STRING_CALLER = "caller"
 LIT_MAGIC_STRING_CHAR_AT_UL = "charAt"
 LIT_MAGIC_STRING_CONCAT = "concat"
 LIT_MAGIC_STRING_CREATE = "create"
+LIT_MAGIC_STRING_DELETE = "delete"
 LIT_MAGIC_STRING_ESCAPE = "escape"
 LIT_MAGIC_STRING_FILTER = "filter"
 LIT_MAGIC_STRING_FREEZE = "freeze"
@@ -162,6 +168,7 @@ LIT_MAGIC_STRING_IS_SEALED_UL = "isSealed"
 LIT_MAGIC_STRING_PARSE_INT = "parseInt"
 LIT_MAGIC_STRING_SET_HOURS_UL = "setHours"
 LIT_MAGIC_STRING_SET_MONTH_UL = "setMonth"
+LIT_MAGIC_STRING_SUBARRAY = "subarray"
 LIT_MAGIC_STRING_TO_STRING_UL = "toString"
 LIT_MAGIC_STRING_UNESCAPE = "unescape"
 LIT_MAGIC_STRING_WRITABLE = "writable"
index 739f5d2923fd00be56404f8d7972903c9d1e3868..223d11ba98f2d00d787309532d38ea1c3b318416 100644 (file)
@@ -373,15 +373,12 @@ lit_read_code_point_from_utf8 (const lit_utf8_byte_t *buf_p, /**< buffer with ch
     bytes_count = 3;
     ret = ((lit_code_point_t) (c & LIT_UTF8_LAST_4_BITS_MASK));
   }
-  else if ((c & LIT_UTF8_4_BYTE_MASK) == LIT_UTF8_4_BYTE_MARKER)
+  else
   {
+    JERRY_ASSERT ((c & LIT_UTF8_4_BYTE_MASK) == LIT_UTF8_4_BYTE_MARKER);
     bytes_count = 4;
     ret = ((lit_code_point_t) (c & LIT_UTF8_LAST_3_BITS_MASK));
   }
-  else
-  {
-    JERRY_ASSERT (false);
-  }
 
   JERRY_ASSERT (buf_size >= bytes_count);
 
@@ -557,7 +554,7 @@ lit_utf8_decr (const lit_utf8_byte_t **buf_p) /**< [in,out] buffer with characte
  *
  * @return ecma-string's hash
  */
-inline lit_string_hash_t __attr_always_inline___
+inline lit_string_hash_t JERRY_ATTR_ALWAYS_INLINE
 lit_utf8_string_hash_combine (lit_string_hash_t hash_basis, /**< hash to be combined with */
                               const lit_utf8_byte_t *utf8_buf_p, /**< characters buffer */
                               lit_utf8_size_t utf8_buf_size) /**< number of characters in the buffer */
@@ -580,7 +577,7 @@ lit_utf8_string_hash_combine (lit_string_hash_t hash_basis, /**< hash to be comb
  *
  * @return ecma-string's hash
  */
-inline lit_string_hash_t __attr_always_inline___
+inline lit_string_hash_t JERRY_ATTR_ALWAYS_INLINE
 lit_utf8_string_calc_hash (const lit_utf8_byte_t *utf8_buf_p, /**< characters buffer */
                            lit_utf8_size_t utf8_buf_size) /**< number of characters in the buffer */
 {
@@ -621,7 +618,7 @@ lit_utf8_string_code_unit_at (const lit_utf8_byte_t *utf8_buf_p, /**< utf-8 stri
  *
  * @return number of bytes occupied in CESU-8
  */
-inline lit_utf8_size_t __attr_always_inline___
+inline lit_utf8_size_t JERRY_ATTR_ALWAYS_INLINE
 lit_get_unicode_char_size_by_utf8_first_byte (const lit_utf8_byte_t first_byte) /**< buffer with characters */
 {
   if ((first_byte & LIT_UTF8_1_BYTE_MASK) == LIT_UTF8_1_BYTE_MARKER)
index c83bf82c3b1ebe199962a7ec8a9ca7551a55e315..208108bde854de0a461e8adde932e43513a53e1a 100644 (file)
@@ -108,7 +108,7 @@ lit_string_hash_t lit_utf8_string_hash_combine (lit_string_hash_t hash_basis, co
 /* code unit access */
 ecma_char_t lit_utf8_string_code_unit_at (const lit_utf8_byte_t *utf8_buf_p, lit_utf8_size_t utf8_buf_size,
                                           ecma_length_t code_unit_offset);
-lit_utf8_size_t lit_get_unicode_char_size_by_utf8_first_byte (lit_utf8_byte_t first_byte);
+lit_utf8_size_t lit_get_unicode_char_size_by_utf8_first_byte (const lit_utf8_byte_t first_byte);
 
 /* conversion */
 lit_utf8_size_t lit_code_unit_to_utf8 (ecma_char_t code_unit, lit_utf8_byte_t *buf_p);
index 43502c03d54c81a441954ae973d4787fcd6470b3..37b608020f0cd1092c3ee59f6f46e3f3a15bac50 100644 (file)
@@ -33,6 +33,9 @@ JERRY_STATIC_ASSERT ((sizeof (cbc_uint16_arguments_t) % sizeof (jmem_cpointer_t)
  * @{
  */
 
+/**
+ * Compact bytecode definition
+ */
 #define CBC_OPCODE(arg1, arg2, arg3, arg4) \
   ((arg2) | (((arg3) + CBC_STACK_ADJUST_BASE) << CBC_STACK_ADJUST_SHIFT)),
 
index a8db0884d6ff231bce1ddf9ee77f50f198682687..f5ebdb37d7719d70ec922a08a4f84a7d6adfdbeb 100644 (file)
 
 #define CBC_HAS_POP_STACK_BYTE_ARG (CBC_HAS_BYTE_ARG | CBC_POP_STACK_BYTE_ARG)
 
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+/**
+ * Checks whether the current opcode is a super constructor call
+ */
+#define CBC_SUPER_CALL_OPERATION(opcode) \
+  ((opcode) >= PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_CALL) \
+    && (opcode) <= PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_CALL_BLOCK))
+#else /* CONFIG_DISABLE_ES2015_CLASS */
+/**
+ * Checks whether the current opcode is a super constructor call
+ */
+#define CBC_SUPER_CALL_OPERATION(opcode) false
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
 /* Debug macro. */
 #define CBC_ARGS_EQ(op, types) \
   ((cbc_flags[op] & CBC_ARG_TYPES) == (types))
 
 /* Debug macro. */
 #define CBC_SAME_ARGS(op1, op2) \
-  ((cbc_flags[op1] & CBC_ARG_TYPES) == (cbc_flags[op2] & CBC_ARG_TYPES))
+  (CBC_SUPER_CALL_OPERATION (op1) ? ((cbc_ext_flags[PARSER_GET_EXT_OPCODE (op1)] & CBC_ARG_TYPES) \
+                                      == (cbc_ext_flags[PARSER_GET_EXT_OPCODE (op2)] & CBC_ARG_TYPES)) \
+                                  : ((cbc_flags[op1] & CBC_ARG_TYPES) == (cbc_flags[op2] & CBC_ARG_TYPES)))
 
 #define CBC_UNARY_OPERATION(name, group) \
   CBC_OPCODE (name, CBC_NO_FLAG, 0, \
 /**
  * Several opcodes (mostly call and assignment opcodes) have
  * two forms: one which does not push a return value onto
- * the stack, and another which does. The reasion is that
+ * the stack, and another which does. The reason is that
  * the return value of these opcodes are often not used
  * and the first form provides smaller byte code.
  *
  * Hence CBC_NO_RESULT_OPERATION (context_p->last_cbc_opcode)
  * cannot be true for an opcode which has a result
  */
-
 #define CBC_NO_RESULT_OPERATION(opcode) \
-  ((opcode) >= CBC_PRE_INCR && (opcode) < CBC_END)
+  (((opcode) >= CBC_PRE_INCR && (opcode) < CBC_END) || CBC_SUPER_CALL_OPERATION ((opcode)))
 
 #define CBC_NO_RESULT_BLOCK(opcode) \
-  ((opcode) >= CBC_PRE_INCR && (opcode) < CBC_ASSIGN_ADD)
+  (((opcode) >= CBC_PRE_INCR && (opcode) < CBC_ASSIGN_ADD) || CBC_SUPER_CALL_OPERATION ((opcode)))
 
 #define CBC_NO_RESULT_COMPOUND_ASSIGMENT(opcode) \
-  ((opcode) >= CBC_ASSIGN_ADD && (opcode) < CBC_END)
+  ((opcode) >= CBC_ASSIGN_ADD && (opcode) < CBC_END && !CBC_SUPER_CALL_OPERATION ((opcode)))
 
 /**
  * Branch instructions are organized in group of 8 opcodes.
 /* PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION must be <= 4 */
 #define PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION 4
 /* PARSER_WITH_CONTEXT_STACK_ALLOCATION must be <= 4 */
-#define PARSER_WITH_CONTEXT_STACK_ALLOCATION 2
+#define PARSER_WITH_CONTEXT_STACK_ALLOCATION 1
+/* PARSER_SUPER_CLASS_CONTEXT_STACK_ALLOCATION must be <= 4 */
+#define PARSER_SUPER_CLASS_CONTEXT_STACK_ALLOCATION 1
 /* PARSER_TRY_CONTEXT_STACK_ALLOCATION must be <= 3 */
 #define PARSER_TRY_CONTEXT_STACK_ALLOCATION 2
 
   CBC_BACKWARD_BRANCH (CBC_BRANCH_IF_FALSE_BACKWARD, -1, \
                        VM_OC_BRANCH_IF_FALSE) \
   CBC_OPCODE (CBC_SET_PROPERTY, CBC_HAS_LITERAL_ARG, -1, \
-              VM_OC_SET_PROPERTY | VM_OC_GET_STACK_LITERAL) \
+              VM_OC_SET_PROPERTY | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_LITERAL) \
   CBC_FORWARD_BRANCH (CBC_JUMP_FORWARD_EXIT_CONTEXT, 0, \
                       VM_OC_JUMP_AND_EXIT_CONTEXT) \
   CBC_OPCODE (CBC_CREATE_ARRAY, CBC_NO_FLAG, 1, \
   CBC_OPCODE (CBC_PUSH_THIS_LITERAL, CBC_HAS_LITERAL_ARG, 2, \
               VM_OC_PUSH_TWO | VM_OC_GET_THIS_LITERAL) \
   CBC_OPCODE (CBC_PUSH_NUMBER_0, CBC_NO_FLAG, 1, \
-              VM_OC_PUSH_NUMBER_0 | VM_OC_PUT_STACK) \
+              VM_OC_PUSH_0 | VM_OC_PUT_STACK) \
   CBC_OPCODE (CBC_PUSH_NUMBER_POS_BYTE, CBC_HAS_BYTE_ARG, 1, \
-              VM_OC_PUSH_NUMBER_POS_BYTE | VM_OC_PUT_STACK) \
+              VM_OC_PUSH_POS_BYTE | VM_OC_PUT_STACK) \
   CBC_OPCODE (CBC_PUSH_NUMBER_NEG_BYTE, CBC_HAS_BYTE_ARG, 1, \
-              VM_OC_PUSH_NUMBER_NEG_BYTE | VM_OC_PUT_STACK) \
+              VM_OC_PUSH_NEG_BYTE | VM_OC_PUT_STACK) \
   CBC_OPCODE (CBC_PUSH_PROP, CBC_NO_FLAG, -1, \
               VM_OC_PROP_GET | VM_OC_GET_STACK_STACK | VM_OC_PUT_STACK) \
   CBC_OPCODE (CBC_PUSH_PROP_LITERAL, CBC_HAS_LITERAL_ARG, 0, \
               VM_OC_RET) \
   CBC_OPCODE (CBC_RETURN_WITH_LITERAL, CBC_HAS_LITERAL_ARG, 0, \
               VM_OC_RET | VM_OC_GET_LITERAL) \
+  CBC_OPCODE (CBC_SET_LITERAL_PROPERTY, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
+              VM_OC_SET_PROPERTY | VM_OC_NON_STATIC_FLAG | VM_OC_GET_LITERAL_LITERAL) \
   CBC_OPCODE (CBC_BREAKPOINT_ENABLED, CBC_NO_FLAG, 0, \
               VM_OC_BREAKPOINT_ENABLED) \
   CBC_OPCODE (CBC_BREAKPOINT_DISABLED, CBC_NO_FLAG, 0, \
   CBC_FORWARD_BRANCH (CBC_EXT_FOR_IN_CREATE_CONTEXT, \
                       -1 + PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION, VM_OC_FOR_IN_CREATE_CONTEXT) \
   CBC_OPCODE (CBC_EXT_SET_GETTER, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
-              VM_OC_SET_GETTER | VM_OC_GET_LITERAL_LITERAL) \
+              VM_OC_SET_GETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_LITERAL_LITERAL) \
   CBC_BACKWARD_BRANCH (CBC_EXT_BRANCH_IF_FOR_IN_HAS_NEXT, 0, \
                        VM_OC_FOR_IN_HAS_NEXT) \
   CBC_OPCODE (CBC_EXT_SET_SETTER, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
-              VM_OC_SET_SETTER | VM_OC_GET_LITERAL_LITERAL) \
+              VM_OC_SET_SETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_LITERAL_LITERAL) \
   CBC_FORWARD_BRANCH (CBC_EXT_TRY_CREATE_CONTEXT, PARSER_TRY_CONTEXT_STACK_ALLOCATION, \
                       VM_OC_TRY) \
   CBC_OPCODE (CBC_EXT_THROW_REFERENCE_ERROR, CBC_NO_FLAG, 1, \
               VM_OC_PUSH_UNDEFINED_BASE | VM_OC_PUT_STACK) \
   CBC_FORWARD_BRANCH (CBC_EXT_FINALLY, 0, \
                       VM_OC_FINALLY) \
+  CBC_OPCODE (CBC_EXT_CLASS_EXPR_CONTEXT_END, CBC_NO_FLAG, 0, \
+              VM_OC_CLASS_EXPR_CONTEXT_END) \
+  CBC_FORWARD_BRANCH (CBC_EXT_SUPER_CLASS_CREATE_CONTEXT, \
+                      -1 + PARSER_SUPER_CLASS_CONTEXT_STACK_ALLOCATION, VM_OC_CLASS_HERITAGE) \
   \
   /* Basic opcodes. */ \
-  CBC_OPCODE (CBC_EXT_DEBUGGER, CBC_NO_FLAG, 0, \
-              VM_OC_NONE) \
+  CBC_OPCODE (CBC_EXT_PUSH_NAMED_FUNC_EXPRESSION, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 1, \
+              VM_OC_PUSH_NAMED_FUNC_EXPR | VM_OC_GET_LITERAL_LITERAL) \
+  CBC_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0, CBC_HAS_LITERAL_ARG, 2, \
+              VM_OC_PUSH_LIT_0 | VM_OC_GET_LITERAL) \
+  CBC_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE, CBC_HAS_LITERAL_ARG | CBC_HAS_BYTE_ARG, 2, \
+              VM_OC_PUSH_LIT_POS_BYTE | VM_OC_GET_LITERAL) \
+  CBC_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE, CBC_HAS_LITERAL_ARG | CBC_HAS_BYTE_ARG, 2, \
+              VM_OC_PUSH_LIT_NEG_BYTE | VM_OC_GET_LITERAL) \
   CBC_OPCODE (CBC_EXT_RESOURCE_NAME, CBC_NO_FLAG, 0, \
               VM_OC_RESOURCE_NAME) \
   CBC_OPCODE (CBC_EXT_LINE, CBC_NO_FLAG, 0, \
               VM_OC_LINE) \
+  CBC_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY, CBC_NO_FLAG, -2, \
+              VM_OC_SET_COMPUTED_PROPERTY | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_STACK) \
+  CBC_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL, CBC_HAS_LITERAL_ARG, -1, \
+              VM_OC_SET_COMPUTED_PROPERTY | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_LITERAL) \
+  CBC_OPCODE (CBC_EXT_SET_COMPUTED_GETTER, CBC_HAS_LITERAL_ARG, -1, \
+              VM_OC_SET_GETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_LITERAL) \
+  CBC_OPCODE (CBC_EXT_SET_COMPUTED_SETTER, CBC_HAS_LITERAL_ARG, -1, \
+              VM_OC_SET_SETTER | VM_OC_NON_STATIC_FLAG | VM_OC_GET_STACK_LITERAL) \
+  CBC_OPCODE (CBC_EXT_SET_STATIC_PROPERTY_LITERAL, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
+              VM_OC_SET_PROPERTY | VM_OC_GET_LITERAL_LITERAL) \
+  CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_PROPERTY_LITERAL, CBC_HAS_LITERAL_ARG, -1, \
+              VM_OC_SET_COMPUTED_PROPERTY | VM_OC_GET_STACK_LITERAL) \
+  CBC_OPCODE (CBC_EXT_SET_STATIC_GETTER, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
+              VM_OC_SET_GETTER | VM_OC_GET_LITERAL_LITERAL) \
+  CBC_OPCODE (CBC_EXT_SET_STATIC_SETTER, CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2, 0, \
+              VM_OC_SET_SETTER | VM_OC_GET_LITERAL_LITERAL) \
+  CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_GETTER, CBC_HAS_LITERAL_ARG, -1, \
+              VM_OC_SET_GETTER | VM_OC_GET_STACK_LITERAL) \
+  CBC_OPCODE (CBC_EXT_SET_STATIC_COMPUTED_SETTER, CBC_HAS_LITERAL_ARG, -1, \
+              VM_OC_SET_SETTER | VM_OC_GET_STACK_LITERAL) \
+  CBC_OPCODE (CBC_EXT_RESOLVE_BASE, CBC_NO_FLAG, 0, \
+              VM_OC_RESOLVE_BASE_FOR_CALL) \
+  \
+  /* Class opcodes */ \
+  CBC_OPCODE (CBC_EXT_INHERIT_AND_SET_CONSTRUCTOR, CBC_NO_FLAG, 0, \
+              VM_OC_CLASS_INHERITANCE) \
+  CBC_OPCODE (CBC_EXT_PUSH_CLASS_CONSTRUCTOR, CBC_NO_FLAG, 1, \
+              VM_OC_PUSH_CLASS_CONSTRUCTOR | VM_OC_PUT_STACK) \
+  CBC_OPCODE (CBC_EXT_IMPLICIT_CONSTRUCTOR_CALL, CBC_NO_FLAG, 0, \
+              VM_OC_PUSH_IMPL_CONSTRUCTOR) \
+  CBC_OPCODE (CBC_EXT_SET_CLASS_LITERAL, CBC_HAS_LITERAL_ARG, 0, \
+              VM_OC_SET_CLASS_CONSTRUCTOR | VM_OC_GET_LITERAL) \
+  CBC_OPCODE (CBC_EXT_CLASS_EVAL, CBC_HAS_BYTE_ARG, 0, \
+              VM_OC_CLASS_EVAL) \
+  CBC_OPCODE (CBC_EXT_SUPER_CALL, CBC_HAS_POP_STACK_BYTE_ARG, -1, \
+              VM_OC_SUPER_CALL) \
+  CBC_OPCODE (CBC_EXT_SUPER_CALL_PUSH_RESULT, CBC_HAS_POP_STACK_BYTE_ARG, 0, \
+              VM_OC_SUPER_CALL | VM_OC_PUT_STACK) \
+  CBC_OPCODE (CBC_EXT_SUPER_CALL_BLOCK, CBC_HAS_POP_STACK_BYTE_ARG, -1, \
+              VM_OC_SUPER_CALL | VM_OC_PUT_BLOCK) \
+  CBC_OPCODE (CBC_EXT_PUSH_CONSTRUCTOR_SUPER, CBC_NO_FLAG, 1, \
+              VM_OC_PUSH_CONSTRUCTOR_SUPER | VM_OC_PUT_STACK) \
+  CBC_OPCODE (CBC_EXT_PUSH_CONSTRUCTOR_SUPER_PROP, CBC_NO_FLAG, 1, \
+              VM_OC_PUSH_CONSTRUCTOR_SUPER | VM_OC_PUT_STACK) \
+  CBC_OPCODE (CBC_EXT_PUSH_SUPER, CBC_NO_FLAG, 1, \
+              VM_OC_PUSH_SUPER | VM_OC_PUT_STACK) \
+  CBC_OPCODE (CBC_EXT_PUSH_STATIC_SUPER, CBC_NO_FLAG, 1, \
+              VM_OC_PUSH_SUPER | VM_OC_PUT_STACK) \
+  CBC_OPCODE (CBC_EXT_PUSH_CONSTRUCTOR_THIS, CBC_NO_FLAG, 1, \
+              VM_OC_PUSH_CONSTRUCTOR_THIS | VM_OC_PUT_STACK) \
+  CBC_OPCODE (CBC_EXT_SUPER_PROP_CALL, CBC_NO_FLAG, 0, \
+              VM_OC_SUPER_PROP_REFERENCE) \
+  CBC_OPCODE (CBC_EXT_SUPER_PROP_ASSIGN, CBC_NO_FLAG, 0, \
+              VM_OC_SUPER_PROP_REFERENCE) \
+  CBC_OPCODE (CBC_EXT_CONSTRUCTOR_RETURN, CBC_NO_FLAG, -1, \
+              VM_OC_CONSTRUCTOR_RET | VM_OC_GET_STACK) \
+  CBC_OPCODE (CBC_EXT_ERROR, CBC_NO_FLAG, 0, \
+              VM_OC_ERROR) \
   \
   /* Binary compound assignment opcodes with pushing the result. */ \
   CBC_EXT_BINARY_LVALUE_OPERATION (CBC_EXT_ASSIGN_ADD, \
@@ -654,13 +741,20 @@ typedef enum
   CBC_CODE_FLAGS_UINT16_ARGUMENTS = (1u << 2), /**< compiled code data is cbc_uint16_arguments_t */
   CBC_CODE_FLAGS_STRICT_MODE = (1u << 3), /**< strict mode is enabled */
   CBC_CODE_FLAGS_ARGUMENTS_NEEDED = (1u << 4), /**< arguments object must be constructed */
-  CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED = (1u << 5), /**< non-strict arguments object must be constructed */
-  CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED = (1u << 6), /**< no need to create a lexical environment */
-  CBC_CODE_FLAGS_ARROW_FUNCTION = (1u << 7), /**< this function is an arrow function */
-  CBC_CODE_FLAGS_STATIC_FUNCTION = (1u << 8), /**< this function is a static snapshot function */
-  CBC_CODE_FLAGS_DEBUGGER_IGNORE = (1u << 9), /**< this function should be ignored by debugger */
+  CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED = (1u << 5), /**< no need to create a lexical environment */
+  CBC_CODE_FLAGS_ARROW_FUNCTION = (1u << 6), /**< this function is an arrow function */
+  CBC_CODE_FLAGS_STATIC_FUNCTION = (1u << 7), /**< this function is a static snapshot function */
+  CBC_CODE_FLAGS_DEBUGGER_IGNORE = (1u << 8), /**< this function should be ignored by debugger */
+  CBC_CODE_FLAGS_CONSTRUCTOR = (1u << 9), /**< this function is a constructor */
 } cbc_code_flags;
 
+/**
+ * Non-strict arguments object must be constructed
+ */
+#define CBC_NON_STRICT_ARGUMENTS_NEEDED(compiled_code_p) \
+  (((compiled_code_p)->status_flags & CBC_CODE_FLAGS_ARGUMENTS_NEEDED) \
+    && !((compiled_code_p)->status_flags & CBC_CODE_FLAGS_STRICT_MODE))
+
 #define CBC_OPCODE(arg1, arg2, arg3, arg4) arg1,
 
 /**
index 1e88a94fcbbbb4941f791e3f9d1f0fd795937a40..e0506aed30d0c72793c6f9ef33f169e886f6e8a4 100644 (file)
@@ -55,24 +55,21 @@ typedef enum
                                          used by the byte code generator. */
 } lexer_literal_type_t;
 
-/* Flags for status_flags. */
-
-/* Local identifier (var, function arg). */
-#define LEXER_FLAG_VAR 0x01
-/* This local identifier cannot be stored in register. */
-#define LEXER_FLAG_NO_REG_STORE 0x02
-/* This local identifier is initialized with a value. */
-#define LEXER_FLAG_INITIALIZED 0x04
-/* This local identifier has a reference to the function itself. */
-#define LEXER_FLAG_FUNCTION_NAME 0x08
-/* This local identifier is a function argument. */
-#define LEXER_FLAG_FUNCTION_ARGUMENT 0x10
-/* This local identifier is not used in the current context. */
-#define LEXER_FLAG_UNUSED_IDENT 0x20
-/* No space is allocated for this character literal. */
-#define LEXER_FLAG_SOURCE_PTR 0x40
-/* Initialize this variable after the byte code is freed. */
-#define LEXER_FLAG_LATE_INIT 0x80
+/**
+ * Flag bits for status_flags member of lexer_literal_t.
+ */
+typedef enum
+{
+  LEXER_FLAG_VAR = (1 << 0), /**< local identifier (var, function arg) */
+  LEXER_FLAG_NO_REG_STORE = (1 << 1), /**< this local identifier cannot be stored in register */
+  LEXER_FLAG_INITIALIZED = (1 << 2), /**< this local identifier is initialized with a value */
+  LEXER_FLAG_FUNCTION_ARGUMENT = (1 << 3), /**< this local identifier is a function argument */
+  LEXER_FLAG_UNUSED_IDENT = (1 << 4), /**< this identifier is referenced by sub-functions,
+                                       *   but not referenced by the currently parsed function */
+  LEXER_FLAG_SOURCE_PTR = (1 << 5), /**< the literal is directly referenced in the source code
+                                     *   (no need to allocate memory) */
+  LEXER_FLAG_LATE_INIT = (1 << 6), /**< initialize this variable after the byte code is freed */
+} lexer_literal_status_flags_t;
 
 /**
  * Type of property length.
index a25498acc814029702410d95dd02bc7fdeda8095..f3ba9cc7ea012857465365c54e442b58a3a5d2ea 100644 (file)
@@ -33,6 +33,9 @@
  * @{
  */
 
+/**
+ * Check whether the UTF-8 intermediate is an octet or not
+ */
 #define IS_UTF8_INTERMEDIATE_OCTET(byte) (((byte) & LIT_UTF8_EXTRA_BYTE_MASK) == LIT_UTF8_2_BYTE_CODE_POINT_MIN)
 
 /**
@@ -274,46 +277,67 @@ lexer_skip_spaces (parser_context_t *context_p) /**< context */
   }
 } /* lexer_skip_spaces */
 
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+/**
+ * Skip all the continuous empty statements.
+ */
+void
+lexer_skip_empty_statements (parser_context_t *context_p) /**< context */
+{
+  lexer_skip_spaces (context_p);
+
+  while (context_p->source_p < context_p->source_end_p
+         && *context_p->source_p == LIT_CHAR_SEMICOLON)
+  {
+    context_p->source_p++;
+    lexer_skip_spaces (context_p);
+  }
+} /* lexer_skip_empty_statements */
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
 /**
  * Keyword data.
  */
 typedef struct
 {
-  const uint8_t *keyword_p;     /**< keyword string */
-  lexer_token_type_t type;      /**< keyword token type */
+  const uint8_t *keyword_p; /**< keyword string */
+  lexer_token_type_t type;  /**< keyword token type */
 } keyword_string_t;
 
+/**
+ * @{
+ * Keyword defines
+ */
 #define LEXER_KEYWORD(name, type) { (const uint8_t *) (name), (type) }
-#define LEXER_KEYWORD_END()       { (const uint8_t *) NULL, LEXER_EOS }
+#define LEXER_KEYWORD_LIST_LENGTH(name) (const uint8_t) (sizeof ((name)) / sizeof ((name)[0]))
+/** @} */
 
 /**
  * Keywords with 2 characters.
  */
-static const keyword_string_t keyword_length_2[4] =
+static const keyword_string_t keywords_with_length_2[] =
 {
   LEXER_KEYWORD ("do", LEXER_KEYW_DO),
   LEXER_KEYWORD ("if", LEXER_KEYW_IF),
   LEXER_KEYWORD ("in", LEXER_KEYW_IN),
-  LEXER_KEYWORD_END ()
 };
 
 /**
  * Keywords with 3 characters.
  */
-static const keyword_string_t keyword_length_3[6] =
+static const keyword_string_t keywords_with_length_3[] =
 {
   LEXER_KEYWORD ("for", LEXER_KEYW_FOR),
   LEXER_KEYWORD ("let", LEXER_KEYW_LET),
   LEXER_KEYWORD ("new", LEXER_KEYW_NEW),
   LEXER_KEYWORD ("try", LEXER_KEYW_TRY),
   LEXER_KEYWORD ("var", LEXER_KEYW_VAR),
-  LEXER_KEYWORD_END ()
 };
 
 /**
  * Keywords with 4 characters.
  */
-static const keyword_string_t keyword_length_4[9] =
+static const keyword_string_t keywords_with_length_4[] =
 {
   LEXER_KEYWORD ("case", LEXER_KEYW_CASE),
   LEXER_KEYWORD ("else", LEXER_KEYW_ELSE),
@@ -323,14 +347,16 @@ static const keyword_string_t keyword_length_4[9] =
   LEXER_KEYWORD ("true", LEXER_LIT_TRUE),
   LEXER_KEYWORD ("void", LEXER_KEYW_VOID),
   LEXER_KEYWORD ("with", LEXER_KEYW_WITH),
-  LEXER_KEYWORD_END ()
 };
 
 /**
  * Keywords with 5 characters.
  */
-static const keyword_string_t keyword_length_5[10] =
+static const keyword_string_t keywords_with_length_5[] =
 {
+#ifndef CONFIG_DISABLE_ES2015
+  LEXER_KEYWORD ("await", LEXER_KEYW_AWAIT),
+#endif /* !CONFIG_DISABLE_ES2015 */
   LEXER_KEYWORD ("break", LEXER_KEYW_BREAK),
   LEXER_KEYWORD ("catch", LEXER_KEYW_CATCH),
   LEXER_KEYWORD ("class", LEXER_KEYW_CLASS),
@@ -340,13 +366,12 @@ static const keyword_string_t keyword_length_5[10] =
   LEXER_KEYWORD ("throw", LEXER_KEYW_THROW),
   LEXER_KEYWORD ("while", LEXER_KEYW_WHILE),
   LEXER_KEYWORD ("yield", LEXER_KEYW_YIELD),
-  LEXER_KEYWORD_END ()
 };
 
 /**
  * Keywords with 6 characters.
  */
-static const keyword_string_t keyword_length_6[9] =
+static const keyword_string_t keywords_with_length_6[] =
 {
   LEXER_KEYWORD ("delete", LEXER_KEYW_DELETE),
   LEXER_KEYWORD ("export", LEXER_KEYW_EXPORT),
@@ -356,71 +381,82 @@ static const keyword_string_t keyword_length_6[9] =
   LEXER_KEYWORD ("static", LEXER_KEYW_STATIC),
   LEXER_KEYWORD ("switch", LEXER_KEYW_SWITCH),
   LEXER_KEYWORD ("typeof", LEXER_KEYW_TYPEOF),
-  LEXER_KEYWORD_END ()
 };
 
 /**
  * Keywords with 7 characters.
  */
-static const keyword_string_t keyword_length_7[6] =
+static const keyword_string_t keywords_with_length_7[] =
 {
   LEXER_KEYWORD ("default", LEXER_KEYW_DEFAULT),
   LEXER_KEYWORD ("extends", LEXER_KEYW_EXTENDS),
   LEXER_KEYWORD ("finally", LEXER_KEYW_FINALLY),
   LEXER_KEYWORD ("package", LEXER_KEYW_PACKAGE),
   LEXER_KEYWORD ("private", LEXER_KEYW_PRIVATE),
-  LEXER_KEYWORD_END ()
 };
 
 /**
  * Keywords with 8 characters.
  */
-static const keyword_string_t keyword_length_8[4] =
+static const keyword_string_t keywords_with_length_8[] =
 {
   LEXER_KEYWORD ("continue", LEXER_KEYW_CONTINUE),
   LEXER_KEYWORD ("debugger", LEXER_KEYW_DEBUGGER),
   LEXER_KEYWORD ("function", LEXER_KEYW_FUNCTION),
-  LEXER_KEYWORD_END ()
 };
 
 /**
  * Keywords with 9 characters.
  */
-static const keyword_string_t keyword_length_9[3] =
+static const keyword_string_t keywords_with_length_9[] =
 {
   LEXER_KEYWORD ("interface", LEXER_KEYW_INTERFACE),
   LEXER_KEYWORD ("protected", LEXER_KEYW_PROTECTED),
-  LEXER_KEYWORD_END ()
 };
 
 /**
  * Keywords with 10 characters.
  */
-static const keyword_string_t keyword_length_10[3] =
+static const keyword_string_t keywords_with_length_10[] =
 {
   LEXER_KEYWORD ("implements", LEXER_KEYW_IMPLEMENTS),
   LEXER_KEYWORD ("instanceof", LEXER_KEYW_INSTANCEOF),
-  LEXER_KEYWORD_END ()
 };
 
 /**
- * List to the keywords.
+ * List of the keyword groups.
+ */
+static const keyword_string_t * const keyword_strings_list[] =
+{
+  keywords_with_length_2,
+  keywords_with_length_3,
+  keywords_with_length_4,
+  keywords_with_length_5,
+  keywords_with_length_6,
+  keywords_with_length_7,
+  keywords_with_length_8,
+  keywords_with_length_9,
+  keywords_with_length_10
+};
+
+/**
+ * List of the keyword groups length.
  */
-static const keyword_string_t * const keyword_string_list[9] =
+static const uint8_t keyword_lengths_list[] =
 {
-  keyword_length_2,
-  keyword_length_3,
-  keyword_length_4,
-  keyword_length_5,
-  keyword_length_6,
-  keyword_length_7,
-  keyword_length_8,
-  keyword_length_9,
-  keyword_length_10
+  LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_2),
+  LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_3),
+  LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_4),
+  LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_5),
+  LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_6),
+  LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_7),
+  LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_8),
+  LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_9),
+  LEXER_KEYWORD_LIST_LENGTH (keywords_with_length_10)
 };
 
 #undef LEXER_KEYWORD
-#undef LEXER_KEYWORD_END
+#undef LEXER_KEYWORD_LIST_LENGTH
 
 /**
  * Parse identifier.
@@ -513,31 +549,52 @@ lexer_parse_identifier (parser_context_t *context_p, /**< context */
       && !context_p->token.lit_location.has_escape
       && (length >= 2 && length <= 10))
   {
-    const keyword_string_t *keyword_p = keyword_string_list[length - 2];
+    const keyword_string_t *keyword_list_p = keyword_strings_list[length - 2];
+
+    int start = 0;
+    int end = keyword_lengths_list[length - 2];
+    int middle = end / 2;
 
     do
     {
-      if (ident_start_p[0] == keyword_p->keyword_p[0]
-          && ident_start_p[1] == keyword_p->keyword_p[1]
-          && memcmp (ident_start_p, keyword_p->keyword_p, length) == 0)
+      const keyword_string_t *keyword_p = keyword_list_p + middle;
+      int compare_result = ident_start_p[0] - keyword_p->keyword_p[0];
+
+      if (compare_result == 0)
       {
-        if (keyword_p->type >= LEXER_FIRST_FUTURE_STRICT_RESERVED_WORD)
+        compare_result = memcmp (ident_start_p, keyword_p->keyword_p, length);
+
+        if (compare_result == 0)
         {
-          if (context_p->status_flags & PARSER_IS_STRICT)
+          if (JERRY_UNLIKELY (keyword_p->type >= LEXER_FIRST_FUTURE_STRICT_RESERVED_WORD))
           {
-            parser_raise_error (context_p, PARSER_ERR_STRICT_IDENT_NOT_ALLOWED);
+            if (context_p->status_flags & PARSER_IS_STRICT)
+            {
+              parser_raise_error (context_p, PARSER_ERR_STRICT_IDENT_NOT_ALLOWED);
+            }
+
+            context_p->token.literal_is_reserved = true;
+            break;
           }
 
-          context_p->token.literal_is_reserved = true;
+          context_p->token.type = (uint8_t) keyword_p->type;
           break;
         }
+      }
 
-        context_p->token.type = keyword_p->type;
-        break;
+      if (compare_result > 0)
+      {
+        start = middle + 1;
       }
-      keyword_p++;
+      else
+      {
+        JERRY_ASSERT (compare_result < 0);
+        end = middle;
+      }
+
+      middle = (start + end) / 2;
     }
-    while (keyword_p->type != LEXER_EOS);
+    while (start < end);
   }
 
   if (context_p->token.type == LEXER_LITERAL)
@@ -901,13 +958,12 @@ lexer_parse_number (parser_context_t *context_p) /**< context */
   }
   else
   {
-    do
+    while (source_p < source_end_p
+           && source_p[0] >= LIT_CHAR_0
+           && source_p[0] <= LIT_CHAR_9)
     {
       source_p++;
     }
-    while (source_p < source_end_p
-           && source_p[0] >= LIT_CHAR_0
-           && source_p[0] <= LIT_CHAR_9);
 
     can_be_float = true;
   }
@@ -971,6 +1027,12 @@ lexer_parse_number (parser_context_t *context_p) /**< context */
   context_p->source_p = source_p;
 } /* lexer_parse_number */
 
+/**
+ * One character long token (e.g. comma).
+ *
+ * @param char1 character
+ * @param type1 type
+ */
 #define LEXER_TYPE_A_TOKEN(char1, type1) \
   case (uint8_t) (char1) : \
   { \
@@ -979,6 +1041,14 @@ lexer_parse_number (parser_context_t *context_p) /**< context */
     break; \
   }
 
+/**
+ * Token pair, where the first token is prefix of the second (e.g. % and %=).
+ *
+ * @param char1 first character
+ * @param type1 type of the first character
+ * @param char2 second character
+ * @param type2 type of the second character
+ */
 #define LEXER_TYPE_B_TOKEN(char1, type1, char2, type2) \
   case (uint8_t) (char1) : \
   { \
@@ -994,6 +1064,16 @@ lexer_parse_number (parser_context_t *context_p) /**< context */
     break; \
   }
 
+/**
+ * Three tokens, where the first is the prefix of the other two (e.g. &, &&, &=).
+ *
+ * @param char1 first character
+ * @param type1 type of the first character
+ * @param char2 second character
+ * @param type2 type of the second character
+ * @param char3 third character
+ * @param type3 type of the third character
+ */
 #define LEXER_TYPE_C_TOKEN(char1, type1, char2, type2, char3, type3) \
   case (uint8_t) (char1) : \
   { \
@@ -1260,21 +1340,22 @@ lexer_next_token (parser_context_t *context_p) /**< context */
 #undef LEXER_TYPE_D_TOKEN
 
 /**
- * Checks whether the next token is a colon.
+ * Checks whether the next token is the specified character.
  *
- * @return true - if the next token is a colon
+ * @return true - if the next is the specified character
  *         false - otherwise
  */
 bool
-lexer_check_colon (parser_context_t *context_p) /**< context */
+lexer_check_next_character (parser_context_t *context_p, /**< context */
+                            lit_utf8_byte_t character) /**< specified character */
 {
   lexer_skip_spaces (context_p);
 
   context_p->token.flags = (uint8_t) (context_p->token.flags | LEXER_NO_SKIP_SPACES);
 
   return (context_p->source_p < context_p->source_end_p
-          && context_p->source_p[0] == (uint8_t) LIT_CHAR_COLON);
-} /* lexer_check_colon */
+          && context_p->source_p[0] == (uint8_t) character);
+} /* lexer_check_next_character */
 
 #ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
 
@@ -1393,7 +1474,9 @@ lexer_process_char_literal (parser_context_t *context_p, /**< context */
   context_p->literal_count++;
 } /* lexer_process_char_literal */
 
-/* Maximum buffer size for identifiers which contains escape sequences. */
+/**
+ * Maximum local buffer size for identifiers which contains escape sequences.
+ */
 #define LEXER_MAX_LITERAL_LOCAL_BUFFER_SIZE 48
 
 /**
@@ -1659,34 +1742,32 @@ lexer_construct_literal_object (parser_context_t *context_p, /**< context */
 
   context_p->lit_object.type = LEXER_LITERAL_OBJECT_ANY;
 
-  if (literal_type == LEXER_IDENT_LITERAL)
+  if (literal_type == LEXER_IDENT_LITERAL
+      && (context_p->status_flags & PARSER_INSIDE_WITH)
+      && context_p->lit_object.literal_p->type == LEXER_IDENT_LITERAL)
   {
-    if ((context_p->status_flags & PARSER_INSIDE_WITH)
-        && context_p->lit_object.literal_p->type == LEXER_IDENT_LITERAL)
-    {
-      context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_NO_REG_STORE;
-    }
+    context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_NO_REG_STORE;
+  }
 
-    if (literal_p->length == 4
-        && source_p[0] == LIT_CHAR_LOWERCASE_E
-        && source_p[3] == LIT_CHAR_LOWERCASE_L
-        && source_p[1] == LIT_CHAR_LOWERCASE_V
-        && source_p[2] == LIT_CHAR_LOWERCASE_A)
-    {
-      context_p->lit_object.type = LEXER_LITERAL_OBJECT_EVAL;
-    }
+  if (literal_p->length == 4
+      && source_p[0] == LIT_CHAR_LOWERCASE_E
+      && source_p[3] == LIT_CHAR_LOWERCASE_L
+      && source_p[1] == LIT_CHAR_LOWERCASE_V
+      && source_p[2] == LIT_CHAR_LOWERCASE_A)
+  {
+    context_p->lit_object.type = LEXER_LITERAL_OBJECT_EVAL;
+  }
 
-    if (literal_p->length == 9
-        && source_p[0] == LIT_CHAR_LOWERCASE_A
-        && source_p[8] == LIT_CHAR_LOWERCASE_S
-        && memcmp (source_p + 1, "rgument", 7) == 0)
+  if (literal_p->length == 9
+      && source_p[0] == LIT_CHAR_LOWERCASE_A
+      && source_p[8] == LIT_CHAR_LOWERCASE_S
+      && memcmp (source_p + 1, "rgument", 7) == 0)
+  {
+    context_p->lit_object.type = LEXER_LITERAL_OBJECT_ARGUMENTS;
+    if (!(context_p->status_flags & PARSER_ARGUMENTS_NOT_NEEDED))
     {
-      context_p->lit_object.type = LEXER_LITERAL_OBJECT_ARGUMENTS;
-      if (!(context_p->status_flags & PARSER_ARGUMENTS_NOT_NEEDED))
-      {
-        context_p->status_flags |= PARSER_ARGUMENTS_NEEDED | PARSER_LEXICAL_ENV_NEEDED;
-        context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_NO_REG_STORE;
-      }
+      context_p->status_flags |= PARSER_ARGUMENTS_NEEDED | PARSER_LEXICAL_ENV_NEEDED;
+      context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_NO_REG_STORE;
     }
   }
 
@@ -1711,7 +1792,7 @@ lexer_construct_literal_object (parser_context_t *context_p, /**< context */
  */
 bool
 lexer_construct_number_object (parser_context_t *context_p, /**< context */
-                               bool push_number_allowed, /**< push number support is allowed */
+                               bool is_expr, /**< expression is parsed */
                                bool is_negative_number) /**< sign is negative */
 {
   parser_list_iterator_t literal_iterator;
@@ -1739,18 +1820,16 @@ lexer_construct_number_object (parser_context_t *context_p, /**< context */
     while (src_p < src_end_p);
   }
 
-  if (push_number_allowed)
+  if (is_expr)
   {
     int32_t int_num = (int32_t) num;
 
-    if (int_num == num)
+    if (int_num == num
+        && int_num <= CBC_PUSH_NUMBER_BYTE_RANGE_END
+        && (int_num != 0 || !is_negative_number))
     {
-      if (int_num <= CBC_PUSH_NUMBER_BYTE_RANGE_END
-          && (int_num != 0 || !is_negative_number))
-      {
-        context_p->lit_object.index = (uint16_t) int_num;
-        return true;
-      }
+      context_p->lit_object.index = (uint16_t) int_num;
+      return true;
     }
   }
 
@@ -1784,22 +1863,99 @@ lexer_construct_number_object (parser_context_t *context_p, /**< context */
   }
 
   literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool);
-  literal_p->prop.length = context_p->token.lit_location.length;
-  literal_p->type = LEXER_UNUSED_LITERAL;
-  literal_p->status_flags = 0;
-
-  context_p->literal_count++;
-
   literal_p->u.value = lit_value;
+  literal_p->prop.length = 0; /* Unused. */
   literal_p->type = LEXER_NUMBER_LITERAL;
+  literal_p->status_flags = 0;
 
   context_p->lit_object.literal_p = literal_p;
   context_p->lit_object.index = (uint16_t) literal_index;
   context_p->lit_object.type = LEXER_LITERAL_OBJECT_ANY;
 
+  context_p->literal_count++;
   return false;
 } /* lexer_construct_number_object */
 
+/**
+ * Convert a push number opcode to push literal opcode
+ */
+void
+lexer_convert_push_number_to_push_literal (parser_context_t *context_p) /**< context */
+{
+  ecma_integer_value_t value;
+  bool two_literals = !PARSER_IS_BASIC_OPCODE (context_p->last_cbc_opcode);
+
+  if (context_p->last_cbc_opcode == CBC_PUSH_NUMBER_0
+      || context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0))
+  {
+    value = 0;
+  }
+  else if (context_p->last_cbc_opcode == CBC_PUSH_NUMBER_POS_BYTE
+           || context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE))
+  {
+    value = ((ecma_integer_value_t) context_p->last_cbc.value) + 1;
+  }
+  else
+  {
+    JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_NUMBER_NEG_BYTE
+                  || context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE));
+    value = -((ecma_integer_value_t) context_p->last_cbc.value) - 1;
+  }
+
+  ecma_value_t lit_value = ecma_make_integer_value (value);
+
+  parser_list_iterator_t literal_iterator;
+  parser_list_iterator_init (&context_p->literal_pool, &literal_iterator);
+
+  context_p->last_cbc_opcode = two_literals ? CBC_PUSH_TWO_LITERALS : CBC_PUSH_LITERAL;
+
+  uint32_t literal_index = 0;
+  lexer_literal_t *literal_p;
+
+  while ((literal_p = (lexer_literal_t *) parser_list_iterator_next (&literal_iterator)) != NULL)
+  {
+    if (literal_p->type == LEXER_NUMBER_LITERAL
+        && literal_p->u.value == lit_value)
+    {
+      if (two_literals)
+      {
+        context_p->last_cbc.value = (uint16_t) literal_index;
+      }
+      else
+      {
+        context_p->last_cbc.literal_index = (uint16_t) literal_index;
+      }
+      return;
+    }
+
+    literal_index++;
+  }
+
+  JERRY_ASSERT (literal_index == context_p->literal_count);
+
+  if (literal_index >= PARSER_MAXIMUM_NUMBER_OF_LITERALS)
+  {
+    parser_raise_error (context_p, PARSER_ERR_LITERAL_LIMIT_REACHED);
+  }
+
+  literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool);
+  literal_p->u.value = lit_value;
+  literal_p->prop.length = 0; /* Unused. */
+  literal_p->type = LEXER_NUMBER_LITERAL;
+  literal_p->status_flags = 0;
+
+  context_p->literal_count++;
+
+  if (two_literals)
+  {
+    context_p->last_cbc.value = (uint16_t) literal_index;
+  }
+  else
+  {
+    context_p->last_cbc.literal_index = (uint16_t) literal_index;
+  }
+} /* lexer_convert_push_number_to_push_literal */
+
 /**
  * Construct a function literal object.
  *
@@ -2035,7 +2191,7 @@ lexer_construct_regexp_object (parser_context_t *context_p, /**< context */
                                           current_flags);
   ecma_deref_ecma_string (pattern_str_p);
 
-  bool is_throw = ECMA_IS_VALUE_ERROR (completion_value) ? true : false;
+  bool is_throw = ECMA_IS_VALUE_ERROR (completion_value) != 0;
 
   ecma_free_value (completion_value);
 
@@ -2113,25 +2269,21 @@ lexer_expect_identifier (parser_context_t *context_p, /**< context */
   parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
 } /* lexer_expect_identifier */
 
-static const lexer_lit_location_t lexer_get_literal =
-{
-  (const uint8_t *) "get", 3, LEXER_IDENT_LITERAL, false
-};
-
-static const lexer_lit_location_t lexer_set_literal =
-{
-  (const uint8_t *) "set", 3, LEXER_IDENT_LITERAL, false
-};
-
 /**
  * Next token must be an identifier.
  */
 void
 lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
-                                bool must_be_identifier) /**< only identifiers are accepted */
+                                uint32_t ident_opts) /**< lexer_obj_ident_opts_t option bits */
 {
   lexer_skip_spaces (context_p);
 
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  int is_class_method = ((ident_opts & LEXER_OBJ_IDENT_CLASS_METHOD)
+                         && !(ident_opts & LEXER_OBJ_IDENT_ONLY_IDENTIFIERS)
+                         && (context_p->token.type != LEXER_KEYW_STATIC));
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
   context_p->token.line = context_p->line;
   context_p->token.column = context_p->column;
 
@@ -2143,7 +2295,7 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
     {
       lexer_parse_identifier (context_p, false);
 
-      if (!must_be_identifier
+      if (!(ident_opts & LEXER_OBJ_IDENT_ONLY_IDENTIFIERS)
           && context_p->token.lit_location.length == 3)
       {
         lexer_skip_spaces (context_p);
@@ -2151,12 +2303,12 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
         if (context_p->source_p < context_p->source_end_p
             && context_p->source_p[0] != LIT_CHAR_COLON)
         {
-          if (lexer_compare_identifier_to_current (context_p, &lexer_get_literal))
+          if (lexer_compare_raw_identifier_to_current (context_p, "get", 3))
           {
             context_p->token.type = LEXER_PROPERTY_GETTER;
             return;
           }
-          else if (lexer_compare_identifier_to_current (context_p, &lexer_set_literal))
+          else if (lexer_compare_raw_identifier_to_current (context_p, "set", 3))
           {
             context_p->token.type = LEXER_PROPERTY_SETTER;
             return;
@@ -2164,6 +2316,15 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
         }
       }
 
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+      if (is_class_method
+          && lexer_compare_raw_identifier_to_current (context_p, "static", 6))
+      {
+        context_p->token.type = LEXER_KEYW_STATIC;
+        return;
+      }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
       create_literal_object = true;
     }
     else if (context_p->source_p[0] == LIT_CHAR_DOUBLE_QUOTE
@@ -2172,7 +2333,23 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
       lexer_parse_string (context_p);
       create_literal_object = true;
     }
-    else if (!must_be_identifier && context_p->source_p[0] == LIT_CHAR_RIGHT_BRACE)
+#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+    else if (context_p->source_p[0] == LIT_CHAR_LEFT_SQUARE)
+    {
+      context_p->source_p += 1;
+      context_p->column++;
+
+      lexer_next_token (context_p);
+      parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
+
+      if (context_p->token.type != LEXER_RIGHT_SQUARE)
+      {
+        parser_raise_error (context_p, PARSER_ERR_RIGHT_SQUARE_EXPECTED);
+      }
+      return;
+    }
+#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+    else if (!(ident_opts & LEXER_OBJ_IDENT_ONLY_IDENTIFIERS) && context_p->source_p[0] == LIT_CHAR_RIGHT_BRACE)
     {
       context_p->token.type = LEXER_RIGHT_BRACE;
       context_p->source_p += 1;
@@ -2200,6 +2377,15 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
 
     if (create_literal_object)
     {
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+      if (is_class_method
+          && lexer_compare_raw_identifier_to_current (context_p, "constructor", 11))
+      {
+        context_p->token.type = LEXER_CLASS_CONSTRUCTOR;
+        return;
+      }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
       lexer_construct_literal_object (context_p,
                                       &context_p->token.lit_location,
                                       LEXER_STRING_LITERAL);
@@ -2215,7 +2401,7 @@ lexer_expect_object_literal_id (parser_context_t *context_p, /**< context */
  */
 void
 lexer_scan_identifier (parser_context_t *context_p, /**< context */
-                       bool propety_name) /**< property name */
+                       bool property_name) /**< property name */
 {
   lexer_skip_spaces (context_p);
   context_p->token.line = context_p->line;
@@ -2226,18 +2412,18 @@ lexer_scan_identifier (parser_context_t *context_p, /**< context */
   {
     lexer_parse_identifier (context_p, false);
 
-    if (propety_name && context_p->token.lit_location.length == 3)
+    if (property_name && context_p->token.lit_location.length == 3)
     {
       lexer_skip_spaces (context_p);
 
       if (context_p->source_p < context_p->source_end_p
           && context_p->source_p[0] != LIT_CHAR_COLON)
       {
-        if (lexer_compare_identifier_to_current (context_p, &lexer_get_literal))
+        if (lexer_compare_raw_identifier_to_current (context_p, "get", 3))
         {
           context_p->token.type = LEXER_PROPERTY_GETTER;
         }
-        else if (lexer_compare_identifier_to_current (context_p, &lexer_set_literal))
+        else if (lexer_compare_raw_identifier_to_current (context_p, "set", 3))
         {
           context_p->token.type = LEXER_PROPERTY_SETTER;
         }
@@ -2246,11 +2432,14 @@ lexer_scan_identifier (parser_context_t *context_p, /**< context */
     return;
   }
 
-  if (propety_name)
+  if (property_name)
   {
     lexer_next_token (context_p);
 
     if (context_p->token.type == LEXER_LITERAL
+#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+        || context_p->token.type == LEXER_LEFT_SQUARE
+#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
         || context_p->token.type == LEXER_RIGHT_BRACE)
     {
       return;
@@ -2261,35 +2450,37 @@ lexer_scan_identifier (parser_context_t *context_p, /**< context */
 } /* lexer_scan_identifier */
 
 /**
- * Compares the given identifier to that which is the current token
- * in the parser context.
+ * Compares the current identifier in the context to the parameter identifier
+ *
+ * Note:
+ *   Escape sequences are allowed.
  *
  * @return true if the input identifiers are the same
  */
 bool
-lexer_compare_identifier_to_current (parser_context_t *context_p,        /**< context */
-                                     const lexer_lit_location_t *right /**< identifier */
+lexer_compare_identifier_to_current (parser_context_t *context_p, /**< context */
+                                     const lexer_lit_location_t *right_ident_p) /**< identifier */
 {
-  lexer_lit_location_t *left = &context_p->token.lit_location;
+  lexer_lit_location_t *left_ident_p = &context_p->token.lit_location;
   const uint8_t *left_p;
   const uint8_t *right_p;
   size_t count;
 
-  JERRY_ASSERT (left->length > 0 && right->length > 0);
+  JERRY_ASSERT (left_ident_p->length > 0 && right_ident_p->length > 0);
 
-  if (left->length != right->length)
+  if (left_ident_p->length != right_ident_p->length)
   {
     return 0;
   }
 
-  if (!left->has_escape && !right->has_escape)
+  if (!left_ident_p->has_escape && !right_ident_p->has_escape)
   {
-    return memcmp (left->char_p, right->char_p, left->length) == 0;
+    return memcmp (left_ident_p->char_p, right_ident_p->char_p, left_ident_p->length) == 0;
   }
 
-  left_p = left->char_p;
-  right_p = right->char_p;
-  count = left->length;
+  left_p = left_ident_p->char_p;
+  right_p = right_ident_p->char_p;
+  count = left_ident_p->length;
 
   do
   {
@@ -2309,9 +2500,9 @@ lexer_compare_identifier_to_current (parser_context_t *context_p,        /**< co
 
     if (*left_p == LIT_CHAR_BACKSLASH && *right_p == LIT_CHAR_BACKSLASH)
     {
-      uint16_t left_chr = lexer_hex_to_character (context_p, left_p, 6);
+      uint16_t left_chr = lexer_hex_to_character (context_p, left_p + 2, 4);
 
-      if (left_chr != lexer_hex_to_character (context_p, right_p, 6))
+      if (left_chr != lexer_hex_to_character (context_p, right_p + 2, 4))
       {
         return false;
       }
@@ -2331,7 +2522,7 @@ lexer_compare_identifier_to_current (parser_context_t *context_p,        /**< co
       right_p = swap_p;
     }
 
-    utf8_len = lit_char_to_utf8_bytes (utf8_buf, lexer_hex_to_character (context_p, left_p, 6));
+    utf8_len = lit_char_to_utf8_bytes (utf8_buf, lexer_hex_to_character (context_p, left_p + 2, 4));
     JERRY_ASSERT (utf8_len > 0);
     count -= utf8_len;
     offset = 0;
@@ -2353,6 +2544,29 @@ lexer_compare_identifier_to_current (parser_context_t *context_p,        /**< co
   return true;
 } /* lexer_compare_identifier_to_current */
 
+/**
+ * Compares the current identifier in the context to the parameter identifier
+ *
+ * Note:
+ *   Escape sequences are not allowed.
+ *
+ * @return true if the input identifiers are the same
+ */
+bool
+lexer_compare_raw_identifier_to_current (parser_context_t *context_p, /**< context */
+                                         const char *right_ident_p, /**< identifier */
+                                         size_t right_ident_length) /**< identifier length */
+{
+  lexer_lit_location_t *left_ident_p = &context_p->token.lit_location;
+
+  if (left_ident_p->length != right_ident_length || left_ident_p->has_escape)
+  {
+    return 0;
+  }
+
+  return memcmp (left_ident_p->char_p, right_ident_p, right_ident_length) == 0;
+} /* lexer_compare_raw_identifier_to_current */
+
 /**
  * @}
  * @}
index 96dfe842db90d5cbe730de9f123a4b52d0a8ed7e..7fe392567ce0c68c9d2dbd5e56b5dd752d0a0721 100644 (file)
@@ -149,30 +149,61 @@ typedef enum
   LEXER_PROPERTY_SETTER,         /**< property setter function */
   LEXER_COMMA_SEP_LIST,          /**< comma separated bracketed expression list */
   LEXER_SCAN_SWITCH,             /**< special value for switch pre-scan */
+  LEXER_CLASS_CONSTRUCTOR,       /**< special value for class constructor method */
 
+#ifdef CONFIG_DISABLE_ES2015
   /* Future reserved words: these keywords
    * must form a group after all other keywords. */
 #define LEXER_FIRST_FUTURE_RESERVED_WORD LEXER_KEYW_CLASS
+#endif /* CONFIG_DISABLE_ES2015 */
   LEXER_KEYW_CLASS,              /**< class */
-  LEXER_KEYW_ENUM,               /**< enum */
   LEXER_KEYW_EXTENDS,            /**< extends */
   LEXER_KEYW_SUPER,              /**< super */
   LEXER_KEYW_CONST,              /**< const */
   LEXER_KEYW_EXPORT,             /**< export */
   LEXER_KEYW_IMPORT,             /**< import */
+#ifndef CONFIG_DISABLE_ES2015
+  /* Future reserved words: these keywords
+   * must form a group after all other keywords.
+   * Note:
+   *      Tokens from LEXER_KEYW_CLASS to LEXER_KEYW_IMPORT
+   *      are no longer future reserved words in ES2015. */
+#define LEXER_FIRST_FUTURE_RESERVED_WORD LEXER_KEYW_ENUM
+#endif /* !CONFIG_DISABLE_ES2015 */
+  LEXER_KEYW_ENUM,               /**< enum */
+#ifndef CONFIG_DISABLE_ES2015
+  LEXER_KEYW_AWAIT,              /**< await */
+#endif /* !CONFIG_DISABLE_ES2015 */
 
   /* Future strict reserved words: these keywords
    * must form a group after future reserved words. */
 #define LEXER_FIRST_FUTURE_STRICT_RESERVED_WORD LEXER_KEYW_IMPLEMENTS
   LEXER_KEYW_IMPLEMENTS,         /**< implements */
-  LEXER_KEYW_LET,                /**< let */
   LEXER_KEYW_PRIVATE,            /**< private */
   LEXER_KEYW_PUBLIC,             /**< public */
-  LEXER_KEYW_YIELD,              /**< yield */
   LEXER_KEYW_INTERFACE,          /**< interface */
   LEXER_KEYW_PACKAGE,            /**< package */
   LEXER_KEYW_PROTECTED,          /**< protected */
+
+#ifndef CONFIG_DISABLE_ES2015
+  /* Context dependent strict reserved words:
+   * See also: ECMA-262 v6, 11.6.2.1 */
+#define LEXER_FIRST_CONTEXT_DEPENDENT_RESERVED_WORD LEXER_KEYW_STATIC
   LEXER_KEYW_STATIC,             /**< static */
+#else /* CONFIG_DISABLE_ES2015 */
+  /* Context dependent strict reserved words:
+   * See also: ECMA-262 v6, 11.6.2.1 */
+#define LEXER_FIRST_CONTEXT_DEPENDENT_RESERVED_WORD
+#endif /* !CONFIG_DISABLE_ES2015 */
+
+  /* Context dependent future strict reserved words:
+   * See also: ECMA-262 v6, 11.6.2.1 */
+#define LEXER_FIRST_CONTEXT_DEPENDENT_FUTURE_RESERVED_WORD LEXER_KEYW_LET
+  LEXER_KEYW_LET,                /**< let */
+  LEXER_KEYW_YIELD,              /**< yield */
+#ifdef CONFIG_DISABLE_ES2015
+  LEXER_KEYW_STATIC,             /**< static */
+#endif /* CONFIG_DISABLE_ES2015 */
 } lexer_token_type_t;
 
 #define LEXER_NEWLINE_LS_PS_BYTE_1 0xe2
@@ -207,6 +238,16 @@ typedef enum
   LEXER_NO_SKIP_SPACES = (1u << 1)           /**< ignore skip spaces */
 } lexer_newline_flags_t;
 
+/**
+ * Lexer object identifier parse options.
+ */
+typedef enum
+{
+  LEXER_OBJ_IDENT_NO_OPTS = (1u << 0),          /**< no options */
+  LEXER_OBJ_IDENT_ONLY_IDENTIFIERS = (1u << 1), /**< only identifiers are accepted */
+  LEXER_OBJ_IDENT_CLASS_METHOD = (1u << 2),     /**< expect identifier inside a class body */
+} lexer_obj_ident_opts_t;
+
 /**
  * Lexer literal object types.
  */
index 5b1bbad929585ac30a1b798fbb015d8c817eb6b9..9e4f46d111ed91783d3a806a36f79398a31f8597 100644 (file)
 
 #include "js-parser-internal.h"
 
-#ifndef CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS
-#include "lit-char-helpers.h"
-#endif /* !CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS */
-
 #ifndef JERRY_DISABLE_JS_PARSER
+#include "jcontext.h"
+#include "lit-char-helpers.h"
 
 /** \addtogroup parser Parser
  * @{
@@ -60,21 +58,19 @@ parser_push_result (parser_context_t *context_p) /**< context */
   {
     JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, context_p->last_cbc_opcode + 1));
 
-    if (context_p->last_cbc_opcode == CBC_POST_INCR
-        || context_p->last_cbc_opcode == CBC_POST_DECR)
+    if ((context_p->last_cbc_opcode == CBC_POST_INCR
+         || context_p->last_cbc_opcode == CBC_POST_DECR)
+        && context_p->stack_depth >= context_p->stack_limit)
     {
-      if (context_p->stack_depth >= context_p->stack_limit)
-      {
-        /* Stack limit is increased for CBC_POST_INCR_PUSH_RESULT
-         * and CBC_POST_DECR_PUSH_RESULT opcodes. Needed by vm.c. */
-        JERRY_ASSERT (context_p->stack_depth == context_p->stack_limit);
+      /* Stack limit is increased for CBC_POST_INCR_PUSH_RESULT
+       * and CBC_POST_DECR_PUSH_RESULT opcodes. Needed by vm.c. */
+      JERRY_ASSERT (context_p->stack_depth == context_p->stack_limit);
 
-        context_p->stack_limit++;
+      context_p->stack_limit++;
 
-        if (context_p->stack_limit > PARSER_MAXIMUM_STACK_LIMIT)
-        {
-          parser_raise_error (context_p, PARSER_ERR_STACK_LIMIT_REACHED);
-        }
+      if (context_p->stack_limit > PARSER_MAXIMUM_STACK_LIMIT)
+      {
+        parser_raise_error (context_p, PARSER_ERR_STACK_LIMIT_REACHED);
       }
     }
 
@@ -201,7 +197,7 @@ parser_emit_unary_lvalue_opcode (parser_context_t *context_p, /**< context */
         break;
       }
     }
-    parser_emit_cbc (context_p, opcode);
+    parser_emit_cbc (context_p, (uint16_t) opcode);
   }
 } /* parser_emit_unary_lvalue_opcode */
 
@@ -258,6 +254,7 @@ parser_parse_array_literal (parser_context_t *context_p) /**< context */
   }
 } /* parser_parse_array_literal */
 
+#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
 /**
  * Object literal item types.
  */
@@ -354,85 +351,511 @@ parser_append_object_literal_item (parser_context_t *context_p, /**< context */
     context_p->stack_top_uint8 = PARSER_OBJECT_PROPERTY_BOTH_ACCESSORS;
   }
 } /* parser_append_object_literal_item */
+#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+
+#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+#error "Class support requires ES2015 object literal support"
+#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
 
 /**
- * Parse object literal.
+ * Parse class as an object literal.
  */
 static void
-parser_parse_object_literal (parser_context_t *context_p) /**< context */
+parser_parse_class_literal (parser_context_t *context_p) /**< context */
 {
   JERRY_ASSERT (context_p->token.type == LEXER_LEFT_BRACE);
-
   parser_emit_cbc (context_p, CBC_CREATE_OBJECT);
 
-  parser_stack_push_uint8 (context_p, PARSER_OBJECT_PROPERTY_START);
+  bool super_called = false;
+  uint32_t status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | (context_p->status_flags & PARSER_CLASS_HAS_SUPER);
 
   while (true)
   {
-    lexer_expect_object_literal_id (context_p, false);
+    if (!(status_flags & PARSER_CLASS_STATIC_FUNCTION))
+    {
+      lexer_skip_empty_statements (context_p);
+    }
+
+    lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_CLASS_METHOD);
 
     if (context_p->token.type == LEXER_RIGHT_BRACE)
     {
       break;
     }
 
-    if (context_p->token.type == LEXER_PROPERTY_GETTER
-        || context_p->token.type == LEXER_PROPERTY_SETTER)
+    if (context_p->token.type == LEXER_PROPERTY_GETTER || context_p->token.type == LEXER_PROPERTY_SETTER)
     {
-      uint32_t status_flags;
-      cbc_ext_opcode_t opcode;
       uint16_t literal_index, function_literal_index;
-      parser_object_literal_item_types_t item_type;
+      bool is_getter = (context_p->token.type == LEXER_PROPERTY_GETTER);
+
+      uint32_t accessor_status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE;
+      accessor_status_flags |= (is_getter ? PARSER_IS_PROPERTY_GETTER : PARSER_IS_PROPERTY_SETTER);
+
+      lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_CLASS_METHOD | LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
+      literal_index = context_p->lit_object.index;
 
-      if (context_p->token.type == LEXER_PROPERTY_GETTER)
+      bool is_computed = false;
+
+      if (context_p->token.type == LEXER_RIGHT_SQUARE)
       {
-        status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_GETTER;
-        opcode = CBC_EXT_SET_GETTER;
-        item_type = PARSER_OBJECT_PROPERTY_GETTER;
+        is_computed = true;
       }
-      else
+      else if (!(status_flags & PARSER_CLASS_STATIC_FUNCTION)
+               && lexer_compare_raw_identifier_to_current (context_p, "constructor", 11))
       {
-        status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_SETTER;
-        opcode = CBC_EXT_SET_SETTER;
-        item_type = PARSER_OBJECT_PROPERTY_SETTER;
+        parser_raise_error (context_p, PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR);
       }
 
-      lexer_expect_object_literal_id (context_p, true);
-      literal_index = context_p->lit_object.index;
-
-      parser_append_object_literal_item (context_p, literal_index, item_type);
-
       parser_flush_cbc (context_p);
-      function_literal_index = lexer_construct_function_object (context_p, status_flags);
+      function_literal_index = lexer_construct_function_object (context_p, accessor_status_flags);
 
       parser_emit_cbc_literal (context_p,
                                CBC_PUSH_LITERAL,
                                literal_index);
 
       JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
+
+      cbc_ext_opcode_t opcode;
+      bool is_static = (status_flags & PARSER_CLASS_STATIC_FUNCTION) != 0;
+
+      if (is_computed)
+      {
+        context_p->last_cbc.literal_index = function_literal_index;
+
+        if (is_getter)
+        {
+          opcode = is_static ? CBC_EXT_SET_STATIC_COMPUTED_GETTER : CBC_EXT_SET_COMPUTED_GETTER;
+        }
+        else
+        {
+          opcode = is_static ? CBC_EXT_SET_STATIC_COMPUTED_SETTER : CBC_EXT_SET_COMPUTED_SETTER;
+        }
+      }
+      else
+      {
+        context_p->last_cbc.value = function_literal_index;
+
+        if (is_getter)
+        {
+          opcode = is_static ? CBC_EXT_SET_STATIC_GETTER : CBC_EXT_SET_GETTER;
+        }
+        else
+        {
+          opcode = is_static ? CBC_EXT_SET_STATIC_SETTER : CBC_EXT_SET_SETTER;
+        }
+      }
+
       context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode);
-      context_p->last_cbc.value = function_literal_index;
+      status_flags &= (uint32_t) ~PARSER_CLASS_STATIC_FUNCTION;
+      continue;
+    }
 
-      lexer_next_token (context_p);
+    if (!(status_flags & PARSER_CLASS_STATIC_FUNCTION) && context_p->token.type == LEXER_CLASS_CONSTRUCTOR)
+    {
+      if (super_called)
+      {
+        /* 14.5.1 */
+        parser_raise_error (context_p, PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTORS);
+      }
+      else
+      {
+        super_called = true;
+      }
+
+      parser_flush_cbc (context_p);
+      uint32_t constructor_status_flags = status_flags | PARSER_CLASS_CONSTRUCTOR;
+
+      if (context_p->status_flags & PARSER_CLASS_HAS_SUPER)
+      {
+        constructor_status_flags |= PARSER_LEXICAL_ENV_NEEDED;
+      }
+
+      if (context_p->literal_count >= PARSER_MAXIMUM_NUMBER_OF_LITERALS)
+      {
+        parser_raise_error (context_p, PARSER_ERR_LITERAL_LIMIT_REACHED);
+      }
+
+      lexer_literal_t *literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool);
+      literal_p->type = LEXER_UNUSED_LITERAL;
+      literal_p->status_flags = 0;
+      literal_p->u.bytecode_p = parser_parse_function (context_p, constructor_status_flags);
+      literal_p->type = LEXER_FUNCTION_LITERAL;
+      parser_emit_cbc_literal (context_p, PARSER_TO_EXT_OPCODE (CBC_EXT_SET_CLASS_LITERAL), context_p->literal_count);
+      context_p->literal_count++;
+      continue;
+    }
+
+    if (!(status_flags & PARSER_CLASS_STATIC_FUNCTION) && context_p->token.type == LEXER_KEYW_STATIC)
+    {
+      status_flags |= PARSER_CLASS_STATIC_FUNCTION;
+      continue;
+    }
+
+    bool is_computed = false;
+
+    if (context_p->token.type == LEXER_RIGHT_SQUARE)
+    {
+      is_computed = true;
+    }
+    else if ((status_flags & PARSER_CLASS_STATIC_FUNCTION)
+             && lexer_compare_raw_identifier_to_current (context_p, "prototype", 9))
+    {
+      parser_raise_error (context_p, PARSER_ERR_CLASS_STATIC_PROTOTYPE);
+    }
+
+    parser_flush_cbc (context_p);
+
+    uint16_t literal_index = context_p->lit_object.index;
+    uint16_t function_literal_index = lexer_construct_function_object (context_p, status_flags);
+
+    parser_emit_cbc_literal (context_p,
+                             CBC_PUSH_LITERAL,
+                             function_literal_index);
+
+    JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
+
+    context_p->last_cbc.value = literal_index;
+
+    if ((status_flags & PARSER_CLASS_STATIC_FUNCTION))
+    {
+      context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (is_computed ? CBC_EXT_SET_STATIC_COMPUTED_PROPERTY_LITERAL
+                                                                     : CBC_EXT_SET_STATIC_PROPERTY_LITERAL);
+      status_flags &= (uint32_t) ~PARSER_CLASS_STATIC_FUNCTION;
     }
     else
     {
-      uint16_t literal_index = context_p->lit_object.index;
+      context_p->last_cbc_opcode = (is_computed ? PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL)
+                                                : CBC_SET_LITERAL_PROPERTY);
+    }
+  }
+
+  if (!super_called && (context_p->status_flags & PARSER_CLASS_HAS_SUPER))
+  {
+    parser_emit_cbc_ext (context_p, CBC_EXT_IMPLICIT_CONSTRUCTOR_CALL);
+  }
+
+  if (context_p->status_flags & PARSER_CLASS_HAS_SUPER)
+  {
+    parser_emit_cbc_ext (context_p, CBC_EXT_INHERIT_AND_SET_CONSTRUCTOR);
+  }
+} /* parser_parse_class_literal */
 
-      parser_append_object_literal_item (context_p,
-                                         literal_index,
-                                         PARSER_OBJECT_PROPERTY_VALUE);
+/**
+ * Description of "prototype" literal string.
+ */
+static const lexer_lit_location_t lexer_prototype_literal =
+{
+  (const uint8_t *) "prototype", 9, LEXER_STRING_LITERAL, false
+};
+
+/**
+ * Parse class statement or expression.
+ */
+void
+parser_parse_class (parser_context_t *context_p, /**< context */
+                    bool is_statement) /**< true - if class is parsed as a statement
+                                        *   false - otherwise (as an expression) */
+{
+  JERRY_ASSERT (context_p->token.type == LEXER_KEYW_CLASS);
 
+  uint16_t class_ident_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS;
+
+  if (is_statement)
+  {
+    /* Class statement must contain an identifier. */
+    lexer_expect_identifier (context_p, LEXER_IDENT_LITERAL);
+    JERRY_ASSERT (context_p->token.type == LEXER_LITERAL
+                  && context_p->token.lit_location.type == LEXER_IDENT_LITERAL);
+
+    class_ident_index = context_p->lit_object.index;
+    context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_VAR;
+    lexer_next_token (context_p);
+  }
+  else
+  {
+    lexer_next_token (context_p);
+
+    /* Class expression may contain an identifier. */
+    if (context_p->token.type == LEXER_LITERAL && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
+    {
+      /* NOTE: If 'Function.name' will be supported, the current literal object must be set to 'name' property. */
       lexer_next_token (context_p);
-      if (context_p->token.type != LEXER_COLON)
+    }
+  }
+
+  if (context_p->token.type == LEXER_KEYW_EXTENDS)
+  {
+    parser_parse_super_class_context_start (context_p);
+  }
+
+  if (context_p->token.type != LEXER_LEFT_BRACE)
+  {
+    parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_EXPECTED);
+  }
+
+  parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_CLASS_CONSTRUCTOR);
+
+  bool is_strict = context_p->status_flags & PARSER_IS_STRICT;
+
+  /* 14.5. A ClassBody is always strict code. */
+  context_p->status_flags |= PARSER_IS_STRICT;
+
+  /* ClassDeclaration is parsed. Continue with class body. */
+  parser_parse_class_literal (context_p);
+
+  JERRY_ASSERT (context_p->token.type == LEXER_RIGHT_BRACE);
+
+  lexer_construct_literal_object (context_p,
+                                  (lexer_lit_location_t *) &lexer_prototype_literal,
+                                  lexer_prototype_literal.type);
+
+  parser_emit_cbc_literal (context_p, CBC_SET_PROPERTY, context_p->lit_object.index);
+
+  if (is_statement)
+  {
+    parser_emit_cbc_literal (context_p, CBC_ASSIGN_SET_IDENT, class_ident_index);
+  }
+
+  if (context_p->status_flags & PARSER_CLASS_HAS_SUPER)
+  {
+    parser_parse_super_class_context_end (context_p, is_statement);
+    context_p->status_flags &= (uint32_t) ~PARSER_CLASS_HAS_SUPER;
+  }
+
+  parser_flush_cbc (context_p);
+
+  if (!is_strict)
+  {
+    /* Restore flag */
+    context_p->status_flags &= (uint32_t) ~PARSER_IS_STRICT;
+  }
+
+  lexer_next_token (context_p);
+} /* parser_parse_class */
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
+#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+/**
+ * Parse object initializer method definition.
+ *
+ * See also: ES2015 14.3
+ */
+static void
+parser_parse_object_method (parser_context_t *context_p) /**< context */
+{
+  parser_flush_cbc (context_p);
+
+  context_p->source_p--;
+  context_p->column--;
+  uint16_t function_literal_index = lexer_construct_function_object (context_p,
+                                                                     PARSER_IS_FUNCTION | PARSER_IS_CLOSURE);
+
+  parser_emit_cbc_literal (context_p,
+                           CBC_PUSH_LITERAL,
+                           function_literal_index);
+
+  lexer_next_token (context_p);
+} /* parser_parse_object_method */
+#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+
+/**
+ * Parse object literal.
+ */
+static void
+parser_parse_object_literal (parser_context_t *context_p) /**< context */
+{
+  JERRY_ASSERT (context_p->token.type == LEXER_LEFT_BRACE);
+
+  parser_emit_cbc (context_p, CBC_CREATE_OBJECT);
+
+#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+  parser_stack_push_uint8 (context_p, PARSER_OBJECT_PROPERTY_START);
+#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+
+  while (true)
+  {
+    lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_NO_OPTS);
+
+    switch (context_p->token.type)
+    {
+      case LEXER_RIGHT_BRACE:
       {
-        parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
+        break;
       }
+      case LEXER_PROPERTY_GETTER:
+      case LEXER_PROPERTY_SETTER:
+      {
+        uint32_t status_flags;
+        cbc_ext_opcode_t opcode;
+        uint16_t literal_index, function_literal_index;
+#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+        parser_object_literal_item_types_t item_type;
+#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+
+        if (context_p->token.type == LEXER_PROPERTY_GETTER)
+        {
+          status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_GETTER;
+          opcode = CBC_EXT_SET_GETTER;
+#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+          item_type = PARSER_OBJECT_PROPERTY_GETTER;
+#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+        }
+        else
+        {
+          status_flags = PARSER_IS_FUNCTION | PARSER_IS_CLOSURE | PARSER_IS_PROPERTY_SETTER;
+          opcode = CBC_EXT_SET_SETTER;
+#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+          item_type = PARSER_OBJECT_PROPERTY_SETTER;
+#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+        }
 
-      lexer_next_token (context_p);
-      parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
+        lexer_expect_object_literal_id (context_p, LEXER_OBJ_IDENT_ONLY_IDENTIFIERS);
+
+        /* This assignment is a nop for computed getters/setters. */
+        literal_index = context_p->lit_object.index;
+
+#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+        if (context_p->token.type == LEXER_RIGHT_SQUARE)
+        {
+          opcode = ((opcode == CBC_EXT_SET_GETTER) ? CBC_EXT_SET_COMPUTED_GETTER
+                                                   : CBC_EXT_SET_COMPUTED_SETTER);
+        }
+#else /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+        parser_append_object_literal_item (context_p, literal_index, item_type);
+#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+
+        parser_flush_cbc (context_p);
+        function_literal_index = lexer_construct_function_object (context_p, status_flags);
+
+#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+        if (opcode >= CBC_EXT_SET_COMPUTED_GETTER)
+        {
+          literal_index = function_literal_index;
+        }
+#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
 
-      parser_emit_cbc_literal (context_p, CBC_SET_PROPERTY, literal_index);
+        parser_emit_cbc_literal (context_p,
+                                 CBC_PUSH_LITERAL,
+                                 literal_index);
+
+        JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
+        context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (opcode);
+        context_p->last_cbc.value = function_literal_index;
+
+        lexer_next_token (context_p);
+        break;
+      }
+#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+      case LEXER_RIGHT_SQUARE:
+      {
+        lexer_next_token (context_p);
+
+        if (context_p->token.type == LEXER_LEFT_PAREN)
+        {
+          parser_parse_object_method (context_p);
+
+          JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
+          context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
+          break;
+        }
+
+        if (context_p->token.type != LEXER_COLON)
+        {
+          parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
+        }
+
+        lexer_next_token (context_p);
+        parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
+
+        if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
+        {
+          context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SET_COMPUTED_PROPERTY_LITERAL);
+        }
+        else
+        {
+          parser_emit_cbc_ext (context_p, CBC_EXT_SET_COMPUTED_PROPERTY);
+        }
+        break;
+      }
+#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+      default:
+      {
+        uint16_t literal_index = context_p->lit_object.index;
+
+#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+        parser_append_object_literal_item (context_p,
+                                           literal_index,
+                                           PARSER_OBJECT_PROPERTY_VALUE);
+#else /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+        parser_line_counter_t start_line = context_p->token.line;
+        parser_line_counter_t start_column = context_p->token.column;
+#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+
+        lexer_next_token (context_p);
+
+#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+        if (context_p->token.type == LEXER_LEFT_PAREN)
+        {
+          parser_parse_object_method (context_p);
+
+          JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
+          context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
+          context_p->last_cbc.value = literal_index;
+          break;
+        }
+
+        if (context_p->token.type == LEXER_RIGHT_BRACE
+            || context_p->token.type == LEXER_COMMA)
+        {
+          /* Re-parse the literal as common identifier. */
+          context_p->source_p = context_p->token.lit_location.char_p;
+          context_p->line = start_line;
+          context_p->column = start_column;
+
+          lexer_next_token (context_p);
+
+          if (context_p->token.type != LEXER_LITERAL
+              || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
+          {
+            parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
+          }
+
+          lexer_construct_literal_object (context_p,
+                                          &context_p->token.lit_location,
+                                          context_p->token.lit_location.type);
+
+          parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
+
+          context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
+          context_p->last_cbc.value = literal_index;
+
+          lexer_next_token (context_p);
+          break;
+        }
+#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+
+        if (context_p->token.type != LEXER_COLON)
+        {
+          parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
+        }
+
+        lexer_next_token (context_p);
+        parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
+
+        if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
+        {
+          context_p->last_cbc_opcode = CBC_SET_LITERAL_PROPERTY;
+          context_p->last_cbc.value = literal_index;
+        }
+        else
+        {
+          parser_emit_cbc_literal (context_p, CBC_SET_PROPERTY, literal_index);
+        }
+
+        break;
+      }
     }
 
     if (context_p->token.type == LEXER_RIGHT_BRACE)
@@ -445,12 +868,14 @@ parser_parse_object_literal (parser_context_t *context_p) /**< context */
     }
   }
 
+#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
   while (context_p->stack_top_uint8 != PARSER_OBJECT_PROPERTY_START)
   {
     parser_stack_pop (context_p, NULL, 3);
   }
 
   parser_stack_pop_uint8 (context_p);
+#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
 } /* parser_parse_object_literal */
 
 /**
@@ -464,6 +889,52 @@ parser_parse_function_expression (parser_context_t *context_p, /**< context */
   uint16_t literal1 = 0;
   uint16_t literal2 = 0;
   uint16_t function_literal_index;
+  int32_t function_name_index = -1;
+
+  if (status_flags & PARSER_IS_FUNC_EXPRESSION)
+  {
+#ifdef JERRY_DEBUGGER
+    parser_line_counter_t debugger_line = context_p->token.line;
+    parser_line_counter_t debugger_column = context_p->token.column;
+#endif /* JERRY_DEBUGGER */
+
+    if (!lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN))
+    {
+      lexer_next_token (context_p);
+
+      if (context_p->token.type != LEXER_LITERAL
+          || context_p->token.lit_location.type != LEXER_IDENT_LITERAL)
+      {
+        parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
+      }
+
+      parser_flush_cbc (context_p);
+
+      lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_STRING_LITERAL);
+
+#ifdef JERRY_DEBUGGER
+      if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
+      {
+        jerry_debugger_send_string (JERRY_DEBUGGER_FUNCTION_NAME,
+                                    JERRY_DEBUGGER_NO_SUBTYPE,
+                                    context_p->lit_object.literal_p->u.char_p,
+                                    context_p->lit_object.literal_p->prop.length);
+
+        /* Reset token position for the function. */
+        context_p->token.line = debugger_line;
+        context_p->token.column = debugger_column;
+      }
+#endif /* JERRY_DEBUGGER */
+
+      if (context_p->token.literal_is_reserved
+          || context_p->lit_object.type != LEXER_LITERAL_OBJECT_ANY)
+      {
+        status_flags |= PARSER_HAS_NON_STRICT_ARG;
+      }
+
+      function_name_index = context_p->lit_object.index;
+    }
+  }
 
   if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
   {
@@ -505,6 +976,12 @@ parser_parse_function_expression (parser_context_t *context_p, /**< context */
     parser_emit_cbc_literal (context_p,
                              CBC_PUSH_LITERAL,
                              function_literal_index);
+
+    if (function_name_index != -1)
+    {
+      context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_NAMED_FUNC_EXPRESSION);
+      context_p->last_cbc.value = (uint16_t) function_name_index;
+    }
   }
 
   context_p->last_cbc.literal_type = LEXER_FUNCTION_LITERAL;
@@ -808,12 +1285,6 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
         {
           JERRY_ASSERT (context_p->lit_object.index <= CBC_PUSH_NUMBER_BYTE_RANGE_END);
 
-          if (context_p->lit_object.index == 0)
-          {
-            parser_emit_cbc (context_p, CBC_PUSH_NUMBER_0);
-            break;
-          }
-
           parser_emit_cbc_push_number (context_p, is_negative_number);
           break;
         }
@@ -848,7 +1319,7 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
         }
       }
 
-      parser_emit_cbc_literal_from_token (context_p, opcode);
+      parser_emit_cbc_literal_from_token (context_p, (uint16_t) opcode);
       break;
     }
     case LEXER_KEYW_FUNCTION:
@@ -895,7 +1366,18 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
     }
     case LEXER_KEYW_THIS:
     {
-      parser_emit_cbc (context_p, CBC_PUSH_THIS);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+      if (PARSER_IS_CLASS_CONSTRUCTOR_SUPER (context_p->status_flags))
+      {
+        parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_CONSTRUCTOR_THIS);
+      }
+      else
+      {
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+        parser_emit_cbc (context_p, CBC_PUSH_THIS);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+      }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
       break;
     }
     case LEXER_LIT_TRUE:
@@ -913,6 +1395,45 @@ parser_parse_unary_expression (parser_context_t *context_p, /**< context */
       parser_emit_cbc (context_p, CBC_PUSH_NULL);
       break;
     }
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+    case LEXER_KEYW_CLASS:
+    {
+      parser_parse_class (context_p, false);
+      return;
+    }
+    case LEXER_KEYW_SUPER:
+    {
+      if ((lexer_check_next_character (context_p, LIT_CHAR_DOT)
+            || lexer_check_next_character (context_p, LIT_CHAR_LEFT_SQUARE))
+          && context_p->status_flags & (PARSER_CLASS_HAS_SUPER | PARSER_IS_ARROW_FUNCTION))
+      {
+        if (!LEXER_IS_BINARY_OP_TOKEN (context_p->stack_top_uint8))
+        {
+          context_p->status_flags |= PARSER_CLASS_SUPER_PROP_REFERENCE;
+        }
+
+        if (context_p->status_flags & PARSER_CLASS_CONSTRUCTOR)
+        {
+          parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_CONSTRUCTOR_SUPER_PROP);
+          break;
+        }
+
+        bool is_static = (context_p->status_flags & PARSER_CLASS_STATIC_FUNCTION) != 0;
+        parser_emit_cbc_ext (context_p, is_static ? CBC_EXT_PUSH_STATIC_SUPER : CBC_EXT_PUSH_SUPER);
+        break;
+      }
+
+      if (lexer_check_next_character (context_p, LIT_CHAR_LEFT_PAREN)
+          && (context_p->status_flags & PARSER_CLASS_HAS_SUPER)
+          && (context_p->status_flags & (PARSER_IS_ARROW_FUNCTION | PARSER_CLASS_CONSTRUCTOR)))
+      {
+        parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_CONSTRUCTOR_SUPER);
+        break;
+      }
+
+      parser_raise_error (context_p, PARSER_ERR_UNEXPECTED_SUPER_REFERENCE);
+    }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
 #ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
     case LEXER_RIGHT_PAREN:
     {
@@ -1055,6 +1576,12 @@ parser_process_unary_expression (parser_context_t *context_p) /**< context */
             context_p->last_cbc_opcode = CBC_PUSH_PROP_THIS_LITERAL_REFERENCE;
             opcode = CBC_CALL_PROP;
           }
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+          else if (context_p->last_cbc_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_CONSTRUCTOR_SUPER))
+          {
+            opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_SUPER_CALL);
+          }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
           else if ((context_p->status_flags & (PARSER_INSIDE_WITH | PARSER_RESOLVE_BASE_FOR_CALLS))
                    && PARSER_IS_PUSH_LITERAL (context_p->last_cbc_opcode)
                    && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL)
@@ -1081,6 +1608,8 @@ parser_process_unary_expression (parser_context_t *context_p) /**< context */
                                        CBC_PUSH_IDENT_REFERENCE,
                                        context_p->last_cbc.third_literal_index);
             }
+
+            parser_emit_cbc_ext (context_p, CBC_EXT_RESOLVE_BASE);
           }
         }
 
@@ -1114,9 +1643,30 @@ parser_process_unary_expression (parser_context_t *context_p) /**< context */
 
         if (is_eval)
         {
-          parser_emit_cbc (context_p, CBC_EVAL);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+          if (context_p->status_flags & PARSER_CLASS_HAS_SUPER)
+          {
+            parser_flush_cbc (context_p);
+            context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_CLASS_EVAL);
+            context_p->last_cbc.value = PARSER_GET_CLASS_ECMA_PARSE_OPTS (context_p->status_flags);
+          }
+          else
+          {
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+            parser_emit_cbc (context_p, CBC_EVAL);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+          }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
         }
 
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+        if ((context_p->status_flags & PARSER_CLASS_SUPER_PROP_REFERENCE) && opcode == CBC_CALL_PROP)
+        {
+          parser_emit_cbc_ext (context_p, CBC_EXT_SUPER_PROP_CALL);
+          context_p->status_flags &= (uint32_t) ~PARSER_CLASS_SUPER_PROP_REFERENCE;
+        }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
         if (call_arguments == 0)
         {
           if (opcode == CBC_CALL)
@@ -1349,6 +1899,14 @@ parser_append_binary_token (parser_context_t *context_p) /**< context */
         parser_stack_push_uint16 (context_p, context_p->last_cbc.literal_index);
         parser_stack_push_uint8 (context_p, CBC_ASSIGN_PROP_LITERAL);
         context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+        if (context_p->status_flags & PARSER_CLASS_SUPER_PROP_REFERENCE)
+        {
+          parser_emit_cbc_ext (context_p, CBC_EXT_SUPER_PROP_ASSIGN);
+          parser_flush_cbc (context_p);
+        }
+        context_p->status_flags &= (uint32_t) ~PARSER_CLASS_SUPER_PROP_REFERENCE;
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
       }
       else
       {
@@ -1507,22 +2065,20 @@ parser_process_binary_opcodes (parser_context_t *context_p, /**< context */
       opcode = (cbc_opcode_t) context_p->stack_top_uint8;
       parser_stack_pop_uint8 (context_p);
 
-      if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
+      if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL
+          && opcode == CBC_ASSIGN_SET_IDENT)
       {
-        if (opcode == CBC_ASSIGN_SET_IDENT)
-        {
-          JERRY_ASSERT (CBC_ARGS_EQ (CBC_ASSIGN_LITERAL_SET_IDENT,
-                                     CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2));
-          context_p->last_cbc.value = parser_stack_pop_uint16 (context_p);
-          context_p->last_cbc_opcode = CBC_ASSIGN_LITERAL_SET_IDENT;
-          continue;
-        }
+        JERRY_ASSERT (CBC_ARGS_EQ (CBC_ASSIGN_LITERAL_SET_IDENT,
+                                   CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2));
+        context_p->last_cbc.value = parser_stack_pop_uint16 (context_p);
+        context_p->last_cbc_opcode = CBC_ASSIGN_LITERAL_SET_IDENT;
+        continue;
       }
 
       if (cbc_flags[opcode] & CBC_HAS_LITERAL_ARG)
       {
         uint16_t index = parser_stack_pop_uint16 (context_p);
-        parser_emit_cbc_literal (context_p, opcode, index);
+        parser_emit_cbc_literal (context_p, (uint16_t) opcode, index);
 
         if (opcode == CBC_ASSIGN_PROP_THIS_LITERAL
             && (context_p->stack_depth >= context_p->stack_limit))
@@ -1563,6 +2119,11 @@ parser_process_binary_opcodes (parser_context_t *context_p, /**< context */
     {
       opcode = LEXER_BINARY_OP_TOKEN_TO_OPCODE (token);
 
+      if (PARSER_IS_PUSH_NUMBER (context_p->last_cbc_opcode))
+      {
+        lexer_convert_push_number_to_push_literal (context_p);
+      }
+
       if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
       {
         JERRY_ASSERT (CBC_SAME_ARGS (context_p->last_cbc_opcode, opcode + CBC_BINARY_WITH_LITERAL));
@@ -1577,7 +2138,7 @@ parser_process_binary_opcodes (parser_context_t *context_p, /**< context */
         continue;
       }
     }
-    parser_emit_cbc (context_p, opcode);
+    parser_emit_cbc (context_p, (uint16_t) opcode);
   }
 } /* parser_process_binary_opcodes */
 
@@ -1663,7 +2224,7 @@ parser_parse_expression (parser_context_t *context_p, /**< context */
           opcode = CBC_BRANCH_IF_TRUE_FORWARD;
         }
 
-        parser_emit_cbc_forward_branch (context_p, opcode, &cond_branch);
+        parser_emit_cbc_forward_branch (context_p, (uint16_t) opcode, &cond_branch);
 
         lexer_next_token (context_p);
         parser_parse_expression (context_p, PARSE_EXPR_NO_COMMA);
index 0a5d6b195ea15b3d59f652d8f02da5dd4dff3e27..5c9002fddc1058c76c39b62e9263fb7af38a7957 100644 (file)
@@ -45,7 +45,6 @@ typedef enum
   PARSER_IS_FUNC_EXPRESSION = (1u << 3),      /**< a function expression is parsed */
   PARSER_IS_PROPERTY_GETTER = (1u << 4),      /**< a property getter function is parsed */
   PARSER_IS_PROPERTY_SETTER = (1u << 5),      /**< a property setter function is parsed */
-  PARSER_NAMED_FUNCTION_EXP = (1u << 6),      /**< a function expression has a name binding */
   PARSER_HAS_NON_STRICT_ARG = (1u << 7),      /**< the function has arguments which
                                                *   are not supported in strict mode */
   PARSER_ARGUMENTS_NEEDED = (1u << 8),        /**< arguments object must be created */
@@ -67,6 +66,14 @@ typedef enum
   PARSER_IS_ARROW_FUNCTION = (1u << 18),      /**< an arrow function is parsed */
   PARSER_ARROW_PARSE_ARGS = (1u << 19),       /**< parse the argument list of an arrow function */
 #endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  /* These three status flags must be in this order. See PARSER_CLASS_PARSE_OPTS_OFFSET. */
+  PARSER_CLASS_CONSTRUCTOR = (1u << 20),      /**< a class constructor is parsed (this value must be kept in
+                                               *   in sync with ECMA_PARSE_CLASS_CONSTRUCTOR) */
+  PARSER_CLASS_HAS_SUPER = (1u << 21),        /**< class has super reference */
+  PARSER_CLASS_STATIC_FUNCTION = (1u << 22),  /**< this function is a static class method */
+  PARSER_CLASS_SUPER_PROP_REFERENCE = (1u << 23),  /**< super property call or assignment */
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
 } parser_general_flags_t;
 
 /**
@@ -82,6 +89,54 @@ typedef enum
                                                *   CBC_PUSH_LITERAL instruction  */
 } parser_expression_flags_t;
 
+/**
+ * Mask for strict mode code
+ */
+#define PARSER_STRICT_MODE_MASK 0x1
+
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+/**
+ * Offset between PARSER_CLASS_CONSTRUCTOR and ECMA_PARSE_CLASS_CONSTRUCTOR
+ */
+#define PARSER_CLASS_PARSE_OPTS_OFFSET \
+  (JERRY_LOG2 (PARSER_CLASS_CONSTRUCTOR) - JERRY_LOG2 (ECMA_PARSE_CLASS_CONSTRUCTOR))
+
+/**
+ * Count of ecma_parse_opts_t class parsing options related bits
+ */
+#define PARSER_CLASS_PARSE_OPTS_COUNT \
+  (JERRY_LOG2 (ECMA_PARSE_HAS_STATIC_SUPER) - JERRY_LOG2 (ECMA_PARSE_CLASS_CONSTRUCTOR))
+
+/**
+ * Mask for get class option bits from ecma_parse_opts_t
+ */
+#define PARSER_CLASS_ECMA_PARSE_OPTS_TO_PARSER_OPTS_MASK \
+  (((1 << PARSER_CLASS_PARSE_OPTS_COUNT) - 1) << JERRY_LOG2 (ECMA_PARSE_CLASS_CONSTRUCTOR))
+
+/**
+ * Get class option bits from ecma_parse_opts_t
+ */
+#define PARSER_GET_CLASS_PARSER_OPTS(opts) \
+  (((opts) & PARSER_CLASS_ECMA_PARSE_OPTS_TO_PARSER_OPTS_MASK) << PARSER_CLASS_PARSE_OPTS_OFFSET)
+
+/**
+ * Get class option bits from parser_general_flags_t
+ */
+#define PARSER_GET_CLASS_ECMA_PARSE_OPTS(opts) \
+  ((uint16_t) (((opts) >> PARSER_CLASS_PARSE_OPTS_OFFSET) & PARSER_CLASS_ECMA_PARSE_OPTS_TO_PARSER_OPTS_MASK))
+
+/**
+ * Class constructor with heritage context representing bits
+ */
+#define PARSER_CLASS_CONSTRUCTOR_SUPER (PARSER_CLASS_CONSTRUCTOR | PARSER_CLASS_HAS_SUPER)
+
+/**
+ * Check the scope is a class constructor with heritage context
+ */
+#define PARSER_IS_CLASS_CONSTRUCTOR_SUPER(flag) \
+  (((flag) & PARSER_CLASS_CONSTRUCTOR_SUPER) == PARSER_CLASS_CONSTRUCTOR_SUPER)
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
 /* The maximum of PARSER_CBC_STREAM_PAGE_SIZE is 127. */
 #define PARSER_CBC_STREAM_PAGE_SIZE \
   ((uint32_t) (64 - sizeof (void *)))
@@ -117,6 +172,13 @@ typedef struct
   ((opcode) == CBC_PUSH_LITERAL \
    || (opcode) == CBC_PUSH_TWO_LITERALS \
    || (opcode) == CBC_PUSH_THREE_LITERALS)
+#define PARSER_IS_PUSH_NUMBER(opcode) \
+  ((opcode) == CBC_PUSH_NUMBER_0 \
+   || (opcode) == CBC_PUSH_NUMBER_POS_BYTE \
+   || (opcode) == CBC_PUSH_NUMBER_NEG_BYTE \
+   || (opcode) == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0) \
+   || (opcode) == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE) \
+   || (opcode) == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE))
 
 #define PARSER_GET_LITERAL(literal_index) \
   ((lexer_literal_t *) parser_list_get (&context_p->literal_pool, (literal_index)))
@@ -221,6 +283,13 @@ typedef struct
 {
   uint32_t value;                             /**< line or offset of the breakpoint */
 } parser_breakpoint_info_t;
+
+/**
+ * Maximum number of breakpoint info.
+ */
+#define PARSER_MAX_BREAKPOINT_INFO_COUNT \
+  (JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE / sizeof (parser_breakpoint_info_t))
+
 #endif /* JERRY_DEBUGGER */
 
 /**
@@ -305,8 +374,7 @@ typedef struct
 #endif /* PARSER_DUMP_BYTE_CODE */
 
 #ifdef JERRY_DEBUGGER
-  /** extra data for each breakpoint */
-  parser_breakpoint_info_t breakpoint_info[JERRY_DEBUGGER_MAX_BUFFER_SIZE / sizeof (parser_breakpoint_info_t)];
+  parser_breakpoint_info_t breakpoint_info[PARSER_MAX_BREAKPOINT_INFO_COUNT]; /**< breakpoint info list */
   uint16_t breakpoint_info_count; /**< current breakpoint index */
   parser_line_counter_t last_breakpoint_line; /**< last line where breakpoint has been inserted */
 #endif /* JERRY_DEBUGGER */
@@ -418,21 +486,27 @@ void parser_set_continues_to_current_position (parser_context_t *context_p, pars
 /* Lexer functions */
 
 void lexer_next_token (parser_context_t *context_p);
-bool lexer_check_colon (parser_context_t *context_p);
+bool lexer_check_next_character (parser_context_t *context_p, lit_utf8_byte_t character);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+void lexer_skip_empty_statements (parser_context_t *context_p);
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
 #ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
 lexer_token_type_t lexer_check_arrow (parser_context_t *context_p);
 #endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
 void lexer_parse_string (parser_context_t *context_p);
 void lexer_expect_identifier (parser_context_t *context_p, uint8_t literal_type);
-void lexer_scan_identifier (parser_context_t *context_p, bool propety_name);
+void lexer_scan_identifier (parser_context_t *context_p, bool property_name);
 ecma_char_t lexer_hex_to_character (parser_context_t *context_p, const uint8_t *source_p, int length);
-void lexer_expect_object_literal_id (parser_context_t *context_p, bool must_be_identifier);
+void lexer_expect_object_literal_id (parser_context_t *context_p, uint32_t ident_opts);
 void lexer_construct_literal_object (parser_context_t *context_p, lexer_lit_location_t *literal_p,
                                      uint8_t literal_type);
-bool lexer_construct_number_object (parser_context_t *context_p, bool push_number_allowed, bool is_negative_number);
+bool lexer_construct_number_object (parser_context_t *context_p, bool is_expr, bool is_negative_number);
+void lexer_convert_push_number_to_push_literal (parser_context_t *context_p);
 uint16_t lexer_construct_function_object (parser_context_t *context_p, uint32_t extra_status_flags);
 void lexer_construct_regexp_object (parser_context_t *context_p, bool parse_only);
-bool lexer_compare_identifier_to_current (parser_context_t *context_p, const lexer_lit_location_t *right);
+bool lexer_compare_identifier_to_current (parser_context_t *context_p, const lexer_lit_location_t *right_ident_p);
+bool lexer_compare_raw_identifier_to_current (parser_context_t *context_p, const char *right_ident_p,
+                                              size_t right_ident_length);
 
 /**
  * @}
@@ -444,6 +518,11 @@ bool lexer_compare_identifier_to_current (parser_context_t *context_p, const lex
 /* Parser functions. */
 
 void parser_parse_expression (parser_context_t *context_p, int options);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+void parser_parse_class (parser_context_t *context_p, bool is_statement);
+void parser_parse_super_class_context_start (parser_context_t *context_p);
+void parser_parse_super_class_context_end (parser_context_t *context_p, bool is_statement);
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
 
 /**
  * @}
@@ -485,7 +564,6 @@ void parser_raise_error (parser_context_t *context_p, parser_error_t error);
 #ifdef JERRY_DEBUGGER
 
 void parser_append_breakpoint_info (parser_context_t *context_p, jerry_debugger_header_type_t type, uint32_t value);
-void parser_send_breakpoints (parser_context_t *context_p, jerry_debugger_header_type_t type);
 
 #endif /* JERRY_DEBUGGER */
 
index 01774261a874c15f8e7572ea897d6e99d80944b1..5d6673003190fc25cb2c9af9c959d35f767e8797 100644 (file)
  * @{
  */
 
-/* Maximum identifier length accepted by the parser.
- * Limit: LEXER_MAX_STRING_LENGTH. */
+/**
+ * Maximum identifier length accepted by the parser.
+ * Limit: LEXER_MAX_STRING_LENGTH.
+ */
 #ifndef PARSER_MAXIMUM_IDENT_LENGTH
 #define PARSER_MAXIMUM_IDENT_LENGTH 255
 #endif /* !PARSER_MAXIMUM_IDENT_LENGTH */
 
-/* Maximum string limit.
- * Limit: 2147483647 / 65535. */
+/**
+ * Maximum string limit.
+ * Limit: 2147483647 / 65535.
+ */
 #ifdef JERRY_CPOINTER_32_BIT
 #define PARSER_MAXIMUM_STRING_LIMIT 2147483647
 #else /* !JERRY_CPOINTER_32_BIT */
 #define PARSER_MAXIMUM_STRING_LIMIT 65535
 #endif /* JERRY_CPOINTER_32_BIT */
 
-/* Maximum string length.
- * Limit: PARSER_MAXIMUM_STRING_LIMIT. */
+/**
+ * Maximum string length.
+ * Limit: PARSER_MAXIMUM_STRING_LIMIT.
+ */
 #ifndef PARSER_MAXIMUM_STRING_LENGTH
 #define PARSER_MAXIMUM_STRING_LENGTH PARSER_MAXIMUM_STRING_LIMIT
 #endif /* !PARSER_MAXIMUM_STRING_LENGTH */
 
-/* Maximum number of literals.
- * Limit: 32767. Recommended: 510, 32767 */
+/**
+ * Maximum number of literals.
+ * Limit: 32767. Recommended: 510, 32767
+ */
 #ifndef PARSER_MAXIMUM_NUMBER_OF_LITERALS
 #define PARSER_MAXIMUM_NUMBER_OF_LITERALS 32767
 #endif /* !PARSER_MAXIMUM_NUMBER_OF_LITERALS */
 
-/* Maximum number of registers.
- * Limit: PARSER_MAXIMUM_NUMBER_OF_LITERALS */
+/**
+ * Maximum number of registers.
+ * Limit: PARSER_MAXIMUM_NUMBER_OF_LITERALS
+ */
 #ifndef PARSER_MAXIMUM_NUMBER_OF_REGISTERS
 #define PARSER_MAXIMUM_NUMBER_OF_REGISTERS 256
 #endif /* !PARSER_MAXIMUM_NUMBER_OF_REGISTERS */
 
-/* Maximum code size.
- * Limit: 16777215. Recommended: 65535, 16777215. */
+/**
+ * Maximum code size.
+ * Limit: 16777215. Recommended: 65535, 16777215.
+ */
 #ifndef PARSER_MAXIMUM_CODE_SIZE
 #define PARSER_MAXIMUM_CODE_SIZE (65535 << (JMEM_ALIGNMENT_LOG))
 #endif /* !PARSER_MAXIMUM_CODE_SIZE */
 
-/* Maximum number of values pushed onto the stack by a function.
- * Limit: 65500. Recommended: 1024. */
+/**
+ * Maximum number of values pushed onto the stack by a function.
+ * Limit: 65500. Recommended: 1024.
+ */
 #ifndef PARSER_MAXIMUM_STACK_LIMIT
 #define PARSER_MAXIMUM_STACK_LIMIT 1024
 
index c3f0447e934730840e9a32da8bd2c8787bcaaf3c..17adefc4cba1fd829087ad8a9c9d75e74a83f842 100644 (file)
  */
 
 #include "js-parser-internal.h"
-
-#ifndef CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS
 #include "lit-char-helpers.h"
-#endif /* !CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS */
 
 #ifndef JERRY_DISABLE_JS_PARSER
 
@@ -46,6 +43,10 @@ typedef enum
   SCAN_MODE_STATEMENT,                     /**< scanning statement */
   SCAN_MODE_FUNCTION_ARGUMENTS,            /**< scanning function arguments */
   SCAN_MODE_PROPERTY_NAME,                 /**< scanning property name */
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  SCAN_MODE_CLASS_DECLARATION,             /**< scanning class declaration */
+  SCAN_MODE_CLASS_METHOD,                  /**< scanning class method */
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
 } scan_modes_t;
 
 /**
@@ -55,17 +56,27 @@ typedef enum
 {
   SCAN_STACK_HEAD,                         /**< head */
   SCAN_STACK_PAREN_EXPRESSION,             /**< parent expression group */
-  SCAN_STACK_PAREN_STATEMENT,              /**< parent stetement group */
+  SCAN_STACK_PAREN_STATEMENT,              /**< parent statement group */
   SCAN_STACK_COLON_EXPRESSION,             /**< colon expression group */
-  SCAN_STACK_COLON_STATEMENT,              /**< colon statement group*/
+  SCAN_STACK_COLON_STATEMENT,              /**< colon statement group */
   SCAN_STACK_SQUARE_BRACKETED_EXPRESSION,  /**< square bracketed expression group */
   SCAN_STACK_OBJECT_LITERAL,               /**< object literal group */
   SCAN_STACK_BLOCK_STATEMENT,              /**< block statement group */
   SCAN_STACK_BLOCK_EXPRESSION,             /**< block expression group */
   SCAN_STACK_BLOCK_PROPERTY,               /**< block property group */
+#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+  SCAN_STACK_COMPUTED_PROPERTY,            /**< computed property name */
+#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
 #ifndef CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS
   SCAN_STACK_TEMPLATE_STRING,              /**< template string */
 #endif /* !CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS */
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  SCAN_STACK_CLASS,                        /**< class language element */
+  SCAN_STACK_CLASS_EXTENDS,                /**< class extends expression */
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+#ifndef CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER
+  SCAN_STACK_FUNCTION_PARAMETERS,          /**< function parameter initializer */
+#endif /* !CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER */
 } scan_stack_modes_t;
 
 /**
@@ -149,6 +160,14 @@ parser_scan_primary_expression (parser_context_t *context_p, /**< context */
       *mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
       break;
     }
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+    case LEXER_KEYW_CLASS:
+    {
+      parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_EXPRESSION);
+      *mode = SCAN_MODE_CLASS_DECLARATION;
+      break;
+    }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
     case LEXER_RIGHT_SQUARE:
     {
       if (stack_top != SCAN_STACK_SQUARE_BRACKETED_EXPRESSION)
@@ -317,6 +336,9 @@ parser_scan_primary_expression_end (parser_context_t *context_p, /**< context */
 
   if ((type == LEXER_RIGHT_SQUARE && stack_top == SCAN_STACK_SQUARE_BRACKETED_EXPRESSION)
       || (type == LEXER_RIGHT_PAREN && stack_top == SCAN_STACK_PAREN_EXPRESSION)
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+      || (type == LEXER_LEFT_BRACE && stack_top == SCAN_STACK_CLASS_EXTENDS)
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
       || (type == LEXER_RIGHT_BRACE && stack_top == SCAN_STACK_OBJECT_LITERAL))
   {
     parser_stack_pop_uint8 (context_p);
@@ -327,6 +349,12 @@ parser_scan_primary_expression_end (parser_context_t *context_p, /**< context */
       *mode = SCAN_MODE_ARROW_FUNCTION;
     }
 #endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+    if (stack_top == SCAN_STACK_CLASS_EXTENDS)
+    {
+      *mode = SCAN_MODE_CLASS_METHOD;
+    }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
     return false;
   }
 
@@ -357,9 +385,67 @@ parser_scan_primary_expression_end (parser_context_t *context_p, /**< context */
     return false;
   }
 
+#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+  if (context_p->token.type == LEXER_RIGHT_SQUARE && stack_top == SCAN_STACK_COMPUTED_PROPERTY)
+  {
+    lexer_next_token (context_p);
+
+    parser_stack_pop_uint8 (context_p);
+    stack_top = (scan_stack_modes_t) context_p->stack_top_uint8;
+
+    if (stack_top == SCAN_STACK_BLOCK_PROPERTY)
+    {
+      if (context_p->token.type != LEXER_LEFT_PAREN)
+      {
+        parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIST_EXPECTED);
+      }
+
+      *mode = SCAN_MODE_FUNCTION_ARGUMENTS;
+      return true;
+    }
+
+    JERRY_ASSERT (stack_top == SCAN_STACK_OBJECT_LITERAL);
+
+    if (context_p->token.type == LEXER_LEFT_PAREN)
+    {
+      parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_PROPERTY);
+      *mode = SCAN_MODE_FUNCTION_ARGUMENTS;
+      return true;
+    }
+
+    if (context_p->token.type != LEXER_COLON)
+    {
+      parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
+    }
+
+    *mode = SCAN_MODE_PRIMARY_EXPRESSION;
+    return false;
+  }
+#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+
+#ifndef CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER
+  if (context_p->token.type == LEXER_RIGHT_PAREN && stack_top == SCAN_STACK_FUNCTION_PARAMETERS)
+  {
+    lexer_next_token (context_p);
+
+    parser_stack_pop_uint8 (context_p);
+
+    if (context_p->token.type != LEXER_LEFT_BRACE)
+    {
+      parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_EXPECTED);
+    }
+    *mode = SCAN_MODE_STATEMENT;
+    return false;
+  }
+#endif /* !CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER */
+
   /* Check whether we can enter to statement mode. */
   if (stack_top != SCAN_STACK_BLOCK_STATEMENT
       && stack_top != SCAN_STACK_BLOCK_EXPRESSION
+      && stack_top != SCAN_STACK_BLOCK_PROPERTY
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+      && stack_top != SCAN_STACK_CLASS
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
       && !(stack_top == SCAN_STACK_HEAD && end_type == LEXER_SCAN_SWITCH))
   {
     parser_raise_error (context_p, PARSER_ERR_INVALID_EXPRESSION);
@@ -445,7 +531,8 @@ parser_scan_statement (parser_context_t *context_p, /**< context */
     {
       lexer_next_token (context_p);
       if (!(context_p->token.flags & LEXER_WAS_NEWLINE)
-          && context_p->token.type != LEXER_SEMICOLON)
+          && context_p->token.type != LEXER_SEMICOLON
+          && context_p->token.type != LEXER_RIGHT_BRACE)
       {
         *mode = SCAN_MODE_PRIMARY_EXPRESSION;
       }
@@ -482,6 +569,9 @@ parser_scan_statement (parser_context_t *context_p, /**< context */
     {
       if (stack_top == SCAN_STACK_BLOCK_STATEMENT
           || stack_top == SCAN_STACK_BLOCK_EXPRESSION
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+          || stack_top == SCAN_STACK_CLASS
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
           || stack_top == SCAN_STACK_BLOCK_PROPERTY)
       {
         parser_stack_pop_uint8 (context_p);
@@ -490,6 +580,12 @@ parser_scan_statement (parser_context_t *context_p, /**< context */
         {
           *mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
         }
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+        else if (stack_top == SCAN_STACK_CLASS)
+        {
+          *mode = SCAN_MODE_CLASS_METHOD;
+        }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
         else if (stack_top == SCAN_STACK_BLOCK_PROPERTY)
         {
           *mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
@@ -516,6 +612,14 @@ parser_scan_statement (parser_context_t *context_p, /**< context */
       *mode = SCAN_MODE_FUNCTION_ARGUMENTS;
       return false;
     }
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+    case LEXER_KEYW_CLASS:
+    {
+      parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_STATEMENT);
+      *mode = SCAN_MODE_CLASS_DECLARATION;
+      return false;
+    }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
     default:
     {
       break;
@@ -620,6 +724,60 @@ parser_scan_until (parser_context_t *context_p, /**< context */
         }
         break;
       }
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+      case SCAN_MODE_CLASS_DECLARATION:
+      {
+        if (context_p->token.type == LEXER_LITERAL && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
+        {
+          lexer_next_token (context_p);
+        }
+
+        if (context_p->token.type == LEXER_KEYW_EXTENDS)
+        {
+          parser_stack_push_uint8 (context_p, SCAN_STACK_CLASS_EXTENDS);
+          mode = SCAN_MODE_PRIMARY_EXPRESSION;
+          break;
+        }
+        else if (context_p->token.type != LEXER_LEFT_BRACE)
+        {
+          parser_raise_error (context_p, PARSER_ERR_LEFT_BRACE_EXPECTED);
+        }
+
+        mode = SCAN_MODE_CLASS_METHOD;
+        break;
+      }
+      case SCAN_MODE_CLASS_METHOD:
+      {
+        if (type == LEXER_SEMICOLON)
+        {
+          break;
+        }
+
+        if (type == LEXER_RIGHT_BRACE
+            && (stack_top == SCAN_STACK_BLOCK_STATEMENT
+                || stack_top == SCAN_STACK_BLOCK_EXPRESSION))
+        {
+          mode = (stack_top == SCAN_STACK_BLOCK_EXPRESSION) ? SCAN_MODE_PRIMARY_EXPRESSION_END : SCAN_MODE_STATEMENT;
+          parser_stack_pop_uint8 (context_p);
+          break;
+        }
+
+        if (lexer_compare_raw_identifier_to_current (context_p, "static", 6))
+        {
+          lexer_next_token (context_p);
+        }
+
+        if (lexer_compare_raw_identifier_to_current (context_p, "get", 3)
+            || lexer_compare_raw_identifier_to_current (context_p, "set", 3))
+        {
+          lexer_next_token (context_p);
+        }
+
+        parser_stack_push_uint8 (context_p, SCAN_STACK_CLASS);
+        mode = SCAN_MODE_FUNCTION_ARGUMENTS;
+        continue;
+      }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
 #ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
       case SCAN_MODE_ARROW_FUNCTION:
       {
@@ -678,12 +836,20 @@ parser_scan_until (parser_context_t *context_p, /**< context */
       }
       case SCAN_MODE_FUNCTION_ARGUMENTS:
       {
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+        JERRY_ASSERT (stack_top == SCAN_STACK_BLOCK_STATEMENT
+                      || stack_top == SCAN_STACK_BLOCK_EXPRESSION
+                      || stack_top == SCAN_STACK_CLASS
+                      || stack_top == SCAN_STACK_BLOCK_PROPERTY);
+#else /* CONFIG_DISABLE_ES2015_CLASS */
         JERRY_ASSERT (stack_top == SCAN_STACK_BLOCK_STATEMENT
                       || stack_top == SCAN_STACK_BLOCK_EXPRESSION
                       || stack_top == SCAN_STACK_BLOCK_PROPERTY);
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
 
         if (context_p->token.type == LEXER_LITERAL
             && (context_p->token.lit_location.type == LEXER_IDENT_LITERAL
+                || context_p->token.lit_location.type == LEXER_STRING_LITERAL
                 || context_p->token.lit_location.type == LEXER_NUMBER_LITERAL))
         {
           lexer_next_token (context_p);
@@ -714,6 +880,15 @@ parser_scan_until (parser_context_t *context_p, /**< context */
           }
         }
 
+#ifndef CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER
+        if (context_p->token.type == LEXER_ASSIGN)
+        {
+          parser_stack_push_uint8 (context_p, SCAN_STACK_FUNCTION_PARAMETERS);
+          mode = SCAN_MODE_PRIMARY_EXPRESSION;
+          break;
+        }
+#endif /* !CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER */
+
         if (context_p->token.type != LEXER_RIGHT_PAREN)
         {
           parser_raise_error (context_p, PARSER_ERR_RIGHT_PAREN_EXPECTED);
@@ -734,6 +909,15 @@ parser_scan_until (parser_context_t *context_p, /**< context */
 
         lexer_scan_identifier (context_p, true);
 
+#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+        if (context_p->token.type == LEXER_LEFT_SQUARE)
+        {
+          parser_stack_push_uint8 (context_p, SCAN_STACK_COMPUTED_PROPERTY);
+          mode = SCAN_MODE_PRIMARY_EXPRESSION;
+          break;
+        }
+#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+
         if (context_p->token.type == LEXER_RIGHT_BRACE)
         {
           parser_stack_pop_uint8 (context_p);
@@ -744,12 +928,51 @@ parser_scan_until (parser_context_t *context_p, /**< context */
         if (context_p->token.type == LEXER_PROPERTY_GETTER
             || context_p->token.type == LEXER_PROPERTY_SETTER)
         {
+          lexer_next_token (context_p);
+
           parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_PROPERTY);
+
+#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+          if (context_p->token.type == LEXER_LEFT_SQUARE)
+          {
+            parser_stack_push_uint8 (context_p, SCAN_STACK_COMPUTED_PROPERTY);
+            mode = SCAN_MODE_PRIMARY_EXPRESSION;
+            break;
+          }
+#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+
+          if (context_p->token.type != LEXER_LITERAL)
+          {
+            parser_raise_error (context_p, PARSER_ERR_IDENTIFIER_EXPECTED);
+          }
+
           mode = SCAN_MODE_FUNCTION_ARGUMENTS;
-          break;
+          continue;
         }
 
         lexer_next_token (context_p);
+
+#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+        if (context_p->token.type == LEXER_LEFT_PAREN)
+        {
+          parser_stack_push_uint8 (context_p, SCAN_STACK_BLOCK_PROPERTY);
+          mode = SCAN_MODE_FUNCTION_ARGUMENTS;
+          continue;
+        }
+
+        if (context_p->token.type == LEXER_COMMA)
+        {
+          continue;
+        }
+
+        if (context_p->token.type == LEXER_RIGHT_BRACE)
+        {
+          parser_stack_pop_uint8 (context_p);
+          mode = SCAN_MODE_POST_PRIMARY_EXPRESSION;
+          break;
+        }
+#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+
         if (context_p->token.type != LEXER_COLON)
         {
           parser_raise_error (context_p, PARSER_ERR_COLON_EXPECTED);
index 28b978f45e18a860c4761b23f005522f1a7f9b1e..d17061c337ccc2543536551816d70e116c4e72a3 100644 (file)
 #include "js-parser-internal.h"
 
 #ifndef JERRY_DISABLE_JS_PARSER
-
-#if defined (JERRY_DEBUGGER) || defined (JERRY_ENABLE_LINE_INFO)
 #include "jcontext.h"
-#endif /* JERRY_DEBUGGER || JERRY_ENABLE_LINE_INFO */
+#include "lit-char-helpers.h"
 
 /** \addtogroup parser Parser
  * @{
  * @{
  */
 
-/* Strict mode string literal in directive prologues */
+/**
+ * @{
+ * Strict mode string literal in directive prologues
+ */
 #define PARSER_USE_STRICT_LITERAL  "use strict"
 #define PARSER_USE_STRICT_LENGTH   10
+/** @} */
 
 /**
  * Parser statement types.
@@ -253,6 +255,8 @@ parser_stack_iterator_init (parser_context_t *context_p, /**< context */
 
 /**
  * Read the next byte from the stack.
+ *
+ * @return byte
  */
 static inline uint8_t
 parser_stack_iterator_read_uint8 (parser_stack_iterator_t *iterator) /**< iterator */
@@ -320,8 +324,6 @@ parser_parse_var_statement (parser_context_t *context_p) /**< context */
 
     context_p->lit_object.literal_p->status_flags |= LEXER_FLAG_VAR;
 
-    parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
-
     lexer_next_token (context_p);
 
     if (context_p->token.type == LEXER_ASSIGN)
@@ -330,19 +332,11 @@ parser_parse_var_statement (parser_context_t *context_p) /**< context */
       if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
           && ident_line_counter != context_p->last_breakpoint_line)
       {
-        JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
-
-        cbc_argument_t last_cbc = context_p->last_cbc;
-        context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
-
         parser_emit_cbc (context_p, CBC_BREAKPOINT_DISABLED);
         parser_flush_cbc (context_p);
 
         parser_append_breakpoint_info (context_p, JERRY_DEBUGGER_BREAKPOINT_LIST, ident_line_counter);
 
-        context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
-        context_p->last_cbc = last_cbc;
-
         context_p->last_breakpoint_line = ident_line_counter;
       }
 #endif /* JERRY_DEBUGGER */
@@ -354,16 +348,10 @@ parser_parse_var_statement (parser_context_t *context_p) /**< context */
       }
 #endif /* JERRY_ENABLE_LINE_INFO */
 
+      parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
       parser_parse_expression (context_p,
                                PARSE_EXPR_STATEMENT | PARSE_EXPR_NO_COMMA | PARSE_EXPR_HAS_LITERAL);
     }
-    else
-    {
-      JERRY_ASSERT (context_p->last_cbc_opcode == CBC_PUSH_LITERAL
-                    && context_p->last_cbc.literal_type == LEXER_IDENT_LITERAL);
-      /* We don't need to assign anything to this variable. */
-      context_p->last_cbc_opcode = PARSER_CBC_UNAVAILABLE;
-    }
 
     if (context_p->token.type != LEXER_COMMA)
     {
@@ -425,7 +413,7 @@ parser_parse_function_statement (parser_context_t *context_p) /**< context */
 
   if (name_p->status_flags & LEXER_FLAG_INITIALIZED)
   {
-    if (!(name_p->status_flags & (LEXER_FLAG_FUNCTION_NAME | LEXER_FLAG_FUNCTION_ARGUMENT)))
+    if (!(name_p->status_flags & LEXER_FLAG_FUNCTION_ARGUMENT))
     {
       /* Overwrite the previous initialization. */
       ecma_compiled_code_t *compiled_code_p;
@@ -496,6 +484,9 @@ parser_parse_if_statement_start (parser_context_t *context_p) /**< context */
 
 /**
  * Parse if statement (ending part).
+ *
+ * @return true  - if parsing an 'else' statement
+ *         false - otherwise
  */
 static bool
 parser_parse_if_statement_end (parser_context_t *context_p) /**< context */
@@ -608,6 +599,68 @@ parser_parse_with_statement_end (parser_context_t *context_p) /**< context */
   }
 } /* parser_parse_with_statement_end */
 
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+/**
+ * Parse super class context like a with statement (starting part).
+ */
+void
+parser_parse_super_class_context_start (parser_context_t *context_p) /**< context */
+{
+  JERRY_ASSERT (context_p->token.type == LEXER_KEYW_EXTENDS);
+
+  parser_with_statement_t with_statement;
+
+  lexer_next_token (context_p);
+
+  /* NOTE: Currently there is no proper way to check whether the currently parsed expression
+     is a valid lefthand-side expression or not, so we do not throw syntax error and parse
+     the class extending value as an expression. */
+  parser_parse_expression (context_p, PARSE_EXPR | PARSE_EXPR_NO_COMMA);
+
+#ifndef JERRY_NDEBUG
+  PARSER_PLUS_EQUAL_U16 (context_p->context_stack_depth, PARSER_SUPER_CLASS_CONTEXT_STACK_ALLOCATION);
+#endif /* !JERRY_NDEBUG */
+
+  context_p->status_flags |= PARSER_CLASS_HAS_SUPER;
+  parser_emit_cbc_ext_forward_branch (context_p,
+                                      CBC_EXT_SUPER_CLASS_CREATE_CONTEXT,
+                                      &with_statement.branch);
+
+  parser_stack_push (context_p, &with_statement, sizeof (parser_with_statement_t));
+  parser_stack_push_uint8 (context_p, PARSER_STATEMENT_WITH);
+} /* parser_parse_super_class_context_start */
+
+/**
+ * Parse super class context like a with statement (ending part).
+ */
+void
+parser_parse_super_class_context_end (parser_context_t *context_p, /**< context */
+                                      bool is_statement) /**< true - if class is parsed as a statement
+                                                          *   false - otherwise (as an expression) */
+{
+  parser_with_statement_t with_statement;
+  parser_stack_pop_uint8 (context_p);
+  parser_stack_pop (context_p, &with_statement, sizeof (parser_with_statement_t));
+
+  parser_flush_cbc (context_p);
+  PARSER_MINUS_EQUAL_U16 (context_p->stack_depth, PARSER_SUPER_CLASS_CONTEXT_STACK_ALLOCATION);
+#ifndef JERRY_NDEBUG
+  PARSER_MINUS_EQUAL_U16 (context_p->context_stack_depth, PARSER_SUPER_CLASS_CONTEXT_STACK_ALLOCATION);
+#endif /* !JERRY_NDEBUG */
+
+  if (is_statement)
+  {
+    parser_emit_cbc (context_p, CBC_CONTEXT_END);
+  }
+  else
+  {
+    parser_emit_cbc_ext (context_p, CBC_EXT_CLASS_EXPR_CONTEXT_END);
+  }
+
+  parser_set_branch_to_current_position (context_p, &with_statement.branch);
+} /* parser_parse_super_class_context_end */
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
 /**
  * Parse do-while statement (ending part).
  */
@@ -651,7 +704,7 @@ parser_parse_do_while_statement_end (parser_context_t *context_p) /**< context *
     parser_stack_iterator_skip (&iterator, sizeof (parser_loop_statement_t));
     parser_stack_iterator_read (&iterator, &do_while_statement, sizeof (parser_do_while_statement_t));
 
-    parser_emit_cbc_backward_branch (context_p, opcode, do_while_statement.start_offset);
+    parser_emit_cbc_backward_branch (context_p, (uint16_t) opcode, do_while_statement.start_offset);
   }
   else
   {
@@ -701,7 +754,7 @@ parser_parse_while_statement_start (parser_context_t *context_p) /**< context */
 /**
  * Parse while statement (ending part).
  */
-static void __attr_noinline___
+static void JERRY_ATTR_NOINLINE
 parser_parse_while_statement_end (parser_context_t *context_p) /**< context */
 {
   parser_while_statement_t while_statement;
@@ -750,7 +803,7 @@ parser_parse_while_statement_end (parser_context_t *context_p) /**< context */
   parser_stack_pop (context_p, NULL, 1 + sizeof (parser_loop_statement_t) + sizeof (parser_while_statement_t));
   parser_stack_iterator_init (context_p, &context_p->last_statement);
 
-  parser_emit_cbc_backward_branch (context_p, opcode, while_statement.start_offset);
+  parser_emit_cbc_backward_branch (context_p, (uint16_t) opcode, while_statement.start_offset);
   parser_set_breaks_to_current_position (context_p, loop.branch_list_p);
 
   parser_set_range (context_p, &range);
@@ -947,7 +1000,7 @@ parser_parse_for_statement_start (parser_context_t *context_p) /**< context */
 /**
  * Parse for statement (ending part).
  */
-static void __attr_noinline___
+static void JERRY_ATTR_NOINLINE
 parser_parse_for_statement_end (parser_context_t *context_p) /**< context */
 {
   parser_for_statement_t for_statement;
@@ -1018,7 +1071,7 @@ parser_parse_for_statement_end (parser_context_t *context_p) /**< context */
   parser_stack_pop (context_p, NULL, 1 + sizeof (parser_loop_statement_t) + sizeof (parser_for_statement_t));
   parser_stack_iterator_init (context_p, &context_p->last_statement);
 
-  parser_emit_cbc_backward_branch (context_p, opcode, for_statement.start_offset);
+  parser_emit_cbc_backward_branch (context_p, (uint16_t) opcode, for_statement.start_offset);
   parser_set_breaks_to_current_position (context_p, loop.branch_list_p);
 
   parser_set_range (context_p, &range);
@@ -1028,7 +1081,7 @@ parser_parse_for_statement_end (parser_context_t *context_p) /**< context */
 /**
  * Parse switch statement (starting part).
  */
-static void __attr_noinline___
+static void JERRY_ATTR_NOINLINE
 parser_parse_switch_statement_start (parser_context_t *context_p) /**< context */
 {
   parser_switch_statement_t switch_statement;
@@ -1236,13 +1289,11 @@ parser_parse_try_statement_end (parser_context_t *context_p) /**< context */
         try_statement.type = parser_finally_block;
       }
     }
-    else if (try_statement.type == parser_try_block)
+    else if (try_statement.type == parser_try_block
+             && context_p->token.type != LEXER_KEYW_CATCH
+             && context_p->token.type != LEXER_KEYW_FINALLY)
     {
-      if (context_p->token.type != LEXER_KEYW_CATCH
-          && context_p->token.type != LEXER_KEYW_FINALLY)
-      {
-        parser_raise_error (context_p, PARSER_ERR_CATCH_FINALLY_EXPECTED);
-      }
+      parser_raise_error (context_p, PARSER_ERR_CATCH_FINALLY_EXPECTED);
     }
   }
 
@@ -1420,7 +1471,7 @@ parser_parse_break_statement (parser_context_t *context_p) /**< context */
         if (lexer_compare_identifier_to_current (context_p, &label_statement.label_ident))
         {
           label_statement.break_list_p = parser_emit_cbc_forward_branch_item (context_p,
-                                                                              opcode,
+                                                                              (uint16_t) opcode,
                                                                               label_statement.break_list_p);
           parser_stack_iterator_write (&iterator, &label_statement, sizeof (parser_label_statement_t));
           lexer_next_token (context_p);
@@ -1463,7 +1514,7 @@ parser_parse_break_statement (parser_context_t *context_p) /**< context */
       parser_stack_iterator_skip (&iterator, 1);
       parser_stack_iterator_read (&iterator, &loop, sizeof (parser_loop_statement_t));
       loop.branch_list_p = parser_emit_cbc_forward_branch_item (context_p,
-                                                                opcode,
+                                                                (uint16_t) opcode,
                                                                 loop.branch_list_p);
       parser_stack_iterator_write (&iterator, &loop, sizeof (parser_loop_statement_t));
       return;
@@ -1519,7 +1570,7 @@ parser_parse_continue_statement (parser_context_t *context_p) /**< context */
           parser_stack_iterator_skip (&loop_iterator, 1);
           parser_stack_iterator_read (&loop_iterator, &loop, sizeof (parser_loop_statement_t));
           loop.branch_list_p = parser_emit_cbc_forward_branch_item (context_p,
-                                                                    opcode,
+                                                                    (uint16_t) opcode,
                                                                     loop.branch_list_p);
           loop.branch_list_p->branch.offset |= CBC_HIGHEST_BIT_MASK;
           parser_stack_iterator_write (&loop_iterator, &loop, sizeof (parser_loop_statement_t));
@@ -1576,7 +1627,7 @@ parser_parse_continue_statement (parser_context_t *context_p) /**< context */
       parser_stack_iterator_skip (&iterator, 1);
       parser_stack_iterator_read (&iterator, &loop, sizeof (parser_loop_statement_t));
       loop.branch_list_p = parser_emit_cbc_forward_branch_item (context_p,
-                                                                opcode,
+                                                                (uint16_t) opcode,
                                                                 loop.branch_list_p);
       loop.branch_list_p->branch.offset |= CBC_HIGHEST_BIT_MASK;
       parser_stack_iterator_write (&iterator, &loop, sizeof (parser_loop_statement_t));
@@ -1670,9 +1721,6 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
   {
     lexer_lit_location_t lit_location;
     uint32_t status_flags = context_p->status_flags;
-#ifdef PARSER_DUMP_BYTE_CODE
-    bool switch_to_strict_mode = false;
-#endif /* PARSER_DUMP_BYTE_CODE */
 
     JERRY_ASSERT (context_p->stack_depth == 0);
 
@@ -1683,55 +1731,50 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
         && memcmp (PARSER_USE_STRICT_LITERAL, lit_location.char_p, PARSER_USE_STRICT_LENGTH) == 0)
     {
       context_p->status_flags |= PARSER_IS_STRICT;
-
-#ifdef PARSER_DUMP_BYTE_CODE
-      switch_to_strict_mode = true;
-#endif /* PARSER_DUMP_BYTE_CODE */
     }
 
     lexer_next_token (context_p);
 
     if (context_p->token.type != LEXER_SEMICOLON
-        && context_p->token.type != LEXER_RIGHT_BRACE)
+        && context_p->token.type != LEXER_RIGHT_BRACE
+        && (!(context_p->token.flags & LEXER_WAS_NEWLINE)
+            || LEXER_IS_BINARY_OP_TOKEN (context_p->token.type)
+            || context_p->token.type == LEXER_LEFT_PAREN
+            || context_p->token.type == LEXER_LEFT_SQUARE
+            || context_p->token.type == LEXER_DOT))
     {
-      if (!(context_p->token.flags & LEXER_WAS_NEWLINE)
-          || LEXER_IS_BINARY_OP_TOKEN (context_p->token.type)
-          || context_p->token.type == LEXER_LEFT_PAREN
-          || context_p->token.type == LEXER_LEFT_SQUARE
-          || context_p->token.type == LEXER_DOT)
-      {
-        /* The string is part of an expression statement. */
-        context_p->status_flags = status_flags;
+      /* The string is part of an expression statement. */
+      context_p->status_flags = status_flags;
 
 #ifdef JERRY_DEBUGGER
-        if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
-        {
-          JERRY_ASSERT (context_p->last_breakpoint_line == 0);
+      if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
+      {
+        JERRY_ASSERT (context_p->last_breakpoint_line == 0);
 
-          parser_emit_cbc (context_p, CBC_BREAKPOINT_DISABLED);
-          parser_flush_cbc (context_p);
+        parser_emit_cbc (context_p, CBC_BREAKPOINT_DISABLED);
+        parser_flush_cbc (context_p);
 
-          parser_append_breakpoint_info (context_p, JERRY_DEBUGGER_BREAKPOINT_LIST, context_p->token.line);
+        parser_append_breakpoint_info (context_p, JERRY_DEBUGGER_BREAKPOINT_LIST, context_p->token.line);
 
-          context_p->last_breakpoint_line = context_p->token.line;
-        }
+        context_p->last_breakpoint_line = context_p->token.line;
+      }
 #endif /* JERRY_DEBUGGER */
 #ifdef JERRY_ENABLE_LINE_INFO
-        parser_emit_line_info (context_p, context_p->token.line, false);
+      parser_emit_line_info (context_p, context_p->token.line, false);
 #endif /* JERRY_ENABLE_LINE_INFO */
 
-        lexer_construct_literal_object (context_p, &lit_location, LEXER_STRING_LITERAL);
-        parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
-        /* The extra_value is used for saving the token. */
-        context_p->token.extra_value = context_p->token.type;
-        context_p->token.type = LEXER_EXPRESSION_START;
-        break;
-      }
+      lexer_construct_literal_object (context_p, &lit_location, LEXER_STRING_LITERAL);
+      parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
+      /* The extra_value is used for saving the token. */
+      context_p->token.extra_value = context_p->token.type;
+      context_p->token.type = LEXER_EXPRESSION_START;
+      break;
     }
 
 #ifdef PARSER_DUMP_BYTE_CODE
     if (context_p->is_show_opcodes
-        && switch_to_strict_mode)
+        && !(status_flags & PARSER_IS_STRICT)
+        && (context_p->status_flags & PARSER_IS_STRICT))
     {
       JERRY_DEBUG_MSG ("  Note: switch to strict mode\n\n");
     }
@@ -1743,16 +1786,14 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
     }
 
     /* The last directive prologue can be the result of the script. */
-    if (!(context_p->status_flags & PARSER_IS_FUNCTION))
+    if (!(context_p->status_flags & PARSER_IS_FUNCTION)
+        && (context_p->token.type != LEXER_LITERAL
+            || context_p->token.lit_location.type != LEXER_STRING_LITERAL))
     {
-      if (context_p->token.type != LEXER_LITERAL
-          || context_p->token.lit_location.type != LEXER_STRING_LITERAL)
-      {
-        lexer_construct_literal_object (context_p, &lit_location, LEXER_STRING_LITERAL);
-        parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
-        parser_emit_cbc (context_p, CBC_POP_BLOCK);
-        parser_flush_cbc (context_p);
-      }
+      lexer_construct_literal_object (context_p, &lit_location, LEXER_STRING_LITERAL);
+      parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
+      parser_emit_cbc (context_p, CBC_POP_BLOCK);
+      parser_flush_cbc (context_p);
     }
   }
 
@@ -1840,6 +1881,14 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
         break;
       }
 
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+      case LEXER_KEYW_CLASS:
+      {
+        parser_parse_class (context_p, true);
+        continue;
+      }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
       case LEXER_KEYW_FUNCTION:
       {
         parser_parse_function_statement (context_p);
@@ -1965,37 +2014,73 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
         }
 
         lexer_next_token (context_p);
+
         if ((context_p->token.flags & LEXER_WAS_NEWLINE)
             || context_p->token.type == LEXER_SEMICOLON
             || context_p->token.type == LEXER_RIGHT_BRACE)
         {
-          parser_emit_cbc (context_p, CBC_RETURN_WITH_BLOCK);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+          if (JERRY_UNLIKELY (PARSER_IS_CLASS_CONSTRUCTOR_SUPER (context_p->status_flags)))
+          {
+            parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_CONSTRUCTOR_THIS);
+            parser_emit_cbc (context_p, CBC_RETURN);
+          }
+          else
+          {
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+            parser_emit_cbc (context_p, CBC_RETURN_WITH_BLOCK);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+          }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
           break;
         }
 
         parser_parse_expression (context_p, PARSE_EXPR);
-        if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
+
+        bool return_with_literal = (context_p->last_cbc_opcode == CBC_PUSH_LITERAL);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+        return_with_literal = return_with_literal && !PARSER_IS_CLASS_CONSTRUCTOR_SUPER (context_p->status_flags);
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
+        if (return_with_literal)
         {
           context_p->last_cbc_opcode = CBC_RETURN_WITH_LITERAL;
         }
         else
         {
-          parser_emit_cbc (context_p, CBC_RETURN);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+          if (JERRY_UNLIKELY (PARSER_IS_CLASS_CONSTRUCTOR_SUPER (context_p->status_flags)))
+          {
+            parser_emit_cbc_ext (context_p, CBC_EXT_CONSTRUCTOR_RETURN);
+          }
+          else
+          {
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+            parser_emit_cbc (context_p, CBC_RETURN);
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+          }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
         }
         break;
       }
 
       case LEXER_KEYW_DEBUGGER:
       {
-        parser_emit_cbc_ext (context_p, CBC_EXT_DEBUGGER);
+#ifdef JERRY_DEBUGGER
+        /* This breakpoint location is not reported to the
+         * debugger, so it is impossible to disable it. */
+        if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
+        {
+          parser_emit_cbc (context_p, CBC_BREAKPOINT_ENABLED);
+        }
+#endif /* JERRY_DEBUGGER */
         lexer_next_token (context_p);
         break;
       }
-
       case LEXER_LITERAL:
       {
         if (context_p->token.lit_location.type == LEXER_IDENT_LITERAL
-            && lexer_check_colon (context_p))
+            && lexer_check_next_character (context_p, LIT_CHAR_COLON))
         {
           parser_parse_label (context_p);
           lexer_next_token (context_p);
@@ -2075,6 +2160,15 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
 #endif /* !JERRY_NDEBUG */
           /* There is no lexer_next_token here, since the
            * next token belongs to the parent context. */
+
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+          if (JERRY_UNLIKELY (PARSER_IS_CLASS_CONSTRUCTOR_SUPER (context_p->status_flags)))
+          {
+            parser_emit_cbc_ext (context_p, CBC_EXT_PUSH_CONSTRUCTOR_THIS);
+            parser_emit_cbc (context_p, CBC_RETURN);
+            parser_flush_cbc (context_p);
+          }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
           return;
         }
         parser_raise_error (context_p, PARSER_ERR_INVALID_RIGHT_SQUARE);
@@ -2208,7 +2302,7 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
 /**
  * Free jumps stored on the stack if a parse error is occured.
  */
-void __attr_noinline___
+void JERRY_ATTR_NOINLINE
 parser_free_jumps (parser_stack_iterator_t iterator) /**< iterator position */
 {
   while (true)
index e3c25b545871058cbbb6dbe0ce1a6750f6088753..ae31aad1a0fa99d46adf50381d17c87b28e2f5e0 100644 (file)
@@ -72,6 +72,12 @@ parser_emit_two_bytes (parser_context_t *context_p, /**< context */
   }
 } /* parser_emit_two_bytes */
 
+/**
+ * Append byte to the end of the current byte code stream.
+ *
+ * @param context_p parser context
+ * @param byte byte
+ */
 #define PARSER_APPEND_TO_BYTE_CODE(context_p, byte) \
   if ((context_p)->byte_code.last_position >= PARSER_CBC_STREAM_PAGE_SIZE) \
   { \
@@ -86,17 +92,18 @@ void
 parser_flush_cbc (parser_context_t *context_p) /**< context */
 {
   uint8_t flags;
+  uint16_t last_opcode = context_p->last_cbc_opcode;
 
-  if (context_p->last_cbc_opcode == PARSER_CBC_UNAVAILABLE)
+  if (last_opcode == PARSER_CBC_UNAVAILABLE)
   {
     return;
   }
 
   context_p->status_flags |= PARSER_NO_END_LABEL;
 
-  if (PARSER_IS_BASIC_OPCODE (context_p->last_cbc_opcode))
+  if (PARSER_IS_BASIC_OPCODE (last_opcode))
   {
-    cbc_opcode_t opcode = (cbc_opcode_t) context_p->last_cbc_opcode;
+    cbc_opcode_t opcode = (cbc_opcode_t) last_opcode;
 
     JERRY_ASSERT (opcode < CBC_END);
     flags = cbc_flags[opcode];
@@ -106,11 +113,11 @@ parser_flush_cbc (parser_context_t *context_p) /**< context */
   }
   else
   {
-    cbc_ext_opcode_t opcode = (cbc_ext_opcode_t) PARSER_GET_EXT_OPCODE (context_p->last_cbc_opcode);
+    cbc_ext_opcode_t opcode = (cbc_ext_opcode_t) PARSER_GET_EXT_OPCODE (last_opcode);
 
     JERRY_ASSERT (opcode < CBC_EXT_END);
     flags = cbc_ext_flags[opcode];
-    parser_emit_two_bytes (context_p, CBC_EXT_OPCODE, opcode);
+    parser_emit_two_bytes (context_p, CBC_EXT_OPCODE, (uint8_t) opcode);
     context_p->byte_code_size += 2;
   }
 
@@ -167,18 +174,10 @@ parser_flush_cbc (parser_context_t *context_p) /**< context */
 #ifdef PARSER_DUMP_BYTE_CODE
   if (context_p->is_show_opcodes)
   {
-    const char *name_p;
-
-    if (PARSER_IS_BASIC_OPCODE (context_p->last_cbc_opcode))
-    {
-      name_p = cbc_names[context_p->last_cbc_opcode];
-    }
-    else
-    {
-      name_p = cbc_ext_names[PARSER_GET_EXT_OPCODE (context_p->last_cbc_opcode)];
-    }
-
-    JERRY_DEBUG_MSG ("  [%3d] %s", (int) context_p->stack_depth, name_p);
+    JERRY_DEBUG_MSG ("  [%3d] %s",
+                     (int) context_p->stack_depth,
+                     PARSER_IS_BASIC_OPCODE (last_opcode) ? cbc_names[last_opcode]
+                                                          : cbc_ext_names[PARSER_GET_EXT_OPCODE (last_opcode)]);
 
     if (flags & (CBC_HAS_LITERAL_ARG | CBC_HAS_LITERAL_ARG2))
     {
@@ -207,7 +206,20 @@ parser_flush_cbc (parser_context_t *context_p) /**< context */
 
     if (flags & CBC_HAS_BYTE_ARG)
     {
-      JERRY_DEBUG_MSG (" byte_arg:%d", (int) context_p->last_cbc.value);
+      if ((last_opcode == CBC_PUSH_NUMBER_POS_BYTE)
+          || (last_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE)))
+      {
+        JERRY_DEBUG_MSG (" number:%d", (int) context_p->last_cbc.value + 1);
+      }
+      else if ((last_opcode == CBC_PUSH_NUMBER_NEG_BYTE)
+               || (last_opcode == PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE)))
+      {
+        JERRY_DEBUG_MSG (" number:%d", -((int) context_p->last_cbc.value + 1));
+      }
+      else
+      {
+        JERRY_DEBUG_MSG (" byte_arg:%d", (int) context_p->last_cbc.value);
+      }
     }
 
     JERRY_DEBUG_MSG ("\n");
@@ -312,48 +324,66 @@ parser_emit_cbc_push_number (parser_context_t *context_p, /**< context */
                              bool is_negative_number) /**< sign is negative */
 {
   uint16_t value = context_p->lit_object.index;
+  uint16_t lit_value = UINT16_MAX;
 
   if (context_p->last_cbc_opcode != PARSER_CBC_UNAVAILABLE)
   {
-    parser_flush_cbc (context_p);
-  }
-
-  cbc_opcode_t opcode = is_negative_number ? CBC_PUSH_NUMBER_NEG_BYTE : CBC_PUSH_NUMBER_POS_BYTE;
-
-  JERRY_ASSERT (value > 0 && value <= CBC_PUSH_NUMBER_BYTE_RANGE_END);
-  JERRY_ASSERT (CBC_STACK_ADJUST_VALUE (cbc_flags[opcode]) == 1);
+    if (context_p->last_cbc_opcode == CBC_PUSH_LITERAL)
+    {
+      lit_value = context_p->last_cbc.literal_index;
+    }
+    else
+    {
+      if (context_p->last_cbc_opcode == CBC_PUSH_TWO_LITERALS)
+      {
+        context_p->last_cbc_opcode = CBC_PUSH_LITERAL;
+        lit_value = context_p->last_cbc.value;
+      }
+      else if (context_p->last_cbc_opcode == CBC_PUSH_THREE_LITERALS)
+      {
+        context_p->last_cbc_opcode = CBC_PUSH_TWO_LITERALS;
+        lit_value = context_p->last_cbc.third_literal_index;
+      }
 
-  context_p->stack_depth++;
+      parser_flush_cbc (context_p);
+    }
+  }
 
-#ifdef PARSER_DUMP_BYTE_CODE
-  if (context_p->is_show_opcodes)
+  if (value == 0)
   {
-    int real_value = value;
-
-    if (is_negative_number)
+    if (lit_value == UINT16_MAX)
     {
-      real_value = -real_value;
+      context_p->last_cbc_opcode = CBC_PUSH_NUMBER_0;
+      return;
     }
 
-    JERRY_DEBUG_MSG ("  [%3d] %s number:%d\n",
-                     (int) context_p->stack_depth,
-                     cbc_names[opcode],
-                     real_value);
+    context_p->last_cbc_opcode = PARSER_TO_EXT_OPCODE (CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_0);
+    context_p->last_cbc.literal_index = lit_value;
+    return;
   }
-#endif /* PARSER_DUMP_BYTE_CODE */
 
-  parser_emit_two_bytes (context_p, opcode, (uint8_t) (value - 1));
+  uint16_t opcode;
 
-  context_p->byte_code_size += 2;
+  if (lit_value == UINT16_MAX)
+  {
+    opcode = (is_negative_number ? CBC_PUSH_NUMBER_NEG_BYTE
+                                 : CBC_PUSH_NUMBER_POS_BYTE);
 
-  if (context_p->stack_depth > context_p->stack_limit)
+    JERRY_ASSERT (CBC_STACK_ADJUST_VALUE (PARSER_GET_FLAGS (opcode)) == 1);
+  }
+  else
   {
-    context_p->stack_limit = context_p->stack_depth;
-    if (context_p->stack_limit > PARSER_MAXIMUM_STACK_LIMIT)
-    {
-      parser_raise_error (context_p, PARSER_ERR_STACK_LIMIT_REACHED);
-    }
+    opcode = PARSER_TO_EXT_OPCODE (is_negative_number ? CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE
+                                                      : CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE);
+    JERRY_ASSERT (CBC_STACK_ADJUST_VALUE (PARSER_GET_FLAGS (opcode)) == 2);
+
+    context_p->last_cbc.literal_index = lit_value;
   }
+
+  JERRY_ASSERT (value > 0 && value <= CBC_PUSH_NUMBER_BYTE_RANGE_END);
+
+  context_p->last_cbc_opcode = opcode;
+  context_p->last_cbc.value = (uint16_t) (value - 1);
 } /* parser_emit_cbc_push_number */
 
 #ifdef JERRY_ENABLE_LINE_INFO
@@ -388,13 +418,21 @@ parser_emit_line_info (parser_context_t *context_p, /**< context */
 
   context_p->last_line_info_line = line;
 
+  const uint32_t max_shift_plus_7 = 7 * 5;
+  uint32_t shift = 7;
+
+  while (shift < max_shift_plus_7 && (line >> shift) > 0)
+  {
+    shift += 7;
+  }
+
   do
   {
-    uint8_t byte = (uint8_t) (line & CBC_LOWER_SEVEN_BIT_MASK);
+    shift -= 7;
 
-    line >>= 7;
+    uint8_t byte = (uint8_t) ((line >> shift) & CBC_LOWER_SEVEN_BIT_MASK);
 
-    if (line > 0)
+    if (shift > 0)
     {
       byte = (uint8_t) (byte | CBC_HIGHEST_BIT_MASK);
     }
@@ -402,7 +440,7 @@ parser_emit_line_info (parser_context_t *context_p, /**< context */
     PARSER_APPEND_TO_BYTE_CODE (context_p, byte);
     context_p->byte_code_size++;
   }
-  while (line > 0);
+  while (shift > 0);
 } /* parser_emit_line_info */
 
 #endif /* JERRY_ENABLE_LINE_INFO */
@@ -453,14 +491,9 @@ parser_emit_cbc_forward_branch (parser_context_t *context_p, /**< context */
 #ifdef PARSER_DUMP_BYTE_CODE
   if (context_p->is_show_opcodes)
   {
-    if (extra_byte_code_increase == 0)
-    {
-      JERRY_DEBUG_MSG ("  [%3d] %s\n", (int) context_p->stack_depth, cbc_names[opcode]);
-    }
-    else
-    {
-      JERRY_DEBUG_MSG ("  [%3d] %s\n", (int) context_p->stack_depth, cbc_ext_names[opcode]);
-    }
+    JERRY_DEBUG_MSG ("  [%3d] %s\n",
+                     (int) context_p->stack_depth,
+                     extra_byte_code_increase == 0 ? cbc_names[opcode] : cbc_ext_names[opcode]);
   }
 #endif /* PARSER_DUMP_BYTE_CODE */
 
@@ -495,7 +528,9 @@ parser_emit_cbc_forward_branch (parser_context_t *context_p, /**< context */
 } /* parser_emit_cbc_forward_branch */
 
 /**
- * Append a branch byte code and create an item
+ * Append a branch byte code and create an item.
+ *
+ * @return newly created parser branch node
  */
 parser_branch_node_t *
 parser_emit_cbc_forward_branch_item (parser_context_t *context_p, /**< context */
@@ -863,6 +898,24 @@ parser_error_to_string (parser_error_t error) /**< error code */
     {
       return "Case statement must be in a switch block.";
     }
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+    case PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTORS:
+    {
+      return "Multiple constructors are not allowed.";
+    }
+    case PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR:
+    {
+      return "Class constructor may not be an accessor.";
+    }
+    case PARSER_ERR_CLASS_STATIC_PROTOTYPE:
+    {
+      return "Classes may not have a static property called 'prototype'.";
+    }
+    case PARSER_ERR_UNEXPECTED_SUPER_REFERENCE:
+    {
+      return "Super is not allowed to be used here.";
+    }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
     case PARSER_ERR_LEFT_PAREN_EXPECTED:
     {
       return "Expected '(' token.";
@@ -985,6 +1038,12 @@ parser_error_to_string (parser_error_t error) /**< error code */
     {
       return "Duplicated label.";
     }
+#ifndef CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER
+    case PARSER_ERR_DUPLICATED_ARGUMENT_NAMES:
+    {
+      return "Duplicated function argument names are not allowed here.";
+    }
+#endif /* !CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER */
     case PARSER_ERR_OBJECT_PROPERTY_REDEFINED:
     {
       return "Property of object literal redefined.";
index d09520d33a5dbb8e5bfd3bd76b4ee1c51a30ee7d..45346b7f43009e6768aaa65f13259f6c74a7828b 100644 (file)
 
 #ifndef JERRY_DISABLE_JS_PARSER
 
+JERRY_STATIC_ASSERT ((int) ECMA_PARSE_STRICT_MODE == (int) PARSER_IS_STRICT,
+                     ecma_parse_strict_mode_must_be_equal_to_parser_is_strict);
+
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+JERRY_STATIC_ASSERT ((ECMA_PARSE_CLASS_CONSTRUCTOR << PARSER_CLASS_PARSE_OPTS_OFFSET) == PARSER_CLASS_CONSTRUCTOR,
+                     ecma_class_parse_options_must_be_able_to_be_shifted_to_ecma_general_flags);
+#endif /* !CONFIG_DISABLE_ES2015 */
+
 /** \addtogroup parser Parser
  * @{
  *
@@ -204,6 +212,8 @@ parser_compute_indicies (parser_context_t *context_p, /**< context */
         if (!(literal_p->status_flags & LEXER_FLAG_SOURCE_PTR))
         {
           jmem_heap_free_block ((void *) char_p, literal_p->prop.length);
+          /* This literal should not be freed even if an error is encountered later. */
+          literal_p->status_flags |= LEXER_FLAG_SOURCE_PTR;
         }
       }
     }
@@ -222,17 +232,6 @@ parser_compute_indicies (parser_context_t *context_p, /**< context */
 
           if (literal_p->status_flags & LEXER_FLAG_INITIALIZED)
           {
-            if (literal_p->status_flags & LEXER_FLAG_FUNCTION_NAME)
-            {
-              JERRY_ASSERT (literal_p == PARSER_GET_LITERAL (0));
-
-              status_flags |= PARSER_NAMED_FUNCTION_EXP;
-              context_p->status_flags = status_flags;
-
-              literal_p->status_flags |= LEXER_FLAG_NO_REG_STORE;
-              context_p->literal_count++;
-            }
-
             if (literal_p->status_flags & LEXER_FLAG_FUNCTION_ARGUMENT)
             {
               if ((status_flags & PARSER_ARGUMENTS_NEEDED)
@@ -356,11 +355,6 @@ parser_compute_indicies (parser_context_t *context_p, /**< context */
   {
     uint16_t init_index;
 
-    if (literal_p->status_flags & LEXER_FLAG_UNUSED_IDENT)
-    {
-      continue;
-    }
-
     if (literal_p->type != LEXER_IDENT_LITERAL)
     {
       if (literal_p->type == LEXER_STRING_LITERAL
@@ -392,6 +386,11 @@ parser_compute_indicies (parser_context_t *context_p, /**< context */
       continue;
     }
 
+    if (literal_p->status_flags & LEXER_FLAG_UNUSED_IDENT)
+    {
+      continue;
+    }
+
     if (!(literal_p->status_flags & LEXER_FLAG_VAR))
     {
       literal_p->prop.index = ident_index;
@@ -450,14 +449,11 @@ parser_compute_indicies (parser_context_t *context_p, /**< context */
       init_index = literal_index;
       literal_index++;
 
-      if (!(literal_p->status_flags & LEXER_FLAG_FUNCTION_NAME))
-      {
-        lexer_literal_t *func_literal_p = (lexer_literal_t *) parser_list_iterator_next (&literal_iterator);
+      lexer_literal_t *func_literal_p = (lexer_literal_t *) parser_list_iterator_next (&literal_iterator);
 
-        JERRY_ASSERT (func_literal_p != NULL
-                      && func_literal_p->type == LEXER_FUNCTION_LITERAL);
-        func_literal_p->prop.index = init_index;
-      }
+      JERRY_ASSERT (func_literal_p != NULL
+                    && func_literal_p->type == LEXER_FUNCTION_LITERAL);
+      func_literal_p->prop.index = init_index;
     }
 
     /* A CBC_INITIALIZE_VAR instruction or part of a CBC_INITIALIZE_VARS instruction. */
@@ -537,7 +533,6 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
                               ecma_value_t *literal_pool_p, /**< start of literal pool */
                               uint16_t uninitialized_var_end, /**< end of the uninitialized var group */
                               uint16_t initialized_var_end, /**< end of the initialized var group */
-                              uint16_t const_literal_end, /**< end of the const literal group */
                               uint16_t literal_one_byte_limit) /**< maximum value of a literal
                                                                 *   encoded in one byte */
 {
@@ -560,8 +555,6 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
     uint16_t next_index = uninitialized_var_end;
 #endif /* !JERRY_NDEBUG */
 
-    context_p->status_flags |= PARSER_LEXICAL_ENV_NEEDED;
-
     *dst_p++ = CBC_INITIALIZE_VARS;
     dst_p = parser_encode_literal (dst_p,
                                    (uint16_t) uninitialized_var_end,
@@ -591,12 +584,7 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
 #endif /* !JERRY_NDEBUG */
         literal_p->status_flags = (uint8_t) (literal_p->status_flags & ~LEXER_FLAG_INITIALIZED);
 
-
-        if (literal_p->status_flags & LEXER_FLAG_FUNCTION_NAME)
-        {
-          init_index = const_literal_end;
-        }
-        else if (literal_p->status_flags & LEXER_FLAG_FUNCTION_ARGUMENT)
+        if (literal_p->status_flags & LEXER_FLAG_FUNCTION_ARGUMENT)
         {
           init_index = (uint16_t) (argument_count - 1);
         }
@@ -638,12 +626,6 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
                                                                          literal_p->prop.length);
             literal_pool_p[literal_p->prop.index] = lit_value;
           }
-
-          if (!context_p->is_show_opcodes
-              && !(literal_p->status_flags & LEXER_FLAG_SOURCE_PTR))
-          {
-            jmem_heap_free_block ((void *) literal_p->u.char_p, literal_p->prop.length);
-          }
 #else /* !PARSER_DUMP_BYTE_CODE */
           if (!(literal_p->status_flags & LEXER_FLAG_UNUSED_IDENT))
           {
@@ -651,6 +633,14 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
           }
 #endif /* PARSER_DUMP_BYTE_CODE */
         }
+
+#ifdef PARSER_DUMP_BYTE_CODE
+        if (!context_p->is_show_opcodes
+            && !(literal_p->status_flags & LEXER_FLAG_SOURCE_PTR))
+        {
+          jmem_heap_free_block ((void *) literal_p->u.char_p, literal_p->prop.length);
+        }
+#endif /* PARSER_DUMP_BYTE_CODE */
       }
       else if ((literal_p->type == LEXER_FUNCTION_LITERAL)
                || (literal_p->type == LEXER_REGEXP_LITERAL))
@@ -681,11 +671,7 @@ parser_generate_initializers (parser_context_t *context_p, /**< context */
 
       JERRY_ASSERT (literal_p->type == LEXER_IDENT_LITERAL);
 
-      if (literal_p->status_flags & LEXER_FLAG_FUNCTION_NAME)
-      {
-        init_index = const_literal_end;
-      }
-      else if (literal_p->status_flags & LEXER_FLAG_FUNCTION_ARGUMENT)
+      if (literal_p->status_flags & LEXER_FLAG_FUNCTION_ARGUMENT)
       {
         init_index = (uint16_t) (argument_count - 1);
 
@@ -1208,6 +1194,13 @@ parse_print_final_cbc (ecma_compiled_code_t *compiled_code_p, /**< compiled code
   }
 #endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
 
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  if (compiled_code_p->status_flags & CBC_CODE_FLAGS_CONSTRUCTOR)
+  {
+    JERRY_DEBUG_MSG (",constructor");
+  }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
   JERRY_DEBUG_MSG ("]\n");
 
   JERRY_DEBUG_MSG ("  Argument range end: %d\n", (int) argument_end);
@@ -1228,23 +1221,15 @@ parse_print_final_cbc (ecma_compiled_code_t *compiled_code_p, /**< compiled code
   }
 
   byte_code_start_p += (unsigned int) (literal_end - register_end) * sizeof (ecma_value_t);
-  if (unlikely (compiled_code_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED))
-  {
-    byte_code_start_p += argument_end * sizeof (ecma_value_t);
-  }
 
   byte_code_end_p = byte_code_start_p + length;
   byte_code_p = byte_code_start_p;
 
   while (byte_code_p < byte_code_end_p)
   {
-    cbc_opcode_t opcode;
-    cbc_ext_opcode_t ext_opcode;
-    size_t cbc_offset;
-
-    opcode = (cbc_opcode_t) *byte_code_p;
-    ext_opcode = CBC_EXT_NOP;
-    cbc_offset = (size_t) (byte_code_p - byte_code_start_p);
+    cbc_opcode_t opcode = (cbc_opcode_t) *byte_code_p;
+    cbc_ext_opcode_t ext_opcode = CBC_EXT_NOP;
+    size_t cbc_offset = (size_t) (byte_code_p - byte_code_start_p);
 
     if (opcode != CBC_EXT_OPCODE)
     {
@@ -1271,20 +1256,6 @@ parse_print_final_cbc (ecma_compiled_code_t *compiled_code_p, /**< compiled code
                                                literal_pool_p);
         continue;
       }
-
-      if (opcode == CBC_PUSH_NUMBER_POS_BYTE)
-      {
-        int value = *byte_code_p++;
-        JERRY_DEBUG_MSG (" number:%d\n", value + 1);
-        continue;
-      }
-
-      if (opcode == CBC_PUSH_NUMBER_NEG_BYTE)
-      {
-        int value = *byte_code_p++;
-        JERRY_DEBUG_MSG (" number:%d\n", -(value + 1));
-        continue;
-      }
     }
     else
     {
@@ -1336,34 +1307,38 @@ parse_print_final_cbc (ecma_compiled_code_t *compiled_code_p, /**< compiled code
 
     if (flags & CBC_HAS_BYTE_ARG)
     {
-      JERRY_DEBUG_MSG (" byte_arg:%d", *byte_code_p);
+      if (opcode == CBC_PUSH_NUMBER_POS_BYTE
+          || ext_opcode == CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_POS_BYTE)
+      {
+        JERRY_DEBUG_MSG (" number:%d", (int) *byte_code_p + 1);
+      }
+      else if (opcode == CBC_PUSH_NUMBER_NEG_BYTE
+               || ext_opcode == CBC_EXT_PUSH_LITERAL_PUSH_NUMBER_NEG_BYTE)
+      {
+        JERRY_DEBUG_MSG (" number:%d", -((int) *byte_code_p + 1));
+      }
+      else
+      {
+        JERRY_DEBUG_MSG (" byte_arg:%d", *byte_code_p);
+      }
       byte_code_p++;
     }
 
     if (flags & CBC_HAS_BRANCH_ARG)
     {
-      size_t branch_offset_length = CBC_BRANCH_OFFSET_LENGTH (opcode);
+      size_t branch_offset_length = (opcode != CBC_EXT_OPCODE ? CBC_BRANCH_OFFSET_LENGTH (opcode)
+                                                              : CBC_BRANCH_OFFSET_LENGTH (ext_opcode));
       size_t offset = 0;
 
-      if (opcode == CBC_EXT_OPCODE)
-      {
-        branch_offset_length = CBC_BRANCH_OFFSET_LENGTH (ext_opcode);
-      }
-
       do
       {
         offset = (offset << 8) | *byte_code_p++;
       }
       while (--branch_offset_length > 0);
 
-      if (CBC_BRANCH_IS_FORWARD (flags))
-      {
-        JERRY_DEBUG_MSG (" offset:%d(->%d)", (int) offset, (int) (cbc_offset + offset));
-      }
-      else
-      {
-        JERRY_DEBUG_MSG (" offset:%d(->%d)", (int) offset, (int) (cbc_offset - offset));
-      }
+      JERRY_DEBUG_MSG (" offset:%d(->%d)",
+                       (int) offset,
+                       (int) (cbc_offset + (CBC_BRANCH_IS_FORWARD (flags) ? offset : -offset)));
     }
 
     JERRY_DEBUG_MSG ("\n");
@@ -1374,6 +1349,54 @@ parse_print_final_cbc (ecma_compiled_code_t *compiled_code_p, /**< compiled code
 
 #endif /* PARSER_DUMP_BYTE_CODE */
 
+#ifdef JERRY_DEBUGGER
+
+/**
+ * Send current breakpoint list.
+ */
+static void
+parser_send_breakpoints (parser_context_t *context_p, /**< context */
+                         jerry_debugger_header_type_t type) /**< message type */
+{
+  JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
+  JERRY_ASSERT (context_p->breakpoint_info_count > 0);
+
+  jerry_debugger_send_data (type,
+                            context_p->breakpoint_info,
+                            context_p->breakpoint_info_count * sizeof (parser_breakpoint_info_t));
+
+  context_p->breakpoint_info_count = 0;
+} /* parser_send_breakpoints */
+
+/**
+ * Append a breakpoint info.
+ */
+void
+parser_append_breakpoint_info (parser_context_t *context_p, /**< context */
+                               jerry_debugger_header_type_t type, /**< message type */
+                               uint32_t value) /**< line or offset of the breakpoint */
+{
+  JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
+
+  context_p->status_flags |= PARSER_DEBUGGER_BREAKPOINT_APPENDED;
+
+  if (context_p->breakpoint_info_count >= JERRY_DEBUGGER_SEND_MAX (parser_breakpoint_info_t))
+  {
+    parser_send_breakpoints (context_p, type);
+  }
+
+  context_p->breakpoint_info[context_p->breakpoint_info_count].value = value;
+  context_p->breakpoint_info_count = (uint16_t) (context_p->breakpoint_info_count + 1);
+} /* parser_append_breakpoint_info */
+
+#endif /* JERRY_DEBUGGER */
+
+/**
+ * Forward iterator: move to the next byte code
+ *
+ * @param page_p page
+ * @param offset offset
+ */
 #define PARSER_NEXT_BYTE(page_p, offset) \
   do { \
     if (++(offset) >= PARSER_CBC_STREAM_PAGE_SIZE) \
@@ -1383,6 +1406,13 @@ parse_print_final_cbc (ecma_compiled_code_t *compiled_code_p, /**< compiled code
     } \
   } while (0)
 
+/**
+ * Forward iterator: move to the next byte code. Also updates the offset of the previous byte code.
+ *
+ * @param page_p page
+ * @param offset offset
+ * @param real_offset real offset
+ */
 #define PARSER_NEXT_BYTE_UPDATE(page_p, offset, real_offset) \
   do { \
     page_p->bytes[offset] = real_offset; \
@@ -1507,6 +1537,13 @@ parser_post_processing (parser_context_t *context_p) /**< context */
       PARSER_NEXT_BYTE (page_p, offset);
       length++;
 
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+      if (ext_opcode == CBC_EXT_CONSTRUCTOR_RETURN)
+      {
+        last_opcode = CBC_RETURN;
+      }
+#endif /* !CONFIG_DISABLE_ES2015 */
+
 #ifdef JERRY_ENABLE_LINE_INFO
       if (ext_opcode == CBC_EXT_LINE)
       {
@@ -1747,11 +1784,6 @@ parser_post_processing (parser_context_t *context_p) /**< context */
   {
     compiled_code_p->status_flags |= CBC_CODE_FLAGS_ARGUMENTS_NEEDED;
 
-    if (!(context_p->status_flags & PARSER_IS_STRICT))
-    {
-      compiled_code_p->status_flags |= CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED;
-    }
-
     /* Arguments is stored in the lexical environment. */
     context_p->status_flags |= PARSER_LEXICAL_ENV_NEEDED;
   }
@@ -1768,6 +1800,13 @@ parser_post_processing (parser_context_t *context_p) /**< context */
   }
 #endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
 
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  if (context_p->status_flags & PARSER_CLASS_CONSTRUCTOR)
+  {
+    compiled_code_p->status_flags |= CBC_CODE_FLAGS_CONSTRUCTOR;
+  }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
   literal_pool_p = (ecma_value_t *) byte_code_p;
   literal_pool_p -= context_p->register_count;
   byte_code_p += literal_length;
@@ -1777,7 +1816,6 @@ parser_post_processing (parser_context_t *context_p) /**< context */
                                         literal_pool_p,
                                         uninitialized_var_end,
                                         initialized_var_end,
-                                        const_literal_end,
                                         literal_one_byte_limit);
 
   JERRY_ASSERT (dst_p == byte_code_p + initializers_length);
@@ -1818,7 +1856,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
     }
 
     /* Storing the opcode */
-    *dst_p++ = opcode;
+    *dst_p++ = (uint8_t) opcode;
     real_offset++;
     PARSER_NEXT_BYTE_UPDATE (page_p, offset, real_offset);
     flags = cbc_flags[opcode];
@@ -1840,7 +1878,7 @@ parser_post_processing (parser_context_t *context_p) /**< context */
       branch_offset_length = CBC_BRANCH_OFFSET_LENGTH (ext_opcode);
 
       /* Storing the extended opcode */
-      *dst_p++ = ext_opcode;
+      *dst_p++ = (uint8_t) ext_opcode;
       opcode_p++;
       real_offset++;
       PARSER_NEXT_BYTE_UPDATE (page_p, offset, real_offset);
@@ -2070,12 +2108,6 @@ parser_post_processing (parser_context_t *context_p) /**< context */
   }
 #endif /* JERRY_ENABLE_LINE_INFO */
 
-  if (context_p->status_flags & PARSER_NAMED_FUNCTION_EXP)
-  {
-    ECMA_SET_INTERNAL_VALUE_POINTER (literal_pool_p[const_literal_end],
-                                     compiled_code_p);
-  }
-
 #ifdef JERRY_DEBUGGER
   if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
   {
@@ -2114,6 +2146,11 @@ static void
 parser_parse_function_arguments (parser_context_t *context_p, /**< context */
                                  lexer_token_type_t end_type) /**< expected end type */
 {
+#ifndef CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER
+  bool duplicated_argument_names = false;
+  bool initializer_found = false;
+#endif /* !CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER */
+
   if (context_p->token.type == end_type)
   {
     return;
@@ -2155,6 +2192,14 @@ parser_parse_function_arguments (parser_context_t *context_p, /**< context */
     {
       lexer_literal_t *literal_p;
 
+#ifndef CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER
+      if (initializer_found)
+      {
+        parser_raise_error (context_p, PARSER_ERR_DUPLICATED_ARGUMENT_NAMES);
+      }
+      duplicated_argument_names = true;
+#endif /* !CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER */
+
       if (context_p->literal_count >= PARSER_MAXIMUM_NUMBER_OF_LITERALS)
       {
         parser_raise_error (context_p, PARSER_ERR_LITERAL_LIMIT_REACHED);
@@ -2191,6 +2236,29 @@ parser_parse_function_arguments (parser_context_t *context_p, /**< context */
 
     lexer_next_token (context_p);
 
+#ifndef CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER
+    if (context_p->token.type == LEXER_ASSIGN)
+    {
+      parser_branch_t skip_init;
+
+      if (duplicated_argument_names)
+      {
+        parser_raise_error (context_p, PARSER_ERR_DUPLICATED_ARGUMENT_NAMES);
+      }
+      initializer_found = true;
+
+      /* LEXER_ASSIGN does not overwrite lit_object. */
+      parser_emit_cbc (context_p, CBC_PUSH_UNDEFINED);
+      parser_emit_cbc_literal (context_p, CBC_STRICT_EQUAL_RIGHT_LITERAL, context_p->lit_object.index);
+      parser_emit_cbc_forward_branch (context_p, CBC_BRANCH_IF_FALSE_FORWARD, &skip_init);
+
+      parser_emit_cbc_literal_from_token (context_p, CBC_PUSH_LITERAL);
+      parser_parse_expression (context_p, PARSE_EXPR_STATEMENT | PARSE_EXPR_NO_COMMA | PARSE_EXPR_HAS_LITERAL);
+
+      parser_set_branch_to_current_position (context_p, &skip_init);
+    }
+#endif /* !CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER */
+
     if (context_p->token.type != LEXER_COMMA)
     {
       break;
@@ -2222,7 +2290,7 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
                      size_t arg_list_size, /**< size of function argument list */
                      const uint8_t *source_p, /**< valid UTF-8 source code */
                      size_t source_size, /**< size of the source code */
-                     int strict_mode, /**< strict mode */
+                     uint32_t parse_opts, /**< ecma_parse_opts_t option bits */
                      parser_error_location_t *error_location_p) /**< error location */
 {
   parser_context_t context;
@@ -2261,11 +2329,11 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
   context.stack_limit = 0;
   context.last_context_p = NULL;
   context.last_statement.current_p = NULL;
+  context.status_flags |= parse_opts & PARSER_STRICT_MODE_MASK;
 
-  if (strict_mode)
-  {
-    context.status_flags |= PARSER_IS_STRICT;
-  }
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  context.status_flags |= PARSER_GET_CLASS_PARSER_OPTS (parse_opts);
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
 
   context.token.flags = 0;
   context.line = 1;
@@ -2503,55 +2571,19 @@ parser_parse_function (parser_context_t *context_p, /**< context */
 #ifdef PARSER_DUMP_BYTE_CODE
   if (context_p->is_show_opcodes)
   {
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+    JERRY_DEBUG_MSG ("\n--- %s parsing start ---\n\n",
+                     (context_p->status_flags & PARSER_CLASS_CONSTRUCTOR) ? "Class constructor"
+                                                                          : "Function");
+#else /* CONFIG_DISABLE_ES2015_CLASS */
     JERRY_DEBUG_MSG ("\n--- Function parsing start ---\n\n");
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
   }
 #endif /* PARSER_DUMP_BYTE_CODE */
 
-#ifdef JERRY_DEBUGGER
-  parser_line_counter_t debugger_line = context_p->token.line;
-  parser_line_counter_t debugger_column = context_p->token.column;
-#endif /* JERRY_DEBUGGER */
-
-  lexer_next_token (context_p);
-
-  if (context_p->status_flags & PARSER_IS_FUNC_EXPRESSION
-      && context_p->token.type == LEXER_LITERAL
-      && context_p->token.lit_location.type == LEXER_IDENT_LITERAL)
-  {
-    lexer_construct_literal_object (context_p,
-                                    &context_p->token.lit_location,
-                                    LEXER_IDENT_LITERAL);
-
-#ifdef JERRY_DEBUGGER
-    if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
-    {
-      jerry_debugger_send_string (JERRY_DEBUGGER_FUNCTION_NAME,
-                                  JERRY_DEBUGGER_NO_SUBTYPE,
-                                  context_p->lit_object.literal_p->u.char_p,
-                                  context_p->lit_object.literal_p->prop.length);
-    }
-#endif /* JERRY_DEBUGGER */
-
-    /* The arguments object is created later than the binding to the
-     * function expression name, so there is no need to assign special flags. */
-    if (context_p->lit_object.type != LEXER_LITERAL_OBJECT_ARGUMENTS)
-    {
-      uint8_t lexer_flags = LEXER_FLAG_VAR | LEXER_FLAG_INITIALIZED | LEXER_FLAG_FUNCTION_NAME;
-      context_p->lit_object.literal_p->status_flags |= lexer_flags;
-    }
-
-    if (context_p->token.literal_is_reserved
-        || context_p->lit_object.type != LEXER_LITERAL_OBJECT_ANY)
-    {
-      context_p->status_flags |= PARSER_HAS_NON_STRICT_ARG;
-    }
-
-    lexer_next_token (context_p);
-  }
-
 #ifdef JERRY_DEBUGGER
   if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
-      && jerry_debugger_send_parse_function (debugger_line, debugger_column))
+      && jerry_debugger_send_parse_function (context_p->token.line, context_p->token.column))
   {
     /* This option has a high memory and performance costs,
      * but it is necessary for executing eval operations by the debugger. */
@@ -2559,6 +2591,8 @@ parser_parse_function (parser_context_t *context_p, /**< context */
   }
 #endif /* JERRY_DEBUGGER */
 
+  lexer_next_token (context_p);
+
   if (context_p->token.type != LEXER_LEFT_PAREN)
   {
     parser_raise_error (context_p, PARSER_ERR_ARGUMENT_LIST_EXPECTED);
@@ -2595,13 +2629,26 @@ parser_parse_function (parser_context_t *context_p, /**< context */
   }
 
   lexer_next_token (context_p);
+
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  if ((context_p->status_flags & PARSER_CLASS_CONSTRUCTOR_SUPER) == PARSER_CLASS_CONSTRUCTOR_SUPER)
+  {
+    context_p->status_flags |= PARSER_LEXICAL_ENV_NEEDED;
+  }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
   parser_parse_statements (context_p);
   compiled_code_p = parser_post_processing (context_p);
 
 #ifdef PARSER_DUMP_BYTE_CODE
   if (context_p->is_show_opcodes)
   {
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+    JERRY_DEBUG_MSG ("\n--- %s parsing end ---\n\n",
+                     (context_p->status_flags & PARSER_CLASS_CONSTRUCTOR) ? "Class constructor"
+                                                                          : "Function");
+#else /* CONFIG_DISABLE_ES2015_CLASS */
     JERRY_DEBUG_MSG ("\n--- Function parsing end ---\n\n");
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
   }
 #endif /* PARSER_DUMP_BYTE_CODE */
 
@@ -2628,6 +2675,9 @@ parser_parse_arrow_function (parser_context_t *context_p, /**< context */
                  && (status_flags & PARSER_IS_ARROW_FUNCTION));
   parser_save_context (context_p, &saved_context);
   context_p->status_flags |= status_flags | PARSER_ARGUMENTS_NOT_NEEDED;
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  context_p->status_flags |= saved_context.status_flags & PARSER_CLASS_HAS_SUPER;
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
 
 #ifdef PARSER_DUMP_BYTE_CODE
   if (context_p->is_show_opcodes)
@@ -2762,48 +2812,6 @@ parser_raise_error (parser_context_t *context_p, /**< context */
   JERRY_ASSERT (0);
 } /* parser_raise_error */
 
-#ifdef JERRY_DEBUGGER
-
-/**
- * Append a breakpoint info.
- */
-void
-parser_append_breakpoint_info (parser_context_t *context_p, /**< context */
-                               jerry_debugger_header_type_t type, /**< message type */
-                               uint32_t value) /**< line or offset of the breakpoint */
-{
-  JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
-
-  context_p->status_flags |= PARSER_DEBUGGER_BREAKPOINT_APPENDED;
-
-  if (context_p->breakpoint_info_count >= JERRY_DEBUGGER_SEND_MAX (parser_breakpoint_info_t))
-  {
-    parser_send_breakpoints (context_p, type);
-  }
-
-  context_p->breakpoint_info[context_p->breakpoint_info_count].value = value;
-  context_p->breakpoint_info_count = (uint16_t) (context_p->breakpoint_info_count + 1);
-} /* parser_append_breakpoint_info */
-
-/**
- * Send current breakpoint list.
- */
-void
-parser_send_breakpoints (parser_context_t *context_p, /**< context */
-                         jerry_debugger_header_type_t type) /**< message type */
-{
-  JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
-  JERRY_ASSERT (context_p->breakpoint_info_count > 0);
-
-  jerry_debugger_send_data (type,
-                            context_p->breakpoint_info,
-                            context_p->breakpoint_info_count * sizeof (parser_breakpoint_info_t));
-
-  context_p->breakpoint_info_count = 0;
-} /* parser_send_breakpoints */
-
-#endif /* JERRY_DEBUGGER */
-
 #endif /* !JERRY_DISABLE_JS_PARSER */
 
 /**
@@ -2821,7 +2829,7 @@ parser_parse_script (const uint8_t *arg_list_p, /**< function argument list */
                      size_t arg_list_size, /**< size of function argument list */
                      const uint8_t *source_p, /**< source code */
                      size_t source_size, /**< size of the source code */
-                     bool is_strict, /**< strict mode */
+                     uint32_t parse_opts, /**< ecma_parse_opts_t option bits */
                      ecma_compiled_code_t **bytecode_data_p) /**< [out] JS bytecode */
 {
 #ifndef JERRY_DISABLE_JS_PARSER
@@ -2841,7 +2849,7 @@ parser_parse_script (const uint8_t *arg_list_p, /**< function argument list */
                                           arg_list_size,
                                           source_p,
                                           source_size,
-                                          is_strict,
+                                          parse_opts,
                                           &parser_error);
 
   if (!*bytecode_data_p)
@@ -2902,7 +2910,7 @@ parser_parse_script (const uint8_t *arg_list_p, /**< function argument list */
         break;
       }
 
-      jerry_debugger_sleep ();
+      jerry_debugger_transport_sleep ();
     }
   }
 #endif /* JERRY_DEBUGGER */
@@ -2913,7 +2921,7 @@ parser_parse_script (const uint8_t *arg_list_p, /**< function argument list */
   JERRY_UNUSED (arg_list_size);
   JERRY_UNUSED (source_p);
   JERRY_UNUSED (source_size);
-  JERRY_UNUSED (is_strict);
+  JERRY_UNUSED (parse_opts);
   JERRY_UNUSED (bytecode_data_p);
 
   return ecma_raise_syntax_error (ECMA_ERR_MSG ("The parser has been disabled."));
index e5b90c331701e0a57f1727222d1f766e1d0215ec..7aa6a2a7e7fac392835df2847383a18c988d97cc 100644 (file)
@@ -79,6 +79,12 @@ typedef enum
   PARSER_ERR_MULTIPLE_DEFAULTS_NOT_ALLOWED,           /**< multiple default cases are not allowed */
   PARSER_ERR_DEFAULT_NOT_IN_SWITCH,                   /**< default statement is not in switch block */
   PARSER_ERR_CASE_NOT_IN_SWITCH,                      /**< case statement is not in switch block */
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  PARSER_ERR_MULTIPLE_CLASS_CONSTRUCTORS,             /**< multiple class constructor */
+  PARSER_ERR_CLASS_CONSTRUCTOR_AS_ACCESSOR,           /**< class constructor cannot be an accessor */
+  PARSER_ERR_CLASS_STATIC_PROTOTYPE,                  /**< static method name 'prototype' is not allowed */
+  PARSER_ERR_UNEXPECTED_SUPER_REFERENCE,              /**< unexpected super keyword */
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
 
   PARSER_ERR_LEFT_PAREN_EXPECTED,                     /**< left paren expected */
   PARSER_ERR_LEFT_BRACE_EXPECTED,                     /**< left brace expected */
@@ -113,11 +119,16 @@ typedef enum
   PARSER_ERR_INVALID_RETURN,                          /**< return must be inside a function */
   PARSER_ERR_INVALID_RIGHT_SQUARE,                    /**< right square must terminate a block */
   PARSER_ERR_DUPLICATED_LABEL,                        /**< duplicated label */
+#ifndef CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER
+  PARSER_ERR_DUPLICATED_ARGUMENT_NAMES,               /**< duplicated argument names */
+#endif /* !CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER */
   PARSER_ERR_OBJECT_PROPERTY_REDEFINED,               /**< property of object literal redefined */
   PARSER_ERR_NON_STRICT_ARG_DEFINITION                /**< non-strict argument definition */
 } parser_error_t;
 
-/* Source code line counter type. */
+/**
+ * Source code line counter type.
+ */
 typedef uint32_t parser_line_counter_t;
 
 /**
@@ -133,9 +144,11 @@ typedef struct
 /* Note: source must be a valid UTF-8 string */
 ecma_value_t parser_parse_script (const uint8_t *arg_list_p, size_t arg_list_size,
                                   const uint8_t *source_p, size_t source_size,
-                                  bool is_strict, ecma_compiled_code_t **bytecode_data_p);
+                                  uint32_t parse_opts, ecma_compiled_code_t **bytecode_data_p);
 
+#ifdef JERRY_ENABLE_ERROR_MESSAGES
 const char *parser_error_to_string (parser_error_t);
+#endif /* JERRY_ENABLE_ERROR_MESSAGES */
 
 /**
  * @}
index 71a72af12927038ea68f8cc7a3abd9689a4af004..a193bef6809764457e8a138edf472a347c677c36 100644 (file)
@@ -123,7 +123,7 @@ re_bytecode_list_insert (re_bytecode_ctx_t *bc_ctx_p, /**< RegExp bytecode conte
  *
  * @return ecma character
  */
-inline ecma_char_t __attr_always_inline___
+inline ecma_char_t JERRY_ATTR_ALWAYS_INLINE
 re_get_char (uint8_t **bc_p) /**< pointer to bytecode start */
 {
   ecma_char_t chr;
@@ -137,7 +137,7 @@ re_get_char (uint8_t **bc_p) /**< pointer to bytecode start */
  *
  * @return current RegExp opcode
  */
-inline re_opcode_t __attr_always_inline___
+inline re_opcode_t JERRY_ATTR_ALWAYS_INLINE
 re_get_opcode (uint8_t **bc_p) /**< pointer to bytecode start */
 {
   uint8_t bytecode = **bc_p;
@@ -150,7 +150,7 @@ re_get_opcode (uint8_t **bc_p) /**< pointer to bytecode start */
  *
  * @return opcode parameter
  */
-inline uint32_t __attr_always_inline___
+inline uint32_t JERRY_ATTR_ALWAYS_INLINE
 re_get_value (uint8_t **bc_p) /**< pointer to bytecode start */
 {
   uint32_t value;
@@ -164,7 +164,7 @@ re_get_value (uint8_t **bc_p) /**< pointer to bytecode start */
  *
  * @return bytecode length (unsigned integer)
  */
-inline uint32_t __attr_pure___ __attr_always_inline___
+inline uint32_t JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
 re_get_bytecode_length (re_bytecode_ctx_t *bc_ctx_p) /**< RegExp bytecode context */
 {
   return ((uint32_t) (bc_ctx_p->current_p - bc_ctx_p->block_start_p));
index 45846e01c0556162c0f9e376d327a2e86d7f6c4a..d4f1765b801b36fe04b858ba8026b383478a72ca 100644 (file)
@@ -103,7 +103,7 @@ typedef struct
 re_opcode_t re_get_opcode (uint8_t **bc_p);
 ecma_char_t re_get_char (uint8_t **bc_p);
 uint32_t re_get_value (uint8_t **bc_p);
-uint32_t re_get_bytecode_length (re_bytecode_ctx_t *bc_ctx_p) __attr_pure___;
+uint32_t JERRY_ATTR_PURE re_get_bytecode_length (re_bytecode_ctx_t *bc_ctx_p);
 
 void re_append_opcode (re_bytecode_ctx_t *bc_ctx_p, re_opcode_t opcode);
 void re_append_u32 (re_bytecode_ctx_t *bc_ctx_p, uint32_t value);
index 9046fa46efe7a288a39cb35495d29abd341cf6a5..89df5829af631c184b48652c741c4e2f2ea134a4 100644 (file)
@@ -75,7 +75,8 @@ re_insert_simple_iterator (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler con
   }
   else if (qmin > qmax)
   {
-    return ecma_raise_syntax_error (ECMA_ERR_MSG ("RegExp quantifier error: qmin > qmax."));
+    /* ECMA-262 v5.1 15.10.2.5 */
+    return ecma_raise_syntax_error (ECMA_ERR_MSG ("RegExp quantifier error: min > max."));
   }
 
   /* TODO: optimize bytecode length. Store 0 rather than INF */
@@ -166,23 +167,31 @@ re_get_end_opcode_type (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler contex
 
 /**
  * Enclose the given bytecode to a group
+ *
+ * @return empty ecma value - if inserted successfully
+ *         error ecma value - otherwise
+ *
+ *         Returned value must be freed with ecma_free_value
  */
-static void
+static ecma_value_t
 re_insert_into_group (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context */
                       uint32_t group_start_offset, /**< offset of group start */
                       uint32_t idx, /**< index of group */
                       bool is_capturable) /**< is capturable group */
 {
-  uint32_t qmin, qmax;
+  uint32_t qmin = re_ctx_p->current_token.qmin;
+  uint32_t qmax = re_ctx_p->current_token.qmax;
+
+  if (qmin > qmax)
+  {
+    /* ECMA-262 v5.1 15.10.2.5 */
+    return ecma_raise_syntax_error (ECMA_ERR_MSG ("RegExp quantifier error: min > max."));
+  }
+
   re_opcode_t start_opcode = re_get_start_opcode_type (re_ctx_p, is_capturable);
   re_opcode_t end_opcode = re_get_end_opcode_type (re_ctx_p, is_capturable);
-  uint32_t start_head_offset_len;
 
-  qmin = re_ctx_p->current_token.qmin;
-  qmax = re_ctx_p->current_token.qmax;
-  JERRY_ASSERT (qmin <= qmax);
-
-  start_head_offset_len = re_get_bytecode_length (re_ctx_p->bytecode_ctx_p);
+  uint32_t start_head_offset_len = re_get_bytecode_length (re_ctx_p->bytecode_ctx_p);
   re_insert_u32 (re_ctx_p->bytecode_ctx_p, group_start_offset, idx);
   re_insert_opcode (re_ctx_p->bytecode_ctx_p, group_start_offset, start_opcode);
   start_head_offset_len = re_get_bytecode_length (re_ctx_p->bytecode_ctx_p) - start_head_offset_len;
@@ -201,12 +210,19 @@ re_insert_into_group (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context
                    group_start_offset,
                    re_get_bytecode_length (re_ctx_p->bytecode_ctx_p) - group_start_offset);
   }
+
+  return ECMA_VALUE_EMPTY;
 } /* re_insert_into_group */
 
 /**
  * Enclose the given bytecode to a group and inster jump value
+ *
+ * @return empty ecma value - if inserted successfully
+ *         error ecma value - otherwise
+ *
+ *         Returned value must be freed with ecma_free_value
  */
-static void
+static ecma_value_t
 re_insert_into_group_with_jump (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context */
                                 uint32_t group_start_offset, /**< offset of group start */
                                 uint32_t idx, /**< index of group */
@@ -215,7 +231,7 @@ re_insert_into_group_with_jump (re_compiler_ctx_t *re_ctx_p, /**< RegExp compile
   re_insert_u32 (re_ctx_p->bytecode_ctx_p,
                  group_start_offset,
                  re_get_bytecode_length (re_ctx_p->bytecode_ctx_p) - group_start_offset);
-  re_insert_into_group (re_ctx_p, group_start_offset, idx, is_capturable);
+  return re_insert_into_group (re_ctx_p, group_start_offset, idx, is_capturable);
 } /* re_insert_into_group_with_jump */
 
 /**
@@ -261,7 +277,7 @@ re_parse_alternative (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context
 
         if (ecma_is_value_empty (ret_value))
         {
-          re_insert_into_group (re_ctx_p, new_atom_start_offset, idx, true);
+          ret_value = re_insert_into_group (re_ctx_p, new_atom_start_offset, idx, true);
         }
 
         break;
@@ -275,7 +291,7 @@ re_parse_alternative (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context
 
         if (ecma_is_value_empty (ret_value))
         {
-          re_insert_into_group (re_ctx_p, new_atom_start_offset, idx, false);
+          ret_value = re_insert_into_group (re_ctx_p, new_atom_start_offset, idx, false);
         }
 
         break;
@@ -345,7 +361,7 @@ re_parse_alternative (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context
         {
           re_append_opcode (bc_ctx_p, RE_OP_MATCH);
 
-          re_insert_into_group_with_jump (re_ctx_p, new_atom_start_offset, idx, false);
+          ret_value = re_insert_into_group_with_jump (re_ctx_p, new_atom_start_offset, idx, false);
         }
 
         break;
@@ -362,7 +378,7 @@ re_parse_alternative (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context
         {
           re_append_opcode (bc_ctx_p, RE_OP_MATCH);
 
-          re_insert_into_group_with_jump (re_ctx_p, new_atom_start_offset, idx, false);
+          ret_value = re_insert_into_group_with_jump (re_ctx_p, new_atom_start_offset, idx, false);
         }
 
         break;
@@ -381,7 +397,7 @@ re_parse_alternative (re_compiler_ctx_t *re_ctx_p, /**< RegExp compiler context
         re_append_opcode (bc_ctx_p, RE_OP_BACKREFERENCE);
         re_append_u32 (bc_ctx_p, backref);
 
-        re_insert_into_group_with_jump (re_ctx_p, new_atom_start_offset, idx, false);
+        ret_value = re_insert_into_group_with_jump (re_ctx_p, new_atom_start_offset, idx, false);
         break;
       }
       case RE_TOK_DIGIT:
index b26eba9a22f0198647ca6fb1cb2211ec2fc86de9..cf215b6ebb77717bca1b9b8aaa3d78247104201b 100644 (file)
@@ -68,7 +68,7 @@ re_hex_lookup (re_parser_ctx_t *parser_ctx_p, /**< RegExp parser context */
  * @return true - if non-greedy character found
  *         false - otherwise
  */
-static inline bool __attr_always_inline___
+static inline bool JERRY_ATTR_ALWAYS_INLINE
 re_parse_non_greedy_char (re_parser_ctx_t *parser_ctx_p) /**< RegExp parser context */
 {
   if (parser_ctx_p->input_curr_p < parser_ctx_p->input_end_p
@@ -262,7 +262,10 @@ re_count_num_of_groups (re_parser_ctx_t *parser_ctx_p) /**< RegExp parser contex
     {
       case LIT_CHAR_BACKSLASH:
       {
-        lit_utf8_incr (&curr_p);
+        if (curr_p < parser_ctx_p->input_end_p)
+        {
+          lit_utf8_incr (&curr_p);
+        }
         break;
       }
       case LIT_CHAR_LEFT_SQUARE:
@@ -406,7 +409,7 @@ re_parse_char_class (re_parser_ctx_t *parser_ctx_p, /**< number of classes */
           }
         }
       }
-      else if (ch == LIT_CHAR_LOWERCASE_X)
+      else if (ch == LIT_CHAR_LOWERCASE_X && re_hex_lookup (parser_ctx_p, 2))
       {
         ecma_char_t code_unit;
 
@@ -416,7 +419,9 @@ re_parse_char_class (re_parser_ctx_t *parser_ctx_p, /**< number of classes */
         }
 
         parser_ctx_p->input_curr_p += 2;
-        if (is_range == false && lit_utf8_peek_next (parser_ctx_p->input_curr_p) == LIT_CHAR_MINUS)
+        if (parser_ctx_p->input_curr_p < parser_ctx_p->input_end_p
+            && is_range == false
+            && lit_utf8_peek_next (parser_ctx_p->input_curr_p) == LIT_CHAR_MINUS)
         {
           start = code_unit;
           continue;
@@ -424,7 +429,7 @@ re_parse_char_class (re_parser_ctx_t *parser_ctx_p, /**< number of classes */
 
         ch = code_unit;
       }
-      else if (ch == LIT_CHAR_LOWERCASE_U)
+      else if (ch == LIT_CHAR_LOWERCASE_U && re_hex_lookup (parser_ctx_p, 4))
       {
         ecma_char_t code_unit;
 
@@ -434,7 +439,9 @@ re_parse_char_class (re_parser_ctx_t *parser_ctx_p, /**< number of classes */
         }
 
         parser_ctx_p->input_curr_p += 4;
-        if (is_range == false && lit_utf8_peek_next (parser_ctx_p->input_curr_p) == LIT_CHAR_MINUS)
+        if (parser_ctx_p->input_curr_p < parser_ctx_p->input_end_p
+            && is_range == false
+            && lit_utf8_peek_next (parser_ctx_p->input_curr_p) == LIT_CHAR_MINUS)
         {
           start = code_unit;
           continue;
index f5204600469b8da4277ea7196f6e3ff69ea3a115..2904206db46fde9c970a601095d7066c643bda8d 100644 (file)
@@ -1,4 +1,3 @@
-
 ### About profile files
 
 Specify compile definitions in profile files to use when compiling the `jerry-core` target.
@@ -14,26 +13,96 @@ You can specify the profile for the build system in the following ways:
 #### Restrictions
 Only single line options are allowed in the profile file. Any line starting with hash-mark is ignored. Semicolon character is not allowed.
 
-### Example usage:
+
+### Example usage
 
 #### 1. Using the build script
 
+If you want to use a predefined profile, run the build script as follows
+(assuming that you are in the project root folder):
+
 ```
-# assuming you are in jerryscript folder
-./tools/build.py --profile=/absolute/path/to/my_profile.any_extension
+./tools/build.py --profile=minimal
 ```
 
-or
+Alternatively, if you want to use a custom profile at
+`/absolute/path/to/my.profile`:
 
 ```
-# assuming you are in jerryscript folder
-./tools/build.py --profile=minimal
+# Turn off every ES2015 feature EXCEPT the arrow functions
+CONFIG_DISABLE_ES2015_BUILTIN
+CONFIG_DISABLE_ES2015_CLASS
+CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER
+CONFIG_DISABLE_ES2015_MAP_BUILTIN
+CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
+CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS
+CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
+```
+
+Run the build script as follows (assuming that you are in the project root
+folder):
+
+```
+./tools/build.py --profile=/absolute/path/to/my.profile
 ```
 
-This command selects the profiles/minimal.profile file.
 
 #### 2. Using only CMake build system
 
 Set FEATURE_PROFILE option to one of the following values:
 * the profile with absolute path
 * name of the profile (which needs to exist in the `profiles` folder)
+
+
+### Configurations
+
+In JerryScript all of the features are enabled by default, so an empty profile file turns on all of the available ECMA features.
+
+* `CONFIG_DISABLE_ANNEXB_BUILTIN`:
+  Disable the [Annex B](http://www.ecma-international.org/ecma-262/5.1/index.html#sec-B) of the ECMA5.1 standard.
+* `CONFIG_DISABLE_ARRAY_BUILTIN`:
+  Disable the [Array](http://www.ecma-international.org/ecma-262/5.1/index.html#sec-15.4) built-in.
+* `CONFIG_DISABLE_BOOLEAN_BUILTIN`:
+  Disable the [Boolean](http://www.ecma-international.org/ecma-262/5.1/index.html#sec-15.6) built-in.
+* `CONFIG_DISABLE_DATE_BUILTIN`:
+  Disable the [Date](http://www.ecma-international.org/ecma-262/5.1/index.html#sec-15.9) built-in.
+* `CONFIG_DISABLE_ERROR_BUILTINS`:
+  Disable the [Native Error Types](http://www.ecma-international.org/ecma-262/5.1/index.html#sec-15.11.6) (EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError).
+  **Note**: The [Error](http://www.ecma-international.org/ecma-262/5.1/index.html#sec-15.11.2) object remains available.
+* `CONFIG_DISABLE_JSON_BUILTIN`:
+  Disable the [JSON](http://www.ecma-international.org/ecma-262/5.1/index.html#sec-15.12) built-in.
+* `CONFIG_DISABLE_MATH_BUILTIN`:
+  Disable the [Math](http://www.ecma-international.org/ecma-262/5.1/index.html#sec-15.8) built-in.
+* `CONFIG_DISABLE_NUMBER_BUILTIN`:
+  Disable the [Number](http://www.ecma-international.org/ecma-262/5.1/index.html#sec-15.7) built-in.
+* `CONFIG_DISABLE_REGEXP_BUILTIN`:
+  Disable the [RegExp](http://www.ecma-international.org/ecma-262/5.1/index.html#sec-15.10) built-in.
+* `CONFIG_DISABLE_STRING_BUILTIN`:
+  Disable the [String](http://www.ecma-international.org/ecma-262/5.1/index.html#sec-15.5) built-in.
+* `CONFIG_DISABLE_BUILTINS`:
+  Disable all of the [Standard Built-in ECMAScript 5.1 Objects](http://www.ecma-international.org/ecma-262/5.1/index.html#sec-15)
+  (equivalent to `CONFIG_DISABLE_ANNEXB_BUILTIN`, `CONFIG_DISABLE_ARRAY_BUILTIN`, `CONFIG_DISABLE_BOOLEAN_BUILTIN`, `CONFIG_DISABLE_DATE_BUILTIN`, `CONFIG_DISABLE_ERROR_BUILTINS`, `CONFIG_DISABLE_JSON_BUILTIN`, `CONFIG_DISABLE_MATH_BUILTIN`, `CONFIG_DISABLE_NUMBER_BUILTIN`, `CONFIG_DISABLE_REGEXP_BUILTIN`, and `CONFIG_DISABLE_STRING_BUILTIN`).
+
+* `CONFIG_DISABLE_ES2015_ARROW_FUNCTION`:
+  Disable the [arrow functions](http://www.ecma-international.org/ecma-262/6.0/#sec-arrow-function-definitions).
+* `CONFIG_DISABLE_ES2015_BUILTIN`:
+  Disable the built-in updates of the 5.1 standard. There are some differences in those built-ins which available in both [5.1](http://www.ecma-international.org/ecma-262/5.1/) and [2015](http://www.ecma-international.org/ecma-262/6.0/) versions of the standard. JerryScript uses the latest definition by default.
+* `CONFIG_DISABLE_ES2015_CLASS`:
+  Disable the [class](https://www.ecma-international.org/ecma-262/6.0/#sec-class-definitions) language element.
+* `CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER`:
+  Disable the [default value](http://www.ecma-international.org/ecma-262/6.0/#sec-function-definitions) for formal parameters.
+* `CONFIG_DISABLE_ES2015_MAP_BUILTIN`:
+  Disable the [Map](http://www.ecma-international.org/ecma-262/6.0/#sec-keyed-collection) built-ins.
+* `CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER`:
+  Disable the [enhanced object initializer](http://www.ecma-international.org/ecma-262/6.0/#sec-object-initializer) language element.
+* `CONFIG_DISABLE_ES2015_PROMISE_BUILTIN`:
+  Disable the [Promise](http://www.ecma-international.org/ecma-262/6.0/#sec-promise-objects) built-in.
+* `CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS`:
+  Disable the [template strings](http://www.ecma-international.org/ecma-262/6.0/#sec-static-semantics-templatestrings).
+* `CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN`:
+  Disable the [ArrayBuffer](http://www.ecma-international.org/ecma-262/6.0/#sec-arraybuffer-objects) and [TypedArray](http://www.ecma-international.org/ecma-262/6.0/#sec-typedarray-objects) built-ins.
+* `CONFIG_DISABLE_ES2015`: Disable all of the implemented [ECMAScript2015 features](http://www.ecma-international.org/ecma-262/6.0/).
+  (equivalent to `CONFIG_DISABLE_ES2015_ARROW_FUNCTION`, `CONFIG_DISABLE_ES2015_BUILTIN`, `CONFIG_DISABLE_ES2015_CLASS`,
+  `CONFIG_DISABLE_ES2015_FUNCTION_PARAMETER_INITIALIZER`, `CONFIG_DISABLE_ES2015_MAP_BUILTIN`, `CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER`,
+  `CONFIG_DISABLE_ES2015_PROMISE_BUILTIN`, `CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS`, and `CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN`).
index aa7e9093bb69d68bc55941e2680b2ff24e5833a5..89b439e8172ed528b939845bbebdde35764c1634 100644 (file)
@@ -130,18 +130,29 @@ opfunc_in (ecma_value_t left_value, /**< left value */
     return ecma_raise_type_error (ECMA_ERR_MSG ("Expected an object in 'in' check."));
   }
 
-  ecma_value_t left_string_value = ecma_op_to_string (left_value);
-  if (ECMA_IS_VALUE_ERROR (left_string_value))
+  bool to_string = !ecma_is_value_string (left_value);
+
+  if (to_string)
   {
-    return left_string_value;
+    left_value = ecma_op_to_string (left_value);
+
+    if (ECMA_IS_VALUE_ERROR (left_value))
+    {
+      return left_value;
+    }
   }
 
-  ecma_string_t *left_value_prop_name_p = ecma_get_string_from_value (left_string_value);
+  ecma_string_t *left_value_prop_name_p = ecma_get_string_from_value (left_value);
   ecma_object_t *right_value_obj_p = ecma_get_object_from_value (right_value);
 
-  ecma_free_value (left_string_value);
+  ecma_value_t result = ecma_make_boolean_value (ecma_op_object_has_property (right_value_obj_p,
+                                                                              left_value_prop_name_p));
 
-  return ecma_make_boolean_value (ecma_op_object_has_property (right_value_obj_p, left_value_prop_name_p));
+  if (to_string)
+  {
+    ecma_free_value (left_value);
+  }
+  return result;
 } /* opfunc_in */
 
 /**
index b887d99273c37e9f4e5d4a6555264e60a161fbfa..eb295ed8ef2617f2320c2a4d422df5bc3750a016 100644 (file)
@@ -67,20 +67,6 @@ vm_var_decl (vm_frame_ctx_t *frame_ctx_p, /**< interpreter context */
   return ECMA_VALUE_EMPTY;
 } /* vm_var_decl */
 
-/**
- * 'Logical NOT Operator' opcode handler.
- *
- * See also: ECMA-262 v5, 11.4.9
- *
- * @return ecma value
- *         Returned value must be freed with ecma_free_value
- */
-ecma_value_t
-opfunc_logical_not (ecma_value_t left_value) /**< left value */
-{
-  return ecma_make_boolean_value (!ecma_op_to_boolean (left_value));
-} /* opfunc_logical_not */
-
 /**
  * 'typeof' opcode handler.
  *
@@ -101,12 +87,10 @@ opfunc_typeof (ecma_value_t left_value) /**< left value */
 void
 opfunc_set_accessor (bool is_getter, /**< is getter accessor */
                      ecma_value_t object, /**< object value */
-                     ecma_value_t accessor_name, /**< accessor name value */
+                     ecma_string_t *accessor_name_p, /**< accessor name */
                      ecma_value_t accessor) /**< accessor value */
 {
   ecma_object_t *object_p = ecma_get_object_from_value (object);
-  JERRY_ASSERT (ecma_is_value_string (accessor_name) || ecma_is_value_number (accessor_name));
-  ecma_string_t *accessor_name_p = ecma_get_string_from_value (ecma_op_to_string (accessor_name));
   ecma_property_t *property_p = ecma_find_named_property (object_p, accessor_name_p);
 
   if (property_p != NULL
@@ -153,8 +137,6 @@ opfunc_set_accessor (bool is_getter, /**< is getter accessor */
                                              ECMA_PROPERTY_VALUE_PTR (property_p),
                                              setter_func_p);
   }
-
-  ecma_deref_ecma_string (accessor_name_p);
 } /* opfunc_set_accessor */
 
 /**
@@ -260,7 +242,8 @@ opfunc_for_in (ecma_value_t left_value, /**< left value */
   /* ecma_op_to_object will only raise error on null/undefined values but those are handled above. */
   JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (obj_expr_value));
   ecma_object_t *obj_p = ecma_get_object_from_value (obj_expr_value);
-  ecma_collection_header_t *prop_names_coll_p = ecma_op_object_get_property_names (obj_p, false, true, true);
+  ecma_collection_header_t *prop_names_coll_p;
+  prop_names_coll_p = ecma_op_object_get_property_names (obj_p, ECMA_LIST_ENUMERABLE_PROTOTYPE);
 
   if (prop_names_coll_p->item_count != 0)
   {
index 5114578fa297590b3f26c277037cbf6d27953328..0df56ae5941f649f643cd8bb3f87bd3cf87b1e2c 100644 (file)
@@ -78,14 +78,11 @@ opfunc_in (ecma_value_t left_value, ecma_value_t right_value);
 ecma_value_t
 opfunc_instanceof (ecma_value_t left_value, ecma_value_t right_value);
 
-ecma_value_t
-opfunc_logical_not (ecma_value_t left_value);
-
 ecma_value_t
 opfunc_typeof (ecma_value_t left_value);
 
 void
-opfunc_set_accessor (bool is_getter, ecma_value_t object, ecma_value_t accessor_name, ecma_value_t accessor);
+opfunc_set_accessor (bool is_getter, ecma_value_t object, ecma_string_t *accessor_name_p, ecma_value_t accessor);
 
 ecma_value_t
 vm_op_delete_prop (ecma_value_t object, ecma_value_t property, bool is_strict);
index 9ad4c3a5eb6335820ec25a6852d647b9ca37863e..610316b57dd26e6b174e250d586f4c422232143a 100644 (file)
  */
 
 /**
- * Helpers for updating uint16_t values.
+ * Helper for += on uint16_t values.
  */
 #define VM_PLUS_EQUAL_U16(base, value) (base) = (uint16_t) ((base) + (value))
+
+/**
+ * Helper for -= on uint16_t values.
+ */
 #define VM_MINUS_EQUAL_U16(base, value) (base) = (uint16_t) ((base) - (value))
 
 /**
@@ -50,7 +54,7 @@ typedef struct vm_frame_ctx_t
   ecma_object_t *lex_env_p;                           /**< current lexical environment */
   struct vm_frame_ctx_t *prev_context_p;              /**< previous context */
   ecma_value_t this_binding;                          /**< this binding */
-  ecma_value_t call_block_result;                     /**< preserve block result during a call */
+  ecma_value_t block_result;                          /**< block result */
 #ifdef JERRY_ENABLE_LINE_INFO
   ecma_value_t resource_name;                         /**< current resource name (usually a file name) */
   uint32_t current_line;                              /**< currently executed line */
index d0278b7980a86ed46cd7b472e4631815aac81ede..893e91b92cb2ea66e988b7ec2ca4ad4f5d4c00a1 100644 (file)
@@ -26,6 +26,9 @@
  * @{
  */
 
+JERRY_STATIC_ASSERT (PARSER_WITH_CONTEXT_STACK_ALLOCATION == PARSER_SUPER_CLASS_CONTEXT_STACK_ALLOCATION,
+                     parser_with_context_stack_allocation_must_be_equal_to_parser_super_class_context_stack_allocation);
+
 /**
  * Abort (finalize) the current stack context, and remove it.
  *
@@ -54,19 +57,32 @@ vm_stack_context_abort (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
       break;
     }
     case VM_CONTEXT_CATCH:
-    case VM_CONTEXT_WITH:
     {
-      ecma_deref_object (frame_ctx_p->lex_env_p);
-      frame_ctx_p->lex_env_p = ecma_get_object_from_value (vm_stack_top_p[-2]);
+      JERRY_ASSERT (PARSER_TRY_CONTEXT_STACK_ALLOCATION > PARSER_WITH_CONTEXT_STACK_ALLOCATION);
 
-      JERRY_ASSERT (PARSER_TRY_CONTEXT_STACK_ALLOCATION == PARSER_WITH_CONTEXT_STACK_ALLOCATION);
+      const uint16_t size_diff = PARSER_TRY_CONTEXT_STACK_ALLOCATION - PARSER_WITH_CONTEXT_STACK_ALLOCATION;
 
-      VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_TRY_CONTEXT_STACK_ALLOCATION);
-      vm_stack_top_p -= PARSER_TRY_CONTEXT_STACK_ALLOCATION;
+      VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, size_diff);
+      vm_stack_top_p -= size_diff;
+      /* FALLTHRU */
+    }
+    case VM_CONTEXT_WITH:
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+    case VM_CONTEXT_SUPER_CLASS:
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+    {
+      ecma_object_t *lex_env_p = frame_ctx_p->lex_env_p;
+      frame_ctx_p->lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
+      ecma_deref_object (lex_env_p);
+
+      VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_WITH_CONTEXT_STACK_ALLOCATION);
+      vm_stack_top_p -= PARSER_WITH_CONTEXT_STACK_ALLOCATION;
       break;
     }
-    case VM_CONTEXT_FOR_IN:
+    default:
     {
+      JERRY_ASSERT (VM_GET_CONTEXT_TYPE (vm_stack_top_p[-1]) == VM_CONTEXT_FOR_IN);
+
       ecma_collection_chunk_t *chunk_p;
       chunk_p = ECMA_GET_INTERNAL_VALUE_ANY_POINTER (ecma_collection_chunk_t, vm_stack_top_p[-2]);
       uint32_t index = vm_stack_top_p[-3];
@@ -75,9 +91,10 @@ vm_stack_context_abort (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
       {
         ecma_value_t value = chunk_p->items[index];
 
-        if (unlikely (ecma_is_value_collection_chunk (value)))
+        if (JERRY_UNLIKELY (ecma_is_value_pointer (value)))
         {
-          ecma_collection_chunk_t *next_chunk_p = ecma_get_collection_chunk_from_value (value);
+          ecma_collection_chunk_t *next_chunk_p;
+          next_chunk_p = (ecma_collection_chunk_t *) ecma_get_pointer_from_value (value);
           jmem_heap_free_block (chunk_p, sizeof (ecma_collection_chunk_t));
 
           chunk_p = next_chunk_p;
@@ -96,11 +113,6 @@ vm_stack_context_abort (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
       vm_stack_top_p -= PARSER_FOR_IN_CONTEXT_STACK_ALLOCATION;
       break;
     }
-    default:
-    {
-      JERRY_UNREACHABLE ();
-      break;
-    }
   }
 
   return vm_stack_top_p;
@@ -221,8 +233,9 @@ vm_stack_find_finally (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
       }
       else
       {
-        ecma_deref_object (frame_ctx_p->lex_env_p);
-        frame_ctx_p->lex_env_p = ecma_get_object_from_value (vm_stack_top_p[-2]);
+        ecma_object_t *lex_env_p = frame_ctx_p->lex_env_p;
+        frame_ctx_p->lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
+        ecma_deref_object (lex_env_p);
 
         if (byte_code_p[0] == CBC_CONTEXT_END)
         {
index 0f921162e2243ad04189c2a051f115c133a9c21d..323cddaab43ed56d8095dcc4c4e0751b7e315090 100644 (file)
  * @{
  */
 
-/**
- * Number of ecma values inlined into stack frame
- */
-#define VM_STACK_FRAME_INLINED_VALUES_NUMBER CONFIG_VM_STACK_FRAME_INLINED_VALUES_NUMBER
-
 /**
  * Header of a ECMA stack frame's chunk
  */
@@ -62,6 +57,9 @@ typedef enum
   VM_CONTEXT_TRY,                             /**< try context */
   VM_CONTEXT_CATCH,                           /**< catch context */
   VM_CONTEXT_WITH,                            /**< with context */
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  VM_CONTEXT_SUPER_CLASS,                     /**< super class context */
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
   VM_CONTEXT_FOR_IN,                          /**< for-in context */
 } vm_stack_context_type_t;
 
index a79a4b95a639d8de37dec5375182351517ebbd66..081634086466d20c43078b4975ae73a49b9318df 100644 (file)
@@ -44,7 +44,7 @@ vm_is_strict_mode (void)
  *                without 'this' argument,
  *         false - otherwise
  */
-inline bool __attr_always_inline___
+inline bool JERRY_ATTR_ALWAYS_INLINE
 vm_is_direct_eval_form_call (void)
 {
   return (JERRY_CONTEXT (status_flags) & ECMA_STATUS_DIRECT_EVAL) != 0;
@@ -84,9 +84,8 @@ vm_get_backtrace (uint32_t max_depth) /**< maximum backtrace depth, 0 = unlimite
 
     if (ecma_string_is_empty (str_p))
     {
-      const char *unknown_str_p = "<unknown>:";
-      str_p = ecma_new_ecma_string_from_utf8 ((const lit_utf8_byte_t *) unknown_str_p,
-                                              (lit_utf8_size_t) strlen (unknown_str_p));
+      const lit_utf8_byte_t unknown_str[] = "<unknown>:";
+      str_p = ecma_new_ecma_string_from_utf8 (unknown_str, sizeof (unknown_str) - 1);
     }
     else
     {
index 8b094df52fa521c0119d6e7e29e0a92f958666fe..f6c06b762458422c8b4cf48d40af51da779baca4 100644 (file)
@@ -53,7 +53,6 @@ vm_op_get_value (ecma_value_t object, /**< base object */
 {
   if (ecma_is_value_object (object))
   {
-    ecma_object_t *object_p = ecma_get_object_from_value (object);
     ecma_string_t *property_name_p = NULL;
 
     if (ecma_is_value_integer_number (property))
@@ -73,6 +72,8 @@ vm_op_get_value (ecma_value_t object, /**< base object */
 
     if (property_name_p != NULL)
     {
+#ifndef CONFIG_ECMA_LCACHE_DISABLE
+      ecma_object_t *object_p = ecma_get_object_from_value (object);
       ecma_property_t *property_p = ecma_lcache_lookup (object_p, property_name_p);
 
       if (property_p != NULL &&
@@ -80,13 +81,14 @@ vm_op_get_value (ecma_value_t object, /**< base object */
       {
         return ecma_fast_copy_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
       }
+#endif /* !CONFIG_ECMA_LCACHE_DISABLE */
 
       /* There is no need to free the name. */
       return ecma_op_object_get (ecma_get_object_from_value (object), property_name_p);
     }
   }
 
-  if (unlikely (ecma_is_value_undefined (object) || ecma_is_value_null (object)))
+  if (JERRY_UNLIKELY (ecma_is_value_undefined (object) || ecma_is_value_null (object)))
   {
 #ifdef JERRY_ENABLE_ERROR_MESSAGES
     ecma_value_t error_value = ecma_raise_standard_error_with_format (ECMA_ERROR_TYPE,
@@ -129,7 +131,7 @@ vm_op_set_value (ecma_value_t object, /**< base object */
                  ecma_value_t value, /**< ecma value */
                  bool is_strict) /**< strict mode */
 {
-  if (unlikely (!ecma_is_value_object (object)))
+  if (JERRY_UNLIKELY (!ecma_is_value_object (object)))
   {
     ecma_value_t to_object = ecma_op_to_object (object);
     ecma_free_value (object);
@@ -195,6 +197,7 @@ vm_op_set_value (ecma_value_t object, /**< base object */
   return completion_value;
 } /* vm_op_set_value */
 
+/** Compact bytecode define */
 #define CBC_OPCODE(arg1, arg2, arg3, arg4) arg4,
 
 /**
@@ -219,17 +222,14 @@ static const uint16_t vm_decode_table[] JERRY_CONST_DATA =
 ecma_value_t
 vm_run_global (const ecma_compiled_code_t *bytecode_p) /**< pointer to bytecode to run */
 {
-  ecma_object_t *glob_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL);
-
-  ecma_value_t ret_value = vm_run (bytecode_p,
-                                   ecma_make_object_value (glob_obj_p),
-                                   ecma_get_global_environment (),
-                                   false,
-                                   NULL,
-                                   0);
-
-  ecma_deref_object (glob_obj_p);
-  return ret_value;
+  ecma_object_t *glob_obj_p = ecma_builtin_get_global ();
+
+  return vm_run (bytecode_p,
+                 ecma_make_object_value (glob_obj_p),
+                 ecma_get_global_environment (),
+                 false,
+                 NULL,
+                 0);
 } /* vm_run_global */
 
 /**
@@ -239,20 +239,42 @@ vm_run_global (const ecma_compiled_code_t *bytecode_p) /**< pointer to bytecode
  */
 ecma_value_t
 vm_run_eval (ecma_compiled_code_t *bytecode_data_p, /**< byte-code data */
-             bool is_direct) /**< is eval called in direct mode? */
+             uint32_t parse_opts) /**< ecma_parse_opts_t option bits */
 {
   ecma_value_t this_binding;
   ecma_object_t *lex_env_p;
 
   /* ECMA-262 v5, 10.4.2 */
-  if (is_direct)
+  if (parse_opts & ECMA_PARSE_DIRECT_EVAL)
   {
     this_binding = ecma_copy_value (JERRY_CONTEXT (vm_top_context_p)->this_binding);
     lex_env_p = JERRY_CONTEXT (vm_top_context_p)->lex_env_p;
+
+#ifdef JERRY_DEBUGGER
+    uint32_t chain_index = parse_opts >> ECMA_PARSE_CHAIN_INDEX_SHIFT;
+
+    while (chain_index != 0)
+    {
+      lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
+
+      if (JERRY_UNLIKELY (lex_env_p == NULL))
+      {
+        return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid scope chain index for eval"));
+      }
+
+      if ((ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND)
+          || (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE))
+      {
+        chain_index--;
+      }
+    }
+#endif
   }
   else
   {
-    this_binding = ecma_make_object_value (ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL));
+    ecma_object_t *global_obj_p = ecma_builtin_get_global ();
+    ecma_ref_object (global_obj_p);
+    this_binding = ecma_make_object_value (global_obj_p);
     lex_env_p = ecma_get_global_environment ();
   }
 
@@ -269,7 +291,7 @@ vm_run_eval (ecma_compiled_code_t *bytecode_data_p, /**< byte-code data */
   ecma_value_t completion_value = vm_run (bytecode_data_p,
                                           this_binding,
                                           lex_env_p,
-                                          true,
+                                          parse_opts,
                                           NULL,
                                           0);
 
@@ -297,52 +319,26 @@ static ecma_value_t
 vm_construct_literal_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
                              ecma_value_t lit_value) /**< literal */
 {
-#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
   ecma_compiled_code_t *bytecode_p;
 
-  if (likely (!(frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)))
+#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
+  if (JERRY_LIKELY (!(frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)))
   {
+#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
     bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
                                                   lit_value);
+#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
   }
   else
   {
     uint8_t *byte_p = ((uint8_t *) frame_ctx_p->bytecode_header_p) + lit_value;
     bytecode_p = (ecma_compiled_code_t *) byte_p;
   }
-#else /* !JERRY_ENABLE_SNAPSHOT_EXEC */
-  ecma_compiled_code_t *bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
-                                                                      lit_value);
 #endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
 
-  bool is_function = ((bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION) != 0);
-
-  if (is_function)
-  {
-    ecma_object_t *func_obj_p;
-
-#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
-    if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION))
-    {
-      func_obj_p = ecma_op_create_function_object (frame_ctx_p->lex_env_p,
-                                                   bytecode_p);
-    }
-    else
-    {
-      func_obj_p = ecma_op_create_arrow_function_object (frame_ctx_p->lex_env_p,
-                                                         bytecode_p,
-                                                         frame_ctx_p->this_binding);
-    }
-#else /* CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
-    func_obj_p = ecma_op_create_function_object (frame_ctx_p->lex_env_p,
-                                                 bytecode_p);
-#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
-
-    return ecma_make_object_value (func_obj_p);
-  }
-  else
-  {
 #ifndef CONFIG_DISABLE_REGEXP_BUILTIN
+  if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION))
+  {
     ecma_value_t ret_value;
     ret_value = ecma_op_create_regexp_object_from_bytecode ((re_compiled_code_t *) bytecode_p);
 
@@ -353,10 +349,30 @@ vm_construct_literal_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
     }
 
     return ret_value;
-#else /* CONFIG_DISABLE_REGEXP_BUILTIN */
-    JERRY_UNREACHABLE (); /* Regular Expressions are not supported in the selected profile! */
+  }
 #endif /* !CONFIG_DISABLE_REGEXP_BUILTIN */
+
+  JERRY_ASSERT (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION);
+
+  ecma_object_t *func_obj_p;
+
+#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
+  if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION))
+  {
+#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
+    func_obj_p = ecma_op_create_function_object (frame_ctx_p->lex_env_p,
+                                                 bytecode_p);
+#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
   }
+  else
+  {
+    func_obj_p = ecma_op_create_arrow_function_object (frame_ctx_p->lex_env_p,
+                                                       bytecode_p,
+                                                       frame_ctx_p->this_binding);
+  }
+#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
+
+  return ecma_make_object_value (func_obj_p);
 } /* vm_construct_literal_object */
 
 /**
@@ -365,7 +381,7 @@ vm_construct_literal_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
  * @return true - if the implicit 'this' value is updated,
  *         false - otherwise
  */
-static inline bool __attr_always_inline___
+static inline bool JERRY_ATTR_ALWAYS_INLINE
 vm_get_implicit_this_value (ecma_value_t *this_value_p) /**< [in,out] this value */
 {
   if (ecma_is_value_object (*this_value_p))
@@ -385,6 +401,92 @@ vm_get_implicit_this_value (ecma_value_t *this_value_p) /**< [in,out] this value
   return false;
 } /* vm_get_implicit_this_value */
 
+/**
+ * Special bytecode sequence for error handling while the vm_loop
+ * is preserved for an execute operation
+ */
+static const uint8_t vm_error_byte_code_p[] =
+{
+  CBC_EXT_OPCODE, CBC_EXT_ERROR
+};
+
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+/**
+ * 'super(...)' function call handler.
+ */
+static void
+vm_super_call (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
+{
+  JERRY_ASSERT (frame_ctx_p->call_operation == VM_EXEC_SUPER_CALL);
+  JERRY_ASSERT (frame_ctx_p->byte_code_p[0] == CBC_EXT_OPCODE);
+
+  uint8_t *byte_code_p = frame_ctx_p->byte_code_p + 3;
+  uint8_t opcode = byte_code_p[-2];
+  uint32_t arguments_list_len = byte_code_p[-1];
+
+  ecma_value_t *stack_top_p = frame_ctx_p->stack_top_p - arguments_list_len;
+
+  ecma_value_t func_value = stack_top_p[-1];
+  ecma_value_t completion_value;
+  ecma_op_set_super_called (frame_ctx_p->lex_env_p);
+  ecma_value_t this_value = ecma_op_get_class_this_binding (frame_ctx_p->lex_env_p);
+
+  if (!ecma_is_constructor (func_value))
+  {
+    completion_value = ecma_raise_type_error ("Class extends value is not a constructor.");
+  }
+  else
+  {
+    completion_value = ecma_op_function_construct (ecma_get_object_from_value (func_value),
+                                                   this_value,
+                                                   stack_top_p,
+                                                   arguments_list_len);
+
+    if (this_value != completion_value && ecma_is_value_object (completion_value))
+    {
+      ecma_op_set_class_prototype (completion_value, this_value);
+      ecma_op_set_class_this_binding (frame_ctx_p->lex_env_p, completion_value);
+    }
+  }
+
+  /* Free registers. */
+  for (uint32_t i = 0; i < arguments_list_len; i++)
+  {
+    ecma_fast_free_value (stack_top_p[i]);
+  }
+
+  if (JERRY_UNLIKELY (ECMA_IS_VALUE_ERROR (completion_value)))
+  {
+#ifdef JERRY_DEBUGGER
+    JERRY_CONTEXT (debugger_exception_byte_code_p) = frame_ctx_p->byte_code_p;
+#endif /* JERRY_DEBUGGER */
+    frame_ctx_p->byte_code_p = (uint8_t *) vm_error_byte_code_p;
+  }
+  else
+  {
+    frame_ctx_p->byte_code_p = byte_code_p;
+    ecma_free_value (*(--stack_top_p));
+    uint32_t opcode_data = vm_decode_table[(CBC_END + 1) + opcode];
+
+    if (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK)))
+    {
+      ecma_fast_free_value (completion_value);
+    }
+    else if (opcode_data & VM_OC_PUT_STACK)
+    {
+      *stack_top_p++ = completion_value;
+    }
+    else
+    {
+      ecma_fast_free_value (frame_ctx_p->block_result);
+      frame_ctx_p->block_result = completion_value;
+    }
+  }
+
+  frame_ctx_p->stack_top_p = stack_top_p;
+} /* vm_super_call */
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
 /**
  * 'Function call' opcode handler.
  *
@@ -393,7 +495,8 @@ vm_get_implicit_this_value (ecma_value_t *this_value_p) /**< [in,out] this value
 static void
 opfunc_call (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
 {
-  uint8_t opcode = frame_ctx_p->byte_code_p[0];
+  uint8_t *byte_code_p = frame_ctx_p->byte_code_p + 1;
+  uint8_t opcode = byte_code_p[-1];
   uint32_t arguments_list_len;
 
   if (opcode >= CBC_CALL0)
@@ -402,31 +505,13 @@ opfunc_call (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
   }
   else
   {
-    arguments_list_len = frame_ctx_p->byte_code_p[1];
+    arguments_list_len = *byte_code_p++;
   }
 
   bool is_call_prop = ((opcode - CBC_CALL) % 6) >= 3;
 
-  ecma_value_t this_value = ECMA_VALUE_UNDEFINED;
   ecma_value_t *stack_top_p = frame_ctx_p->stack_top_p - arguments_list_len;
-
-  if (is_call_prop)
-  {
-    this_value = stack_top_p[-3];
-
-    if (this_value == ECMA_VALUE_REGISTER_REF)
-    {
-      /* Lexical environment cannot be 'this' value. */
-      stack_top_p[-2] = ECMA_VALUE_UNDEFINED;
-      this_value = ECMA_VALUE_UNDEFINED;
-    }
-    else if (vm_get_implicit_this_value (&this_value))
-    {
-      ecma_free_value (stack_top_p[-3]);
-      stack_top_p[-3] = this_value;
-    }
-  }
-
+  ecma_value_t this_value = is_call_prop ? stack_top_p[-3] : ECMA_VALUE_UNDEFINED;
   ecma_value_t func_value = stack_top_p[-1];
   ecma_value_t completion_value;
 
@@ -458,8 +543,33 @@ opfunc_call (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
     ecma_free_value (*(--stack_top_p));
   }
 
-  ecma_free_value (stack_top_p[-1]);
-  stack_top_p[-1] = completion_value;
+  if (JERRY_UNLIKELY (ECMA_IS_VALUE_ERROR (completion_value)))
+  {
+#ifdef JERRY_DEBUGGER
+    JERRY_CONTEXT (debugger_exception_byte_code_p) = frame_ctx_p->byte_code_p;
+#endif /* JERRY_DEBUGGER */
+    frame_ctx_p->byte_code_p = (uint8_t *) vm_error_byte_code_p;
+  }
+  else
+  {
+    frame_ctx_p->byte_code_p = byte_code_p;
+    ecma_free_value (*(--stack_top_p));
+    uint32_t opcode_data = vm_decode_table[opcode];
+
+    if (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK)))
+    {
+      ecma_fast_free_value (completion_value);
+    }
+    else if (opcode_data & VM_OC_PUT_STACK)
+    {
+      *stack_top_p++ = completion_value;
+    }
+    else
+    {
+      ecma_fast_free_value (frame_ctx_p->block_result);
+      frame_ctx_p->block_result = completion_value;
+    }
+  }
 
   frame_ctx_p->stack_top_p = stack_top_p;
 } /* opfunc_call */
@@ -472,7 +582,8 @@ opfunc_call (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
 static void
 opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
 {
-  uint8_t opcode = frame_ctx_p->byte_code_p[0];
+  uint8_t *byte_code_p = frame_ctx_p->byte_code_p + 1;
+  uint8_t opcode = byte_code_p[-1];
   unsigned int arguments_list_len;
 
   if (opcode >= CBC_NEW0)
@@ -481,7 +592,7 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
   }
   else
   {
-    arguments_list_len = frame_ctx_p->byte_code_p[1];
+    arguments_list_len = *byte_code_p++;
   }
 
   ecma_value_t *stack_top_p = frame_ctx_p->stack_top_p - arguments_list_len;
@@ -497,6 +608,7 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
     ecma_object_t *constructor_obj_p = ecma_get_object_from_value (constructor_value);
 
     completion_value = ecma_op_function_construct (constructor_obj_p,
+                                                   ECMA_VALUE_UNDEFINED,
                                                    stack_top_p,
                                                    arguments_list_len);
   }
@@ -507,12 +619,28 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
     ecma_fast_free_value (stack_top_p[i]);
   }
 
-  ecma_free_value (stack_top_p[-1]);
-  stack_top_p[-1] = completion_value;
+  if (JERRY_UNLIKELY (ECMA_IS_VALUE_ERROR (completion_value)))
+  {
+#ifdef JERRY_DEBUGGER
+    JERRY_CONTEXT (debugger_exception_byte_code_p) = frame_ctx_p->byte_code_p;
+#endif /* JERRY_DEBUGGER */
+    frame_ctx_p->byte_code_p = (uint8_t *) vm_error_byte_code_p;
+  }
+  else
+  {
+    ecma_free_value (stack_top_p[-1]);
+    frame_ctx_p->byte_code_p = byte_code_p;
+    stack_top_p[-1] = completion_value;
+  }
 
   frame_ctx_p->stack_top_p = stack_top_p;
 } /* opfunc_construct */
 
+/**
+ * Read literal index from the byte code stream into destination.
+ *
+ * @param destination destination
+ */
 #define READ_LITERAL_INDEX(destination) \
   do \
   { \
@@ -524,9 +652,16 @@ opfunc_construct (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
   } \
   while (0)
 
-/* TODO: For performance reasons, we define this as a macro.
+/**
+ * Get literal value by literal index.
+ *
+ * @param literal_index literal index
+ * @param target_value target value
+ *
+ * TODO: For performance reasons, we define this as a macro.
  * When we are able to construct a function with similar speed,
- * we can remove this macro. */
+ * we can remove this macro.
+ */
 #define READ_LITERAL(literal_index, target_value) \
   do \
   { \
@@ -579,17 +714,6 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
   uint16_t register_end;
   ecma_value_t *literal_start_p = frame_ctx_p->literal_start_p;
   bool is_strict = ((frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0);
-  ecma_value_t self_reference;
-
-#ifdef JERRY_ENABLE_SNAPSHOT_EXEC
-  self_reference = 0;
-  if (!(bytecode_header_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION))
-  {
-    ECMA_SET_INTERNAL_VALUE_POINTER (self_reference, bytecode_header_p);
-  }
-#else /* !JERRY_ENABLE_SNAPSHOT_EXEC */
-  ECMA_SET_INTERNAL_VALUE_POINTER (self_reference, bytecode_header_p);
-#endif
 
   /* Prepare. */
   if (!(bytecode_header_p->status_flags & CBC_CODE_FLAGS_FULL_LITERAL_ENCODING))
@@ -658,7 +782,6 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
         {
           uint32_t value_index;
           ecma_value_t lit_value;
-          bool is_immutable_binding = false;
 
           READ_LITERAL_INDEX (value_index);
 
@@ -668,7 +791,6 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
           }
           else
           {
-            is_immutable_binding = (self_reference == literal_start_p[value_index]);
             lit_value = vm_construct_literal_object (frame_ctx_p,
                                                      literal_start_p[value_index]);
           }
@@ -681,29 +803,22 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
           {
             ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]);
 
-            if (likely (!is_immutable_binding))
-            {
-              vm_var_decl (frame_ctx_p, name_p);
+            vm_var_decl (frame_ctx_p, name_p);
 
-              ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (frame_ctx_p->lex_env_p, name_p);
+            ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (frame_ctx_p->lex_env_p, name_p);
 
-              ecma_value_t put_value_result = ecma_op_put_value_lex_env_base (ref_base_lex_env_p,
-                                                                              name_p,
-                                                                              is_strict,
-                                                                              lit_value);
+            ecma_value_t put_value_result = ecma_op_put_value_lex_env_base (ref_base_lex_env_p,
+                                                                            name_p,
+                                                                            is_strict,
+                                                                            lit_value);
 
-              JERRY_ASSERT (ecma_is_value_boolean (put_value_result)
-                            || ecma_is_value_empty (put_value_result)
-                            || ECMA_IS_VALUE_ERROR (put_value_result));
+            JERRY_ASSERT (ecma_is_value_boolean (put_value_result)
+                          || ecma_is_value_empty (put_value_result)
+                          || ECMA_IS_VALUE_ERROR (put_value_result));
 
-              if (ECMA_IS_VALUE_ERROR (put_value_result))
-              {
-                ecma_free_value (JERRY_CONTEXT (error_value));
-              }
-            }
-            else
+            if (ECMA_IS_VALUE_ERROR (put_value_result))
             {
-              ecma_op_create_immutable_binding (frame_ctx_p->lex_env_p, name_p, lit_value);
+              ecma_free_value (JERRY_CONTEXT (error_value));
             }
 
             if (value_index >= register_end)
@@ -740,7 +855,7 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
  *
  * @return ecma value
  */
-static ecma_value_t __attr_noinline___
+static ecma_value_t JERRY_ATTR_NOINLINE
 vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
 {
   const ecma_compiled_code_t *bytecode_header_p = frame_ctx_p->bytecode_header_p;
@@ -758,7 +873,6 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
   ecma_value_t left_value;
   ecma_value_t right_value;
   ecma_value_t result = ECMA_VALUE_EMPTY;
-  ecma_value_t block_result = ECMA_VALUE_UNDEFINED;
   bool is_strict = ((frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0);
 
   /* Prepare for byte code execution. */
@@ -840,6 +954,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
             default:
             {
               JERRY_ASSERT (operands == VM_OC_GET_THIS_LITERAL);
+
               right_value = left_value;
               left_value = ecma_copy_value (frame_ctx_p->this_binding);
               break;
@@ -869,12 +984,12 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
 
         branch_offset = *(byte_code_p++);
 
-        if (unlikely (branch_offset_length != 1))
+        if (JERRY_UNLIKELY (branch_offset_length != 1))
         {
           branch_offset <<= 8;
           branch_offset |= *(byte_code_p++);
 
-          if (unlikely (branch_offset_length == 3))
+          if (JERRY_UNLIKELY (branch_offset_length == 3))
           {
             branch_offset <<= 8;
             branch_offset |= *(byte_code_p++);
@@ -919,11 +1034,6 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
 
       switch (VM_OC_GROUP_GET_INDEX (opcode_data))
       {
-        case VM_OC_NONE:
-        {
-          JERRY_ASSERT (opcode == CBC_EXT_DEBUGGER);
-          continue;
-        }
         case VM_OC_POP:
         {
           JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end);
@@ -932,8 +1042,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
         }
         case VM_OC_POP_BLOCK:
         {
-          ecma_fast_free_value (block_result);
-          block_result = *(--stack_top_p);
+          ecma_fast_free_value (frame_ctx_p->block_result);
+          frame_ctx_p->block_result = *(--stack_top_p);
           continue;
         }
         case VM_OC_PUSH:
@@ -986,45 +1096,97 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
           *stack_top_p++ = ecma_copy_value (frame_ctx_p->this_binding);
           continue;
         }
-        case VM_OC_PUSH_NUMBER_0:
+        case VM_OC_PUSH_0:
         {
           *stack_top_p++ = ecma_make_integer_value (0);
           continue;
         }
-        case VM_OC_PUSH_NUMBER_POS_BYTE:
+        case VM_OC_PUSH_POS_BYTE:
         {
           ecma_integer_value_t number = *byte_code_p++;
           *stack_top_p++ = ecma_make_integer_value (number + 1);
           continue;
         }
-        case VM_OC_PUSH_NUMBER_NEG_BYTE:
+        case VM_OC_PUSH_NEG_BYTE:
         {
           ecma_integer_value_t number = *byte_code_p++;
           *stack_top_p++ = ecma_make_integer_value (-(number + 1));
           continue;
         }
+        case VM_OC_PUSH_LIT_0:
+        {
+          stack_top_p[0] = left_value;
+          stack_top_p[1] = ecma_make_integer_value (0);
+          stack_top_p += 2;
+          continue;
+        }
+        case VM_OC_PUSH_LIT_POS_BYTE:
+        {
+          ecma_integer_value_t number = *byte_code_p++;
+          stack_top_p[0] = left_value;
+          stack_top_p[1] = ecma_make_integer_value (number + 1);
+          stack_top_p += 2;
+          continue;
+        }
+        case VM_OC_PUSH_LIT_NEG_BYTE:
+        {
+          ecma_integer_value_t number = *byte_code_p++;
+          stack_top_p[0] = left_value;
+          stack_top_p[1] = ecma_make_integer_value (-(number + 1));
+          stack_top_p += 2;
+          continue;
+        }
         case VM_OC_PUSH_OBJECT:
         {
-          ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
-          ecma_object_t *obj_p = ecma_create_object (prototype_p,
+          ecma_object_t *obj_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE),
                                                      0,
                                                      ECMA_OBJECT_TYPE_GENERAL);
 
-          ecma_deref_object (prototype_p);
           *stack_top_p++ = ecma_make_object_value (obj_p);
           continue;
         }
+        case VM_OC_PUSH_NAMED_FUNC_EXPR:
+        {
+          ecma_object_t *func_p = ecma_get_object_from_value (left_value);
+
+          JERRY_ASSERT (ecma_get_object_type (func_p) == ECMA_OBJECT_TYPE_FUNCTION);
+
+          ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_p;
+
+          JERRY_ASSERT (frame_ctx_p->lex_env_p == ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
+                                                                                   ext_func_p->u.function.scope_cp));
+
+          ecma_object_t *name_lex_env = ecma_create_decl_lex_env (frame_ctx_p->lex_env_p);
+
+          ecma_op_create_immutable_binding (name_lex_env, ecma_get_string_from_value (right_value), left_value);
+
+          ECMA_SET_INTERNAL_VALUE_POINTER (ext_func_p->u.function.scope_cp, name_lex_env);
+
+          ecma_free_value (right_value);
+          ecma_deref_object (name_lex_env);
+          *stack_top_p++ = left_value;
+          continue;
+        }
+#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+        case VM_OC_SET_COMPUTED_PROPERTY:
+        {
+          /* Swap values. */
+          left_value ^= right_value;
+          right_value ^= left_value;
+          left_value ^= right_value;
+          /* FALLTHRU */
+        }
+#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
         case VM_OC_SET_PROPERTY:
         {
-          ecma_object_t *object_p = ecma_get_object_from_value (stack_top_p[-1]);
-          ecma_string_t *prop_name_p;
-          ecma_property_t *property_p;
+          JERRY_STATIC_ASSERT (VM_OC_NON_STATIC_FLAG == VM_OC_BACKWARD_BRANCH,
+                               vm_oc_non_static_flag_must_be_equal_to_vm_oc_backward_branch);
 
-          if (ecma_is_value_string (right_value))
-          {
-            prop_name_p = ecma_get_string_from_value (right_value);
-          }
-          else
+          JERRY_ASSERT ((opcode_data >> VM_OC_NON_STATIC_SHIFT) <= 0x1);
+
+          result = right_value;
+
+          if (JERRY_UNLIKELY (!ecma_is_value_string (right_value)))
           {
             result = ecma_op_to_string (right_value);
 
@@ -1032,11 +1194,30 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
             {
               goto error;
             }
+          }
+
+          ecma_string_t *prop_name_p = ecma_get_string_from_value (result);
+
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+          if (JERRY_UNLIKELY (ecma_compare_ecma_string_to_magic_id (prop_name_p, LIT_MAGIC_STRING_PROTOTYPE))
+              && !(opcode_data & VM_OC_NON_STATIC_FLAG))
+          {
+            if (!ecma_is_value_string (right_value))
+            {
+              ecma_deref_ecma_string (prop_name_p);
+            }
 
-            prop_name_p = ecma_get_string_from_value (result);
+            result = ecma_raise_type_error (ECMA_ERR_MSG ("prototype property of a class is non-configurable"));
+            goto error;
           }
 
-          property_p = ecma_find_named_property (object_p, prop_name_p);
+          const int index = (int) (opcode_data >> VM_OC_NON_STATIC_SHIFT) - 2;
+#else /* CONFIG_DISABLE_ES2015_CLASS */
+          const int index = -1;
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
+          ecma_object_t *object_p = ecma_get_object_from_value (stack_top_p[index]);
+          ecma_property_t *property_p = ecma_find_named_property (object_p, prop_name_p);
 
           if (property_p != NULL
               && ECMA_PROPERTY_GET_TYPE (*property_p) != ECMA_PROPERTY_TYPE_NAMEDDATA)
@@ -1071,11 +1252,50 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
         case VM_OC_SET_GETTER:
         case VM_OC_SET_SETTER:
         {
+          JERRY_ASSERT ((opcode_data >> VM_OC_NON_STATIC_SHIFT) <= 0x1);
+
+          result = left_value;
+
+          if (JERRY_UNLIKELY (!ecma_is_value_string (left_value)))
+          {
+            result = ecma_op_to_string (left_value);
+
+            if (ECMA_IS_VALUE_ERROR (result))
+            {
+              goto error;
+            }
+          }
+
+          ecma_string_t *prop_name_p = ecma_get_string_from_value (result);
+
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+          if (JERRY_UNLIKELY (ecma_compare_ecma_string_to_magic_id (prop_name_p, LIT_MAGIC_STRING_PROTOTYPE))
+              && !(opcode_data & VM_OC_NON_STATIC_FLAG))
+          {
+            if (!ecma_is_value_string (left_value))
+            {
+              ecma_deref_ecma_string (prop_name_p);
+            }
+
+            result = ecma_raise_type_error (ECMA_ERR_MSG ("prototype property of a class is non-configurable"));
+            goto error;
+          }
+
+          const int index = (int) (opcode_data >> VM_OC_NON_STATIC_SHIFT) - 2;
+#else /* CONFIG_DISABLE_ES2015_CLASS */
+          const int index = -1;
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+
           opfunc_set_accessor (VM_OC_GROUP_GET_INDEX (opcode_data) == VM_OC_SET_GETTER,
-                               stack_top_p[-1],
-                               left_value,
+                               stack_top_p[index],
+                               prop_name_p,
                                right_value);
 
+          if (!ecma_is_value_string (left_value))
+          {
+            ecma_deref_ecma_string (prop_name_p);
+          }
+
           goto free_both_values;
         }
         case VM_OC_PUSH_ARRAY:
@@ -1090,6 +1310,279 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
           *stack_top_p++ = result;
           continue;
         }
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+        case VM_OC_SUPER_CALL:
+        {
+          frame_ctx_p->call_operation = VM_EXEC_SUPER_CALL;
+          frame_ctx_p->byte_code_p = byte_code_start_p;
+          frame_ctx_p->stack_top_p = stack_top_p;
+          return ECMA_VALUE_UNDEFINED;
+        }
+        case VM_OC_CLASS_HERITAGE:
+        {
+          ecma_value_t super_value = *(--stack_top_p);
+          ecma_object_t *super_class_p;
+          branch_offset += (int32_t) (byte_code_start_p - frame_ctx_p->byte_code_start_p);
+
+          JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
+
+          if (ecma_is_value_null (super_value))
+          {
+            super_class_p = ecma_create_object (NULL, 0, ECMA_OBJECT_TYPE_GENERAL);
+          }
+          else
+          {
+            result = ecma_op_to_object (super_value);
+            ecma_free_value (super_value);
+
+            if (ECMA_IS_VALUE_ERROR (result) || !ecma_is_constructor (result))
+            {
+              if (ECMA_IS_VALUE_ERROR (result))
+              {
+                ecma_free_value (JERRY_CONTEXT (error_value));
+              }
+
+              ecma_free_value (result);
+
+              result = ecma_raise_type_error ("Value provided by class extends is not an object or null.");
+              goto error;
+            }
+            else
+            {
+              super_class_p = ecma_get_object_from_value (result);
+            }
+          }
+
+          ecma_object_t *super_env_p = ecma_create_object_lex_env (frame_ctx_p->lex_env_p,
+                                                                   super_class_p,
+                                                                   ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND);
+
+          ecma_deref_object (super_class_p);
+
+          VM_PLUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_SUPER_CLASS_CONTEXT_STACK_ALLOCATION);
+          stack_top_p += PARSER_SUPER_CLASS_CONTEXT_STACK_ALLOCATION;
+
+          stack_top_p[-1] = VM_CREATE_CONTEXT (VM_CONTEXT_SUPER_CLASS, branch_offset);
+
+          frame_ctx_p->lex_env_p = super_env_p;
+
+          continue;
+        }
+        case VM_OC_CLASS_INHERITANCE:
+        {
+          ecma_value_t child_value = stack_top_p[-2];
+          ecma_value_t child_prototype_value = stack_top_p[-1];
+
+          ecma_object_t *child_class_p = ecma_get_object_from_value (child_value);
+          ecma_object_t *child_prototype_class_p = ecma_get_object_from_value (child_prototype_value);
+          ecma_property_value_t *prop_value_p;
+
+          prop_value_p = ecma_create_named_data_property (child_prototype_class_p,
+                                                          ecma_get_magic_string (LIT_MAGIC_STRING_CONSTRUCTOR),
+                                                          ECMA_PROPERTY_CONFIGURABLE_WRITABLE,
+                                                          NULL);
+
+          ecma_named_data_property_assign_value (child_prototype_class_p, prop_value_p, child_value);
+
+          ecma_object_t *super_class_p = ecma_get_lex_env_binding_object (frame_ctx_p->lex_env_p);
+
+          if (ecma_get_object_prototype (super_class_p))
+          {
+            ecma_value_t super_prototype_value = ecma_op_object_get_by_magic_id (super_class_p,
+                                                                                 LIT_MAGIC_STRING_PROTOTYPE);
+            if (ecma_get_object_type (super_class_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION
+                && !ecma_is_value_object (super_prototype_value))
+            {
+              ecma_free_value (super_prototype_value);
+              result = ecma_raise_type_error (ECMA_ERR_MSG ("Class extends value does not have valid "
+                                                            "prototype property."));
+              goto error;
+            }
+            if (!(ECMA_IS_VALUE_ERROR (super_prototype_value) || !ecma_is_value_object (super_prototype_value)))
+            {
+              ecma_object_t *super_prototype_class_p = ecma_get_object_from_value (super_prototype_value);
+
+              ECMA_SET_POINTER (child_prototype_class_p->prototype_or_outer_reference_cp, super_prototype_class_p);
+              ECMA_SET_POINTER (child_class_p->prototype_or_outer_reference_cp, super_class_p);
+
+            }
+            ecma_free_value (super_prototype_value);
+          }
+
+          continue;
+        }
+        case VM_OC_PUSH_CLASS_CONSTRUCTOR:
+        {
+          ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
+
+          ecma_object_t *function_obj_p = ecma_create_object (prototype_obj_p,
+                                                              sizeof (ecma_extended_object_t),
+                                                              ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
+
+          ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) function_obj_p;
+          ext_func_obj_p->u.external_handler_cb = ecma_op_function_implicit_constructor_handler_cb;
+
+          *stack_top_p++ = ecma_make_object_value (function_obj_p);
+
+          continue;
+        }
+        case VM_OC_SET_CLASS_CONSTRUCTOR:
+        {
+          ecma_object_t *new_constructor_obj_p = ecma_get_object_from_value (left_value);
+          ecma_object_t *current_constructor_obj_p = ecma_get_object_from_value (stack_top_p[-2]);
+
+          ecma_extended_object_t *new_ext_func_obj_p = (ecma_extended_object_t *) new_constructor_obj_p;
+          ecma_extended_object_t *current_ext_func_obj_p = (ecma_extended_object_t *) current_constructor_obj_p;
+
+          uint16_t type_flags_refs = current_constructor_obj_p->type_flags_refs;
+          const int new_type = ECMA_OBJECT_TYPE_FUNCTION - ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION;
+          current_constructor_obj_p->type_flags_refs = (uint16_t) (type_flags_refs + new_type);
+
+          ecma_compiled_code_t *bytecode_p;
+          bytecode_p = (ecma_compiled_code_t *) ecma_op_function_get_compiled_code (new_ext_func_obj_p);
+          bytecode_p->status_flags |= CBC_CODE_FLAGS_CONSTRUCTOR;
+          ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_p);
+          ECMA_SET_INTERNAL_VALUE_POINTER (current_ext_func_obj_p->u.function.bytecode_cp,
+                                           bytecode_p);
+          ECMA_SET_INTERNAL_VALUE_POINTER (current_ext_func_obj_p->u.function.scope_cp,
+                                           ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_object_t,
+                                                                            new_ext_func_obj_p->u.function.scope_cp));
+          ecma_deref_object (new_constructor_obj_p);
+          continue;
+        }
+        case VM_OC_PUSH_IMPL_CONSTRUCTOR:
+        {
+          ecma_object_t *current_constructor_obj_p = ecma_get_object_from_value (stack_top_p[-2]);
+
+          uint16_t type_flags_refs = current_constructor_obj_p->type_flags_refs;
+          const int new_type = ECMA_OBJECT_TYPE_BOUND_FUNCTION - ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION;
+          current_constructor_obj_p->type_flags_refs = (uint16_t) (type_flags_refs + new_type);
+
+          ecma_extended_object_t *ext_function_p = (ecma_extended_object_t *) current_constructor_obj_p;
+          ecma_object_t *super_obj_p = ecma_op_resolve_super_reference_value (frame_ctx_p->lex_env_p);
+
+          ECMA_SET_INTERNAL_VALUE_POINTER (ext_function_p->u.bound_function.target_function,
+                                           super_obj_p);
+          ext_function_p->u.bound_function.args_len_or_this = ECMA_VALUE_IMPLICIT_CONSTRUCTOR;
+
+          continue;
+        }
+        case VM_OC_CLASS_EXPR_CONTEXT_END:
+        {
+          JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p - 1);
+
+          JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_top_p[-2]) == VM_CONTEXT_SUPER_CLASS);
+          stack_top_p = vm_stack_context_abort (frame_ctx_p, stack_top_p - 1);
+
+          JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
+          stack_top_p++;
+          stack_top_p[-1] = *stack_top_p;
+          continue;
+        }
+        case VM_OC_CLASS_EVAL:
+        {
+          ECMA_SET_SUPER_EVAL_PARSER_OPTS (*byte_code_p++);
+          continue;
+        }
+        case VM_OC_PUSH_CONSTRUCTOR_SUPER:
+        {
+          JERRY_ASSERT (byte_code_start_p[0] == CBC_EXT_OPCODE);
+
+          bool is_super_called = ecma_op_is_super_called (frame_ctx_p->lex_env_p);
+
+          if (byte_code_start_p[1] != CBC_EXT_PUSH_CONSTRUCTOR_SUPER_PROP)
+          {
+            /* Calling super(...) */
+            if (is_super_called)
+            {
+              result = ecma_raise_reference_error (ECMA_ERR_MSG ("Super constructor may only be called once."));
+
+              goto error;
+            }
+          }
+          else if (!is_super_called)
+          {
+            /* Reference to super.method or super["method"] */
+            result = ecma_raise_reference_error (ECMA_ERR_MSG ("Must call super constructor in derived class before "
+                                                               "accessing 'super'."));
+            goto error;
+          }
+
+          /* FALLTHRU */
+        }
+        case VM_OC_PUSH_SUPER:
+        {
+          JERRY_ASSERT (byte_code_start_p[0] == CBC_EXT_OPCODE);
+
+          if (byte_code_start_p[1] == CBC_EXT_PUSH_SUPER
+              || byte_code_start_p[1] == CBC_EXT_PUSH_CONSTRUCTOR_SUPER_PROP)
+          {
+            ecma_object_t *super_class_p = ecma_op_resolve_super_reference_value (frame_ctx_p->lex_env_p);
+
+            ecma_value_t super_prototype = ecma_op_object_get_by_magic_id (super_class_p,
+                                                                           LIT_MAGIC_STRING_PROTOTYPE);
+
+            if (ECMA_IS_VALUE_ERROR (super_prototype))
+            {
+              result = super_prototype;
+              goto error;
+            }
+
+            *stack_top_p++ = super_prototype;
+          }
+          else
+          {
+            ecma_object_t *super_class_p = ecma_op_resolve_super_reference_value (frame_ctx_p->lex_env_p);
+            *stack_top_p++ = ecma_fast_copy_value (ecma_make_object_value (super_class_p));
+          }
+
+          continue;
+        }
+        case VM_OC_PUSH_CONSTRUCTOR_THIS:
+        {
+          if (!ecma_op_is_super_called (frame_ctx_p->lex_env_p))
+          {
+            result = ecma_raise_reference_error (ECMA_ERR_MSG ("Must call super constructor in derived class before "
+                                                               "accessing 'this' or returning from it."));
+            goto error;
+          }
+
+          *stack_top_p++ = ecma_copy_value (ecma_op_get_class_this_binding (frame_ctx_p->lex_env_p));
+          continue;
+        }
+        case VM_OC_SUPER_PROP_REFERENCE:
+        {
+          const int index = (byte_code_start_p[1] == CBC_EXT_SUPER_PROP_ASSIGN) ? -1 : -3;
+          ecma_free_value (stack_top_p[index]);
+          stack_top_p[index] = ecma_copy_value (frame_ctx_p->this_binding);
+          continue;
+        }
+        case VM_OC_CONSTRUCTOR_RET:
+        {
+          result = left_value;
+          left_value = ECMA_VALUE_UNDEFINED;
+
+          if (!ecma_is_value_object (result))
+          {
+            if (ecma_is_value_undefined (result))
+            {
+              if (!ecma_op_is_super_called (frame_ctx_p->lex_env_p))
+              {
+                result = ecma_raise_reference_error (ECMA_ERR_MSG ("Must call super constructor in derived class "
+                                                                   "before returning from derived constructor"));
+              }
+            }
+            else
+            {
+              ecma_free_value (result);
+              result = ecma_raise_type_error (ECMA_ERR_MSG ("Derived constructors may only "
+                                                            "return object or undefined."));
+            }
+          }
+
+          goto error;
+        }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
         case VM_OC_PUSH_ELISON:
         {
           *stack_top_p++ = ECMA_VALUE_ARRAY_HOLE;
@@ -1184,6 +1677,18 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
           }
           continue;
         }
+        case VM_OC_PROP_GET:
+        {
+          result = vm_op_get_value (left_value, right_value);
+
+          if (ECMA_IS_VALUE_ERROR (result))
+          {
+            goto error;
+          }
+
+          *stack_top_p++ = result;
+          goto free_both_values;
+        }
         case VM_OC_PROP_REFERENCE:
         {
           /* Forms with reference requires preserving the base and offset. */
@@ -1208,7 +1713,6 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
           }
           /* FALLTHRU */
         }
-        case VM_OC_PROP_GET:
         case VM_OC_PROP_PRE_INCR:
         case VM_OC_PROP_PRE_DECR:
         case VM_OC_PROP_POST_INCR:
@@ -1217,23 +1721,16 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
           result = vm_op_get_value (left_value,
                                     right_value);
 
-          if (ECMA_IS_VALUE_ERROR (result))
-          {
-            if (opcode >= CBC_PUSH_PROP_REFERENCE && opcode < CBC_PRE_INCR)
-            {
-              left_value = ECMA_VALUE_UNDEFINED;
-              right_value = ECMA_VALUE_UNDEFINED;
-            }
-            goto error;
-          }
-
           if (opcode < CBC_PRE_INCR)
           {
-            if (opcode >= CBC_PUSH_PROP_REFERENCE)
+            left_value = ECMA_VALUE_UNDEFINED;
+            right_value = ECMA_VALUE_UNDEFINED;
+
+            if (ECMA_IS_VALUE_ERROR (result))
             {
-              left_value = ECMA_VALUE_UNDEFINED;
-              right_value = ECMA_VALUE_UNDEFINED;
+              goto error;
             }
+
             break;
           }
 
@@ -1271,7 +1768,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
               int_increase = 1 << ECMA_DIRECT_SHIFT;
             }
 
-            if (likely (int_increase != 0))
+            if (JERRY_LIKELY (int_increase != 0))
             {
               /* Postfix operators require the unmodifed number value. */
               if (opcode_flags & VM_OC_POST_INCR_DECR_OPERATOR_FLAG)
@@ -1302,8 +1799,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
                 }
                 else if (opcode_data & VM_OC_PUT_BLOCK)
                 {
-                  ecma_free_value (block_result);
-                  block_result = result;
+                  ecma_free_value (frame_ctx_p->block_result);
+                  frame_ctx_p->block_result = result;
                   opcode_data &= (uint32_t) ~VM_OC_PUT_BLOCK;
                 }
               }
@@ -1365,8 +1862,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
             }
             else if (opcode_data & VM_OC_PUT_BLOCK)
             {
-              ecma_free_value (block_result);
-              block_result = ecma_copy_value (result);
+              ecma_free_value (frame_ctx_p->block_result);
+              frame_ctx_p->block_result = ecma_copy_value (result);
               opcode_data &= (uint32_t) ~VM_OC_PUT_BLOCK;
             }
           }
@@ -1410,8 +1907,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
 
           if (opcode == CBC_RETURN_WITH_BLOCK)
           {
-            left_value = block_result;
-            block_result = ECMA_VALUE_UNDEFINED;
+            left_value = frame_ctx_p->block_result;
+            frame_ctx_p->block_result = ECMA_VALUE_UNDEFINED;
           }
 
           result = left_value;
@@ -1440,72 +1937,44 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
         }
         case VM_OC_CALL:
         {
-          if (frame_ctx_p->call_operation == VM_NO_EXEC_OP)
-          {
-            frame_ctx_p->call_operation = VM_EXEC_CALL;
-            frame_ctx_p->byte_code_p = byte_code_start_p;
-            frame_ctx_p->stack_top_p = stack_top_p;
-            frame_ctx_p->call_block_result = block_result;
-            return ECMA_VALUE_UNDEFINED;
-          }
-
-          if (opcode < CBC_CALL0)
-          {
-            byte_code_p++;
-          }
-
-          frame_ctx_p->call_operation = VM_NO_EXEC_OP;
-
-          result = *(--stack_top_p);
-          block_result = frame_ctx_p->call_block_result;
-
-          if (ECMA_IS_VALUE_ERROR (result))
-          {
-            goto error;
-          }
-
-          if (!(opcode_data & (VM_OC_PUT_STACK | VM_OC_PUT_BLOCK)))
-          {
-            ecma_fast_free_value (result);
-          }
-          else if (opcode_data & VM_OC_PUT_STACK)
-          {
-            *stack_top_p++ = result;
-          }
-          else
-          {
-            ecma_fast_free_value (block_result);
-            block_result = result;
-          }
-          continue;
+          frame_ctx_p->call_operation = VM_EXEC_CALL;
+          frame_ctx_p->byte_code_p = byte_code_start_p;
+          frame_ctx_p->stack_top_p = stack_top_p;
+          return ECMA_VALUE_UNDEFINED;
         }
         case VM_OC_NEW:
         {
-          if (frame_ctx_p->call_operation == VM_NO_EXEC_OP)
-          {
-            frame_ctx_p->call_operation = VM_EXEC_CONSTRUCT;
-            frame_ctx_p->byte_code_p = byte_code_start_p;
-            frame_ctx_p->stack_top_p = stack_top_p;
-            frame_ctx_p->call_block_result = block_result;
-            return ECMA_VALUE_UNDEFINED;
-          }
+          frame_ctx_p->call_operation = VM_EXEC_CONSTRUCT;
+          frame_ctx_p->byte_code_p = byte_code_start_p;
+          frame_ctx_p->stack_top_p = stack_top_p;
+          return ECMA_VALUE_UNDEFINED;
+        }
+        case VM_OC_ERROR:
+        {
+          JERRY_ASSERT (frame_ctx_p->byte_code_p[1] == CBC_EXT_ERROR);
+#ifdef JERRY_DEBUGGER
+          frame_ctx_p->byte_code_p = JERRY_CONTEXT (debugger_exception_byte_code_p);
+#endif /* JERRY_DEBUGGER */
+
+          result = ECMA_VALUE_ERROR;
+          goto error;
+        }
+        case VM_OC_RESOLVE_BASE_FOR_CALL:
+        {
+          ecma_value_t this_value = stack_top_p[-3];
 
-          if (opcode < CBC_NEW0)
+          if (this_value == ECMA_VALUE_REGISTER_REF)
           {
-            byte_code_p++;
+            /* Lexical environment cannot be 'this' value. */
+            stack_top_p[-2] = ECMA_VALUE_UNDEFINED;
+            stack_top_p[-3] = ECMA_VALUE_UNDEFINED;
           }
-
-          frame_ctx_p->call_operation = VM_NO_EXEC_OP;
-
-          result = *(--stack_top_p);
-          block_result = frame_ctx_p->call_block_result;
-
-          if (ECMA_IS_VALUE_ERROR (result))
+          else if (vm_get_implicit_this_value (&this_value))
           {
-            goto error;
+            ecma_free_value (stack_top_p[-3]);
+            stack_top_p[-3] = this_value;
           }
 
-          *stack_top_p++ = result;
           continue;
         }
         case VM_OC_PROP_DELETE:
@@ -1610,14 +2079,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
         }
         case VM_OC_NOT:
         {
-          result = opfunc_logical_not (left_value);
-
-          if (ECMA_IS_VALUE_ERROR (result))
-          {
-            goto error;
-          }
-
-          *stack_top_p++ = result;
+          *stack_top_p++ = ecma_make_boolean_value (!ecma_op_to_boolean (left_value));
+          JERRY_ASSERT (ecma_is_value_boolean (stack_top_p[-1]));
           goto free_left_value;
         }
         case VM_OC_BIT_NOT:
@@ -2090,11 +2553,11 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
               {
                 branch_offset = *(byte_code_p++);
 
-                if (unlikely (branch_offset_length != 1))
+                if (JERRY_UNLIKELY (branch_offset_length != 1))
                 {
                   branch_offset <<= 8;
                   branch_offset |= *(byte_code_p++);
-                  if (unlikely (branch_offset_length == 3))
+                  if (JERRY_UNLIKELY (branch_offset_length == 3))
                   {
                     branch_offset <<= 8;
                     branch_offset |= *(byte_code_p++);
@@ -2271,15 +2734,13 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
 
           with_env_p = ecma_create_object_lex_env (frame_ctx_p->lex_env_p,
                                                    object_p,
-                                                   true);
-
+                                                   ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
           ecma_deref_object (object_p);
 
           VM_PLUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_WITH_CONTEXT_STACK_ALLOCATION);
           stack_top_p += PARSER_WITH_CONTEXT_STACK_ALLOCATION;
 
           stack_top_p[-1] = VM_CREATE_CONTEXT (VM_CONTEXT_WITH, branch_offset);
-          stack_top_p[-2] = ecma_make_object_value (frame_ctx_p->lex_env_p);
 
           frame_ctx_p->lex_env_p = with_env_p;
           continue;
@@ -2322,12 +2783,12 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
 
           uint32_t index = context_top_p[-3];
 
-          JERRY_ASSERT (!ecma_is_value_collection_chunk (chunk_p->items[index]));
+          JERRY_ASSERT (!ecma_is_value_pointer (chunk_p->items[index]));
 
           *stack_top_p++ = chunk_p->items[index];
           index++;
 
-          if (likely (!ecma_is_value_collection_chunk (chunk_p->items[index])))
+          if (JERRY_LIKELY (!ecma_is_value_pointer (chunk_p->items[index])))
           {
             context_top_p[-3] = index;
             continue;
@@ -2335,7 +2796,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
 
           context_top_p[-3] = 0;
 
-          ecma_collection_chunk_t *next_chunk_p = ecma_get_collection_chunk_from_value (chunk_p->items[index]);
+          ecma_collection_chunk_t *next_chunk_p;
+          next_chunk_p = (ecma_collection_chunk_t *) ecma_get_pointer_from_value (chunk_p->items[index]);
           ECMA_SET_INTERNAL_VALUE_ANY_POINTER (context_top_p[-2], next_chunk_p);
 
           jmem_heap_free_block (chunk_p, sizeof (ecma_collection_chunk_t));
@@ -2364,7 +2826,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
 
             ecma_string_t *prop_name_p = ecma_get_string_from_value (chunk_p->items[index]);
 
-            if (likely (ecma_op_object_has_property (object_p, prop_name_p)))
+            if (JERRY_LIKELY (ecma_op_object_has_property (object_p, prop_name_p)))
             {
               byte_code_p = byte_code_start_p + branch_offset;
               break;
@@ -2373,7 +2835,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
             index++;
             ecma_value_t value = chunk_p->items[index];
 
-            if (likely (!ecma_is_value_collection_chunk (value)))
+            if (JERRY_LIKELY (!ecma_is_value_pointer (value)))
             {
               stack_top_p[-3] = index;
             }
@@ -2382,7 +2844,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
               index = 0;
               stack_top_p[-3] = 0;
 
-              ecma_collection_chunk_t *next_chunk_p = ecma_get_collection_chunk_from_value (value);
+              ecma_collection_chunk_t *next_chunk_p;
+              next_chunk_p = (ecma_collection_chunk_t *) ecma_get_pointer_from_value (value);
               ECMA_SET_INTERNAL_VALUE_ANY_POINTER (stack_top_p[-2], next_chunk_p);
 
               jmem_heap_free_block (chunk_p, sizeof (ecma_collection_chunk_t));
@@ -2426,8 +2889,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
 
           if (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_CATCH)
           {
-            ecma_deref_object (frame_ctx_p->lex_env_p);
-            frame_ctx_p->lex_env_p = ecma_get_object_from_value (stack_top_p[-2]);
+            ecma_object_t *lex_env_p = frame_ctx_p->lex_env_p;
+            frame_ctx_p->lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
+            ecma_deref_object (lex_env_p);
           }
 
           stack_top_p[-1] = (ecma_value_t) VM_CREATE_CONTEXT (VM_CONTEXT_FINALLY_JUMP, branch_offset);
@@ -2519,9 +2983,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
           JERRY_ASSERT (frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth == stack_top_p);
           continue;
         }
+#ifdef JERRY_DEBUGGER
         case VM_OC_BREAKPOINT_ENABLED:
         {
-#ifdef JERRY_DEBUGGER
           if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_IGNORE)
           {
             continue;
@@ -2539,12 +3003,10 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
             result = ECMA_VALUE_ERROR;
             goto error;
           }
-#endif /* JERRY_DEBUGGER */
           continue;
         }
         case VM_OC_BREAKPOINT_DISABLED:
         {
-#ifdef JERRY_DEBUGGER
           if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_IGNORE)
           {
             continue;
@@ -2593,15 +3055,15 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
               goto error;
             }
           }
-#endif /* JERRY_DEBUGGER */
           continue;
         }
+#endif /* JERRY_DEBUGGER */
 #ifdef JERRY_ENABLE_LINE_INFO
         case VM_OC_RESOURCE_NAME:
         {
           ecma_length_t formal_params_number = 0;
 
-          if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_NON_STRICT_ARGUMENTS_NEEDED)
+          if (CBC_NON_STRICT_ARGUMENTS_NEEDED (bytecode_header_p))
           {
             if (bytecode_header_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
             {
@@ -2644,8 +3106,10 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
 #endif /* JERRY_ENABLE_LINE_INFO */
         default:
         {
+          JERRY_ASSERT (VM_OC_GROUP_GET_INDEX (opcode_data) == VM_OC_NONE);
+
+          jerry_fatal (ERR_DISABLED_BYTE_CODE);
           JERRY_UNREACHABLE ();
-          continue;
         }
       }
 
@@ -2738,8 +3202,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
       }
       else if (opcode_data & VM_OC_PUT_BLOCK)
       {
-        ecma_fast_free_value (block_result);
-        block_result = result;
+        ecma_fast_free_value (frame_ctx_p->block_result);
+        frame_ctx_p->block_result = result;
       }
 
 free_both_values:
@@ -2778,7 +3242,8 @@ error:
                                   | JERRY_DEBUGGER_VM_EXCEPTION_THROWN);
 
       if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
-          && !(frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_DEBUGGER_IGNORE)
+          && !(frame_ctx_p->bytecode_header_p->status_flags
+               & (CBC_CODE_FLAGS_DEBUGGER_IGNORE | CBC_CODE_FLAGS_STATIC_FUNCTION))
           && !(JERRY_CONTEXT (debugger_flags) & dont_stop))
       {
         /* Save the error to a local value, because the engine enters breakpoint mode after,
@@ -2810,7 +3275,8 @@ error:
     {
       /* In most cases there is no context. */
 
-      ecma_fast_free_value (block_result);
+      ecma_fast_free_value (frame_ctx_p->block_result);
+      frame_ctx_p->call_operation = VM_NO_EXEC_OP;
       return result;
     }
 
@@ -2858,11 +3324,13 @@ error:
           }
 
           ecma_object_t *catch_env_p = ecma_create_decl_lex_env (frame_ctx_p->lex_env_p);
+#ifdef JERRY_DEBUGGER
+          catch_env_p->type_flags_refs |= (uint16_t) ECMA_OBJECT_FLAG_NON_CLOSURE;
+#endif /* JERRY_DEBUGGER */
 
           ecma_string_t *catch_name_p = ecma_get_string_from_value (literal_start_p[literal_index]);
           ecma_op_create_mutable_binding (catch_env_p, catch_name_p, false);
 
-          stack_top_p[-2 - 1] = ecma_make_object_value (frame_ctx_p->lex_env_p);
           frame_ctx_p->lex_env_p = catch_env_p;
         }
         else
@@ -2885,7 +3353,9 @@ error:
       while (frame_ctx_p->context_depth > 0);
     }
 
-    ecma_free_value (block_result);
+    ecma_free_value (frame_ctx_p->block_result);
+    frame_ctx_p->call_operation = VM_NO_EXEC_OP;
+
     return result;
   }
 } /* vm_loop */
@@ -2898,7 +3368,7 @@ error:
  *
  * @return ecma value
  */
-static ecma_value_t __attr_noinline___
+static ecma_value_t JERRY_ATTR_NOINLINE
 vm_execute (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
             const ecma_value_t *arg_p, /**< arguments list */
             ecma_length_t arg_list_len) /**< length of arguments list */
@@ -2957,39 +3427,49 @@ vm_execute (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
   {
     completion_value = vm_loop (frame_ctx_p);
 
-    if (frame_ctx_p->call_operation == VM_NO_EXEC_OP)
-    {
-      break;
-    }
-
-    if (frame_ctx_p->call_operation == VM_EXEC_CALL)
-    {
-      opfunc_call (frame_ctx_p);
-    }
-    else
+    switch (frame_ctx_p->call_operation)
     {
-      JERRY_ASSERT (frame_ctx_p->call_operation == VM_EXEC_CONSTRUCT);
-      opfunc_construct (frame_ctx_p);
-    }
-  }
+      case VM_EXEC_CALL:
+      {
+        opfunc_call (frame_ctx_p);
+        break;
+      }
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+      case VM_EXEC_SUPER_CALL:
+      {
+        vm_super_call (frame_ctx_p);
+        break;
+      }
+#endif /* !CONFIG_DISABLE_ES2015_CLASS */
+      case VM_EXEC_CONSTRUCT:
+      {
+        opfunc_construct (frame_ctx_p);
+        break;
+      }
+      default:
+      {
+        JERRY_ASSERT (frame_ctx_p->call_operation == VM_NO_EXEC_OP);
 
-  /* Free arguments and registers */
-  for (uint32_t i = 0; i < register_end; i++)
-  {
-    ecma_fast_free_value (frame_ctx_p->registers_p[i]);
-  }
+        /* Free arguments and registers */
+        for (uint32_t i = 0; i < register_end; i++)
+        {
+          ecma_fast_free_value (frame_ctx_p->registers_p[i]);
+        }
 
 #ifdef JERRY_DEBUGGER
-  if (JERRY_CONTEXT (debugger_stop_context) == JERRY_CONTEXT (vm_top_context_p))
-  {
-    /* The engine will stop when the next breakpoint is reached. */
-    JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_STOP);
-    JERRY_CONTEXT (debugger_stop_context) = NULL;
-  }
+        if (JERRY_CONTEXT (debugger_stop_context) == JERRY_CONTEXT (vm_top_context_p))
+        {
+          /* The engine will stop when the next breakpoint is reached. */
+          JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_STOP);
+          JERRY_CONTEXT (debugger_stop_context) = NULL;
+        }
 #endif /* JERRY_DEBUGGER */
 
-  JERRY_CONTEXT (vm_top_context_p) = frame_ctx_p->prev_context_p;
-  return completion_value;
+        JERRY_CONTEXT (vm_top_context_p) = frame_ctx_p->prev_context_p;
+        return completion_value;
+      }
+    }
+  }
 } /* vm_execute */
 
 /**
@@ -3001,7 +3481,7 @@ ecma_value_t
 vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data header */
         ecma_value_t this_binding_value, /**< value of 'ThisBinding' */
         ecma_object_t *lex_env_p, /**< lexical environment to use */
-        bool is_eval_code, /**< is the code is eval code (ECMA-262 v5, 10.1) */
+        uint32_t parse_opts, /**< ecma_parse_opts_t option bits */
         const ecma_value_t *arg_list_p, /**< arguments list */
         ecma_length_t arg_list_len) /**< length of arguments list */
 {
@@ -3036,16 +3516,16 @@ vm_run (const ecma_compiled_code_t *bytecode_header_p, /**< byte-code data heade
   frame_ctx.lex_env_p = lex_env_p;
   frame_ctx.prev_context_p = JERRY_CONTEXT (vm_top_context_p);
   frame_ctx.this_binding = this_binding_value;
+  frame_ctx.block_result = ECMA_VALUE_UNDEFINED;
 #ifdef JERRY_ENABLE_LINE_INFO
   frame_ctx.resource_name = ECMA_VALUE_UNDEFINED;
   frame_ctx.current_line = 0;
 #endif /* JERRY_ENABLE_LINE_INFO */
   frame_ctx.context_depth = 0;
-  frame_ctx.is_eval_code = is_eval_code;
-  frame_ctx.call_operation = VM_NO_EXEC_OP;
+  frame_ctx.is_eval_code = parse_opts & ECMA_PARSE_DIRECT_EVAL;
 
   /* Use JERRY_MAX() to avoid array declaration with size 0. */
-  ecma_value_t stack[JERRY_MAX (call_stack_size, 1)];
+  JERRY_VLA (ecma_value_t, stack, JERRY_MAX (call_stack_size, 1));
   frame_ctx.registers_p = stack;
 
   return vm_execute (&frame_ctx, arg_list_p, arg_list_len);
index 1aedee4800f0260f2c256f440925e7531dd7d83f..c7c98fbeb9ef58ad972f77f88b8bfac95ca17558 100644 (file)
@@ -41,7 +41,8 @@
  */
 
 /**
- * Branch argument is a backward branch
+ * If VM_OC_GET_ARGS_INDEX(opcode) == VM_OC_GET_BRANCH,
+ * this flag signals that the branch is a backward branch.
  */
 #define VM_OC_BACKWARD_BRANCH 0x4000
 
@@ -102,22 +103,28 @@ typedef enum
  */
 typedef enum
 {
-  VM_OC_NONE,                    /**< do nothing */
   VM_OC_POP,                     /**< pop from stack */
   VM_OC_POP_BLOCK,               /**< pop block */
-  VM_OC_PUSH,                    /**< push one element  */
-  VM_OC_PUSH_TWO,                /**< push two elements onto the stack */
-  VM_OC_PUSH_THREE,              /**< push three elements onto the stack */
+  VM_OC_PUSH,                    /**< push one literal  */
+  VM_OC_PUSH_TWO,                /**< push two literals */
+  VM_OC_PUSH_THREE,              /**< push three literals */
   VM_OC_PUSH_UNDEFINED,          /**< push undefined value */
   VM_OC_PUSH_TRUE,               /**< push true value */
   VM_OC_PUSH_FALSE,              /**< push false value */
   VM_OC_PUSH_NULL,               /**< push null value */
   VM_OC_PUSH_THIS,               /**< push this */
-  VM_OC_PUSH_NUMBER_0,           /**< push number zero */
-  VM_OC_PUSH_NUMBER_POS_BYTE,    /**< push number between 1 and 256 */
-  VM_OC_PUSH_NUMBER_NEG_BYTE,    /**< push number between -1 and -256 */
+  VM_OC_PUSH_0,                  /**< push number zero */
+  VM_OC_PUSH_POS_BYTE,           /**< push number between 1 and 256 */
+  VM_OC_PUSH_NEG_BYTE,           /**< push number between -1 and -256 */
+  VM_OC_PUSH_LIT_0,              /**< push literal and number zero */
+  VM_OC_PUSH_LIT_POS_BYTE,       /**< push literal and number between 1 and 256 */
+  VM_OC_PUSH_LIT_NEG_BYTE,       /**< push literal and number between -1 and -256 */
   VM_OC_PUSH_OBJECT,             /**< push object */
+  VM_OC_PUSH_NAMED_FUNC_EXPR,    /**< push named function expression */
   VM_OC_SET_PROPERTY,            /**< set property */
+#ifndef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+  VM_OC_SET_COMPUTED_PROPERTY,   /**< set computed property */
+#endif /* !CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
   VM_OC_SET_GETTER,              /**< set getter */
   VM_OC_SET_SETTER,              /**< set setter */
   VM_OC_PUSH_UNDEFINED_BASE,     /**< push undefined base */
@@ -152,6 +159,8 @@ typedef enum
   VM_OC_EVAL,                    /**< eval */
   VM_OC_CALL,                    /**< call */
   VM_OC_NEW,                     /**< new */
+  VM_OC_RESOLVE_BASE_FOR_CALL,   /**< resolve base value before call */
+  VM_OC_ERROR,                   /**< error while the vm_loop is suspended */
 
   VM_OC_JUMP,                    /**< jump */
   VM_OC_BRANCH_IF_STRICT_EQUAL,  /**< branch if stric equal */
@@ -203,12 +212,66 @@ typedef enum
   VM_OC_FINALLY,                 /**< finally */
   VM_OC_CONTEXT_END,             /**< context end */
   VM_OC_JUMP_AND_EXIT_CONTEXT,   /**< jump and exit context */
+#ifndef CONFIG_DISABLE_ES2015_CLASS
+  VM_OC_CLASS_HERITAGE,          /**< create a super class context */
+  VM_OC_CLASS_INHERITANCE,       /**< inherit properties from the 'super' class */
+  VM_OC_PUSH_CLASS_CONSTRUCTOR,  /**< push class constructor */
+  VM_OC_SET_CLASS_CONSTRUCTOR,   /**< set class constructor to the given function literal */
+  VM_OC_PUSH_IMPL_CONSTRUCTOR,   /**< create implicit class constructor */
+  VM_OC_CLASS_EXPR_CONTEXT_END,  /**< class expression heritage context end */
+  VM_OC_CLASS_EVAL,              /**< eval inside a class */
+  VM_OC_SUPER_CALL,              /**< call the 'super' constructor */
+  VM_OC_SUPER_PROP_REFERENCE,    /**< resolve super property reference */
+  VM_OC_PUSH_SUPER,              /**< push resolvable super reference */
+  VM_OC_PUSH_CONSTRUCTOR_SUPER,  /**< push 'super' inside a class constructor */
+  VM_OC_PUSH_CONSTRUCTOR_THIS,   /**< push 'this' inside a class constructor */
+  VM_OC_CONSTRUCTOR_RET,         /**< explicit return from a class constructor */
+#endif /* !CONFIG_DISABLE_ES2015 */
+#ifdef JERRY_DEBUGGER
   VM_OC_BREAKPOINT_ENABLED,      /**< enabled breakpoint for debugger */
   VM_OC_BREAKPOINT_DISABLED,     /**< disabled breakpoint for debugger */
+#endif /* JERRY_DEBUGGER */
+#ifdef JERRY_ENABLE_LINE_INFO
   VM_OC_RESOURCE_NAME,           /**< resource name of the current function */
   VM_OC_LINE,                    /**< line number of the next statement */
+#endif /* JERRY_ENABLE_LINE_INFO */
+  VM_OC_NONE,                    /**< a special opcode for unsupported byte codes */
 } vm_oc_types;
 
+/**
+ * Unused opcodes, but required by byte-code types.
+ */
+typedef enum
+{
+#ifdef CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER
+  VM_OC_SET_COMPUTED_PROPERTY = VM_OC_NONE,   /**< set computed property is unused */
+#endif /* CONFIG_DISABLE_ES2015_OBJECT_INITIALIZER */
+#ifndef JERRY_DEBUGGER
+  VM_OC_BREAKPOINT_ENABLED = VM_OC_NONE,      /**< enabled breakpoint for debugger is unused */
+  VM_OC_BREAKPOINT_DISABLED = VM_OC_NONE,     /**< disabled breakpoint for debugger is unused */
+#endif /* !JERRY_DEBUGGER */
+#ifndef JERRY_ENABLE_LINE_INFO
+  VM_OC_RESOURCE_NAME = VM_OC_NONE,           /**< resource name of the current function is unused */
+  VM_OC_LINE = VM_OC_NONE,                    /**< line number of the next statement is unused */
+#endif /* !JERRY_ENABLE_LINE_INFO */
+#ifdef CONFIG_DISABLE_ES2015_CLASS
+  VM_OC_CLASS_HERITAGE = VM_OC_NONE,          /**< create a super class context */
+  VM_OC_CLASS_INHERITANCE = VM_OC_NONE,       /**< inherit properties from the 'super' class */
+  VM_OC_PUSH_CLASS_CONSTRUCTOR = VM_OC_NONE,  /**< push class constructor */
+  VM_OC_SET_CLASS_CONSTRUCTOR = VM_OC_NONE,   /**< set class constructor to the given function literal */
+  VM_OC_PUSH_IMPL_CONSTRUCTOR = VM_OC_NONE,   /**< create implicit class constructor */
+  VM_OC_CLASS_EXPR_CONTEXT_END = VM_OC_NONE,  /**< class expression heritage context end */
+  VM_OC_CLASS_EVAL = VM_OC_NONE,              /**< eval inside a class */
+  VM_OC_SUPER_CALL = VM_OC_NONE,              /**< call the 'super' constructor */
+  VM_OC_SUPER_PROP_REFERENCE = VM_OC_NONE,    /**< resolve super property reference */
+  VM_OC_PUSH_SUPER = VM_OC_NONE,              /**< push resolvable super reference */
+  VM_OC_PUSH_CONSTRUCTOR_SUPER = VM_OC_NONE,  /**< push 'super' inside a class constructor */
+  VM_OC_PUSH_CONSTRUCTOR_THIS = VM_OC_NONE,   /**< push 'this' inside a class constructor */
+  VM_OC_CONSTRUCTOR_RET = VM_OC_NONE,         /**< explicit return from a class constructor */
+#endif /* CONFIG_DISABLE_ES2015 */
+  VM_OC_UNUSED = VM_OC_NONE                   /**< placeholder if the list is empty */
+} vm_oc_unused_types;
+
 /**
  * Decrement operator.
  */
@@ -234,6 +297,16 @@ typedef enum
  */
 #define VM_OC_LOGICAL_BRANCH_FLAG 0x2
 
+/**
+ * Bit index shift for non-static property initializers.
+ */
+#define VM_OC_NON_STATIC_SHIFT 14
+
+/**
+ * This flag is set for static property initializers.
+ */
+#define VM_OC_NON_STATIC_FLAG (0x1 << VM_OC_NON_STATIC_SHIFT)
+
 /**
  * Position of "put result" opcode.
  */
@@ -275,14 +348,15 @@ typedef enum
 {
   VM_NO_EXEC_OP,                 /**< do nothing */
   VM_EXEC_CALL,                  /**< invoke a function */
+  VM_EXEC_SUPER_CALL,            /**< invoke a function through 'super' keyword */
   VM_EXEC_CONSTRUCT,             /**< construct a new object */
 } vm_call_operation;
 
 ecma_value_t vm_run_global (const ecma_compiled_code_t *bytecode_p);
-ecma_value_t vm_run_eval (ecma_compiled_code_t *bytecode_data_p, bool is_direct);
+ecma_value_t vm_run_eval (ecma_compiled_code_t *bytecode_data_p, uint32_t parse_opts);
 
 ecma_value_t vm_run (const ecma_compiled_code_t *bytecode_header_p, ecma_value_t this_binding_value,
-                     ecma_object_t *lex_env_p, bool is_eval_code, const ecma_value_t *arg_list_p,
+                     ecma_object_t *lex_env_p, uint32_t parse_opts, const ecma_value_t *arg_list_p,
                      ecma_length_t arg_list_len);
 
 bool vm_is_strict_mode (void);
diff --git a/deps/jerry/jerry-debugger/README.md b/deps/jerry/jerry-debugger/README.md
new file mode 100644 (file)
index 0000000..3aab06a
--- /dev/null
@@ -0,0 +1,5 @@
+# Available JerryScript debugger tools
+
+  - JerryScript console debugger client ( jerry_client.py )
+  - IoT.js Code ( https://github.com/Samsung/iotjscode )
+  - JerryScript debugger Chrome webtool ( https://github.com/jerryscript-project/jerryscript-debugger-ts )
diff --git a/deps/jerry/jerry-debugger/jerry-client-ws-html.py b/deps/jerry/jerry-debugger/jerry-client-ws-html.py
deleted file mode 100644 (file)
index b79072c..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-import argparse
-import os
-import webbrowser
-
-
-def main():
-    parser = argparse.ArgumentParser(description="JerryScript debugger client in HTML")
-    parser.add_argument("address", action="store", nargs="?", default="localhost:5001",
-                        help="specify a unique network address for connection (default: %(default)s)")
-    args = parser.parse_args()
-
-    webbrowser.open_new("file://%s?address=%s" % (os.path.abspath("jerry-client-ws.html"), args.address))
-
-
-if __name__ == "__main__":
-    main()
diff --git a/deps/jerry/jerry-debugger/jerry-client-ws.html b/deps/jerry/jerry-debugger/jerry-client-ws.html
deleted file mode 100644 (file)
index 9cc3097..0000000
+++ /dev/null
@@ -1,1555 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="UTF-8">
-<title>
-JerryScript HTML (WebSocket) Debugger Client
-</title>
-<style>
-body {
-  background-color: #feffd6;
-  text-align: center;
-}
-
-input {
-  margin-top: 10px;
-  width: 650px;
-}
-
-textarea {
-  width: 750px;
-  margin-top: 30px;
-  resize: none;
-}
-</style>
-</head>
-<body>
-<h2>JerryScript HTML (WebSocket) Debugger Client</h2>
-<div class="container">
-  <div>
-    <textarea readonly rows="16" id="log"></textarea>
-  </div>
-  <p role="alert">Getting help: type <b>help</b> in the command line below.</p>
-  <div>
-    <input id="command" rows="1" type="text" onkeypress="debuggerCommand(event); return true;">
-  <div>
-</div>
-<script>
-// Expected JerryScript debugger protocol version
-var JERRY_DEBUGGER_VERSION = 3;
-
-// Messages sent by the server to client.
-var JERRY_DEBUGGER_CONFIGURATION = 1;
-var JERRY_DEBUGGER_PARSE_ERROR = 2;
-var JERRY_DEBUGGER_BYTE_CODE_CP = 3;
-var JERRY_DEBUGGER_PARSE_FUNCTION = 4;
-var JERRY_DEBUGGER_BREAKPOINT_LIST = 5;
-var JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST = 6;
-var JERRY_DEBUGGER_SOURCE_CODE = 7;
-var JERRY_DEBUGGER_SOURCE_CODE_END = 8;
-var JERRY_DEBUGGER_SOURCE_CODE_NAME = 9;
-var JERRY_DEBUGGER_SOURCE_CODE_NAME_END = 10;
-var JERRY_DEBUGGER_FUNCTION_NAME = 11;
-var JERRY_DEBUGGER_FUNCTION_NAME_END = 12;
-var JERRY_DEBUGGER_WAITING_AFTER_PARSE = 13;
-var JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 14;
-var JERRY_DEBUGGER_MEMSTATS_RECEIVE = 15;
-var JERRY_DEBUGGER_BREAKPOINT_HIT = 16;
-var JERRY_DEBUGGER_EXCEPTION_HIT = 17;
-var JERRY_DEBUGGER_EXCEPTION_STR = 18;
-var JERRY_DEBUGGER_EXCEPTION_STR_END = 19;
-var JERRY_DEBUGGER_BACKTRACE = 20;
-var JERRY_DEBUGGER_BACKTRACE_END = 21;
-var JERRY_DEBUGGER_EVAL_RESULT = 22;
-var JERRY_DEBUGGER_EVAL_RESULT_END = 23;
-var JERRY_DEBUGGER_WAIT_FOR_SOURCE = 24;
-var JERRY_DEBUGGER_OUTPUT_RESULT = 25;
-var JERRY_DEBUGGER_OUTPUT_RESULT_END = 26;
-
-// Subtypes of eval
-JERRY_DEBUGGER_EVAL_EVAL = "\0"
-JERRY_DEBUGGER_EVAL_THROW = "\1"
-JERRY_DEBUGGER_EVAL_ABORT = "\2"
-
-// Subtypes of eval result
-var JERRY_DEBUGGER_EVAL_OK = 1;
-var JERRY_DEBUGGER_EVAL_ERROR = 2;
-
-// Subtypes of output result
-var JERRY_DEBUGGER_OUTPUT_OK = 1;
-var JERRY_DEBUGGER_OUTPUT_ERROR = 2;
-var JERRY_DEBUGGER_OUTPUT_WARNING = 3;
-var JERRY_DEBUGGER_OUTPUT_DEBUG = 4;
-var JERRY_DEBUGGER_OUTPUT_TRACE = 5;
-
-// Messages sent by the client to server.
-var JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1;
-var JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2;
-var JERRY_DEBUGGER_EXCEPTION_CONFIG = 3;
-var JERRY_DEBUGGER_PARSER_CONFIG = 4;
-var JERRY_DEBUGGER_MEMSTATS = 5;
-var JERRY_DEBUGGER_STOP = 6;
-var JERRY_DEBUGGER_PARSER_RESUME = 7;
-var JERRY_DEBUGGER_CLIENT_SOURCE = 8;
-var JERRY_DEBUGGER_CLIENT_SOURCE_PART = 9;
-var JERRY_DEBUGGER_NO_MORE_SOURCES = 10;
-var JERRY_DEBUGGER_CONTEXT_RESET = 11;
-var JERRY_DEBUGGER_CONTINUE = 12;
-var JERRY_DEBUGGER_STEP = 13;
-var JERRY_DEBUGGER_NEXT = 14;
-var JERRY_DEBUGGER_FINISH = 15;
-var JERRY_DEBUGGER_GET_BACKTRACE = 16;
-var JERRY_DEBUGGER_EVAL = 17;
-var JERRY_DEBUGGER_EVAL_PART = 18;
-
-var textBox = document.getElementById("log");
-var commandBox = document.getElementById("command");
-var socket = null;
-
-var address = "localhost";
-var params = window.location.search.slice(1).split("&");
-for (var i = 0; i < params.length; i++)
-{
-  var nv = params[i].split("=");
-  var name = nv[0], value = nv[1];
-  if (name == "address")
-  {
-    address = value;
-  }
-}
-
-textBox.value = ""
-commandBox.value = "connect " + address
-
-function appendLog(str)
-{
-  textBox.value += str + "\n";
-  textBox.scrollTop = textBox.scrollHeight;
-}
-
-var debuggerObj = null;
-
-function DebuggerClient(address)
-{
-  appendLog("ws://" + address + "/jerry-debugger");
-
-  var parseObj = null;
-  var maxMessageSize = 0;
-  var cpointerSize = 0;
-  var littleEndian = true;
-  var functions = { };
-  var lineList = new Multimap();
-  var lastBreakpointHit = null;
-  var activeBreakpoints = { };
-  var nextBreakpointIndex = 1;
-  var pendingBreakpoints = [ ];
-  var backtraceFrame = 0;
-  var evalResult = null;
-  var outputResult = null;
-  var exceptionData = null;
-  var display = 0;
-  var version = 0;
-
-  function assert(expr)
-  {
-    if (!expr)
-    {
-      throw new Error("Assertion failed.");
-    }
-  }
-
-  function setUint32(array, offset, value)
-  {
-    if (littleEndian)
-    {
-      array[offset] = value & 0xff;
-      array[offset + 1] = (value >> 8) & 0xff;
-      array[offset + 2] = (value >> 16) & 0xff;
-      array[offset + 3] = (value >> 24) & 0xff;
-    }
-    else
-    {
-      array[offset] = (value >> 24) & 0xff;
-      array[offset + 1] = (value >> 16) & 0xff;
-      array[offset + 2] = (value >> 8) & 0xff;
-      array[offset + 3] = value & 0xff;
-    }
-  }
-
-  /* Concat the two arrays. The first byte (opcode) of nextArray is ignored. */
-  function concatUint8Arrays(baseArray, nextArray)
-  {
-    if (nextArray.byteLength <= 1)
-    {
-      /* Nothing to append. */
-      return baseArray;
-    }
-
-    if (!baseArray)
-    {
-      /* Cut the first byte (opcode). */
-      return nextArray.slice(1);
-    }
-
-    var baseLength = baseArray.byteLength;
-    var nextLength = nextArray.byteLength - 1;
-
-    var result = new Uint8Array(baseLength + nextLength);
-    result.set(nextArray, baseLength - 1);
-
-    /* This set operation overwrites the opcode. */
-    result.set(baseArray);
-
-    return result;
-  }
-
-  function cesu8ToString(array)
-  {
-    if (!array)
-    {
-      return "";
-    }
-
-    var length = array.byteLength;
-
-    var i = 0;
-    var result = "";
-
-    while (i < length)
-    {
-      var chr = array[i];
-
-      ++i;
-
-      if (chr >= 0x7f)
-      {
-        if (chr & 0x20)
-        {
-          /* Three byte long character. */
-          chr = ((chr & 0xf) << 12) | ((array[i] & 0x3f) << 6) | (array[i + 1] & 0x3f);
-          i += 2;
-        }
-        else
-        {
-          /* Two byte long character. */
-          chr = ((chr & 0x1f) << 6) | (array[i] & 0x3f);
-          ++i;
-        }
-      }
-
-      result += String.fromCharCode(chr);
-    }
-
-    return result;
-  }
-
-  function stringToCesu8(string)
-  {
-    assert(string != "");
-
-    var length = string.length;
-    var byteLength = length;
-
-    for (var i = 0; i < length; i++)
-    {
-      var chr = string.charCodeAt(i);
-
-      if (chr > 0x7ff)
-      {
-        byteLength++;
-      }
-
-      if (chr >= 0x7f)
-      {
-        byteLength++;
-      }
-    }
-
-    var result = new Uint8Array(byteLength + 1 + 4);
-
-    result[0] = JERRY_DEBUGGER_EVAL;
-
-    setUint32(result, 1, byteLength);
-
-    var offset = 5;
-
-    for (var i = 0; i < length; i++)
-    {
-      var chr = string.charCodeAt(i);
-
-      if (chr > 0x7ff)
-      {
-        result[offset] = 0xe0 | (chr >> 12);
-        result[offset + 1] = 0x80 | ((chr >> 6) & 0x3f);
-        result[offset + 2] = 0x80 | (chr & 0x3f);
-        offset += 3;
-      }
-      else if (chr >= 0x7f)
-      {
-        result[offset] = 0xc0 | (chr >> 6);
-        result[offset + 1] = 0x80 | (chr & 0x3f);
-      }
-      else
-      {
-        result[offset] = chr;
-        offset++;
-      }
-    }
-
-    return result;
-  }
-
-  function breakpointToString(breakpoint)
-  {
-    var name = breakpoint.func.name;
-
-    var result = breakpoint.func.sourceName;
-
-    if (!result)
-    {
-      result = "<unknown>";
-    }
-
-    result += ":" + breakpoint.line;
-
-    if (breakpoint.func.is_func)
-    {
-      result += " (in "
-                + (breakpoint.func.name ? breakpoint.func.name : "function")
-                + "() at line:"
-                + breakpoint.func.line
-                + ", col:"
-                + breakpoint.func.column
-                + ")";
-    }
-
-    return result;
-  }
-
-  function Multimap()
-  {
-    /* Each item is an array of items. */
-
-    var map = { };
-
-    this.get = function(key)
-    {
-      var item = map[key];
-      return item ? item : [ ];
-    }
-
-    this.insert = function(key, value)
-    {
-      var item = map[key];
-
-      if (item)
-      {
-        item.push(value);
-        return;
-      }
-
-      map[key] = [ value ];
-    }
-
-    this.delete = function(key, value)
-    {
-      var array = map[key];
-
-      assert(array);
-
-      var newLength = array.length - 1;
-      var i = array.indexOf(value);
-
-      assert(i != -1);
-
-      array.splice(i, 1);
-      array.length = newLength;
-    }
-  }
-
-  var socket = new WebSocket("ws://" + address + "/jerry-debugger");
-  socket.binaryType = 'arraybuffer';
-
-  function abortConnection(message)
-  {
-    assert(socket && debuggerObj);
-
-    socket.close();
-    socket = null;
-    debuggerObj = null;
-
-    appendLog("Abort connection: " + message);
-    throw new Error(message);
-  }
-
-  socket.onerror = function(event)
-  {
-    if (socket)
-    {
-      socket = null;
-      debuggerObj = null;
-      appendLog("Connection closed.");
-    }
-  }
-  socket.onclose = socket.onerror;
-
-  socket.onopen = function(event)
-  {
-    appendLog("Connection created.");
-  }
-
-  function getFormatSize(format)
-  {
-    var length = 0;
-
-    for (var i = 0; i < format.length; i++)
-    {
-      if (format[i] == "B")
-      {
-        length++;
-        continue;
-      }
-
-      if (format[i] == "C")
-      {
-        length += cpointerSize;
-        continue;
-      }
-
-      assert(format[i] == "I")
-
-      length += 4;
-    }
-
-    return length;
-  }
-
-  function decodeMessage(format, message, offset)
-  {
-    /* Format: B=byte I=int32 C=cpointer.
-     * Returns an array of decoded numbers. */
-
-    var result = []
-    var value;
-
-    if (!offset)
-    {
-      offset = 0;
-    }
-
-    if (offset + getFormatSize(format) > message.byteLength)
-    {
-      abortConnection("received message too short.");
-    }
-
-    for (var i = 0; i < format.length; i++)
-    {
-      if (format[i] == "B")
-      {
-        result.push(message[offset])
-        offset++;
-        continue;
-      }
-
-      if (format[i] == "C" && cpointerSize == 2)
-      {
-        if (littleEndian)
-        {
-          value = message[offset] | (message[offset + 1] << 8);
-        }
-        else
-        {
-          value = (message[offset] << 8) | message[offset + 1];
-        }
-
-        result.push(value);
-        offset += 2;
-        continue;
-      }
-
-      assert(format[i] == "I" || (format[i] == "C" && cpointerSize == 4));
-
-      if (littleEndian)
-      {
-        value = (message[offset] | (message[offset + 1] << 8)
-                 | (message[offset + 2] << 16) | (message[offset + 3] << 24));
-      }
-      else
-      {
-        value = ((message[offset] << 24) | (message[offset + 1] << 16)
-                 | (message[offset + 2] << 8) | message[offset + 3] << 24);
-      }
-
-      result.push(value);
-      offset += 4;
-    }
-
-    return result;
-  }
-
-  function encodeMessage(format, values)
-  {
-    /* Format: B=byte I=int32 C=cpointer.
-     * Sends a message after the encoding is completed. */
-
-    var length = getFormatSize(format);
-    var message = new Uint8Array(length);
-    var offset = 0;
-
-    for (var i = 0; i < format.length; i++)
-    {
-      var value = values[i];
-
-      if (format[i] == "B")
-      {
-        message[offset] = value;
-        offset++;
-        continue;
-      }
-
-      if (format[i] == "C" && cpointerSize == 2)
-      {
-        if (littleEndian)
-        {
-          message[offset] = value & 0xff;
-          message[offset + 1] = (value >> 8) & 0xff;
-        }
-        else
-        {
-          message[offset] = (value >> 8) & 0xff;
-          message[offset + 1] = value & 0xff;
-        }
-
-        offset += 2;
-        continue;
-      }
-
-      setUint32(message, offset, value);
-      offset += 4;
-    }
-
-    socket.send(message);
-  }
-
-  function releaseFunction(message)
-  {
-    var byte_code_cp = decodeMessage("C", message, 1)[0];
-    var func = functions[byte_code_cp];
-
-    for (var i in func.lines)
-    {
-      lineList.delete(i, func);
-
-      var breakpoint = func.lines[i];
-
-      assert(i == breakpoint.line);
-
-      if (breakpoint.activeIndex >= 0)
-      {
-        delete activeBreakpoints[breakpoint.activeIndex];
-      }
-    }
-
-    delete functions[byte_code_cp];
-
-    message[0] = JERRY_DEBUGGER_FREE_BYTE_CODE_CP;
-    socket.send(message);
-  }
-
-  function getBreakpoint(breakpointData)
-  {
-    var returnValue = {};
-    var func = functions[breakpointData[0]];
-    var offset = breakpointData[1];
-
-    if (offset in func.offsets)
-    {
-      returnValue.breakpoint = func.offsets[offset];
-      returnValue.at = true;
-      return returnValue;
-    }
-
-    if (offset < func.firstBreakpointOffset)
-    {
-      returnValue.breakpoint = func.offsets[func.firstBreakpointOffset];
-      returnValue.at = true;
-      return returnValue;
-    }
-
-    nearest_offset = -1;
-
-    for (var current_offset in func.offsets)
-    {
-      if ((current_offset <= offset) && (current_offset > nearest_offset))
-      {
-        nearest_offset = current_offset;
-      }
-    }
-
-    returnValue.breakpoint = func.offsets[nearest_offset];
-    returnValue.at = false;
-    return returnValue;
-  }
-
-  this.encodeMessage = encodeMessage;
-
-  function ParseSource()
-  {
-    var source = "";
-    var sourceData = null;
-    var sourceName = "";
-    var sourceNameData = null;
-    var functionName = null;
-    var stack = [{ is_func: false,
-                   line: 1,
-                   column: 1,
-                   name: "",
-                   source: "",
-                   lines: [],
-                   offsets: [] }];
-    var newFunctions = { };
-
-    this.receive = function(message)
-    {
-      switch (message[0])
-      {
-        case JERRY_DEBUGGER_PARSE_ERROR:
-        {
-          /* Parse error occured in JerryScript. */
-          parseObj = null;
-          return;
-        }
-
-        case JERRY_DEBUGGER_SOURCE_CODE:
-        case JERRY_DEBUGGER_SOURCE_CODE_END:
-        {
-          sourceData = concatUint8Arrays(sourceData, message);
-
-          if (message[0] == JERRY_DEBUGGER_SOURCE_CODE_END)
-          {
-            source = cesu8ToString(sourceData);
-          }
-          return;
-        }
-
-        case JERRY_DEBUGGER_SOURCE_CODE_NAME:
-        case JERRY_DEBUGGER_SOURCE_CODE_NAME_END:
-        {
-          sourceNameData = concatUint8Arrays(sourceNameData, message);
-
-          if (message[0] == JERRY_DEBUGGER_SOURCE_CODE_NAME_END)
-          {
-            sourceName = cesu8ToString(sourceNameData);
-          }
-          return;
-        }
-
-        case JERRY_DEBUGGER_FUNCTION_NAME:
-        case JERRY_DEBUGGER_FUNCTION_NAME_END:
-        {
-          functionName = concatUint8Arrays(functionName, message);
-          return;
-        }
-
-        case JERRY_DEBUGGER_PARSE_FUNCTION:
-        {
-          position = decodeMessage("II", message, 1);
-
-          stack.push({ is_func: true,
-                       line: position[0],
-                       column: position[1],
-                       name: cesu8ToString(functionName),
-                       source: source,
-                       sourceName: sourceName,
-                       lines: [],
-                       offsets: [] });
-          functionName = null;
-          return;
-        }
-
-        case JERRY_DEBUGGER_BREAKPOINT_LIST:
-        case JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST:
-        {
-          var array;
-
-          if (message.byteLength < 1 + 4)
-          {
-            abortConnection("message too short.");
-          }
-
-          if (message[0] == JERRY_DEBUGGER_BREAKPOINT_LIST)
-          {
-            array = stack[stack.length - 1].lines;
-          }
-          else
-          {
-            array = stack[stack.length - 1].offsets;
-          }
-
-          for (var i = 1; i < message.byteLength; i += 4)
-          {
-            array.push(decodeMessage("I", message, i)[0]);
-          }
-          return;
-        }
-
-        case JERRY_DEBUGGER_BYTE_CODE_CP:
-        {
-          var func = stack.pop();
-          func.byte_code_cp = decodeMessage("C", message, 1)[0];
-
-          lines = {}
-          offsets = {}
-
-          func.firstBreakpointLine = func.lines[0];
-          func.firstBreakpointOffset = func.offsets[0];
-
-          for (var i = 0; i < func.lines.length; i++)
-          {
-            var breakpoint = { line: func.lines[i], offset: func.offsets[i], func: func, activeIndex: -1 };
-
-            lines[breakpoint.line] = breakpoint;
-            offsets[breakpoint.offset] = breakpoint;
-          }
-
-          func.lines = lines;
-          func.offsets = offsets;
-
-          newFunctions[func.byte_code_cp] = func;
-
-          if (stack.length > 0)
-          {
-            return;
-          }
-
-          func.source = source.split(/\r\n|[\r\n]/);
-          func.sourceName = sourceName;
-          break;
-        }
-
-        case JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP:
-        {
-          var byte_code_cp = decodeMessage("C", message, 1)[0];
-
-          if (byte_code_cp in newFunctions)
-          {
-            delete newFunctions[byte_code_cp];
-          }
-          else
-          {
-            releaseFunction(message);
-          }
-          return;
-        }
-
-        default:
-        {
-          abortConnection("unexpected message.");
-          return;
-        }
-      }
-
-      for (var i in newFunctions)
-      {
-        var func = newFunctions[i];
-
-        functions[i] = func;
-
-        for (var j in func.lines)
-        {
-          lineList.insert(j, func);
-        }
-      }
-
-      if (pendingBreakpoints.length != 0)
-      {
-        appendLog("Available pending breakpoints");
-
-        for (var i in pendingBreakpoints)
-        {
-          if (Number.isInteger(pendingBreakpoints[i]))
-          {
-            pendingBreakpoints[i] = sourceName + ":" + pendingBreakpoints[i];
-          }
-          appendLog("Try to add: " + pendingBreakpoints[i]);
-          debuggerObj.setBreakpoint(pendingBreakpoints[i], false);
-        }
-      }
-      else
-      {
-        appendLog("No pending breakpoints");
-      }
-
-      parseObj = null;
-    }
-  }
-
-  socket.onmessage = function(event)
-  {
-    var message = new Uint8Array(event.data);
-
-    if (message.byteLength < 1)
-    {
-      abortConnection("message too short.");
-    }
-
-    if (cpointerSize == 0)
-    {
-      if (message[0] != JERRY_DEBUGGER_CONFIGURATION
-          || message.byteLength != 5)
-      {
-        abortConnection("the first message must be configuration.");
-      }
-
-      maxMessageSize = message[1]
-      cpointerSize = message[2]
-      littleEndian = (message[3] != 0);
-
-      version = message[4];
-
-      if (cpointerSize != 2 && cpointerSize != 4)
-      {
-        abortConnection("compressed pointer must be 2 or 4 byte long.");
-      }
-
-      if (version != JERRY_DEBUGGER_VERSION)
-      {
-        abortConnection("incorrect target debugger version detected: "
-                        + version + " expected: " + JERRY_DEBUGGER_VERSION);
-      }
-
-      config = false;
-      return;
-    }
-
-    if (parseObj)
-    {
-      parseObj.receive(message)
-      return;
-    }
-
-    switch (message[0])
-    {
-      case JERRY_DEBUGGER_PARSE_ERROR:
-      case JERRY_DEBUGGER_BYTE_CODE_CP:
-      case JERRY_DEBUGGER_PARSE_FUNCTION:
-      case JERRY_DEBUGGER_BREAKPOINT_LIST:
-      case JERRY_DEBUGGER_SOURCE_CODE:
-      case JERRY_DEBUGGER_SOURCE_CODE_END:
-      case JERRY_DEBUGGER_SOURCE_CODE_NAME:
-      case JERRY_DEBUGGER_SOURCE_CODE_NAME_END:
-      case JERRY_DEBUGGER_FUNCTION_NAME:
-      case JERRY_DEBUGGER_FUNCTION_NAME_END:
-      {
-        parseObj = new ParseSource()
-        parseObj.receive(message)
-        return;
-      }
-
-      case JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP:
-      {
-        releaseFunction(message);
-        return;
-      }
-
-      case JERRY_DEBUGGER_MEMSTATS_RECEIVE:
-      {
-        var messagedata = decodeMessage("IIIII", message, 1);
-
-        appendLog("Allocated bytes: " + messagedata[0]);
-        appendLog("Byte code bytes: " + messagedata[1]);
-        appendLog("String bytes: " + messagedata[2]);
-        appendLog("Object bytes: " + messagedata[3]);
-        appendLog("Property bytes: " + messagedata[4]);
-        return;
-      }
-
-      case JERRY_DEBUGGER_BREAKPOINT_HIT:
-      case JERRY_DEBUGGER_EXCEPTION_HIT:
-      {
-        var breakpointData = decodeMessage("CI", message, 1);
-        var breakpointRef = getBreakpoint(breakpointData);
-        var breakpoint = breakpointRef.breakpoint;
-
-        if (message[0] == JERRY_DEBUGGER_EXCEPTION_HIT)
-        {
-          appendLog("Exception throw detected (to disable automatic stop type exception 0)");
-          if (exceptionData)
-          {
-            appendLog("Exception hint: " + cesu8ToString(exceptionData));
-            exceptionData = null;
-          }
-        }
-
-        lastBreakpointHit = breakpoint;
-
-        var breakpointInfo = "";
-        if (breakpoint.offset.activeIndex >= 0)
-        {
-          breakpointInfo = " breakpoint:" + breakpoint.offset.activeIndex + " ";
-        }
-
-        appendLog("Stopped "
-                  + (breakpoint.at ? "at " : "around ")
-                  + breakpointInfo
-                  + breakpointToString(breakpoint));
-
-        if (debuggerObj.display)
-        {
-          debuggerObj.printSource(debuggerObj.display);
-        }
-        return;
-      }
-
-      case JERRY_DEBUGGER_EXCEPTION_STR:
-      case JERRY_DEBUGGER_EXCEPTION_STR_END:
-      {
-        exceptionData = concatUint8Arrays(exceptionData, message);
-        return;
-      }
-
-      case JERRY_DEBUGGER_BACKTRACE:
-      case JERRY_DEBUGGER_BACKTRACE_END:
-      {
-        for (var i = 1; i < message.byteLength; i += cpointerSize + 4)
-        {
-          var breakpointData = decodeMessage("CI", message, i);
-
-          breakpoint = getBreakpoint(breakpointData).breakpoint;
-
-          appendLog("  frame "
-                    + backtraceFrame
-                    + ": "
-                    + breakpointToString(breakpoint));
-
-          ++backtraceFrame;
-        }
-
-        if (message[0] == JERRY_DEBUGGER_BACKTRACE_END)
-        {
-          backtraceFrame = 0;
-        }
-        return;
-      }
-
-      case JERRY_DEBUGGER_EVAL_RESULT:
-      case JERRY_DEBUGGER_EVAL_RESULT_END:
-      {
-        evalResult = concatUint8Arrays(evalResult, message);
-        var subType = evalResult[evalResult.length - 1];
-        evalResult = evalResult.slice(0, -1);
-        if (subType == JERRY_DEBUGGER_EVAL_OK)
-        {
-          appendLog(cesu8ToString(evalResult));
-          evalResult = null;
-          return;
-        }
-
-        if (subType == JERRY_DEBUGGER_EVAL_ERROR)
-        {
-          appendLog("Uncaught exception: " + cesu8ToString(evalResult));
-          evalResult = null;
-          return;
-        }
-
-        return;
-      }
-      case JERRY_DEBUGGER_OUTPUT_RESULT:
-      case JERRY_DEBUGGER_OUTPUT_RESULT_END:
-      {
-        outputResult = concatUint8Arrays(outputResult, message);
-
-        if (message[0] == JERRY_DEBUGGER_OUTPUT_RESULT_END)
-        {
-          var subType = outputResult[outputResult.length - 1];
-          var outString;
-          outputResult = outputResult.slice(0, -1);
-
-          switch (subType)
-          {
-            case JERRY_DEBUGGER_OUTPUT_OK:
-            case JERRY_DEBUGGER_OUTPUT_DEBUG:
-              outString = "out: " + cesu8ToString(outputResult);
-              break;
-            case JERRY_DEBUGGER_OUTPUT_WARNING:
-              outString = "warning: " + cesu8ToString(outputResult);
-              break;
-            case JERRY_DEBUGGER_OUTPUT_ERROR:
-              outString = "err: " + cesu8ToString(outputResult);
-              break;
-            case JERRY_DEBUGGER_OUTPUT_TRACE:
-              outString = "trace: " + cesu8ToString(outputResult);
-              break;
-          }
-
-          appendLog(outString);
-          outputResult = null;
-        }
-
-        return;
-      }
-
-      case JERRY_DEBUGGER_WAIT_FOR_SOURCE:
-      {
-        // This message does not have effect in this client.
-        return;
-      }
-
-      default:
-      {
-        abortConnection("unexpected message.");
-        return;
-      }
-    }
-  }
-
-  function insertBreakpoint(breakpoint)
-  {
-    if (breakpoint.activeIndex < 0)
-    {
-      breakpoint.activeIndex = nextBreakpointIndex;
-      activeBreakpoints[nextBreakpointIndex] = breakpoint;
-      nextBreakpointIndex++;
-
-      var values = [ JERRY_DEBUGGER_UPDATE_BREAKPOINT,
-                     1,
-                     breakpoint.func.byte_code_cp,
-                     breakpoint.offset ];
-
-      encodeMessage("BBCI", values);
-    }
-
-    appendLog("Breakpoint " + breakpoint.activeIndex + " at " + breakpointToString(breakpoint));
-  }
-
-  this.setBreakpoint = function(str, pending)
-  {
-    line = /^(.+):([1-9][0-9]*)$/.exec(str);
-    var found = false;
-
-    if (line)
-    {
-      var functionList = lineList.get(line[2]);
-
-      for (var i = 0; i < functionList.length; ++i)
-      {
-        var func = functionList[i];
-        var sourceName = func.sourceName;
-
-        if (sourceName == line[1]
-            || sourceName.endsWith("/" + line[1])
-            || sourceName.endsWith("\\" + line[1]))
-        {
-          insertBreakpoint(func.lines[line[2]]);
-          found = true;
-        }
-      }
-    }
-    else
-    {
-      for (var i in functions)
-      {
-        var func = functions[i];
-
-        if (func.name == str)
-        {
-          insertBreakpoint(func.lines[func.firstBreakpointLine]);
-          found = true;
-        }
-      }
-    }
-    if (!found)
-    {
-      appendLog("Breakpoint not found");
-      if (pending)
-      {
-        if (line)
-        {
-          pendingBreakpoints.push(Number(line[2]));
-          appendLog("Pending breakpoint index: " + line[0] + " added");
-        }
-        else
-        {
-          pendingBreakpoints.push(str);
-          appendLog("Pending breakpoint function name: " + str + " added");
-        }
-      }
-    }
-  }
-
-  this.sendExceptionConfig = function(enable)
-  {
-    if (enable == "")
-    {
-      appendLog("Argument required");
-      return;
-    }
-
-    if (enable == 1)
-    {
-      appendLog("Stop at exception enabled");
-    }
-    else if (enable == 0)
-    {
-      appendLog("Stop at exception disabled");
-    }
-    else
-    {
-      appendLog("Invalid input. Usage 1: [Enable] or 0: [Disable].");
-      return;
-    }
-
-    encodeMessage("BB", [ JERRY_DEBUGGER_EXCEPTION_CONFIG, enable ]);
-  }
-
-  this.deleteBreakpoint = function(index)
-  {
-    breakpoint = activeBreakpoints[index];
-
-    if (index == "all")
-    {
-      var found = false;
-
-      for (var i in activeBreakpoints)
-      {
-        delete activeBreakpoints[i];
-        found = true;
-      }
-
-      if (!found)
-      {
-        appendLog("No active breakpoints.")
-      }
-    }
-
-    else if (!breakpoint)
-    {
-      appendLog("No breakpoint found with index " + index);
-      return;
-    }
-
-    assert(breakpoint.activeIndex == index);
-
-    delete activeBreakpoints[index];
-    breakpoint.activeIndex = -1;
-
-    var values = [ JERRY_DEBUGGER_UPDATE_BREAKPOINT,
-                   0,
-                   breakpoint.func.byte_code_cp,
-                   breakpoint.offset ];
-
-    encodeMessage("BBCI", values);
-
-    appendLog("Breakpoint " + index + " is deleted.");
-  }
-
-  this.deletePendingBreakpoint = function(index)
-  {
-    if (index >= pendingBreakpoints.length)
-    {
-      appendLog("Pending breakpoint not found");
-    }
-    else
-    {
-      pendingBreakpoints.splice(index, 1);
-      appendLog("Pending breakpoint " + index + " is deleted.");
-    }
-  }
-
-  this.listBreakpoints = function()
-  {
-    appendLog("List of active breakpoints:");
-    var found = false;
-
-    for (var i in activeBreakpoints)
-    {
-      appendLog("  breakpoint " + i + " at " + breakpointToString(activeBreakpoints[i]));
-      found = true;
-    }
-
-    if (!found)
-    {
-      appendLog("  no active breakpoints");
-    }
-
-    if (pendingBreakpoints.length != 0)
-    {
-      appendLog("List of pending breakpoints:");
-      for (var i in pendingBreakpoints)
-      {
-        appendLog("  pending breakpoint " + i + " at " + pendingBreakpoints[i]);
-      }
-    }
-    else {
-      appendLog("No pending breakpoints");
-    }
-  }
-
-  this.sendResumeExec = function(command)
-  {
-    if (!lastBreakpointHit)
-    {
-      appendLog("This command is allowed only if JavaScript execution is stopped at a breakpoint.");
-      return;
-    }
-
-    encodeMessage("B", [ command ]);
-
-    lastBreakpointHit = null;
-  }
-
-  this.sendGetBacktrace = function(depth)
-  {
-    if (!lastBreakpointHit)
-    {
-      appendLog("This command is allowed only if JavaScript execution is stopped at a breakpoint.");
-      return;
-    }
-
-    encodeMessage("BI", [ JERRY_DEBUGGER_GET_BACKTRACE, max_depth ]);
-
-    appendLog("Backtrace:");
-  }
-
-  this.sendEval = function(str)
-  {
-    if (!lastBreakpointHit)
-    {
-      appendLog("This command is allowed only if JavaScript execution is stopped at a breakpoint.");
-      return;
-    }
-
-    if (str == "")
-    {
-      appendLog("Argument required");
-      return;
-    }
-
-    var array = stringToCesu8(JERRY_DEBUGGER_EVAL_EVAL + str);
-    var byteLength = array.byteLength;
-
-    if (byteLength <= maxMessageSize)
-    {
-      socket.send(array);
-      return;
-    }
-
-    socket.send(array.slice(0, maxMessageSize));
-
-    var offset = maxMessageSize - 1;
-
-    while (offset < byteLength)
-    {
-      array[offset] = JERRY_DEBUGGER_EVAL_PART;
-      socket.send(array.slice(offset, offset + maxMessageSize));
-      offset += maxMessageSize - 1;
-    }
-  }
-
-  this.printSource = function(line_num)
-  {
-    if (!lastBreakpointHit)
-      return;
-
-    lines = lastBreakpointHit.func.source;
-    if (line_num === 0)
-    {
-      var start = 0;
-      var end = lastBreakpointHit.func.source.length - 1;
-    }
-    else
-    {
-      var start = Math.max(lastBreakpointHit.line - line_num, 0)
-      var end = Math.min(lastBreakpointHit.line + line_num - 1,
-                         lastBreakpointHit.func.source.length - 1)
-    }
-
-    if (lastBreakpointHit.func.sourceName)
-      appendLog("Source: " + lastBreakpointHit.func.sourceName);
-
-    for (i = start; i < end; i++)
-    {
-      var str = (i + 1).toString();
-      while (str.length < 4)
-      {
-        str = " " + str;
-      }
-
-      if (i == lastBreakpointHit.line - 1)
-      {
-        appendLog(str + " > " + lines[i]);
-      }
-      else
-      {
-        appendLog(str + "   " + lines[i]);
-      }
-    }
-  }
-
-  this.srcCheckArgs = function(line_num)
-  {
-    line_num = parseInt(line_num);
-    if (isNaN(line_num) || line_num < 0)
-    {
-      appendLog("Non-negative integer number expected");
-      return -1;
-    }
-    else
-    {
-      return line_num;
-    }
-  }
-
-  this.dump = function()
-  {
-    for (var i in functions)
-    {
-      var func = functions[i];
-      var sourceName = func.sourceName;
-
-      if (!sourceName)
-      {
-        sourceName = "<unknown>";
-      }
-
-      appendLog("Function 0x"
-                + Number(i).toString(16)
-                + " '"
-                + func.name
-                + "' at "
-                + sourceName
-                + ":"
-                + func.line
-                + ","
-                + func.column);
-
-      for (var j in func.lines)
-      {
-        var active = "";
-
-        if (func.lines[j].active >= 0)
-        {
-          active = " (active: " + func.lines[j].active + ")";
-        }
-
-        appendLog("  Breakpoint line: " + j + " at memory offset: " + func.lines[j].offset + active);
-      }
-    }
-  }
-}
-
-function debuggerCommand(event)
-{
-  if (event.keyCode != 13)
-  {
-    return true;
-  }
-
-  var command = commandBox.value.trim();
-
-  args = /^([a-zA-Z]+)(?:\s+([^\s].*)|)$/.exec(command);
-
-  if (!args)
-  {
-    appendLog("Invalid command");
-    document.getElementById("command").value = "";
-    return true;
-  }
-
-  if (!args[2])
-  {
-    args[2] = "";
-  }
-
-  if (args[1] == "help")
-  {
-    appendLog("Debugger commands:\n" +
-              "  connect <IP address:PORT> - connect to server (default is localhost:5001)\n" +
-              "  break|b <file_name:line>|<function_name> - set breakpoint\n" +
-              "  fbreak <file_name:line>|<function_name> - set breakpoint if not found, add to pending list\n" +
-              "  delete|d <id> - delete breakpoint\n" +
-              "  pendingdel <id> - delete pending breakpoint\n" +
-              "  list - list breakpoints\n" +
-              "  continue|c - continue execution\n" +
-              "  step|s - step-in execution\n" +
-              "  next|n - execution until the next breakpoint\n" +
-              "  finish|f - continue running until the current function returns\n" +
-              "  eval|e - evaluate expression\n" +
-              "  backtrace|bt <max-depth> - get backtrace\n" +
-              "  src - print current source code\n" +
-              "  dump - dump all breakpoint data");
-
-    commandBox.value = "";
-    return true;
-  }
-
-  if (args[1] == "connect")
-  {
-    if (debuggerObj)
-    {
-      appendLog("Debugger is connected");
-      return true;
-    }
-
-    var ipAddr = args[2];
-    var PORT = "5001";
-
-    if (ipAddr == "")
-    {
-      ipAddr = "localhost";
-    }
-
-    if (ipAddr.match(/.*:\d/))
-    {
-      var fields = ipAddr.split(":");
-      ipAddr = fields[0];
-      PORT = fields[1];
-    }
-
-    var address = ipAddr + ":" + PORT;
-
-    appendLog("Connect to: " + address);
-
-    debuggerObj = new DebuggerClient(address);
-
-    commandBox.value = "";
-    return true;
-  }
-
-  if (!debuggerObj)
-  {
-    appendLog("Debugger is NOT connected");
-
-    commandBox.value = "";
-    return true;
-  }
-
-  switch(args[1])
-  {
-    case "b":
-    case "break":
-      debuggerObj.setBreakpoint(args[2], false);
-      break;
-
-    case "fbreak":
-      debuggerObj.setBreakpoint(args[2], true);
-      break;
-
-    case "d":
-    case "delete":
-      debuggerObj.deleteBreakpoint(args[2]);
-      break;
-
-    case "pendingdel":
-      debuggerObj.deletePendingBreakpoint(args[2]);
-
-    case "st":
-    case "stop":
-      debuggerObj.encodeMessage("B", [ JERRY_DEBUGGER_STOP ]);
-      break;
-
-    case "ms":
-    case "memstats":
-      debuggerObj.encodeMessage("B", [ JERRY_DEBUGGER_MEMSTATS ]);
-      break;
-
-    case "c":
-    case "continue":
-      debuggerObj.sendResumeExec(JERRY_DEBUGGER_CONTINUE);
-      break;
-
-    case "s":
-    case "step":
-      debuggerObj.sendResumeExec(JERRY_DEBUGGER_STEP);
-      break;
-
-    case "n":
-    case "next":
-      debuggerObj.sendResumeExec(JERRY_DEBUGGER_NEXT);
-      break;
-
-    case "f":
-    case "finish":
-      debuggerObj.sendResumeExec(JERRY_DEBUGGER_FINISH);
-      break;
-
-    case "e":
-    case "eval":
-      debuggerObj.sendEval(args[2]);
-      break;
-
-    case "bt":
-    case "backtrace":
-      max_depth = 0;
-
-      if (args[2])
-      {
-        if (/[1-9][0-9]*/.exec(args[2]))
-        {
-          max_depth = parseInt(args[2]);
-        }
-        else
-        {
-          appendLog("Invalid maximum depth argument.");
-          break;
-        }
-      }
-
-      debuggerObj.sendGetBacktrace(max_depth);
-      break;
-
-    case "exception":
-      debuggerObj.sendExceptionConfig(args[2]);
-      break;
-
-    case "source":
-    case "src":
-      if (!args[2])
-      {
-        debuggerObj.printSource(3);
-        break;
-      }
-      var line_num = debuggerObj.srcCheckArgs(args[2]);
-      if (line_num >= 0)
-      {
-        debuggerObj.printSource(line_num);
-        break;
-      }
-      break;
-
-    case "display":
-      if (!args[2])
-      {
-        appendLog("Non-negative integer number expected,\
-                  0 turns off the automatic source code display");
-        break;
-      }
-      var line_num = debuggerObj.srcCheckArgs(args[2]);
-      if (line_num >= 0)
-      {
-        debuggerObj.display = line_num;
-        break;
-      }
-      break;
-
-    case "list":
-      debuggerObj.listBreakpoints();
-      break;
-
-    case "dump":
-      debuggerObj.dump();
-      break;
-
-    default:
-      appendLog("Unknown command: " + args[1]);
-      break;
-  }
-
-  commandBox.value = "";
-  return true;
-}
-
-</script>
-
-</body>
-</html>
diff --git a/deps/jerry/jerry-debugger/jerry-client-ws.py b/deps/jerry/jerry-debugger/jerry-client-ws.py
deleted file mode 100755 (executable)
index c212088..0000000
+++ /dev/null
@@ -1,1305 +0,0 @@
-#!/usr/bin/env python
-
-# 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.
-
-from __future__ import print_function
-from cmd import Cmd
-from pprint import pprint  # For the readable stack printing.
-import argparse
-import logging
-import re
-import select
-import socket
-import struct
-import sys
-import math
-import time
-
-# Expected debugger protocol version.
-JERRY_DEBUGGER_VERSION = 3
-
-# Messages sent by the server to client.
-JERRY_DEBUGGER_CONFIGURATION = 1
-JERRY_DEBUGGER_PARSE_ERROR = 2
-JERRY_DEBUGGER_BYTE_CODE_CP = 3
-JERRY_DEBUGGER_PARSE_FUNCTION = 4
-JERRY_DEBUGGER_BREAKPOINT_LIST = 5
-JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST = 6
-JERRY_DEBUGGER_SOURCE_CODE = 7
-JERRY_DEBUGGER_SOURCE_CODE_END = 8
-JERRY_DEBUGGER_SOURCE_CODE_NAME = 9
-JERRY_DEBUGGER_SOURCE_CODE_NAME_END = 10
-JERRY_DEBUGGER_FUNCTION_NAME = 11
-JERRY_DEBUGGER_FUNCTION_NAME_END = 12
-JERRY_DEBUGGER_WAITING_AFTER_PARSE = 13
-JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 14
-JERRY_DEBUGGER_MEMSTATS_RECEIVE = 15
-JERRY_DEBUGGER_BREAKPOINT_HIT = 16
-JERRY_DEBUGGER_EXCEPTION_HIT = 17
-JERRY_DEBUGGER_EXCEPTION_STR = 18
-JERRY_DEBUGGER_EXCEPTION_STR_END = 19
-JERRY_DEBUGGER_BACKTRACE = 20
-JERRY_DEBUGGER_BACKTRACE_END = 21
-JERRY_DEBUGGER_EVAL_RESULT = 22
-JERRY_DEBUGGER_EVAL_RESULT_END = 23
-JERRY_DEBUGGER_WAIT_FOR_SOURCE = 24
-JERRY_DEBUGGER_OUTPUT_RESULT = 25
-JERRY_DEBUGGER_OUTPUT_RESULT_END = 26
-
-# Subtypes of eval
-JERRY_DEBUGGER_EVAL_EVAL = "\0"
-JERRY_DEBUGGER_EVAL_THROW = "\1"
-JERRY_DEBUGGER_EVAL_ABORT = "\2"
-
-# Subtypes of eval result
-JERRY_DEBUGGER_EVAL_OK = 1
-JERRY_DEBUGGER_EVAL_ERROR = 2
-
-# Subtypes of output
-JERRY_DEBUGGER_OUTPUT_OK = 1
-JERRY_DEBUGGER_OUTPUT_ERROR = 2
-JERRY_DEBUGGER_OUTPUT_WARNING = 3
-JERRY_DEBUGGER_OUTPUT_DEBUG = 4
-JERRY_DEBUGGER_OUTPUT_TRACE = 5
-
-
-# Messages sent by the client to server.
-JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1
-JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2
-JERRY_DEBUGGER_EXCEPTION_CONFIG = 3
-JERRY_DEBUGGER_PARSER_CONFIG = 4
-JERRY_DEBUGGER_MEMSTATS = 5
-JERRY_DEBUGGER_STOP = 6
-JERRY_DEBUGGER_PARSER_RESUME = 7
-JERRY_DEBUGGER_CLIENT_SOURCE = 8
-JERRY_DEBUGGER_CLIENT_SOURCE_PART = 9
-JERRY_DEBUGGER_NO_MORE_SOURCES = 10
-JERRY_DEBUGGER_CONTEXT_RESET = 11
-JERRY_DEBUGGER_CONTINUE = 12
-JERRY_DEBUGGER_STEP = 13
-JERRY_DEBUGGER_NEXT = 14
-JERRY_DEBUGGER_FINISH = 15
-JERRY_DEBUGGER_GET_BACKTRACE = 16
-JERRY_DEBUGGER_EVAL = 17
-JERRY_DEBUGGER_EVAL_PART = 18
-
-MAX_BUFFER_SIZE = 128
-WEBSOCKET_BINARY_FRAME = 2
-WEBSOCKET_FIN_BIT = 0x80
-
-
-def arguments_parse():
-    parser = argparse.ArgumentParser(description="JerryScript debugger client")
-
-    parser.add_argument("address", action="store", nargs="?", default="localhost:5001",
-                        help="specify a unique network address for connection (default: %(default)s)")
-    parser.add_argument("-v", "--verbose", action="store_true", default=False,
-                        help="increase verbosity (default: %(default)s)")
-    parser.add_argument("--non-interactive", action="store_true", default=False,
-                        help="disable stop when newline is pressed (default: %(default)s)")
-    parser.add_argument("--color", action="store_true", default=False,
-                        help="enable color highlighting on source commands (default: %(default)s)")
-    parser.add_argument("--display", action="store", default=None, type=int,
-                        help="set display range")
-    parser.add_argument("--exception", action="store", default=None, type=int, choices=[0, 1],
-                        help="set exception config, usage 1: [Enable] or 0: [Disable]")
-    parser.add_argument("--client-source", action="store", default=[], type=str, nargs="+",
-                        help="specify a javascript source file to execute")
-
-    args = parser.parse_args()
-
-    if args.verbose:
-        logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.DEBUG)
-        logging.debug("Debug logging mode: ON")
-
-    return args
-
-
-class JerryBreakpoint(object):
-
-    def __init__(self, line, offset, function):
-        self.line = line
-        self.offset = offset
-        self.function = function
-        self.active_index = -1
-
-    def __str__(self):
-        result = self.function.source_name or "<unknown>"
-        result += ":%d" % (self.line)
-
-        if self.function.is_func:
-            result += " (in "
-            result += self.function.name or "function"
-            result += "() at line:%d, col:%d)" % (self.function.line, self.function.column)
-        return result
-
-    def __repr__(self):
-        return ("Breakpoint(line:%d, offset:%d, active_index:%d)"
-                % (self.line, self.offset, self.active_index))
-
-class JerryPendingBreakpoint(object):
-    def __init__(self, line=None, source_name=None, function=None):
-        self.function = function
-        self.line = line
-        self.source_name = source_name
-
-        self.index = -1
-
-    def __str__(self):
-        result = self.source_name or ""
-        if self.line:
-            result += ":%d" % (self.line)
-        else:
-            result += "%s()" % (self.function)
-        return result
-
-
-class JerryFunction(object):
-    # pylint: disable=too-many-instance-attributes,too-many-arguments
-    def __init__(self, is_func, byte_code_cp, source, source_name, line, column, name, lines, offsets):
-        self.is_func = is_func
-        self.byte_code_cp = byte_code_cp
-        self.source = re.split("\r\n|[\r\n]", source)
-        self.source_name = source_name
-        self.name = name
-        self.lines = {}
-        self.offsets = {}
-        self.line = line
-        self.column = column
-        self.first_breakpoint_line = lines[0]
-        self.first_breakpoint_offset = offsets[0]
-
-        if len(self.source) > 1 and not self.source[-1]:
-            self.source.pop()
-
-        for i, line in enumerate(lines):
-            offset = offsets[i]
-            breakpoint = JerryBreakpoint(line, offset, self)
-            self.lines[line] = breakpoint
-            self.offsets[offset] = breakpoint
-
-    def __repr__(self):
-        result = ("Function(byte_code_cp:0x%x, source_name:%r, name:%r, line:%d, column:%d { "
-                  % (self.byte_code_cp, self.source_name, self.name, self.line, self.column))
-
-        result += ','.join([str(breakpoint) for breakpoint in self.lines.values()])
-
-        return result + " })"
-
-
-class DebuggerPrompt(Cmd):
-
-    def __init__(self, debugger):
-        Cmd.__init__(self)
-        self.debugger = debugger
-        self.stop = False
-        self.quit = False
-        self.cont = True
-        self.non_interactive = False
-        self.client_sources = []
-
-    def precmd(self, line):
-        self.stop = False
-        self.cont = False
-        if self.non_interactive:
-            print("%s" % line)
-        return line
-
-    def postcmd(self, stop, line):
-        return self.stop
-
-    def do_quit(self, args):
-        """ Exit JerryScript debugger """
-        self.do_delete("all")
-        self.do_exception("0")  # disable the exception handler
-        self._exec_command(args, JERRY_DEBUGGER_CONTINUE)
-        self.stop = True
-        self.quit = True
-
-    def do_break(self, args):
-        """ Insert breakpoints on the given lines or functions """
-        if args == "":
-            print("Error: Breakpoint index expected")
-        elif ':' in args:
-            try:
-                args_second = int(args.split(':', 1)[1])
-                if args_second < 0:
-                    print("Error: Positive breakpoint index expected")
-                else:
-                    set_breakpoint(self.debugger, args, False)
-            except ValueError as val_errno:
-                print("Error: Positive breakpoint index expected: %s" % val_errno)
-        else:
-            set_breakpoint(self.debugger, args, False)
-
-    do_b = do_break
-
-    def _exec_command(self, args, command_id):
-        self.stop = True
-        if args != "":
-            print("Error: No argument expected")
-        else:
-            self.debugger.send_command(command_id)
-
-    def do_continue(self, args):
-        """ Continue execution """
-        self._exec_command(args, JERRY_DEBUGGER_CONTINUE)
-        self.stop = True
-        self.cont = True
-        if not self.non_interactive:
-            print("Press enter to stop JavaScript execution.")
-
-    do_c = do_continue
-
-    def do_step(self, args):
-        """ Next breakpoint, step into functions """
-        self._exec_command(args, JERRY_DEBUGGER_STEP)
-        self.cont = True
-
-    do_s = do_step
-
-    def do_next(self, args):
-        """ Next breakpoint in the same context """
-        if not args:
-            args = 0
-        else:
-            try:
-                args = int(args)
-                if args <= 0:
-                    raise ValueError(args)
-            except ValueError as val_errno:
-                print("Error: expected a positive integer: %s" % val_errno)
-                return
-
-            args = min(args, len(self.debugger.last_breakpoint_hit.function.lines) -
-                       self.debugger.last_breakpoint_hit.function.line) - 1
-            self.debugger.repeats_remain = args
-
-        self._exec_command("", JERRY_DEBUGGER_NEXT)
-        self.cont = True
-
-    do_n = do_next
-
-    def do_finish(self, args):
-        """ Continue running until the current function returns """
-        self._exec_command(args, JERRY_DEBUGGER_FINISH)
-        self.cont = True
-
-    do_f = do_finish
-
-    def do_list(self, _):
-        """ Lists the available breakpoints """
-        if self.debugger.active_breakpoint_list:
-            print("=== %sActive breakpoints %s ===" % (self.debugger.green_bg, self.debugger.nocolor))
-            for breakpoint in self.debugger.active_breakpoint_list.values():
-                print(" %d: %s" % (breakpoint.active_index, breakpoint))
-
-        if self.debugger.pending_breakpoint_list:
-            print("=== %sPending breakpoints%s ===" % (self.debugger.yellow_bg, self.debugger.nocolor))
-            for breakpoint in self.debugger.pending_breakpoint_list.values():
-                print(" %d: %s (pending)" % (breakpoint.index, breakpoint))
-
-        if not self.debugger.active_breakpoint_list and not self.debugger.pending_breakpoint_list:
-            print("No breakpoints")
-
-    def do_delete(self, args):
-        """ Delete the given breakpoint, use 'delete all|active|pending' to clear all the given breakpoints """
-        if not args:
-            print("Error: Breakpoint index expected")
-            return
-        elif args == "all":
-            self.debugger.delete_active()
-            self.debugger.delete_pending()
-        elif args == "pending":
-            self.debugger.delete_pending()
-        elif args == "active":
-            self.debugger.delete_active()
-        else:
-            try:
-                breakpoint_index = int(args)
-            except ValueError as val_errno:
-                print("Error: Integer number expected, %s" % (val_errno))
-                return
-
-            if breakpoint_index in self.debugger.active_breakpoint_list:
-                breakpoint = self.debugger.active_breakpoint_list[breakpoint_index]
-                del self.debugger.active_breakpoint_list[breakpoint_index]
-                breakpoint.active_index = -1
-                self.debugger.send_breakpoint(breakpoint)
-            elif breakpoint_index in self.debugger.pending_breakpoint_list:
-                del self.debugger.pending_breakpoint_list[breakpoint_index]
-                if not self.debugger.pending_breakpoint_list:
-                    self.debugger.send_parser_config(0)
-            else:
-                print("Error: Breakpoint %d not found" % (breakpoint_index))
-
-    def do_backtrace(self, args):
-        """ Get backtrace data from debugger """
-        max_depth = 0
-
-        if args:
-            try:
-                max_depth = int(args)
-                if max_depth <= 0:
-                    print("Error: Positive integer number expected")
-                    return
-            except ValueError as val_errno:
-                print("Error: Positive integer number expected, %s" % (val_errno))
-                return
-
-        message = struct.pack(self.debugger.byte_order + "BBIB" + self.debugger.idx_format,
-                              WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
-                              WEBSOCKET_FIN_BIT + 1 + 4,
-                              0,
-                              JERRY_DEBUGGER_GET_BACKTRACE,
-                              max_depth)
-        self.debugger.send_message(message)
-        self.stop = True
-
-    do_bt = do_backtrace
-
-    def do_src(self, args):
-        """ Get current source code """
-        if args:
-            line_num = src_check_args(args)
-            if line_num >= 0:
-                print_source(self.debugger, line_num, 0)
-            elif line_num == 0:
-                print_source(self.debugger, self.debugger.default_viewrange, 0)
-            else:
-                return
-
-    do_source = do_src
-
-    def _scroll_direction(self, args):
-        """ Helper function for do_scroll """
-        self.debugger.src_offset_diff = int(max(math.floor(self.debugger.display / 3), 1))
-        if args in "up":
-            self.debugger.src_offset -= self.debugger.src_offset_diff
-            print_source(self.debugger, self.debugger.display, self.debugger.src_offset)
-        else:
-            self.debugger.src_offset += self.debugger.src_offset_diff
-            print_source(self.debugger, self.debugger.display, self.debugger.src_offset)
-
-    def do_scroll(self, _):
-        """ Scroll the source up or down """
-        while True:
-            key = sys.stdin.readline()
-            if key == 'w\n':
-                self._scroll_direction("up")
-            elif key == 's\n':
-                self._scroll_direction("down")
-            elif key == 'q\n':
-                break
-            else:
-                print("Invalid key")
-
-    def do_display(self, args):
-        """ Toggle source code display after breakpoints """
-        if args:
-            line_num = src_check_args(args)
-            if line_num >= 0:
-                self.debugger.display = line_num
-            else:
-                return
-
-        else:
-            print("Non-negative integer number expected, 0 turns off this function")
-            return
-
-    def do_dump(self, args):
-        """ Dump all of the debugger data """
-        if args:
-            print("Error: No argument expected")
-            return
-
-        pprint(self.debugger.function_list)
-
-    def _send_string(self, args, message_type):
-        size = len(args)
-
-        # 1: length of type byte
-        # 4: length of an uint32 value
-        message_header = 1 + 4
-        max_fragment = min(self.debugger.max_message_size - message_header, size)
-
-        message = struct.pack(self.debugger.byte_order + "BBIBI",
-                              WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
-                              WEBSOCKET_FIN_BIT + max_fragment + message_header,
-                              0,
-                              message_type,
-                              size)
-
-        if size == max_fragment:
-            self.debugger.send_message(message + args)
-            self.stop = True
-            return
-
-        self.debugger.send_message(message + args[0:max_fragment])
-        offset = max_fragment
-
-        if message_type == JERRY_DEBUGGER_EVAL:
-            message_type = JERRY_DEBUGGER_EVAL_PART
-        else:
-            message_type = JERRY_DEBUGGER_CLIENT_SOURCE_PART
-
-        # 1: length of type byte
-        message_header = 1
-
-        max_fragment = self.debugger.max_message_size - message_header
-        while offset < size:
-            next_fragment = min(max_fragment, size - offset)
-
-            message = struct.pack(self.debugger.byte_order + "BBIB",
-                                  WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
-                                  WEBSOCKET_FIN_BIT + next_fragment + message_header,
-                                  0,
-                                  message_type)
-
-            prev_offset = offset
-            offset += next_fragment
-            self.debugger.send_message(message + args[prev_offset:offset])
-
-        self.stop = True
-
-    def do_eval(self, args):
-        """ Evaluate JavaScript source code """
-        self._send_string(JERRY_DEBUGGER_EVAL_EVAL + args, JERRY_DEBUGGER_EVAL)
-
-    do_e = do_eval
-
-    def do_throw(self, args):
-        """ Throw an exception """
-        self._send_string(JERRY_DEBUGGER_EVAL_THROW + args, JERRY_DEBUGGER_EVAL)
-
-    def do_abort(self, args):
-        """ Throw an exception """
-        self._send_string(JERRY_DEBUGGER_EVAL_ABORT + args, JERRY_DEBUGGER_EVAL)
-
-    def do_exception(self, args):
-        """ Config the exception handler module """
-        if not args:
-            print("Error: Status expected!")
-            return
-
-        enable = int(args)
-
-        if enable == 1:
-            logging.debug("Stop at exception enabled")
-        elif enable == 0:
-            logging.debug("Stop at exception disabled")
-        else:
-            print("Error: Invalid input! Usage 1: [Enable] or 0: [Disable].")
-            return
-
-        self.debugger.send_exception_config(enable)
-
-    def do_memstats(self, args):
-        """ Memory statistics """
-        self._exec_command(args, JERRY_DEBUGGER_MEMSTATS)
-        return
-
-    do_ms = do_memstats
-
-    def store_client_sources(self, args):
-        self.client_sources = args
-
-    def send_client_source(self):
-        # Send no more source message if there is no source
-        if not self.client_sources:
-            self.send_no_more_source()
-            return
-
-        path = self.client_sources.pop(0)
-        if not path.lower().endswith('.js'):
-            sys.exit("Error: Javascript file expected!")
-            return
-
-        with open(path, 'r') as src_file:
-            content = path + "\0" + src_file.read()
-            self._send_string(content, JERRY_DEBUGGER_CLIENT_SOURCE)
-
-    def send_no_more_source(self):
-        self._exec_command("", JERRY_DEBUGGER_NO_MORE_SOURCES)
-        self.cont = True
-
-class Multimap(object):
-
-    def __init__(self):
-        self.map = {}
-
-    def get(self, key):
-        if key in self.map:
-            return self.map[key]
-        return []
-
-    def insert(self, key, value):
-        if key in self.map:
-            self.map[key].append(value)
-        else:
-            self.map[key] = [value]
-
-    def delete(self, key, value):
-        items = self.map[key]
-
-        if len(items) == 1:
-            del self.map[key]
-        else:
-            del items[items.index(value)]
-
-    def __repr__(self):
-        return "Multimap(%r)" % (self.map)
-
-
-class JerryDebugger(object):
-    # pylint: disable=too-many-instance-attributes,too-many-statements
-    def __init__(self, address):
-
-        if ":" not in address:
-            self.host = address
-            self.port = 5001  # use default port
-        else:
-            self.host, self.port = address.split(":")
-            self.port = int(self.port)
-
-        print("Connecting to: %s:%s" % (self.host, self.port))
-
-        self.message_data = b""
-        self.function_list = {}
-        self.last_breakpoint_hit = None
-        self.next_breakpoint_index = 0
-        self.active_breakpoint_list = {}
-        self.pending_breakpoint_list = {}
-        self.line_list = Multimap()
-        self.display = 0
-        self.default_viewrange = 3
-        self.green = ''
-        self.red = ''
-        self.yellow = ''
-        self.green_bg = ''
-        self.yellow_bg = ''
-        self.blue = ''
-        self.nocolor = ''
-        self.src_offset = 0
-        self.src_offset_diff = 0
-        self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        self.client_socket.connect((self.host, self.port))
-        self.repeats_remain = 0
-
-        self.send_message(b"GET /jerry-debugger HTTP/1.1\r\n" +
-                          b"Upgrade: websocket\r\n" +
-                          b"Connection: Upgrade\r\n" +
-                          b"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n")
-        result = b""
-        expected = (b"HTTP/1.1 101 Switching Protocols\r\n" +
-                    b"Upgrade: websocket\r\n" +
-                    b"Connection: Upgrade\r\n" +
-                    b"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")
-
-        len_expected = len(expected)
-
-        while len(result) < len_expected:
-            result += self.client_socket.recv(1024)
-
-        len_result = len(result)
-
-        if result[0:len_expected] != expected:
-            raise Exception("Unexpected handshake")
-
-        if len_result > len_expected:
-            result = result[len_expected:]
-        else:
-            result = b""
-
-        len_expected = 7
-        # Network configurations, which has the following struct:
-        # header [2] - opcode[1], size[1]
-        # type [1]
-        # max_message_size [1]
-        # cpointer_size [1]
-        # little_endian [1]
-        # version [1]
-
-        while len(result) < len_expected:
-            result += self.client_socket.recv(1024)
-
-        len_result = len(result)
-
-        expected = struct.pack("BBB",
-                               WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
-                               5,
-                               JERRY_DEBUGGER_CONFIGURATION)
-
-        if result[0:3] != expected:
-            raise Exception("Unexpected configuration")
-
-        self.max_message_size = ord(result[3])
-        self.cp_size = ord(result[4])
-        self.little_endian = ord(result[5])
-        self.version = ord(result[6])
-
-        if self.version != JERRY_DEBUGGER_VERSION:
-            raise Exception("Incorrect debugger version from target: %d expected: %d" %
-                            (self.version, JERRY_DEBUGGER_VERSION))
-
-
-        if self.little_endian:
-            self.byte_order = "<"
-            logging.debug("Little-endian machine")
-        else:
-            self.byte_order = ">"
-            logging.debug("Big-endian machine")
-
-        if self.cp_size == 2:
-            self.cp_format = "H"
-        else:
-            self.cp_format = "I"
-
-        self.idx_format = "I"
-
-        logging.debug("Compressed pointer size: %d", self.cp_size)
-
-        if len_result > len_expected:
-            self.message_data = result[len_expected:]
-
-    def __del__(self):
-        self.client_socket.close()
-
-    def send_message(self, message):
-        size = len(message)
-        while size > 0:
-            bytes_send = self.client_socket.send(message)
-            if bytes_send < size:
-                message = message[bytes_send:]
-            size -= bytes_send
-
-    def delete_active(self):
-        for i in self.active_breakpoint_list.values():
-            breakpoint = self.active_breakpoint_list[i.active_index]
-            del self.active_breakpoint_list[i.active_index]
-            breakpoint.active_index = -1
-            self.send_breakpoint(breakpoint)
-
-    def delete_pending(self):
-        if self.pending_breakpoint_list:
-            self.pending_breakpoint_list.clear()
-            self.send_parser_config(0)
-
-    def breakpoint_pending_exists(self, breakpoint):
-        for existing_bp in self.pending_breakpoint_list.values():
-            if (breakpoint.line and existing_bp.source_name == breakpoint.source_name and \
-                  existing_bp.line == breakpoint.line) \
-               or (not breakpoint.line and existing_bp.function == breakpoint.function):
-                return True
-
-        return False
-
-    def send_breakpoint(self, breakpoint):
-        message = struct.pack(self.byte_order + "BBIBB" + self.cp_format + self.idx_format,
-                              WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
-                              WEBSOCKET_FIN_BIT + 1 + 1 + self.cp_size + 4,
-                              0,
-                              JERRY_DEBUGGER_UPDATE_BREAKPOINT,
-                              int(breakpoint.active_index >= 0),
-                              breakpoint.function.byte_code_cp,
-                              breakpoint.offset)
-        self.send_message(message)
-
-    def send_bytecode_cp(self, byte_code_cp):
-        message = struct.pack(self.byte_order + "BBIB" + self.cp_format,
-                              WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
-                              WEBSOCKET_FIN_BIT + 1 + self.cp_size,
-                              0,
-                              JERRY_DEBUGGER_FREE_BYTE_CODE_CP,
-                              byte_code_cp)
-        self.send_message(message)
-
-    def send_command(self, command):
-        message = struct.pack(self.byte_order + "BBIB",
-                              WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
-                              WEBSOCKET_FIN_BIT + 1,
-                              0,
-                              command)
-        self.send_message(message)
-
-    def send_exception_config(self, enable):
-        message = struct.pack(self.byte_order + "BBIBB",
-                              WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
-                              WEBSOCKET_FIN_BIT + 1 + 1,
-                              0,
-                              JERRY_DEBUGGER_EXCEPTION_CONFIG,
-                              enable)
-        self.send_message(message)
-
-    def send_parser_config(self, enable):
-        message = struct.pack(self.byte_order + "BBIBB",
-                              WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
-                              WEBSOCKET_FIN_BIT + 1 + 1,
-                              0,
-                              JERRY_DEBUGGER_PARSER_CONFIG,
-                              enable)
-        self.send_message(message)
-
-    def set_colors(self):
-        self.nocolor = '\033[0m'
-        self.green = '\033[92m'
-        self.red = '\033[31m'
-        self.yellow = '\033[93m'
-        self.green_bg = '\033[42m\033[30m'
-        self.yellow_bg = '\033[43m\033[30m'
-        self.blue = '\033[94m'
-
-    def get_message(self, blocking):
-        # Connection was closed
-        if self.message_data is None:
-            return None
-
-        while True:
-            if len(self.message_data) >= 2:
-                if ord(self.message_data[0]) != WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT:
-                    raise Exception("Unexpected data frame")
-
-                size = ord(self.message_data[1])
-                if size == 0 or size >= 126:
-                    raise Exception("Unexpected data frame")
-
-                if len(self.message_data) >= size + 2:
-                    result = self.message_data[0:size + 2]
-                    self.message_data = self.message_data[size + 2:]
-                    return result
-
-            if not blocking:
-                select_result = select.select([self.client_socket], [], [], 0)[0]
-                if self.client_socket not in select_result:
-                    return b''
-
-            data = self.client_socket.recv(MAX_BUFFER_SIZE)
-
-            if not data:
-                self.message_data = None
-                return None
-
-            self.message_data += data
-
-
-# pylint: disable=too-many-branches,too-many-locals,too-many-statements
-def parse_source(debugger, data):
-    source_code = ""
-    source_code_name = ""
-    function_name = ""
-    stack = [{"line": 1,
-              "column": 1,
-              "name": "",
-              "lines": [],
-              "offsets": []}]
-    new_function_list = {}
-
-    while True:
-        if data is None:
-            return
-
-        buffer_type = ord(data[2])
-        buffer_size = ord(data[1]) - 1
-
-        logging.debug("Parser buffer type: %d, message size: %d", buffer_type, buffer_size)
-
-        if buffer_type == JERRY_DEBUGGER_PARSE_ERROR:
-            logging.error("Parser error!")
-            return
-
-        elif buffer_type in [JERRY_DEBUGGER_SOURCE_CODE, JERRY_DEBUGGER_SOURCE_CODE_END]:
-            source_code += data[3:]
-
-        elif buffer_type in [JERRY_DEBUGGER_SOURCE_CODE_NAME, JERRY_DEBUGGER_SOURCE_CODE_NAME_END]:
-            source_code_name += data[3:]
-
-        elif buffer_type in [JERRY_DEBUGGER_FUNCTION_NAME, JERRY_DEBUGGER_FUNCTION_NAME_END]:
-            function_name += data[3:]
-
-        elif buffer_type == JERRY_DEBUGGER_PARSE_FUNCTION:
-            logging.debug("Source name: %s, function name: %s", source_code_name, function_name)
-
-            position = struct.unpack(debugger.byte_order + debugger.idx_format + debugger.idx_format,
-                                     data[3: 3 + 4 + 4])
-
-            stack.append({"source": source_code,
-                          "source_name": source_code_name,
-                          "line": position[0],
-                          "column": position[1],
-                          "name": function_name,
-                          "lines": [],
-                          "offsets": []})
-            function_name = ""
-
-        elif buffer_type in [JERRY_DEBUGGER_BREAKPOINT_LIST, JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST]:
-            name = "lines"
-            if buffer_type == JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST:
-                name = "offsets"
-
-            logging.debug("Breakpoint %s received", name)
-
-            buffer_pos = 3
-            while buffer_size > 0:
-                line = struct.unpack(debugger.byte_order + debugger.idx_format,
-                                     data[buffer_pos: buffer_pos + 4])
-                stack[-1][name].append(line[0])
-                buffer_pos += 4
-                buffer_size -= 4
-
-        elif buffer_type == JERRY_DEBUGGER_BYTE_CODE_CP:
-            byte_code_cp = struct.unpack(debugger.byte_order + debugger.cp_format,
-                                         data[3: 3 + debugger.cp_size])[0]
-
-            logging.debug("Byte code cptr received: {0x%x}", byte_code_cp)
-
-            func_desc = stack.pop()
-
-            # We know the last item in the list is the general byte code.
-            if len(stack) == 0:
-                func_desc["source"] = source_code
-                func_desc["source_name"] = source_code_name
-
-            function = JerryFunction(len(stack) != 0,
-                                     byte_code_cp,
-                                     func_desc["source"],
-                                     func_desc["source_name"],
-                                     func_desc["line"],
-                                     func_desc["column"],
-                                     func_desc["name"],
-                                     func_desc["lines"],
-                                     func_desc["offsets"])
-
-            new_function_list[byte_code_cp] = function
-
-            if len(stack) == 0:
-                logging.debug("Parse completed.")
-                break
-
-        elif buffer_type == JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP:
-            # Redefined functions are dropped during parsing.
-            byte_code_cp = struct.unpack(debugger.byte_order + debugger.cp_format,
-                                         data[3: 3 + debugger.cp_size])[0]
-
-            if byte_code_cp in new_function_list:
-                del new_function_list[byte_code_cp]
-                debugger.send_bytecode_cp(byte_code_cp)
-            else:
-                release_function(debugger, data)
-
-        else:
-            logging.error("Parser error!")
-            return
-
-        data = debugger.get_message(True)
-
-    # Copy the ready list to the global storage.
-    debugger.function_list.update(new_function_list)
-
-    for function in new_function_list.values():
-        for line, breakpoint in function.lines.items():
-            debugger.line_list.insert(line, breakpoint)
-
-    # Try to set the pending breakpoints
-    if debugger.pending_breakpoint_list:
-        logging.debug("Pending breakpoints list: %s", debugger.pending_breakpoint_list)
-        bp_list = debugger.pending_breakpoint_list
-
-        for breakpoint_index, breakpoint in bp_list.items():
-            for src in debugger.function_list.values():
-                if src.source_name == breakpoint.source_name:
-                    source_lines = len(src.source)
-                else:
-                    source_lines = 0
-
-            if breakpoint.line:
-                if breakpoint.line <= source_lines:
-                    command = breakpoint.source_name + ":" + str(breakpoint.line)
-                    if set_breakpoint(debugger, command, True):
-                        del bp_list[breakpoint_index]
-            elif breakpoint.function:
-                command = breakpoint.function
-                if set_breakpoint(debugger, command, True):
-                    del bp_list[breakpoint_index]
-
-        if not bp_list:
-            debugger.send_parser_config(0)
-
-    else:
-        logging.debug("No pending breakpoints")
-
-
-def src_check_args(args):
-    try:
-        line_num = int(args)
-        if line_num < 0:
-            print("Error: Non-negative integer number expected")
-            return -1
-
-        return line_num
-    except ValueError as val_errno:
-        print("Error: Non-negative integer number expected: %s" % (val_errno))
-        return -1
-
-
-def print_source(debugger, line_num, offset):
-    last_bp = debugger.last_breakpoint_hit
-    if not last_bp:
-        return
-
-    lines = last_bp.function.source
-    if last_bp.function.source_name:
-        print("Source: %s" % (last_bp.function.source_name))
-
-    if line_num == 0:
-        start = 0
-        end = len(last_bp.function.source)
-    else:
-        start = max(last_bp.line - line_num, 0)
-        end = min(last_bp.line + line_num - 1, len(last_bp.function.source))
-        if offset:
-            if start + offset < 0:
-                debugger.src_offset += debugger.src_offset_diff
-                offset += debugger.src_offset_diff
-            elif end + offset > len(last_bp.function.source):
-                debugger.src_offset -= debugger.src_offset_diff
-                offset -= debugger.src_offset_diff
-
-            start = max(start + offset, 0)
-            end = min(end + offset, len(last_bp.function.source))
-
-    for i in range(start, end):
-        if i == last_bp.line - 1:
-            print("%s%4d%s %s>%s %s" % (debugger.green, i + 1, debugger.nocolor, debugger.red, \
-                                        debugger.nocolor, lines[i]))
-        else:
-            print("%s%4d%s   %s" % (debugger.green, i + 1, debugger.nocolor, lines[i]))
-
-
-def release_function(debugger, data):
-    byte_code_cp = struct.unpack(debugger.byte_order + debugger.cp_format,
-                                 data[3: 3 + debugger.cp_size])[0]
-
-    function = debugger.function_list[byte_code_cp]
-
-    for line, breakpoint in function.lines.items():
-        debugger.line_list.delete(line, breakpoint)
-        if breakpoint.active_index >= 0:
-            del debugger.active_breakpoint_list[breakpoint.active_index]
-
-    del debugger.function_list[byte_code_cp]
-
-    debugger.send_bytecode_cp(byte_code_cp)
-
-    logging.debug("Function {0x%x} byte-code released", byte_code_cp)
-
-
-def enable_breakpoint(debugger, breakpoint):
-    if isinstance(breakpoint, JerryPendingBreakpoint):
-        if not debugger.breakpoint_pending_exists(breakpoint):
-            debugger.next_breakpoint_index += 1
-            breakpoint.index = debugger.next_breakpoint_index
-            debugger.pending_breakpoint_list[debugger.next_breakpoint_index] = breakpoint
-            print("%sPending breakpoint%s at %s" % (debugger.yellow, debugger.nocolor, breakpoint))
-        else:
-            print("%sPending breakpoint%s already exists" % (debugger.yellow, debugger.nocolor))
-
-    else:
-        if breakpoint.active_index < 0:
-            debugger.next_breakpoint_index += 1
-            debugger.active_breakpoint_list[debugger.next_breakpoint_index] = breakpoint
-            breakpoint.active_index = debugger.next_breakpoint_index
-            debugger.send_breakpoint(breakpoint)
-
-        print("%sBreakpoint %d %sat %s" % (debugger.green, breakpoint.active_index, debugger.nocolor, breakpoint))
-
-
-def set_breakpoint(debugger, string, pending):
-    line = re.match("(.*):(\\d+)$", string)
-    found = False
-
-    if line:
-        source_name = line.group(1)
-        new_line = int(line.group(2))
-
-        for breakpoint in debugger.line_list.get(new_line):
-            func_source = breakpoint.function.source_name
-            if (source_name == func_source or
-                    func_source.endswith("/" + source_name) or
-                    func_source.endswith("\\" + source_name)):
-
-                enable_breakpoint(debugger, breakpoint)
-                found = True
-
-    else:
-        for function in debugger.function_list.values():
-            if function.name == string:
-                enable_breakpoint(debugger, function.lines[function.first_breakpoint_line])
-                found = True
-
-    if not found and not pending:
-        print("No breakpoint found, do you want to add a %spending breakpoint%s? (y or [n])" % \
-              (debugger.yellow, debugger.nocolor))
-
-        ans = sys.stdin.readline()
-        if ans in ['yes\n', 'y\n']:
-            if not debugger.pending_breakpoint_list:
-                debugger.send_parser_config(1)
-
-            if line:
-                breakpoint = JerryPendingBreakpoint(int(line.group(2)), line.group(1))
-            else:
-                breakpoint = JerryPendingBreakpoint(function=string)
-            enable_breakpoint(debugger, breakpoint)
-
-    elif not found and pending:
-        return False
-
-    return True
-
-
-def get_breakpoint(debugger, breakpoint_data):
-    function = debugger.function_list[breakpoint_data[0]]
-    offset = breakpoint_data[1]
-
-    if offset in function.offsets:
-        return (function.offsets[offset], True)
-
-    if offset < function.first_breakpoint_offset:
-        return (function.offsets[function.first_breakpoint_offset], False)
-
-    nearest_offset = -1
-
-    for current_offset in function.offsets:
-        if current_offset <= offset and current_offset > nearest_offset:
-            nearest_offset = current_offset
-
-    return (function.offsets[nearest_offset], False)
-
-
-# pylint: disable=too-many-branches,too-many-locals,too-many-statements
-def main():
-    args = arguments_parse()
-
-    debugger = JerryDebugger(args.address)
-    exception_string = ""
-
-    if args.color:
-        debugger.set_colors()
-
-    non_interactive = args.non_interactive
-
-    logging.debug("Connected to JerryScript on %d port", debugger.port)
-
-    prompt = DebuggerPrompt(debugger)
-    prompt.prompt = "(jerry-debugger) "
-    prompt.non_interactive = non_interactive
-
-    if args.display:
-        prompt.do_display(args.display)
-
-    if args.exception is not None:
-        prompt.do_exception(str(args.exception))
-
-    if args.client_source is not None:
-        prompt.store_client_sources(args.client_source)
-
-    while True:
-        if not non_interactive and prompt.cont:
-            if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
-                sys.stdin.readline()
-                prompt.cont = False
-                debugger.send_command(JERRY_DEBUGGER_STOP)
-
-        data = debugger.get_message(False)
-
-        if data == b'':
-            continue
-
-        if not data:  # Break the while loop if there is no more data.
-            break
-
-        buffer_type = ord(data[2])
-        buffer_size = ord(data[1]) - 1
-
-        logging.debug("Main buffer type: %d, message size: %d", buffer_type, buffer_size)
-
-        if buffer_type in [JERRY_DEBUGGER_PARSE_ERROR,
-                           JERRY_DEBUGGER_BYTE_CODE_CP,
-                           JERRY_DEBUGGER_PARSE_FUNCTION,
-                           JERRY_DEBUGGER_BREAKPOINT_LIST,
-                           JERRY_DEBUGGER_SOURCE_CODE,
-                           JERRY_DEBUGGER_SOURCE_CODE_END,
-                           JERRY_DEBUGGER_SOURCE_CODE_NAME,
-                           JERRY_DEBUGGER_SOURCE_CODE_NAME_END,
-                           JERRY_DEBUGGER_FUNCTION_NAME,
-                           JERRY_DEBUGGER_FUNCTION_NAME_END]:
-            parse_source(debugger, data)
-
-        elif buffer_type == JERRY_DEBUGGER_WAITING_AFTER_PARSE:
-            debugger.send_command(JERRY_DEBUGGER_PARSER_RESUME)
-
-        elif buffer_type == JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP:
-            release_function(debugger, data)
-
-        elif buffer_type in [JERRY_DEBUGGER_BREAKPOINT_HIT, JERRY_DEBUGGER_EXCEPTION_HIT]:
-            breakpoint_data = struct.unpack(debugger.byte_order + debugger.cp_format + debugger.idx_format, data[3:])
-
-            breakpoint = get_breakpoint(debugger, breakpoint_data)
-            debugger.last_breakpoint_hit = breakpoint[0]
-
-            if buffer_type == JERRY_DEBUGGER_EXCEPTION_HIT:
-                print("Exception throw detected (to disable automatic stop type exception 0)")
-                if exception_string:
-                    print("Exception hint: %s" % (exception_string))
-                    exception_string = ""
-
-            if breakpoint[1]:
-                breakpoint_info = "at"
-            else:
-                breakpoint_info = "around"
-
-            if breakpoint[0].active_index >= 0:
-                breakpoint_info += " breakpoint:%s%d%s" % (debugger.red, breakpoint[0].active_index, debugger.nocolor)
-
-            print("Stopped %s %s" % (breakpoint_info, breakpoint[0]))
-            if debugger.display:
-                print_source(prompt.debugger, debugger.display, 0)
-
-            if debugger.repeats_remain:
-                prompt.do_next(debugger.repeats_remain)
-                time.sleep(0.1)
-            else:
-                prompt.cmdloop()
-
-            if prompt.quit:
-                break
-
-        elif buffer_type == JERRY_DEBUGGER_EXCEPTION_STR:
-            exception_string += data[3:]
-
-        elif buffer_type == JERRY_DEBUGGER_EXCEPTION_STR_END:
-            exception_string += data[3:]
-
-        elif buffer_type in [JERRY_DEBUGGER_BACKTRACE, JERRY_DEBUGGER_BACKTRACE_END]:
-            frame_index = 0
-
-            while True:
-
-                buffer_pos = 3
-                while buffer_size > 0:
-                    breakpoint_data = struct.unpack(debugger.byte_order + debugger.cp_format + debugger.idx_format,
-                                                    data[buffer_pos: buffer_pos + debugger.cp_size + 4])
-
-                    breakpoint = get_breakpoint(debugger, breakpoint_data)
-
-                    print("Frame %d: %s" % (frame_index, breakpoint[0]))
-
-                    frame_index += 1
-                    buffer_pos += 6
-                    buffer_size -= 6
-
-                if buffer_type == JERRY_DEBUGGER_BACKTRACE_END:
-                    break
-
-                data = debugger.get_message(True)
-                buffer_type = ord(data[2])
-                buffer_size = ord(data[1]) - 1
-
-                if buffer_type not in [JERRY_DEBUGGER_BACKTRACE,
-                                       JERRY_DEBUGGER_BACKTRACE_END]:
-                    raise Exception("Backtrace data expected")
-
-            prompt.cmdloop()
-
-
-        elif buffer_type in [JERRY_DEBUGGER_EVAL_RESULT,
-                             JERRY_DEBUGGER_EVAL_RESULT_END,
-                             JERRY_DEBUGGER_OUTPUT_RESULT,
-                             JERRY_DEBUGGER_OUTPUT_RESULT_END]:
-            message = b""
-            msg_type = buffer_type
-            while True:
-                if buffer_type in [JERRY_DEBUGGER_EVAL_RESULT_END,
-                                   JERRY_DEBUGGER_OUTPUT_RESULT_END]:
-                    subtype = ord(data[-1])
-                    message += data[3:-1]
-                    break
-                else:
-                    message += data[3:]
-
-                data = debugger.get_message(True)
-                buffer_type = ord(data[2])
-                buffer_size = ord(data[1]) - 1
-                # Checks if the next frame would be an invalid data frame.
-                # If it is not the message type, or the end type of it, an exception is thrown.
-                if buffer_type not in [msg_type, msg_type + 1]:
-                    raise Exception("Invalid data caught")
-
-            # Subtypes of output
-            if buffer_type == JERRY_DEBUGGER_OUTPUT_RESULT_END:
-                message = message.rstrip('\n')
-                if subtype in [JERRY_DEBUGGER_OUTPUT_OK,
-                               JERRY_DEBUGGER_OUTPUT_DEBUG]:
-                    print("%sout: %s%s" % (debugger.blue, debugger.nocolor, message))
-                elif subtype == JERRY_DEBUGGER_OUTPUT_WARNING:
-                    print("%swarning: %s%s" % (debugger.yellow, debugger.nocolor, message))
-                elif subtype == JERRY_DEBUGGER_OUTPUT_ERROR:
-                    print("%serr: %s%s" % (debugger.red, debugger.nocolor, message))
-                elif subtype == JERRY_DEBUGGER_OUTPUT_TRACE:
-                    print("%strace: %s%s" % (debugger.blue, debugger.nocolor, message))
-
-            # Subtypes of eval
-            elif buffer_type == JERRY_DEBUGGER_EVAL_RESULT_END:
-                if subtype == JERRY_DEBUGGER_EVAL_ERROR:
-                    print("Uncaught exception: %s" % (message))
-                else:
-                    print(message)
-
-                prompt.cmdloop()
-
-        elif buffer_type == JERRY_DEBUGGER_MEMSTATS_RECEIVE:
-
-            memory_stats = struct.unpack(debugger.byte_order + debugger.idx_format *5,
-                                         data[3: 3 + 4 *5])
-
-            print("Allocated bytes: %d" % (memory_stats[0]))
-            print("Byte code bytes: %d" % (memory_stats[1]))
-            print("String bytes: %d" % (memory_stats[2]))
-            print("Object bytes: %d" % (memory_stats[3]))
-            print("Property bytes: %d" % (memory_stats[4]))
-
-            prompt.cmdloop()
-
-        elif buffer_type == JERRY_DEBUGGER_WAIT_FOR_SOURCE:
-            prompt.send_client_source()
-
-
-        else:
-            raise Exception("Unknown message")
-
-
-if __name__ == "__main__":
-    try:
-        main()
-    except socket.error as error_msg:
-        ERRNO = error_msg.errno
-        MSG = str(error_msg)
-
-        if ERRNO == 111:
-            sys.exit("Failed to connect to the JerryScript debugger.")
-        elif ERRNO == 32 or ERRNO == 104:
-            sys.exit("Connection closed.")
-        else:
-            sys.exit("Failed to connect to the JerryScript debugger.\nError: %s" % (MSG))
diff --git a/deps/jerry/jerry-debugger/jerry_client.py b/deps/jerry/jerry-debugger/jerry_client.py
new file mode 100755 (executable)
index 0000000..e56ca96
--- /dev/null
@@ -0,0 +1,302 @@
+#!/usr/bin/env python
+
+# 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.
+
+from __future__ import print_function
+from cmd import Cmd
+from pprint import pprint
+import math
+import socket
+import sys
+import logging
+import time
+import jerry_client_ws
+
+def write(string):
+    print(string, end='')
+
+class DebuggerPrompt(Cmd):
+    # pylint: disable=too-many-instance-attributes,too-many-arguments
+    def __init__(self, debugger):
+        Cmd.__init__(self)
+        self.debugger = debugger
+        self.stop = False
+        self.quit = False
+
+    def precmd(self, line):
+        self.stop = False
+        if self.debugger.non_interactive:
+            print("%s" % line)
+        return line
+
+    def postcmd(self, stop, line):
+        return self.stop
+
+    def do_quit(self, _):
+        """ Exit JerryScript debugger """
+        self.debugger.quit()
+        self.quit = True
+        self.stop = True
+
+    def do_display(self, args):
+        """ Toggle source code display after breakpoints """
+        if args:
+            line_num = src_check_args(args)
+            if line_num >= 0:
+                self.debugger.display = line_num
+        else:
+            print("Non-negative integer number expected, 0 turns off this function")
+
+    def do_break(self, args):
+        """ Insert breakpoints on the given lines or functions """
+        write(self.debugger.set_break(args))
+    do_b = do_break
+
+    def do_list(self, _):
+        """ Lists the available breakpoints """
+        write(self.debugger.breakpoint_list())
+
+    def do_delete(self, args):
+        """ Delete the given breakpoint, use 'delete all|active|pending' to clear all the given breakpoints """
+        write(self.debugger.delete(args))
+
+    def do_next(self, args):
+        """ Next breakpoint in the same context """
+        self.stop = True
+        if not args:
+            args = 0
+            self.debugger.next()
+            return
+
+        try:
+            args = int(args)
+            if args <= 0:
+                raise ValueError(args)
+
+            while args > 0:
+                self.debugger.next()
+                time.sleep(0.1)
+
+                while True:
+                    result = self.debugger.process_messages()
+                    res_type = result.get_type()
+
+                    if res_type == result.END:
+                        self.quit = True
+                        return
+                    elif res_type == result.TEXT:
+                        write(result.get_text())
+                    elif res_type == result.PROMPT:
+                        break
+
+                args -= 1
+        except ValueError as val_errno:
+            print("Error: expected a positive integer: %s" % val_errno)
+    do_n = do_next
+
+    def do_step(self, _):
+        """ Next breakpoint, step into functions """
+        self.debugger.step()
+        self.stop = True
+    do_s = do_step
+
+    def do_backtrace(self, args):
+        """ Get backtrace data from debugger """
+        write(self.debugger.backtrace(args))
+        self.stop = True
+    do_bt = do_backtrace
+
+    def do_variables(self, args):
+        """ Get scope variables from debugger """
+        write(self.debugger.scope_variables(args))
+        self.stop = True
+
+    def do_src(self, args):
+        """ Get current source code """
+        if args:
+            line_num = src_check_args(args)
+            if line_num >= 0:
+                write(self.debugger.print_source(line_num, 0))
+    do_source = do_src
+
+    def do_scroll(self, _):
+        """ Scroll the source up or down """
+        while True:
+            key = sys.stdin.readline()
+            if key == 'w\n':
+                _scroll_direction(self.debugger, "up")
+            elif key == 's\n':
+                _scroll_direction(self.debugger, "down")
+            elif key == 'q\n':
+                break
+            else:
+                print("Invalid key")
+
+    def do_continue(self, _):
+        """ Continue execution """
+        self.debugger.get_continue()
+        self.stop = True
+        if not self.debugger.non_interactive:
+            print("Press enter to stop JavaScript execution.")
+    do_c = do_continue
+
+    def do_finish(self, _):
+        """ Continue running until the current function returns """
+        self.debugger.finish()
+        self.stop = True
+    do_f = do_finish
+
+    def do_dump(self, args):
+        """ Dump all of the debugger data """
+        if args:
+            print("Error: No argument expected")
+        else:
+            pprint(self.debugger.function_list)
+
+    def do_eval(self, args):
+        """ Evaluate JavaScript source code """
+        self.debugger.eval(args)
+        self.stop = True
+    do_e = do_eval
+
+    def do_eval_at(self, args):
+        """ Evaluate JavaScript source code at a scope chain level """
+
+        code = ''
+        index = 0
+        try:
+            args = args.split(" ", 1)
+
+            index = int(args[0])
+
+            if len(args) == 2:
+                code = args[1]
+
+            if index < 0 or index > 65535:
+                raise ValueError("Invalid scope chain index: %d (must be between 0 and 65535)" % index)
+
+        except ValueError as val_errno:
+            print("Error: %s" % (val_errno))
+            return
+
+        self.debugger.eval_at(code, index)
+        self.stop = True
+
+    def do_memstats(self, _):
+        """ Memory statistics """
+        self.debugger.memstats()
+        self.stop = True
+    do_ms = do_memstats
+
+    def do_scopes(self, _):
+        """ Memory statistics """
+        self.debugger.scope_chain()
+        self.stop = True
+
+    def do_abort(self, args):
+        """ Throw an exception """
+        self.debugger.abort(args)
+        self.stop = True
+
+    def do_restart(self, _):
+        """ Restart the engine's debug session """
+        self.debugger.restart()
+        self.stop = True
+    do_res = do_restart
+
+    def do_throw(self, args):
+        """ Throw an exception """
+        self.debugger.throw(args)
+        self.stop = True
+
+    def do_exception(self, args):
+        """ Config the exception handler module """
+        write(self.debugger.exception(args))
+
+def _scroll_direction(debugger, direction):
+    """ Helper function for do_scroll """
+    debugger.src_offset_diff = int(max(math.floor(debugger.display / 3), 1))
+    if direction == "up":
+        debugger.src_offset -= debugger.src_offset_diff
+    else:
+        debugger.src_offset += debugger.src_offset_diff
+    print(debugger.print_source(debugger.display, debugger.src_offset)['value'])
+
+def src_check_args(args):
+    try:
+        line_num = int(args)
+        if line_num < 0:
+            print("Error: Non-negative integer number expected")
+            return -1
+
+        return line_num
+    except ValueError as val_errno:
+        print("Error: Non-negative integer number expected: %s" % (val_errno))
+        return -1
+
+# pylint: disable=too-many-branches,too-many-locals,too-many-statements
+def main():
+    args = jerry_client_ws.arguments_parse()
+
+    debugger = jerry_client_ws.JerryDebugger(args.address)
+    debugger.non_interactive = args.non_interactive
+
+    logging.debug("Connected to JerryScript on %d port", debugger.port)
+
+    prompt = DebuggerPrompt(debugger)
+    prompt.prompt = "(jerry-debugger) "
+
+    if args.color:
+        debugger.set_colors()
+
+    if args.display:
+        debugger.display = args.display
+        prompt.do_display(args.display)
+    else:
+        prompt.stop = False
+
+    if args.exception is not None:
+        prompt.do_exception(str(args.exception))
+
+    if args.client_source:
+        debugger.store_client_sources(args.client_source)
+
+    while True:
+        if prompt.quit:
+            break
+
+        result = debugger.process_messages()
+        res_type = result.get_type()
+
+        if res_type == result.END:
+            break
+        elif res_type == result.PROMPT:
+            prompt.cmdloop()
+        elif res_type == result.TEXT:
+            write(result.get_text())
+        continue
+
+if __name__ == "__main__":
+    try:
+        main()
+    except socket.error as error_msg:
+        ERRNO = error_msg.errno
+        MSG = str(error_msg)
+        if ERRNO == 111:
+            sys.exit("Failed to connect to the JerryScript debugger.")
+        elif ERRNO == 32 or ERRNO == 104:
+            sys.exit("Connection closed.")
+        else:
+            sys.exit("Failed to connect to the JerryScript debugger.\nError: %s" % (MSG))
diff --git a/deps/jerry/jerry-debugger/jerry_client_ws.py b/deps/jerry/jerry-debugger/jerry_client_ws.py
new file mode 100644 (file)
index 0000000..defee5b
--- /dev/null
@@ -0,0 +1,1363 @@
+#!/usr/bin/env python
+
+# 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.
+
+from __future__ import print_function
+import argparse
+import logging
+import re
+import select
+import socket
+import struct
+import sys
+
+# Expected debugger protocol version.
+JERRY_DEBUGGER_VERSION = 8
+
+# Messages sent by the server to client.
+JERRY_DEBUGGER_CONFIGURATION = 1
+JERRY_DEBUGGER_PARSE_ERROR = 2
+JERRY_DEBUGGER_BYTE_CODE_CP = 3
+JERRY_DEBUGGER_PARSE_FUNCTION = 4
+JERRY_DEBUGGER_BREAKPOINT_LIST = 5
+JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST = 6
+JERRY_DEBUGGER_SOURCE_CODE = 7
+JERRY_DEBUGGER_SOURCE_CODE_END = 8
+JERRY_DEBUGGER_SOURCE_CODE_NAME = 9
+JERRY_DEBUGGER_SOURCE_CODE_NAME_END = 10
+JERRY_DEBUGGER_FUNCTION_NAME = 11
+JERRY_DEBUGGER_FUNCTION_NAME_END = 12
+JERRY_DEBUGGER_WAITING_AFTER_PARSE = 13
+JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP = 14
+JERRY_DEBUGGER_MEMSTATS_RECEIVE = 15
+JERRY_DEBUGGER_BREAKPOINT_HIT = 16
+JERRY_DEBUGGER_EXCEPTION_HIT = 17
+JERRY_DEBUGGER_EXCEPTION_STR = 18
+JERRY_DEBUGGER_EXCEPTION_STR_END = 19
+JERRY_DEBUGGER_BACKTRACE_TOTAL = 20
+JERRY_DEBUGGER_BACKTRACE = 21
+JERRY_DEBUGGER_BACKTRACE_END = 22
+JERRY_DEBUGGER_EVAL_RESULT = 23
+JERRY_DEBUGGER_EVAL_RESULT_END = 24
+JERRY_DEBUGGER_WAIT_FOR_SOURCE = 25
+JERRY_DEBUGGER_OUTPUT_RESULT = 26
+JERRY_DEBUGGER_OUTPUT_RESULT_END = 27
+JERRY_DEBUGGER_SCOPE_CHAIN = 28
+JERRY_DEBUGGER_SCOPE_CHAIN_END = 29
+JERRY_DEBUGGER_SCOPE_VARIABLES = 30
+JERRY_DEBUGGER_SCOPE_VARIABLES_END = 31
+
+# Debugger option flags
+JERRY_DEBUGGER_LITTLE_ENDIAN = 0x1
+
+# Subtypes of eval
+JERRY_DEBUGGER_EVAL_EVAL = "\0"
+JERRY_DEBUGGER_EVAL_THROW = "\1"
+JERRY_DEBUGGER_EVAL_ABORT = "\2"
+
+# Subtypes of eval result
+JERRY_DEBUGGER_EVAL_OK = 1
+JERRY_DEBUGGER_EVAL_ERROR = 2
+
+# Subtypes of output
+JERRY_DEBUGGER_OUTPUT_OK = 1
+JERRY_DEBUGGER_OUTPUT_ERROR = 2
+JERRY_DEBUGGER_OUTPUT_WARNING = 3
+JERRY_DEBUGGER_OUTPUT_DEBUG = 4
+JERRY_DEBUGGER_OUTPUT_TRACE = 5
+
+
+# Messages sent by the client to server.
+JERRY_DEBUGGER_FREE_BYTE_CODE_CP = 1
+JERRY_DEBUGGER_UPDATE_BREAKPOINT = 2
+JERRY_DEBUGGER_EXCEPTION_CONFIG = 3
+JERRY_DEBUGGER_PARSER_CONFIG = 4
+JERRY_DEBUGGER_MEMSTATS = 5
+JERRY_DEBUGGER_STOP = 6
+JERRY_DEBUGGER_PARSER_RESUME = 7
+JERRY_DEBUGGER_CLIENT_SOURCE = 8
+JERRY_DEBUGGER_CLIENT_SOURCE_PART = 9
+JERRY_DEBUGGER_NO_MORE_SOURCES = 10
+JERRY_DEBUGGER_CONTEXT_RESET = 11
+JERRY_DEBUGGER_CONTINUE = 12
+JERRY_DEBUGGER_STEP = 13
+JERRY_DEBUGGER_NEXT = 14
+JERRY_DEBUGGER_FINISH = 15
+JERRY_DEBUGGER_GET_BACKTRACE = 16
+JERRY_DEBUGGER_EVAL = 17
+JERRY_DEBUGGER_EVAL_PART = 18
+JERRY_DEBUGGER_GET_SCOPE_CHAIN = 19
+JERRY_DEBUGGER_GET_SCOPE_VARIABLES = 20
+
+MAX_BUFFER_SIZE = 128
+WEBSOCKET_BINARY_FRAME = 2
+WEBSOCKET_FIN_BIT = 0x80
+
+JERRY_DEBUGGER_SCOPE_WITH = 1
+JERRY_DEBUGGER_SCOPE_LOCAL = 2
+JERRY_DEBUGGER_SCOPE_CLOSURE = 3
+JERRY_DEBUGGER_SCOPE_GLOBAL = 4
+JERRY_DEBUGGER_SCOPE_NON_CLOSURE = 5
+
+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
+
+def arguments_parse():
+    parser = argparse.ArgumentParser(description="JerryScript debugger client")
+
+    parser.add_argument("address", action="store", nargs="?", default="localhost:5001",
+                        help="specify a unique network address for connection (default: %(default)s)")
+    parser.add_argument("-v", "--verbose", action="store_true", default=False,
+                        help="increase verbosity (default: %(default)s)")
+    parser.add_argument("--non-interactive", action="store_true", default=False,
+                        help="disable stop when newline is pressed (default: %(default)s)")
+    parser.add_argument("--color", action="store_true", default=False,
+                        help="enable color highlighting on source commands (default: %(default)s)")
+    parser.add_argument("--display", action="store", default=None, type=int,
+                        help="set display range")
+    parser.add_argument("--exception", action="store", default=None, type=int, choices=[0, 1],
+                        help="set exception config, usage 1: [Enable] or 0: [Disable]")
+    parser.add_argument("--client-source", action="store", default=[], type=str, nargs="+",
+                        help="specify a javascript source file to execute")
+
+    args = parser.parse_args()
+
+    if args.verbose:
+        logging.basicConfig(format="%(levelname)s: %(message)s", level=logging.DEBUG)
+        logging.debug("Debug logging mode: ON")
+
+    return args
+
+
+class JerryBreakpoint(object):
+
+    def __init__(self, line, offset, function):
+        self.line = line
+        self.offset = offset
+        self.function = function
+        self.active_index = -1
+
+    def __str__(self):
+        result = self.function.source_name or "<unknown>"
+        result += ":%d" % (self.line)
+
+        if self.function.is_func:
+            result += " (in "
+            result += self.function.name or "function"
+            result += "() at line:%d, col:%d)" % (self.function.line, self.function.column)
+        return result
+
+    def __repr__(self):
+        return ("Breakpoint(line:%d, offset:%d, active_index:%d)"
+                % (self.line, self.offset, self.active_index))
+
+class JerryPendingBreakpoint(object):
+    def __init__(self, line=None, source_name=None, function=None):
+        self.function = function
+        self.line = line
+        self.source_name = source_name
+
+        self.index = -1
+
+    def __str__(self):
+        result = self.source_name or ""
+        if self.line:
+            result += ":%d" % (self.line)
+        else:
+            result += "%s()" % (self.function)
+        return result
+
+
+class JerryFunction(object):
+    # pylint: disable=too-many-instance-attributes,too-many-arguments
+    def __init__(self, is_func, byte_code_cp, source, source_name, line, column, name, lines, offsets):
+        self.is_func = bool(is_func)
+        self.byte_code_cp = byte_code_cp
+        self.source = re.split("\r\n|[\r\n]", source)
+        self.source_name = source_name
+        self.name = name
+        self.lines = {}
+        self.offsets = {}
+        self.line = line
+        self.column = column
+        self.first_breakpoint_line = lines[0]
+        self.first_breakpoint_offset = offsets[0]
+
+        if len(self.source) > 1 and not self.source[-1]:
+            self.source.pop()
+
+        for i, _line in enumerate(lines):
+            offset = offsets[i]
+            breakpoint = JerryBreakpoint(_line, offset, self)
+            self.lines[_line] = breakpoint
+            self.offsets[offset] = breakpoint
+
+    def __repr__(self):
+        result = ("Function(byte_code_cp:0x%x, source_name:%r, name:%r, line:%d, column:%d { "
+                  % (self.byte_code_cp, self.source_name, self.name, self.line, self.column))
+
+        result += ','.join([str(breakpoint) for breakpoint in self.lines.values()])
+
+        return result + " })"
+
+
+class Multimap(object):
+
+    def __init__(self):
+        self.map = {}
+
+    def get(self, key):
+        if key in self.map:
+            return self.map[key]
+        return []
+
+    def insert(self, key, value):
+        if key in self.map:
+            self.map[key].append(value)
+        else:
+            self.map[key] = [value]
+
+    def delete(self, key, value):
+        items = self.map[key]
+
+        if len(items) == 1:
+            del self.map[key]
+        else:
+            del items[items.index(value)]
+
+    def __repr__(self):
+        return "Multimap(%r)" % (self.map)
+
+
+class DebuggerAction(object):
+    END = 0
+    WAIT = 1
+    TEXT = 2
+    PROMPT = 3
+
+    def __init__(self, action_type, action_text):
+        self.action_type = action_type
+        self.action_text = action_text
+
+    def get_type(self):
+        return self.action_type
+
+    def get_text(self):
+        return self.action_text
+
+
+class JerryDebugger(object):
+    # pylint: disable=too-many-instance-attributes,too-many-statements,too-many-public-methods,no-self-use
+    def __init__(self, address):
+
+        if ":" not in address:
+            self.host = address
+            self.port = 5001  # use default port
+        else:
+            self.host, self.port = address.split(":")
+            self.port = int(self.port)
+
+        print("Connecting to: %s:%s" % (self.host, self.port))
+
+        self.message_data = b""
+        self.prompt = False
+        self.function_list = {}
+        self.source = ''
+        self.source_name = ''
+        self.exception_string = ''
+        self.frame_index = 0
+        self.scope_vars = ""
+        self.scopes = ""
+        self.client_sources = []
+        self.last_breakpoint_hit = None
+        self.next_breakpoint_index = 0
+        self.active_breakpoint_list = {}
+        self.pending_breakpoint_list = {}
+        self.line_list = Multimap()
+        self.display = 0
+        self.green = ''
+        self.red = ''
+        self.yellow = ''
+        self.green_bg = ''
+        self.yellow_bg = ''
+        self.blue = ''
+        self.nocolor = ''
+        self.src_offset = 0
+        self.src_offset_diff = 0
+        self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.client_socket.connect((self.host, self.port))
+        self.non_interactive = False
+        self.current_out = b""
+        self.current_log = b""
+
+        self.send_message(b"GET /jerry-debugger HTTP/1.1\r\n" +
+                          b"Upgrade: websocket\r\n" +
+                          b"Connection: Upgrade\r\n" +
+                          b"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n")
+        result = b""
+        expected = (b"HTTP/1.1 101 Switching Protocols\r\n" +
+                    b"Upgrade: websocket\r\n" +
+                    b"Connection: Upgrade\r\n" +
+                    b"Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")
+
+        len_expected = len(expected)
+
+        while len(result) < len_expected:
+            result += self.client_socket.recv(1024)
+
+        len_result = len(result)
+
+        if result[0:len_expected] != expected:
+            raise Exception("Unexpected handshake")
+
+        if len_result > len_expected:
+            result = result[len_expected:]
+        else:
+            result = b""
+
+        len_expected = 10
+        # Network configurations, which has the following struct:
+        # header [2] - opcode[1], size[1]
+        # type [1]
+        # configuration [1]
+        # version [4]
+        # max_message_size [1]
+        # cpointer_size [1]
+
+        while len(result) < len_expected:
+            result += self.client_socket.recv(1024)
+
+        len_result = len(result)
+
+        expected = struct.pack("BBB",
+                               WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
+                               8,
+                               JERRY_DEBUGGER_CONFIGURATION)
+
+        if result[0:3] != expected:
+            raise Exception("Unexpected configuration")
+
+        self.little_endian = ord(result[3]) & JERRY_DEBUGGER_LITTLE_ENDIAN
+        self.max_message_size = ord(result[8])
+        self.cp_size = ord(result[9])
+
+        if self.little_endian:
+            self.byte_order = "<"
+            logging.debug("Little-endian machine")
+        else:
+            self.byte_order = ">"
+            logging.debug("Big-endian machine")
+
+        if self.cp_size == 2:
+            self.cp_format = "H"
+        else:
+            self.cp_format = "I"
+
+        self.idx_format = "I"
+
+        self.version = struct.unpack(self.byte_order + self.idx_format, result[4:8])[0]
+        if self.version != JERRY_DEBUGGER_VERSION:
+            raise Exception("Incorrect debugger version from target: %d expected: %d" %
+                            (self.version, JERRY_DEBUGGER_VERSION))
+
+        logging.debug("Compressed pointer size: %d", self.cp_size)
+
+        if len_result > len_expected:
+            self.message_data = result[len_expected:]
+
+    def __del__(self):
+        self.client_socket.close()
+
+    def _exec_command(self, command_id):
+        self.send_command(command_id)
+
+    def quit(self):
+        self.prompt = False
+        self._exec_command(JERRY_DEBUGGER_CONTINUE)
+
+    def stop(self):
+        self.send_command(JERRY_DEBUGGER_STOP)
+
+    def get_continue(self):
+        self.prompt = False
+        self._exec_command(JERRY_DEBUGGER_CONTINUE)
+
+    def finish(self):
+        self.prompt = False
+        self._exec_command(JERRY_DEBUGGER_FINISH)
+
+    def next(self):
+        self.prompt = False
+        self._exec_command(JERRY_DEBUGGER_NEXT)
+
+    def step(self):
+        self.prompt = False
+        self._exec_command(JERRY_DEBUGGER_STEP)
+
+    def memstats(self):
+        self.prompt = False
+        self._exec_command(JERRY_DEBUGGER_MEMSTATS)
+
+    def scope_chain(self):
+        self.prompt = False
+        self._exec_command(JERRY_DEBUGGER_GET_SCOPE_CHAIN)
+
+    def set_break(self, args):
+        if not args:
+            return "Error: Breakpoint index expected"
+
+        if ':' in args:
+            try:
+                if int(args.split(':', 1)[1]) <= 0:
+                    return "Error: Positive breakpoint index expected"
+
+                return self._set_breakpoint(args, False)
+
+            except ValueError as val_errno:
+                return "Error: Positive breakpoint index expected: %s" % (val_errno)
+
+        return self._set_breakpoint(args, False)
+
+    def delete(self, args):
+        if not args:
+            return "Error: Breakpoint index expected\n" \
+                   "Delete the given breakpoint, use 'delete all|active|pending' " \
+                   "to clear all the given breakpoints\n "
+        elif args in ['all', 'pending', 'active']:
+            if args == "all":
+                self.delete_active()
+                self.delete_pending()
+            elif args == "pending":
+                self.delete_pending()
+            elif args == "active":
+                self.delete_active()
+            return ""
+
+        try:
+            breakpoint_index = int(args)
+        except ValueError as val_errno:
+            return "Error: Integer number expected, %s\n" % (val_errno)
+
+        if breakpoint_index in self.active_breakpoint_list:
+            breakpoint = self.active_breakpoint_list[breakpoint_index]
+            del self.active_breakpoint_list[breakpoint_index]
+            breakpoint.active_index = -1
+            self.send_breakpoint(breakpoint)
+            return "Breakpoint %d deleted\n" % (breakpoint_index)
+        elif breakpoint_index in self.pending_breakpoint_list:
+            del self.pending_breakpoint_list[breakpoint_index]
+            if not self.pending_breakpoint_list:
+                self.send_parser_config(0)
+            return "Pending breakpoint %d deleted\n" % (breakpoint_index)
+        else:
+            return "Error: Breakpoint %d not found\n" % (breakpoint_index)
+
+    def breakpoint_list(self):
+        result = ''
+        if self.active_breakpoint_list:
+            result += "=== %sActive breakpoints %s ===\n" % (self.green_bg, self.nocolor)
+            for breakpoint in self.active_breakpoint_list.values():
+                result += " %d: %s\n" % (breakpoint.active_index, breakpoint)
+        if self.pending_breakpoint_list:
+            result += "=== %sPending breakpoints%s ===\n" % (self.yellow_bg, self.nocolor)
+            for breakpoint in self.pending_breakpoint_list.values():
+                result += " %d: %s (pending)\n" % (breakpoint.index, breakpoint)
+
+        if not self.active_breakpoint_list and not self.pending_breakpoint_list:
+            result += "No breakpoints\n"
+
+        return result
+
+    def backtrace(self, args):
+        max_depth = 0
+        min_depth = 0
+        get_total = 0
+
+        if args:
+            args = args.split(" ")
+            try:
+                if "t" in args:
+                    get_total = 1
+                    args.remove("t")
+
+                if len(args) >= 2:
+                    min_depth = int(args[0])
+                    max_depth = int(args[1])
+                    if max_depth <= 0 or min_depth < 0:
+                        return "Error: Positive integer number expected\n"
+                    if min_depth > max_depth:
+                        return "Error: Start depth needs to be lower than or equal to max depth\n"
+                elif len(args) >= 1:
+                    max_depth = int(args[0])
+                    if max_depth <= 0:
+                        return "Error: Positive integer number expected\n"
+
+            except ValueError as val_errno:
+                return "Error: Positive integer number expected, %s\n" % (val_errno)
+
+        self.frame_index = min_depth
+        message = struct.pack(self.byte_order + "BBIB" + self.idx_format + self.idx_format + "B",
+                              WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
+                              WEBSOCKET_FIN_BIT + 1 + 4 + 4 + 1,
+                              0,
+                              JERRY_DEBUGGER_GET_BACKTRACE,
+                              min_depth,
+                              max_depth,
+                              get_total)
+        self.send_message(message)
+        self.prompt = False
+        return ""
+
+    def scope_variables(self, args):
+        index = 0
+        if args:
+            try:
+                index = int(args)
+                if index < 0:
+                    print ("Error: A non negative integer number expected")
+                    return
+
+            except ValueError as val_errno:
+                return "Error: Non negative integer number expected, %s\n" % (val_errno)
+
+        message = struct.pack(self.byte_order + "BBIB" + self.idx_format,
+                              WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
+                              WEBSOCKET_FIN_BIT + 1 + 4,
+                              0,
+                              JERRY_DEBUGGER_GET_SCOPE_VARIABLES,
+                              index)
+        self.send_message(message)
+        self.prompt = False
+        return ""
+
+    def eval(self, code):
+        self._send_string(JERRY_DEBUGGER_EVAL_EVAL + code, JERRY_DEBUGGER_EVAL)
+        self.prompt = False
+
+    def eval_at(self, code, index):
+        self._send_string(JERRY_DEBUGGER_EVAL_EVAL + code, JERRY_DEBUGGER_EVAL, index)
+        self.prompt = False
+
+    def throw(self, code):
+        self._send_string(JERRY_DEBUGGER_EVAL_THROW + code, JERRY_DEBUGGER_EVAL)
+        self.prompt = False
+
+    def abort(self, args):
+        self.delete("all")
+        self.exception("0")  # disable the exception handler
+        self._send_string(JERRY_DEBUGGER_EVAL_ABORT + args, JERRY_DEBUGGER_EVAL)
+        self.prompt = False
+
+    def restart(self):
+        self._send_string(JERRY_DEBUGGER_EVAL_ABORT + "\"r353t\"", JERRY_DEBUGGER_EVAL)
+        self.prompt = False
+
+    def exception(self, args):
+        try:
+            enabled = int(args)
+        except (ValueError, TypeError):
+            enabled = -1
+
+        if enabled not in [0, 1]:
+            return "Error: Invalid input! Usage 1: [Enable] or 0: [Disable]\n"
+
+        if enabled:
+            logging.debug("Stop at exception enabled")
+            self.send_exception_config(enabled)
+
+            return "Stop at exception enabled\n"
+
+        logging.debug("Stop at exception disabled")
+        self.send_exception_config(enabled)
+
+        return "Stop at exception disabled\n"
+
+    def _send_string(self, args, message_type, index=0):
+
+        # 1: length of type byte
+        # 4: length of an uint32 value
+        message_header = 1 + 4
+
+        # Add scope chain index
+        if message_type == JERRY_DEBUGGER_EVAL:
+            args = struct.pack(self.byte_order + "I", index) + args
+
+        size = len(args)
+
+        max_fragment = min(self.max_message_size - message_header, size)
+
+        message = struct.pack(self.byte_order + "BBIBI",
+                              WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
+                              WEBSOCKET_FIN_BIT + max_fragment + message_header,
+                              0,
+                              message_type,
+                              size)
+
+        if size == max_fragment:
+            self.send_message(message + args)
+            return
+
+        self.send_message(message + args[0:max_fragment])
+        offset = max_fragment
+
+        if message_type == JERRY_DEBUGGER_EVAL:
+            message_type = JERRY_DEBUGGER_EVAL_PART
+        else:
+            message_type = JERRY_DEBUGGER_CLIENT_SOURCE_PART
+
+        # 1: length of type byte
+        message_header = 1
+
+        max_fragment = self.max_message_size - message_header
+        while offset < size:
+            next_fragment = min(max_fragment, size - offset)
+
+            message = struct.pack(self.byte_order + "BBIB",
+                                  WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
+                                  WEBSOCKET_FIN_BIT + next_fragment + message_header,
+                                  0,
+                                  message_type)
+
+            prev_offset = offset
+            offset += next_fragment
+            self.send_message(message + args[prev_offset:offset])
+
+    def delete_active(self):
+        for i in self.active_breakpoint_list.values():
+            breakpoint = self.active_breakpoint_list[i.active_index]
+            del self.active_breakpoint_list[i.active_index]
+            breakpoint.active_index = -1
+            self.send_breakpoint(breakpoint)
+
+    def delete_pending(self):
+        if self.pending_breakpoint_list:
+            self.pending_breakpoint_list.clear()
+            self.send_parser_config(0)
+
+    def breakpoint_pending_exists(self, breakpoint):
+        for existing_bp in self.pending_breakpoint_list.values():
+            if (breakpoint.line and existing_bp.source_name == breakpoint.source_name and \
+                  existing_bp.line == breakpoint.line) \
+               or (not breakpoint.line and existing_bp.function == breakpoint.function):
+                return True
+
+        return False
+
+    def send_breakpoint(self, breakpoint):
+        message = struct.pack(self.byte_order + "BBIBB" + self.cp_format + self.idx_format,
+                              WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
+                              WEBSOCKET_FIN_BIT + 1 + 1 + self.cp_size + 4,
+                              0,
+                              JERRY_DEBUGGER_UPDATE_BREAKPOINT,
+                              int(breakpoint.active_index >= 0),
+                              breakpoint.function.byte_code_cp,
+                              breakpoint.offset)
+        self.send_message(message)
+
+    def send_bytecode_cp(self, byte_code_cp):
+        message = struct.pack(self.byte_order + "BBIB" + self.cp_format,
+                              WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
+                              WEBSOCKET_FIN_BIT + 1 + self.cp_size,
+                              0,
+                              JERRY_DEBUGGER_FREE_BYTE_CODE_CP,
+                              byte_code_cp)
+        self.send_message(message)
+
+    def send_command(self, command):
+        message = struct.pack(self.byte_order + "BBIB",
+                              WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
+                              WEBSOCKET_FIN_BIT + 1,
+                              0,
+                              command)
+        self.send_message(message)
+
+    def send_exception_config(self, enable):
+        message = struct.pack(self.byte_order + "BBIBB",
+                              WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
+                              WEBSOCKET_FIN_BIT + 1 + 1,
+                              0,
+                              JERRY_DEBUGGER_EXCEPTION_CONFIG,
+                              enable)
+        self.send_message(message)
+
+    def send_parser_config(self, enable):
+        message = struct.pack(self.byte_order + "BBIBB",
+                              WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT,
+                              WEBSOCKET_FIN_BIT + 1 + 1,
+                              0,
+                              JERRY_DEBUGGER_PARSER_CONFIG,
+                              enable)
+        self.send_message(message)
+
+    def set_colors(self):
+        self.nocolor = '\033[0m'
+        self.green = '\033[92m'
+        self.red = '\033[31m'
+        self.yellow = '\033[93m'
+        self.green_bg = '\033[42m\033[30m'
+        self.yellow_bg = '\033[43m\033[30m'
+        self.blue = '\033[94m'
+
+    def send_message(self, message):
+        size = len(message)
+        while size > 0:
+            bytes_send = self.client_socket.send(message)
+            if bytes_send < size:
+                message = message[bytes_send:]
+            size -= bytes_send
+
+
+    def get_message(self, blocking):
+        # Connection was closed
+        if self.message_data is None:
+            return None
+
+        while True:
+            if len(self.message_data) >= 2:
+                if ord(self.message_data[0]) != WEBSOCKET_BINARY_FRAME | WEBSOCKET_FIN_BIT:
+                    raise Exception("Unexpected data frame")
+
+                size = ord(self.message_data[1])
+                if size == 0 or size >= 126:
+                    raise Exception("Unexpected data frame")
+
+                if len(self.message_data) >= size + 2:
+                    result = self.message_data[0:size + 2]
+                    self.message_data = self.message_data[size + 2:]
+                    return result
+
+            if not blocking:
+                select_result = select.select([self.client_socket], [], [], 0)[0]
+                if self.client_socket not in select_result:
+                    return b''
+
+            data = self.client_socket.recv(MAX_BUFFER_SIZE)
+
+            if not data:
+                self.message_data = None
+                return None
+            self.message_data += data
+
+    def store_client_sources(self, args):
+        self.client_sources = args
+
+    def send_client_source(self):
+        # Send no more source message if there is no source
+        if not self.client_sources:
+            self.send_no_more_source()
+            return
+
+        path = self.client_sources.pop(0)
+        if not path.lower().endswith('.js'):
+            sys.exit("Error: Javascript file expected!")
+            return
+
+        with open(path, 'r') as src_file:
+            content = path + "\0" + src_file.read()
+            self._send_string(content, JERRY_DEBUGGER_CLIENT_SOURCE)
+
+    def send_no_more_source(self):
+        self._exec_command(JERRY_DEBUGGER_NO_MORE_SOURCES)
+
+    # pylint: disable=too-many-branches,too-many-locals,too-many-statements,too-many-return-statements
+    def process_messages(self):
+        result = ""
+
+        while True:
+            data = self.get_message(False)
+            if not self.non_interactive:
+                if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
+                    sys.stdin.readline()
+                    self.stop()
+
+            if data == b'':
+                action_type = DebuggerAction.PROMPT if self.prompt else DebuggerAction.WAIT
+                return DebuggerAction(action_type, "")
+
+            if not data:  # Break the while loop if there is no more data.
+                return DebuggerAction(DebuggerAction.END, "")
+
+            buffer_type = ord(data[2])
+            buffer_size = ord(data[1]) - 1
+
+            logging.debug("Main buffer type: %d, message size: %d", buffer_type, buffer_size)
+
+            if buffer_type in [JERRY_DEBUGGER_PARSE_ERROR,
+                               JERRY_DEBUGGER_BYTE_CODE_CP,
+                               JERRY_DEBUGGER_PARSE_FUNCTION,
+                               JERRY_DEBUGGER_BREAKPOINT_LIST,
+                               JERRY_DEBUGGER_SOURCE_CODE,
+                               JERRY_DEBUGGER_SOURCE_CODE_END,
+                               JERRY_DEBUGGER_SOURCE_CODE_NAME,
+                               JERRY_DEBUGGER_SOURCE_CODE_NAME_END,
+                               JERRY_DEBUGGER_FUNCTION_NAME,
+                               JERRY_DEBUGGER_FUNCTION_NAME_END]:
+                result = self._parse_source(data)
+                if result:
+                    return DebuggerAction(DebuggerAction.TEXT, result)
+
+            elif buffer_type == JERRY_DEBUGGER_WAITING_AFTER_PARSE:
+                self.send_command(JERRY_DEBUGGER_PARSER_RESUME)
+
+            elif buffer_type == JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP:
+                self._release_function(data)
+
+            elif buffer_type in [JERRY_DEBUGGER_BREAKPOINT_HIT, JERRY_DEBUGGER_EXCEPTION_HIT]:
+                breakpoint_data = struct.unpack(self.byte_order + self.cp_format + self.idx_format, data[3:])
+
+                breakpoint = self._get_breakpoint(breakpoint_data)
+                self.last_breakpoint_hit = breakpoint[0]
+
+                if buffer_type == JERRY_DEBUGGER_EXCEPTION_HIT:
+                    result += "Exception throw detected (to disable automatic stop type exception 0)\n"
+                    if self.exception_string:
+                        result += "Exception hint: %s\n" % (self.exception_string)
+                        self.exception_string = ""
+
+                if breakpoint[1]:
+                    breakpoint_info = "at"
+                else:
+                    breakpoint_info = "around"
+
+                if breakpoint[0].active_index >= 0:
+                    breakpoint_info += " breakpoint:%s%d%s" % (self.red, breakpoint[0].active_index, self.nocolor)
+
+                result += "Stopped %s %s\n" % (breakpoint_info, breakpoint[0])
+
+                if self.display > 0:
+                    result += self.print_source(self.display, self.src_offset)
+
+                self.prompt = True
+                return DebuggerAction(DebuggerAction.TEXT, result)
+
+            elif buffer_type == JERRY_DEBUGGER_EXCEPTION_STR:
+                self.exception_string += data[3:]
+
+            elif buffer_type == JERRY_DEBUGGER_EXCEPTION_STR_END:
+                self.exception_string += data[3:]
+
+            elif buffer_type == JERRY_DEBUGGER_BACKTRACE_TOTAL:
+                total = struct.unpack(self.byte_order + self.idx_format, data[3:])[0]
+                result += "Total number of frames: %d\n" % (total)
+                return DebuggerAction(DebuggerAction.TEXT, result)
+
+            elif buffer_type in [JERRY_DEBUGGER_BACKTRACE, JERRY_DEBUGGER_BACKTRACE_END]:
+                frame_index = self.frame_index
+
+                buffer_pos = 3
+                while buffer_size > 0:
+                    breakpoint_data = struct.unpack(self.byte_order + self.cp_format + self.idx_format,
+                                                    data[buffer_pos: buffer_pos + self.cp_size + 4])
+
+                    breakpoint = self._get_breakpoint(breakpoint_data)
+
+                    result += "Frame %d: %s\n" % (frame_index, breakpoint[0])
+
+                    frame_index += 1
+                    buffer_pos += 6
+                    buffer_size -= 6
+
+                if buffer_type == JERRY_DEBUGGER_BACKTRACE_END:
+                    self.prompt = True
+                else:
+                    self.frame_index = frame_index
+
+                return DebuggerAction(DebuggerAction.TEXT, result)
+
+            elif buffer_type in [JERRY_DEBUGGER_EVAL_RESULT,
+                                 JERRY_DEBUGGER_EVAL_RESULT_END,
+                                 JERRY_DEBUGGER_OUTPUT_RESULT,
+                                 JERRY_DEBUGGER_OUTPUT_RESULT_END]:
+
+                result = self._process_incoming_text(buffer_type, data)
+                return DebuggerAction(DebuggerAction.TEXT, result)
+
+            elif buffer_type == JERRY_DEBUGGER_MEMSTATS_RECEIVE:
+
+                memory_stats = struct.unpack(self.byte_order + self.idx_format * 5,
+                                             data[3: 3 + 4 * 5])
+
+                result += "Allocated bytes: %s\n" % memory_stats[0]
+                result += "Byte code bytes: %s\n" % memory_stats[1]
+                result += "String bytes: %s\n" % memory_stats[2]
+                result += "Object bytes: %s\n" % memory_stats[3]
+                result += "Property bytes: %s\n" % memory_stats[4]
+
+                self.prompt = True
+                return DebuggerAction(DebuggerAction.TEXT, result)
+
+            elif buffer_type == JERRY_DEBUGGER_WAIT_FOR_SOURCE:
+                self.send_client_source()
+
+            elif buffer_type in [JERRY_DEBUGGER_SCOPE_CHAIN, JERRY_DEBUGGER_SCOPE_CHAIN_END]:
+                self.scopes = data[3:]
+
+                if buffer_type == JERRY_DEBUGGER_SCOPE_CHAIN_END:
+                    result = self.process_scopes()
+                    self.scopes = ""
+
+                    self.prompt = True
+
+                return DebuggerAction(DebuggerAction.TEXT, result)
+
+            elif buffer_type in [JERRY_DEBUGGER_SCOPE_VARIABLES, JERRY_DEBUGGER_SCOPE_VARIABLES_END]:
+                self.scope_vars += "".join(data[3:])
+
+                if buffer_type == JERRY_DEBUGGER_SCOPE_VARIABLES_END:
+                    result = self.process_scope_variables()
+                    self.scope_vars = ""
+
+                    self.prompt = True
+
+                return DebuggerAction(DebuggerAction.TEXT, result)
+
+            else:
+                raise Exception("Unknown message")
+
+    def print_source(self, line_num, offset):
+        msg = ""
+        last_bp = self.last_breakpoint_hit
+
+        if not last_bp:
+            return ""
+
+        lines = last_bp.function.source
+        if last_bp.function.source_name:
+            msg += "Source: %s\n" % (last_bp.function.source_name)
+
+        if line_num == 0:
+            start = 0
+            end = len(last_bp.function.source)
+        else:
+            start = max(last_bp.line - line_num, 0)
+            end = min(last_bp.line + line_num - 1, len(last_bp.function.source))
+            if offset:
+                if start + offset < 0:
+                    self.src_offset += self.src_offset_diff
+                    offset += self.src_offset_diff
+                elif end + offset > len(last_bp.function.source):
+                    self.src_offset -= self.src_offset_diff
+                    offset -= self.src_offset_diff
+
+                start = max(start + offset, 0)
+                end = min(end + offset, len(last_bp.function.source))
+
+        for i in range(start, end):
+            if i == last_bp.line - 1:
+                msg += "%s%4d%s %s>%s %s\n" % (self.green, i + 1, self.nocolor, self.red, \
+                                                         self.nocolor, lines[i])
+            else:
+                msg += "%s%4d%s   %s\n" % (self.green, i + 1, self.nocolor, lines[i])
+
+        return msg
+
+
+    # pylint: disable=too-many-branches,too-many-locals,too-many-statements
+    def _parse_source(self, data):
+        source_code = ""
+        source_code_name = ""
+        function_name = ""
+        stack = [{"line": 1,
+                  "column": 1,
+                  "name": "",
+                  "lines": [],
+                  "offsets": []}]
+        new_function_list = {}
+        result = ""
+
+        while True:
+            if data is None:
+                return "Error: connection lost during source code receiving"
+
+            buffer_type = ord(data[2])
+            buffer_size = ord(data[1]) - 1
+
+            logging.debug("Parser buffer type: %d, message size: %d", buffer_type, buffer_size)
+
+            if buffer_type == JERRY_DEBUGGER_PARSE_ERROR:
+                logging.error("Syntax error found")
+                return ""
+
+            elif buffer_type in [JERRY_DEBUGGER_SOURCE_CODE, JERRY_DEBUGGER_SOURCE_CODE_END]:
+                source_code += data[3:]
+
+            elif buffer_type in [JERRY_DEBUGGER_SOURCE_CODE_NAME, JERRY_DEBUGGER_SOURCE_CODE_NAME_END]:
+                source_code_name += data[3:]
+
+            elif buffer_type in [JERRY_DEBUGGER_FUNCTION_NAME, JERRY_DEBUGGER_FUNCTION_NAME_END]:
+                function_name += data[3:]
+
+            elif buffer_type == JERRY_DEBUGGER_PARSE_FUNCTION:
+                logging.debug("Source name: %s, function name: %s", source_code_name, function_name)
+
+                position = struct.unpack(self.byte_order + self.idx_format + self.idx_format,
+                                         data[3: 3 + 4 + 4])
+
+                stack.append({"source": source_code,
+                              "source_name": source_code_name,
+                              "line": position[0],
+                              "column": position[1],
+                              "name": function_name,
+                              "lines": [],
+                              "offsets": []})
+                function_name = ""
+
+            elif buffer_type in [JERRY_DEBUGGER_BREAKPOINT_LIST, JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST]:
+                name = "lines"
+                if buffer_type == JERRY_DEBUGGER_BREAKPOINT_OFFSET_LIST:
+                    name = "offsets"
+
+                logging.debug("Breakpoint %s received", name)
+
+                buffer_pos = 3
+                while buffer_size > 0:
+                    line = struct.unpack(self.byte_order + self.idx_format,
+                                         data[buffer_pos: buffer_pos + 4])
+                    stack[-1][name].append(line[0])
+                    buffer_pos += 4
+                    buffer_size -= 4
+
+            elif buffer_type == JERRY_DEBUGGER_BYTE_CODE_CP:
+                byte_code_cp = struct.unpack(self.byte_order + self.cp_format,
+                                             data[3: 3 + self.cp_size])[0]
+
+                logging.debug("Byte code cptr received: {0x%x}", byte_code_cp)
+
+                func_desc = stack.pop()
+
+                # We know the last item in the list is the general byte code.
+                if not stack:
+                    func_desc["source"] = source_code
+                    func_desc["source_name"] = source_code_name
+
+                function = JerryFunction(stack,
+                                         byte_code_cp,
+                                         func_desc["source"],
+                                         func_desc["source_name"],
+                                         func_desc["line"],
+                                         func_desc["column"],
+                                         func_desc["name"],
+                                         func_desc["lines"],
+                                         func_desc["offsets"])
+
+                new_function_list[byte_code_cp] = function
+
+                if not stack:
+                    logging.debug("Parse completed.")
+                    break
+
+            elif buffer_type == JERRY_DEBUGGER_RELEASE_BYTE_CODE_CP:
+                # Redefined functions are dropped during parsing.
+                byte_code_cp = struct.unpack(self.byte_order + self.cp_format,
+                                             data[3: 3 + self.cp_size])[0]
+
+                if byte_code_cp in new_function_list:
+                    del new_function_list[byte_code_cp]
+                    self.send_bytecode_cp(byte_code_cp)
+                else:
+                    self._release_function(data)
+
+            elif buffer_type in [JERRY_DEBUGGER_OUTPUT_RESULT,
+                                 JERRY_DEBUGGER_OUTPUT_RESULT_END]:
+                result += self._process_incoming_text(buffer_type, data)
+
+            else:
+                logging.error("Parser error!")
+                raise Exception("Unexpected message")
+
+            data = self.get_message(True)
+
+        # Copy the ready list to the global storage.
+        self.function_list.update(new_function_list)
+
+        for function in new_function_list.values():
+            for line, breakpoint in function.lines.items():
+                self.line_list.insert(line, breakpoint)
+
+        # Try to set the pending breakpoints
+        if self.pending_breakpoint_list:
+            logging.debug("Pending breakpoints available")
+            bp_list = self.pending_breakpoint_list
+
+            for breakpoint_index, breakpoint in bp_list.items():
+                source_lines = 0
+                for src in new_function_list.values():
+                    if src.source_name == breakpoint.source_name:
+                        source_lines = len(src.source)
+                        break
+
+                if breakpoint.line:
+                    if breakpoint.line <= source_lines:
+                        command = breakpoint.source_name + ":" + str(breakpoint.line)
+                        set_result = self._set_breakpoint(command, True)
+
+                        if set_result:
+                            result += set_result
+                            del bp_list[breakpoint_index]
+                elif breakpoint.function:
+                    command = breakpoint.function
+                    set_result = self._set_breakpoint(command, True)
+
+                    if set_result:
+                        result += set_result
+                        del bp_list[breakpoint_index]
+
+            if not bp_list:
+                self.send_parser_config(0)
+            return result
+
+        logging.debug("No pending breakpoints")
+        return result
+
+
+    def _release_function(self, data):
+        byte_code_cp = struct.unpack(self.byte_order + self.cp_format,
+                                     data[3: 3 + self.cp_size])[0]
+
+        function = self.function_list[byte_code_cp]
+
+        for line, breakpoint in function.lines.items():
+            self.line_list.delete(line, breakpoint)
+            if breakpoint.active_index >= 0:
+                del self.active_breakpoint_list[breakpoint.active_index]
+
+        del self.function_list[byte_code_cp]
+        self.send_bytecode_cp(byte_code_cp)
+        logging.debug("Function {0x%x} byte-code released", byte_code_cp)
+
+
+    def _enable_breakpoint(self, breakpoint):
+        if isinstance(breakpoint, JerryPendingBreakpoint):
+            if self.breakpoint_pending_exists(breakpoint):
+                return "%sPending breakpoint%s already exists\n" % (self.yellow, self.nocolor)
+
+            self.next_breakpoint_index += 1
+            breakpoint.index = self.next_breakpoint_index
+            self.pending_breakpoint_list[self.next_breakpoint_index] = breakpoint
+            return ("%sPending breakpoint %d%s at %s\n" % (self.yellow,
+                                                           breakpoint.index,
+                                                           self.nocolor,
+                                                           breakpoint))
+
+        if breakpoint.active_index < 0:
+            self.next_breakpoint_index += 1
+            self.active_breakpoint_list[self.next_breakpoint_index] = breakpoint
+            breakpoint.active_index = self.next_breakpoint_index
+            self.send_breakpoint(breakpoint)
+
+        return "%sBreakpoint %d%s at %s\n" % (self.green,
+                                              breakpoint.active_index,
+                                              self.nocolor,
+                                              breakpoint)
+
+
+    def _set_breakpoint(self, string, pending):
+        line = re.match("(.*):(\\d+)$", string)
+        result = ""
+
+        if line:
+            source_name = line.group(1)
+            new_line = int(line.group(2))
+
+            for breakpoint in self.line_list.get(new_line):
+                func_source = breakpoint.function.source_name
+                if (source_name == func_source or
+                        func_source.endswith("/" + source_name) or
+                        func_source.endswith("\\" + source_name)):
+
+                    result += self._enable_breakpoint(breakpoint)
+
+        else:
+            for function in self.function_list.values():
+                if function.name == string:
+                    result += self._enable_breakpoint(function.lines[function.first_breakpoint_line])
+
+        if not result and not pending:
+            print("No breakpoint found, do you want to add a %spending breakpoint%s? (y or [n])" % \
+                  (self.yellow, self.nocolor))
+
+            ans = sys.stdin.readline()
+            if ans in ['yes\n', 'y\n']:
+                if not self.pending_breakpoint_list:
+                    self.send_parser_config(1)
+
+                if line:
+                    breakpoint = JerryPendingBreakpoint(int(line.group(2)), line.group(1))
+                else:
+                    breakpoint = JerryPendingBreakpoint(function=string)
+                result += self._enable_breakpoint(breakpoint)
+
+        return result
+
+
+    def _get_breakpoint(self, breakpoint_data):
+        function = self.function_list[breakpoint_data[0]]
+        offset = breakpoint_data[1]
+
+        if offset in function.offsets:
+            return (function.offsets[offset], True)
+
+        if offset < function.first_breakpoint_offset:
+            return (function.offsets[function.first_breakpoint_offset], False)
+
+        nearest_offset = -1
+
+        for current_offset in function.offsets:
+            if current_offset <= offset and current_offset > nearest_offset:
+                nearest_offset = current_offset
+
+        return (function.offsets[nearest_offset], False)
+
+    def _process_incoming_text(self, buffer_type, data):
+        message = b""
+        msg_type = buffer_type
+        while True:
+            if buffer_type in [JERRY_DEBUGGER_EVAL_RESULT_END,
+                               JERRY_DEBUGGER_OUTPUT_RESULT_END]:
+                subtype = ord(data[-1])
+                message += data[3:-1]
+                break
+            else:
+                message += data[3:]
+
+            data = self.get_message(True)
+            buffer_type = ord(data[2])
+            # Checks if the next frame would be an invalid data frame.
+            # If it is not the message type, or the end type of it, an exception is thrown.
+            if buffer_type not in [msg_type, msg_type + 1]:
+                raise Exception("Invalid data caught")
+
+        # Subtypes of output
+        if buffer_type == JERRY_DEBUGGER_OUTPUT_RESULT_END:
+            if subtype == JERRY_DEBUGGER_OUTPUT_OK:
+                log_type = "%sout:%s " % (self.blue, self.nocolor)
+
+                message = self.current_out + message
+                lines = message.split("\n")
+                self.current_out = lines.pop()
+
+                return "".join(["%s%s\n" % (log_type, line) for line in lines])
+
+            if subtype == JERRY_DEBUGGER_OUTPUT_DEBUG:
+                log_type = "%slog:%s " % (self.yellow, self.nocolor)
+
+                message = self.current_log + message
+                lines = message.split("\n")
+                self.current_log = lines.pop()
+
+                return "".join(["%s%s\n" % (log_type, line) for line in lines])
+
+            if not message.endswith("\n"):
+                message += "\n"
+
+            if subtype == JERRY_DEBUGGER_OUTPUT_WARNING:
+                return "%swarning: %s%s" % (self.yellow, self.nocolor, message)
+            elif subtype == JERRY_DEBUGGER_OUTPUT_ERROR:
+                return "%serr: %s%s" % (self.red, self.nocolor, message)
+            elif subtype == JERRY_DEBUGGER_OUTPUT_TRACE:
+                return "%strace: %s%s" % (self.blue, self.nocolor, message)
+
+        # Subtypes of eval
+        self.prompt = True
+
+        if not message.endswith("\n"):
+            message += "\n"
+
+        if subtype == JERRY_DEBUGGER_EVAL_ERROR:
+            return "Uncaught exception: %s" % (message)
+        return message
+
+    def process_scope_variables(self):
+        buff_size = len(self.scope_vars)
+        buff_pos = 0
+
+        table = [['name', 'type', 'value']]
+
+        while buff_pos != buff_size:
+            # Process name
+            name_length = ord(self.scope_vars[buff_pos:buff_pos + 1])
+            buff_pos += 1
+            name = self.scope_vars[buff_pos:buff_pos + name_length]
+            buff_pos += name_length
+
+            # Process type
+            value_type = ord(self.scope_vars[buff_pos:buff_pos + 1])
+
+            buff_pos += 1
+
+            value_length = ord(self.scope_vars[buff_pos:buff_pos + 1])
+            buff_pos += 1
+            value = self.scope_vars[buff_pos: buff_pos + value_length]
+            buff_pos += value_length
+
+            if value_type == JERRY_DEBUGGER_VALUE_UNDEFINED:
+                table.append([name, 'undefined', value])
+            elif value_type == JERRY_DEBUGGER_VALUE_NULL:
+                table.append([name, 'Null', value])
+            elif value_type == JERRY_DEBUGGER_VALUE_BOOLEAN:
+                table.append([name, 'Boolean', value])
+            elif value_type == JERRY_DEBUGGER_VALUE_NUMBER:
+                table.append([name, 'Number', value])
+            elif value_type == JERRY_DEBUGGER_VALUE_STRING:
+                table.append([name, 'String', value])
+            elif value_type == JERRY_DEBUGGER_VALUE_FUNCTION:
+                table.append([name, 'Function', value])
+            elif value_type == JERRY_DEBUGGER_VALUE_ARRAY:
+                table.append([name, 'Array', '[' + value + ']'])
+            elif value_type == JERRY_DEBUGGER_VALUE_OBJECT:
+                table.append([name, 'Object', value])
+
+        result = self.form_table(table)
+
+        return result
+
+    def process_scopes(self):
+        result = ""
+        table = [['level', 'type']]
+
+        for i, level in enumerate(self.scopes):
+            if ord(level) == JERRY_DEBUGGER_SCOPE_WITH:
+                table.append([str(i), 'with'])
+            elif ord(level) == JERRY_DEBUGGER_SCOPE_GLOBAL:
+                table.append([str(i), 'global'])
+            elif ord(level) == JERRY_DEBUGGER_SCOPE_NON_CLOSURE:
+                # Currently it is only marks the catch closure.
+                table.append([str(i), 'catch'])
+            elif ord(level) == JERRY_DEBUGGER_SCOPE_LOCAL:
+                table.append([str(i), 'local'])
+            elif ord(level) == JERRY_DEBUGGER_SCOPE_CLOSURE:
+                table.append([str(i), 'closure'])
+            else:
+                raise Exception("Unexpected scope chain element")
+
+        result = self.form_table(table)
+
+        return result
+
+    def form_table(self, table):
+        result = ""
+        col_width = [max(len(x) for x in col) for col in zip(*table)]
+        for line in table:
+            result += " | ".join("{:{}}".format(x, col_width[i])
+                                 for i, x in enumerate(line)) + " \n"
+
+        return result
index c90c547a6bfe45c59f8c11eba833f1bcd7c80dd6..3f041532f5697ff1f90e5caad796dbd1139e588b 100644 (file)
@@ -16,28 +16,42 @@ cmake_minimum_required (VERSION 2.8.12)
 set(JERRY_EXT_NAME jerry-ext)
 project (${JERRY_EXT_NAME} C)
 
+# Optional features
+set(FEATURE_INIT_FINI OFF CACHE BOOL "Enable init/fini arrays?")
+
+# Status messages
+message(STATUS "FEATURE_INIT_FINI           " ${FEATURE_INIT_FINI})
+
 # Include directories
-set(INCLUDE_EXT "${CMAKE_CURRENT_SOURCE_DIR}/include")
+set(INCLUDE_EXT_PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
+set(INCLUDE_EXT_PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/common")
+
+set(INCLUDE_EXT_PUBLIC ${INCLUDE_EXT_PUBLIC} PARENT_SCOPE) # for jerry-port
 
 if(FEATURE_INIT_FINI)
   set(DEFINES_EXT ${DEFINES_EXT} ENABLE_INIT_FINI)
 endif()
 
 # Source directories
-file(GLOB SOURCE_EXT_ARG      arg/*.c)
-file(GLOB SOURCE_EXT_MODULE   module/*.c)
-file(GLOB SOURCE_EXT_HANDLER  handler/*.c)
+file(GLOB SOURCE_EXT_ARG        arg/*.c)
+file(GLOB SOURCE_EXT_COMMON     common/*.c)
+file(GLOB SOURCE_EXT_DEBUGGER   debugger/*.c)
+file(GLOB SOURCE_EXT_HANDLER    handler/*.c)
+file(GLOB SOURCE_EXT_MODULE     module/*.c)
 
 set(SOURCE_EXT
     ${SOURCE_EXT_ARG}
-    ${SOURCE_EXT_MODULE}
-    ${SOURCE_EXT_HANDLER})
+    ${SOURCE_EXT_COMMON}
+    ${SOURCE_EXT_DEBUGGER}
+    ${SOURCE_EXT_HANDLER}
+    ${SOURCE_EXT_MODULE})
 
-add_library(${JERRY_EXT_NAME} STATIC ${SOURCE_EXT})
+add_library(${JERRY_EXT_NAME} ${SOURCE_EXT})
 
-target_include_directories(${JERRY_EXT_NAME} PUBLIC ${INCLUDE_EXT})
+target_include_directories(${JERRY_EXT_NAME} PUBLIC ${INCLUDE_EXT_PUBLIC})
+target_include_directories(${JERRY_EXT_NAME} PRIVATE ${INCLUDE_EXT_PRIVATE})
 target_compile_definitions(${JERRY_EXT_NAME} PUBLIC ${DEFINES_EXT})
 target_link_libraries(${JERRY_EXT_NAME} jerry-core)
 
 install(TARGETS ${JERRY_EXT_NAME} DESTINATION lib)
-install(DIRECTORY ${INCLUDE_EXT}/ DESTINATION include)
+install(DIRECTORY ${INCLUDE_EXT_PUBLIC}/ DESTINATION include)
index e71b34ab0ea40cd70063b7ffa2d259620492490a..c7f4835d2e5c8e828711431f0c317cbae3fbcf3b 100644 (file)
@@ -79,7 +79,7 @@ jerryx_arg_transform_number_common (jerryx_arg_js_iterator_t *js_arg_iter_p, /**
 
   jerry_value_t to_number = jerry_value_to_number (js_arg);
 
-  if (jerry_value_has_error_flag (to_number))
+  if (jerry_value_is_error (to_number))
   {
     jerry_release_value (to_number);
 
@@ -177,14 +177,14 @@ jerryx_arg_helper_process_double (double *d, /**< [in, out] the number to be pro
   { \
     double tmp = 0.0; \
     jerry_value_t rv = jerryx_arg_transform_number ## suffix ## _common (js_arg_iter_p, &tmp); \
-    if (jerry_value_has_error_flag (rv)) \
+    if (jerry_value_is_error (rv)) \
     { \
       return rv; \
     } \
     jerry_release_value (rv); \
     jerryx_arg_int_option_t *options_p = (jerryx_arg_int_option_t *) &c_arg_p->extra_info; \
     rv = jerryx_arg_helper_process_double (&tmp, min, max, *options_p); \
-    if (jerry_value_has_error_flag (rv)) \
+    if (jerry_value_is_error (rv)) \
     { \
       return rv; \
     } \
@@ -329,7 +329,7 @@ jerryx_arg_transform_string_common (jerryx_arg_js_iterator_t *js_arg_iter_p, /**
 
   jerry_value_t to_string = jerry_value_to_string (js_arg);
 
-  if (jerry_value_has_error_flag (to_string))
+  if (jerry_value_is_error (to_string))
   {
     jerry_release_value (to_string);
 
index 1f587a6fd00b32a706265bf20473f35d4fffc8e2..9239106bae5453811d758f2a71eed49ec0cc2577 100644 (file)
@@ -47,7 +47,7 @@ jerryx_arg_transform_args (const jerry_value_t *js_arg_p, /**< points to the arr
     .js_arg_idx = 0
   };
 
-  for (; c_arg_cnt != 0 && !jerry_value_has_error_flag (ret); c_arg_cnt--, c_arg_p++)
+  for (; c_arg_cnt != 0 && !jerry_value_is_error (ret); c_arg_cnt--, c_arg_p++)
   {
     ret = c_arg_p->func (&iterator, c_arg_p);
   }
@@ -86,7 +86,7 @@ jerryx_arg_transform_this_and_args (const jerry_value_t this_val, /**< the this_
 
   jerry_value_t ret = c_arg_p->func (&iterator, c_arg_p);
 
-  if (jerry_value_has_error_flag (ret))
+  if (jerry_value_is_error (ret))
   {
     jerry_release_value (ret);
 
@@ -115,7 +115,7 @@ jerryx_arg_transform_object_properties (const jerry_value_t obj_val,/**< the JS
     return jerry_create_error (JERRY_ERROR_TYPE, (jerry_char_t *) "Not an object.");
   }
 
-  jerry_value_t prop[name_cnt];
+  JERRY_VLA (jerry_value_t, prop, name_cnt);
 
   for (jerry_length_t i = 0; i < name_cnt; i++, name_p++)
   {
@@ -123,7 +123,7 @@ jerryx_arg_transform_object_properties (const jerry_value_t obj_val,/**< the JS
     prop[i] = jerry_get_property (obj_val, name_str);
     jerry_release_value (name_str);
 
-    if (jerry_value_has_error_flag (prop[i]))
+    if (jerry_value_is_error (prop[i]))
     {
       for (jerry_length_t j = 0; j < i; j++)
       {
@@ -160,13 +160,13 @@ jerryx_arg_transform_array (const jerry_value_t array_val, /**< points to the JS
     return jerry_create_error (JERRY_ERROR_TYPE, (jerry_char_t *) "Not an array.");
   }
 
-  jerry_value_t arr[c_arg_cnt];
+  JERRY_VLA (jerry_value_t, arr, c_arg_cnt);
 
   for (jerry_length_t i = 0; i < c_arg_cnt; i++)
   {
     arr[i] = jerry_get_property_by_index (array_val, i);
 
-    if (jerry_value_has_error_flag (arr[i]))
+    if (jerry_value_is_error (arr[i]))
     {
       for (jerry_length_t j = 0; j < i; j++)
       {
diff --git a/deps/jerry/jerry-ext/common/jext-common.h b/deps/jerry/jerry-ext/common/jext-common.h
new file mode 100644 (file)
index 0000000..9c59e0b
--- /dev/null
@@ -0,0 +1,95 @@
+/* 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 JEXT_COMMON_H
+#define JEXT_COMMON_H
+
+#include <stdio.h>
+#include <string.h>
+
+#include "jerryscript.h"
+#include "jerryscript-port.h"
+
+/*
+ * Make sure unused parameters, variables, or expressions trigger no compiler warning.
+ */
+#define JERRYX_UNUSED(x) ((void) (x))
+
+/*
+ * Asserts
+ *
+ * Warning:
+ *         Don't use JERRY_STATIC_ASSERT in headers, because
+ *         __LINE__ may be the same for asserts in a header
+ *         and in an implementation file.
+ */
+#define JERRYX_STATIC_ASSERT_GLUE_(a, b, c) a ## b ## _ ## c
+#define JERRYX_STATIC_ASSERT_GLUE(a, b, c) JERRYX_STATIC_ASSERT_GLUE_ (a, b, c)
+#define JERRYX_STATIC_ASSERT(x, msg) \
+  enum { JERRYX_STATIC_ASSERT_GLUE (static_assertion_failed_, __LINE__, msg) = 1 / (!!(x)) }
+
+#ifndef JERRY_NDEBUG
+void JERRY_ATTR_NORETURN
+jerry_assert_fail (const char *assertion, const char *file, const char *function, const uint32_t line);
+void JERRY_ATTR_NORETURN
+jerry_unreachable (const char *file, const char *function, const uint32_t line);
+
+#define JERRYX_ASSERT(x) \
+  do \
+  { \
+    if (JERRY_UNLIKELY (!(x))) \
+    { \
+      jerry_assert_fail (#x, __FILE__, __func__, __LINE__); \
+    } \
+  } while (0)
+
+#define JERRYX_UNREACHABLE() \
+  do \
+  { \
+    jerry_unreachable (__FILE__, __func__, __LINE__); \
+  } while (0)
+#else /* JERRY_NDEBUG */
+#define JERRYX_ASSERT(x) \
+  do \
+  { \
+    if (false) \
+    { \
+      JERRYX_UNUSED (x); \
+    } \
+  } while (0)
+
+#ifdef __GNUC__
+#define JERRYX_UNREACHABLE() __builtin_unreachable ()
+#endif /* __GNUC__ */
+
+#ifdef _MSC_VER
+#define JERRYX_UNREACHABLE()  _assume (0)
+#endif /* _MSC_VER */
+
+#ifndef JERRYX_UNREACHABLE
+#define JERRYX_UNREACHABLE()
+#endif /* !JERRYX_UNREACHABLE */
+
+#endif /* !JERRY_NDEBUG */
+
+/*
+ * Logging
+ */
+#define JERRYX_ERROR_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_ERROR, __VA_ARGS__)
+#define JERRYX_WARNING_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_WARNING, __VA_ARGS__)
+#define JERRYX_DEBUG_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_DEBUG, __VA_ARGS__)
+#define JERRYX_TRACE_MSG(...) jerry_port_log (JERRY_LOG_LEVEL_TRACE, __VA_ARGS__)
+
+#endif /* !JEXT_COMMON_H */
diff --git a/deps/jerry/jerry-ext/debugger/debugger-common.c b/deps/jerry/jerry-ext/debugger/debugger-common.c
new file mode 100644 (file)
index 0000000..318bbd6
--- /dev/null
@@ -0,0 +1,38 @@
+/* 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 "jerryscript-ext/debugger.h"
+#include "jext-common.h"
+
+/**
+ * Must be called after the connection has been initialized.
+ */
+void
+jerryx_debugger_after_connect (bool success) /**< tells whether the connection
+                                              *   has been successfully established */
+{
+#ifdef JERRY_DEBUGGER
+  if (success)
+  {
+    jerry_debugger_transport_start ();
+  }
+  else
+  {
+    jerry_debugger_transport_close ();
+  }
+#else /* !JERRY_DEBUGGER */
+  JERRYX_UNUSED (success);
+#endif /* JERRY_DEBUGGER */
+} /* jerryx_debugger_after_connect */
diff --git a/deps/jerry/jerry-ext/debugger/debugger-sha1.c b/deps/jerry/jerry-ext/debugger/debugger-sha1.c
new file mode 100644 (file)
index 0000000..d0ac327
--- /dev/null
@@ -0,0 +1,369 @@
+/* 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.
+ */
+
+/*
+ *  FIPS-180-1 compliant SHA-1 implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ *  The SHA-1 standard was published by NIST in 1993.
+ *
+ *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
+ */
+
+#include "debugger-sha1.h"
+#include "jext-common.h"
+
+#ifdef JERRY_DEBUGGER
+
+/**
+ * SHA-1 context structure.
+ */
+typedef struct
+{
+  uint32_t total[2]; /**< number of bytes processed */
+  uint32_t state[5]; /**< intermediate digest state */
+  uint8_t buffer[64]; /**< data block being processed */
+} jerryx_sha1_context;
+
+/* 32-bit integer manipulation macros (big endian). */
+
+#define JERRYX_SHA1_GET_UINT32_BE(n, b, i) \
+{ \
+  (n) = (((uint32_t) (b)[(i) + 0]) << 24) \
+        | (((uint32_t) (b)[(i) + 1]) << 16) \
+        | (((uint32_t) (b)[(i) + 2]) << 8) \
+        | ((uint32_t) (b)[(i) + 3]); \
+}
+
+#define JERRYX_SHA1_PUT_UINT32_BE(n, b, i) \
+{ \
+  (b)[(i) + 0] = (uint8_t) ((n) >> 24); \
+  (b)[(i) + 1] = (uint8_t) ((n) >> 16); \
+  (b)[(i) + 2] = (uint8_t) ((n) >> 8); \
+  (b)[(i) + 3] = (uint8_t) ((n)); \
+}
+
+/**
+ * Initialize SHA-1 context.
+ */
+static void
+jerryx_sha1_init (jerryx_sha1_context *sha1_context_p) /**< SHA-1 context */
+{
+  memset (sha1_context_p, 0, sizeof (jerryx_sha1_context));
+
+  sha1_context_p->total[0] = 0;
+  sha1_context_p->total[1] = 0;
+
+  sha1_context_p->state[0] = 0x67452301;
+  sha1_context_p->state[1] = 0xEFCDAB89;
+  sha1_context_p->state[2] = 0x98BADCFE;
+  sha1_context_p->state[3] = 0x10325476;
+  sha1_context_p->state[4] = 0xC3D2E1F0;
+} /* jerryx_sha1_init */
+
+#define JERRYX_SHA1_P(a, b, c, d, e, x) \
+do { \
+  e += JERRYX_SHA1_SHIFT (a, 5) + JERRYX_SHA1_F (b, c, d) + K + x; \
+  b = JERRYX_SHA1_SHIFT (b, 30); \
+} while (0)
+
+/**
+ * Update SHA-1 internal buffer status.
+ */
+static void
+jerryx_sha1_process (jerryx_sha1_context *sha1_context_p, /**< SHA-1 context */
+                     const uint8_t data[64]) /**< data buffer */
+{
+  uint32_t temp, W[16], A, B, C, D, E;
+
+  JERRYX_SHA1_GET_UINT32_BE (W[0], data, 0);
+  JERRYX_SHA1_GET_UINT32_BE (W[1], data, 4);
+  JERRYX_SHA1_GET_UINT32_BE (W[2], data, 8);
+  JERRYX_SHA1_GET_UINT32_BE (W[3], data, 12);
+  JERRYX_SHA1_GET_UINT32_BE (W[4], data, 16);
+  JERRYX_SHA1_GET_UINT32_BE (W[5], data, 20);
+  JERRYX_SHA1_GET_UINT32_BE (W[6], data, 24);
+  JERRYX_SHA1_GET_UINT32_BE (W[7], data, 28);
+  JERRYX_SHA1_GET_UINT32_BE (W[8], data, 32);
+  JERRYX_SHA1_GET_UINT32_BE (W[9], data, 36);
+  JERRYX_SHA1_GET_UINT32_BE (W[10], data, 40);
+  JERRYX_SHA1_GET_UINT32_BE (W[11], data, 44);
+  JERRYX_SHA1_GET_UINT32_BE (W[12], data, 48);
+  JERRYX_SHA1_GET_UINT32_BE (W[13], data, 52);
+  JERRYX_SHA1_GET_UINT32_BE (W[14], data, 56);
+  JERRYX_SHA1_GET_UINT32_BE (W[15], data, 60);
+
+#define JERRYX_SHA1_SHIFT(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
+
+#define JERRYX_SHA1_R(t) \
+( \
+  temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ W[(t - 14) & 0x0F] ^ W[t & 0x0F], \
+  W[t & 0x0F] = JERRYX_SHA1_SHIFT (temp, 1) \
+)
+
+  A = sha1_context_p->state[0];
+  B = sha1_context_p->state[1];
+  C = sha1_context_p->state[2];
+  D = sha1_context_p->state[3];
+  E = sha1_context_p->state[4];
+
+  uint32_t K = 0x5A827999;
+
+#define JERRYX_SHA1_F(x, y, z) (z ^ (x & (y ^ z)))
+
+  JERRYX_SHA1_P (A, B, C, D, E, W[0]);
+  JERRYX_SHA1_P (E, A, B, C, D, W[1]);
+  JERRYX_SHA1_P (D, E, A, B, C, W[2]);
+  JERRYX_SHA1_P (C, D, E, A, B, W[3]);
+  JERRYX_SHA1_P (B, C, D, E, A, W[4]);
+  JERRYX_SHA1_P (A, B, C, D, E, W[5]);
+  JERRYX_SHA1_P (E, A, B, C, D, W[6]);
+  JERRYX_SHA1_P (D, E, A, B, C, W[7]);
+  JERRYX_SHA1_P (C, D, E, A, B, W[8]);
+  JERRYX_SHA1_P (B, C, D, E, A, W[9]);
+  JERRYX_SHA1_P (A, B, C, D, E, W[10]);
+  JERRYX_SHA1_P (E, A, B, C, D, W[11]);
+  JERRYX_SHA1_P (D, E, A, B, C, W[12]);
+  JERRYX_SHA1_P (C, D, E, A, B, W[13]);
+  JERRYX_SHA1_P (B, C, D, E, A, W[14]);
+  JERRYX_SHA1_P (A, B, C, D, E, W[15]);
+  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (16));
+  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (17));
+  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (18));
+  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (19));
+
+#undef JERRYX_SHA1_F
+
+  K = 0x6ED9EBA1;
+
+#define JERRYX_SHA1_F(x, y, z) (x ^ y ^ z)
+
+  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (20));
+  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (21));
+  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (22));
+  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (23));
+  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (24));
+  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (25));
+  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (26));
+  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (27));
+  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (28));
+  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (29));
+  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (30));
+  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (31));
+  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (32));
+  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (33));
+  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (34));
+  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (35));
+  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (36));
+  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (37));
+  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (38));
+  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (39));
+
+#undef JERRYX_SHA1_F
+
+  K = 0x8F1BBCDC;
+
+#define JERRYX_SHA1_F(x, y, z) ((x & y) | (z & (x | y)))
+
+  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (40));
+  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (41));
+  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (42));
+  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (43));
+  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (44));
+  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (45));
+  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (46));
+  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (47));
+  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (48));
+  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (49));
+  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (50));
+  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (51));
+  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (52));
+  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (53));
+  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (54));
+  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (55));
+  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (56));
+  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (57));
+  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (58));
+  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (59));
+
+#undef JERRYX_SHA1_F
+
+  K = 0xCA62C1D6;
+
+#define JERRYX_SHA1_F(x, y, z) (x ^ y ^ z)
+
+  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (60));
+  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (61));
+  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (62));
+  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (63));
+  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (64));
+  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (65));
+  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (66));
+  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (67));
+  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (68));
+  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (69));
+  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (70));
+  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (71));
+  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (72));
+  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (73));
+  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (74));
+  JERRYX_SHA1_P (A, B, C, D, E, JERRYX_SHA1_R (75));
+  JERRYX_SHA1_P (E, A, B, C, D, JERRYX_SHA1_R (76));
+  JERRYX_SHA1_P (D, E, A, B, C, JERRYX_SHA1_R (77));
+  JERRYX_SHA1_P (C, D, E, A, B, JERRYX_SHA1_R (78));
+  JERRYX_SHA1_P (B, C, D, E, A, JERRYX_SHA1_R (79));
+
+#undef JERRYX_SHA1_F
+
+  sha1_context_p->state[0] += A;
+  sha1_context_p->state[1] += B;
+  sha1_context_p->state[2] += C;
+  sha1_context_p->state[3] += D;
+  sha1_context_p->state[4] += E;
+
+#undef JERRYX_SHA1_SHIFT
+#undef JERRYX_SHA1_R
+} /* jerryx_sha1_process */
+
+#undef JERRYX_SHA1_P
+
+/**
+ * SHA-1 update buffer.
+ */
+static void
+jerryx_sha1_update (jerryx_sha1_context *sha1_context_p, /**< SHA-1 context */
+                    const uint8_t *source_p, /**< source buffer */
+                    size_t source_length) /**< length of source buffer */
+{
+  size_t fill;
+  uint32_t left;
+
+  if (source_length == 0)
+  {
+    return;
+  }
+
+  left = sha1_context_p->total[0] & 0x3F;
+  fill = 64 - left;
+
+  sha1_context_p->total[0] += (uint32_t) source_length;
+
+  /* Check overflow. */
+  if (sha1_context_p->total[0] < (uint32_t) source_length)
+  {
+    sha1_context_p->total[1]++;
+  }
+
+  if (left && source_length >= fill)
+  {
+    memcpy ((void *) (sha1_context_p->buffer + left), source_p, fill);
+    jerryx_sha1_process (sha1_context_p, sha1_context_p->buffer);
+    source_p += fill;
+    source_length -= fill;
+    left = 0;
+  }
+
+  while (source_length >= 64)
+  {
+    jerryx_sha1_process (sha1_context_p, source_p);
+    source_p += 64;
+    source_length -= 64;
+  }
+
+  if (source_length > 0)
+  {
+    memcpy ((void *) (sha1_context_p->buffer + left), source_p, source_length);
+  }
+} /* jerryx_sha1_update */
+
+/**
+ * SHA-1 final digest.
+ */
+static void
+jerryx_sha1_finish (jerryx_sha1_context *sha1_context_p, /**< SHA-1 context */
+                    uint8_t destination_p[20]) /**< result */
+{
+  uint8_t buffer[16];
+
+  uint32_t high = (sha1_context_p->total[0] >> 29) | (sha1_context_p->total[1] << 3);
+  uint32_t low = (sha1_context_p->total[0] << 3);
+
+  uint32_t last = sha1_context_p->total[0] & 0x3F;
+  uint32_t padn = (last < 56) ? (56 - last) : (120 - last);
+
+  memset (buffer, 0, sizeof (buffer));
+  buffer[0] = 0x80;
+
+  while (padn > sizeof (buffer))
+  {
+    jerryx_sha1_update (sha1_context_p, buffer, sizeof (buffer));
+    buffer[0] = 0;
+    padn -= (uint32_t) sizeof (buffer);
+  }
+
+  jerryx_sha1_update (sha1_context_p, buffer, padn);
+
+  JERRYX_SHA1_PUT_UINT32_BE (high, buffer, 0);
+  JERRYX_SHA1_PUT_UINT32_BE (low, buffer, 4);
+
+  jerryx_sha1_update (sha1_context_p, buffer, 8);
+
+  JERRYX_SHA1_PUT_UINT32_BE (sha1_context_p->state[0], destination_p, 0);
+  JERRYX_SHA1_PUT_UINT32_BE (sha1_context_p->state[1], destination_p, 4);
+  JERRYX_SHA1_PUT_UINT32_BE (sha1_context_p->state[2], destination_p, 8);
+  JERRYX_SHA1_PUT_UINT32_BE (sha1_context_p->state[3], destination_p, 12);
+  JERRYX_SHA1_PUT_UINT32_BE (sha1_context_p->state[4], destination_p, 16);
+} /* jerryx_sha1_finish */
+
+#undef JERRYX_SHA1_GET_UINT32_BE
+#undef JERRYX_SHA1_PUT_UINT32_BE
+
+/**
+ * Computes the SHA-1 value of the combination of the two input buffers.
+ */
+void
+jerryx_debugger_compute_sha1 (const uint8_t *source1_p, /**< first part of the input */
+                              size_t source1_length, /**< length of the first part */
+                              const uint8_t *source2_p, /**< second part of the input */
+                              size_t source2_length, /**< length of the second part */
+                              uint8_t destination_p[20]) /**< result */
+{
+  jerryx_sha1_context sha1_context;
+
+  jerryx_sha1_init (&sha1_context);
+  jerryx_sha1_update (&sha1_context, source1_p, source1_length);
+  jerryx_sha1_update (&sha1_context, source2_p, source2_length);
+  jerryx_sha1_finish (&sha1_context, destination_p);
+} /* jerryx_debugger_compute_sha1 */
+
+#endif /* JERRY_DEBUGGER */
diff --git a/deps/jerry/jerry-ext/debugger/debugger-sha1.h b/deps/jerry/jerry-ext/debugger/debugger-sha1.h
new file mode 100644 (file)
index 0000000..332d986
--- /dev/null
@@ -0,0 +1,31 @@
+/* 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_SHA1_H
+#define DEBUGGER_SHA1_H
+
+#include "jerryscript-debugger-transport.h"
+
+#ifdef JERRY_DEBUGGER
+
+/* JerryScript debugger protocol is a simplified version of RFC-6455 (WebSockets). */
+
+void jerryx_debugger_compute_sha1 (const uint8_t *input1, size_t input1_len,
+                                   const uint8_t *input2, size_t input2_len,
+                                   uint8_t output[20]);
+
+#endif /* JERRY_DEBUGGER */
+
+#endif /* !DEBUGGER_SHA1_H */
diff --git a/deps/jerry/jerry-ext/debugger/debugger-tcp.c b/deps/jerry/jerry-ext/debugger/debugger-tcp.c
new file mode 100644 (file)
index 0000000..12082f6
--- /dev/null
@@ -0,0 +1,267 @@
+/* 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 "jerryscript-debugger-transport.h"
+#include "jerryscript-ext/debugger.h"
+#include "jext-common.h"
+
+#ifdef JERRY_DEBUGGER
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/socket.h>
+
+/**
+ * Implementation of transport over tcp/ip.
+ */
+typedef struct
+{
+  jerry_debugger_transport_header_t header; /**< transport header */
+  int tcp_socket; /**< tcp socket */
+} jerryx_debugger_transport_tcp_t;
+
+/**
+ * Log tcp error message.
+ */
+static void
+jerryx_debugger_tcp_log_error (int err_val)
+{
+  JERRYX_ERROR_MSG ("TCP Error: %s\n", strerror (err_val));
+} /* jerryx_debugger_tcp_log_error */
+
+/**
+ * Close a tcp connection.
+ */
+static void
+jerryx_debugger_tcp_close (jerry_debugger_transport_header_t *header_p) /**< tcp implementation */
+{
+  JERRYX_ASSERT (!jerry_debugger_transport_is_connected ());
+
+  jerryx_debugger_transport_tcp_t *tcp_p = (jerryx_debugger_transport_tcp_t *) header_p;
+
+  JERRYX_DEBUG_MSG ("TCP connection closed.\n");
+
+  close (tcp_p->tcp_socket);
+
+  jerry_heap_free ((void *) header_p, sizeof (jerryx_debugger_transport_tcp_t));
+} /* jerryx_debugger_tcp_close */
+
+/**
+ * Send data over a tcp connection.
+ *
+ * @return true - if the data has been sent successfully
+ *         false - otherwise
+ */
+static bool
+jerryx_debugger_tcp_send (jerry_debugger_transport_header_t *header_p, /**< tcp implementation */
+                          uint8_t *message_p, /**< message to be sent */
+                          size_t message_length) /**< message length in bytes */
+{
+  JERRYX_ASSERT (jerry_debugger_transport_is_connected ());
+
+  jerryx_debugger_transport_tcp_t *tcp_p = (jerryx_debugger_transport_tcp_t *) header_p;
+
+  do
+  {
+#ifdef __linux__
+    ssize_t is_err = recv (tcp_p->tcp_socket, NULL, 0, MSG_PEEK);
+
+    if (is_err == 0 && errno != EWOULDBLOCK)
+    {
+      int err_val = errno;
+      jerry_debugger_transport_close ();
+      jerryx_debugger_tcp_log_error (err_val);
+      return false;
+    }
+#endif /* __linux__ */
+
+    ssize_t sent_bytes = send (tcp_p->tcp_socket, message_p, message_length, 0);
+
+    if (sent_bytes < 0)
+    {
+      if (errno == EWOULDBLOCK)
+      {
+        continue;
+      }
+
+      int err_val = errno;
+      jerry_debugger_transport_close ();
+      jerryx_debugger_tcp_log_error (err_val);
+      return false;
+    }
+
+    message_p += sent_bytes;
+    message_length -= (size_t) sent_bytes;
+  }
+  while (message_length > 0);
+
+  return true;
+} /* jerryx_debugger_tcp_send */
+
+/**
+ * Receive data from a tcp connection.
+ */
+static bool
+jerryx_debugger_tcp_receive (jerry_debugger_transport_header_t *header_p, /**< tcp implementation */
+                             jerry_debugger_transport_receive_context_t *receive_context_p) /**< receive context */
+{
+  jerryx_debugger_transport_tcp_t *tcp_p = (jerryx_debugger_transport_tcp_t *) header_p;
+
+  uint8_t *buffer_p = receive_context_p->buffer_p + receive_context_p->received_length;
+  size_t buffer_size = JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE - receive_context_p->received_length;
+
+  ssize_t length = recv (tcp_p->tcp_socket, buffer_p, buffer_size, 0);
+
+  if (length <= 0)
+  {
+    if (errno != EWOULDBLOCK || length == 0)
+    {
+      int err_val = errno;
+      jerry_debugger_transport_close ();
+      jerryx_debugger_tcp_log_error (err_val);
+      return false;
+    }
+    length = 0;
+  }
+
+  receive_context_p->received_length += (size_t) length;
+
+  if (receive_context_p->received_length > 0)
+  {
+    receive_context_p->message_p = receive_context_p->buffer_p;
+    receive_context_p->message_length = receive_context_p->received_length;
+  }
+
+  return true;
+} /* jerryx_debugger_tcp_receive */
+
+/**
+ * Create a tcp connection.
+ *
+ * @return true if successful,
+ *         false otherwise
+ */
+bool
+jerryx_debugger_tcp_create (uint16_t port) /**< listening port */
+{
+  int server_socket;
+  struct sockaddr_in addr;
+  socklen_t sin_size = sizeof (struct sockaddr_in);
+
+  addr.sin_family = AF_INET;
+  addr.sin_port = htons (port);
+  addr.sin_addr.s_addr = INADDR_ANY;
+
+  if ((server_socket = socket (AF_INET, SOCK_STREAM, 0)) == -1)
+  {
+    JERRYX_ERROR_MSG ("Error: %s\n", strerror (errno));
+    return false;
+  }
+
+  int opt_value = 1;
+
+  if (setsockopt (server_socket, SOL_SOCKET, SO_REUSEADDR, &opt_value, sizeof (int)) == -1)
+  {
+    close (server_socket);
+    JERRYX_ERROR_MSG ("Error: %s\n", strerror (errno));
+    return false;
+  }
+
+  if (bind (server_socket, (struct sockaddr *)&addr, sizeof (struct sockaddr)) == -1)
+  {
+    close (server_socket);
+    JERRYX_ERROR_MSG ("Error: %s\n", strerror (errno));
+    return false;
+  }
+
+  if (listen (server_socket, 1) == -1)
+  {
+    close (server_socket);
+    JERRYX_ERROR_MSG ("Error: %s\n", strerror (errno));
+    return false;
+  }
+
+  JERRYX_DEBUG_MSG ("Waiting for client connection\n");
+
+  int tcp_socket = accept (server_socket, (struct sockaddr *)&addr, &sin_size);
+
+  close (server_socket);
+
+  if (tcp_socket == -1)
+  {
+    JERRYX_ERROR_MSG ("Error: %s\n", strerror (errno));
+    return false;
+  }
+
+  /* Set non-blocking mode. */
+  int socket_flags = fcntl (tcp_socket, F_GETFL, 0);
+
+  if (socket_flags < 0)
+  {
+    close (tcp_socket);
+    return false;
+  }
+
+  if (fcntl (tcp_socket, F_SETFL, socket_flags | O_NONBLOCK) == -1)
+  {
+    close (tcp_socket);
+    return false;
+  }
+
+  JERRYX_DEBUG_MSG ("Connected from: %s\n", inet_ntoa (addr.sin_addr));
+
+  size_t size = sizeof (jerryx_debugger_transport_tcp_t);
+
+  jerry_debugger_transport_header_t *header_p;
+  header_p = (jerry_debugger_transport_header_t *) jerry_heap_alloc (size);
+
+  if (!header_p)
+  {
+    close (tcp_socket);
+    return false;
+  }
+
+  header_p->close = jerryx_debugger_tcp_close;
+  header_p->send = jerryx_debugger_tcp_send;
+  header_p->receive = jerryx_debugger_tcp_receive;
+
+  ((jerryx_debugger_transport_tcp_t *) header_p)->tcp_socket = tcp_socket;
+
+  jerry_debugger_transport_add (header_p,
+                                0,
+                                JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE,
+                                0,
+                                JERRY_DEBUGGER_TRANSPORT_MAX_BUFFER_SIZE);
+
+  return true;
+} /* jerryx_debugger_tcp_create */
+
+#else /* !JERRY_DEBUGGER */
+
+/**
+ * Dummy function when debugger is disabled.
+ *
+ * @return false
+ */
+bool
+jerryx_debugger_tcp_create (uint16_t port)
+{
+  JERRYX_UNUSED (port);
+  return false;
+} /* jerryx_debugger_tcp_create */
+
+#endif /* JERRY_DEBUGGER */
diff --git a/deps/jerry/jerry-ext/debugger/debugger-ws.c b/deps/jerry/jerry-ext/debugger/debugger-ws.c
new file mode 100644 (file)
index 0000000..b79d08d
--- /dev/null
@@ -0,0 +1,466 @@
+/* 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-sha1.h"
+#include "jerryscript-ext/debugger.h"
+#include "jext-common.h"
+
+#ifdef JERRY_DEBUGGER
+
+/* JerryScript debugger protocol is a simplified version of RFC-6455 (WebSockets). */
+
+/**
+ * Last fragment of a Websocket package.
+ */
+#define JERRYX_DEBUGGER_WEBSOCKET_FIN_BIT 0x80
+
+/**
+ * Masking-key is available.
+ */
+#define JERRYX_DEBUGGER_WEBSOCKET_MASK_BIT 0x80
+
+/**
+ * Opcode type mask.
+ */
+#define JERRYX_DEBUGGER_WEBSOCKET_OPCODE_MASK 0x0fu
+
+/**
+ * Packet length mask.
+ */
+#define JERRYX_DEBUGGER_WEBSOCKET_LENGTH_MASK 0x7fu
+
+/**
+ * Size of websocket header size.
+ */
+#define JERRYX_DEBUGGER_WEBSOCKET_HEADER_SIZE 2
+
+/**
+ * Payload mask size in bytes of a websocket package.
+ */
+#define JERRYX_DEBUGGER_WEBSOCKET_MASK_SIZE 4
+
+/**
+ * Maximum message size with 1 byte size field.
+ */
+#define JERRYX_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX 125
+
+/**
+ * WebSocket opcode types.
+ */
+typedef enum
+{
+  JERRYX_DEBUGGER_WEBSOCKET_TEXT_FRAME = 1, /**< text frame */
+  JERRYX_DEBUGGER_WEBSOCKET_BINARY_FRAME = 2, /**< binary frame */
+  JERRYX_DEBUGGER_WEBSOCKET_CLOSE_CONNECTION = 8, /**< close connection */
+  JERRYX_DEBUGGER_WEBSOCKET_PING = 9, /**< ping (keep alive) frame */
+  JERRYX_DEBUGGER_WEBSOCKET_PONG = 10, /**< reply to ping frame */
+} jerryx_websocket_opcode_type_t;
+
+/**
+ * Header for incoming packets.
+ */
+typedef struct
+{
+  uint8_t ws_opcode; /**< websocket opcode */
+  uint8_t size; /**< size of the message */
+  uint8_t mask[4]; /**< mask bytes */
+} jerryx_websocket_receive_header_t;
+
+/**
+ * Convert a 6-bit value to a Base64 character.
+ *
+ * @return Base64 character
+ */
+static uint8_t
+jerryx_to_base64_character (uint8_t value) /**< 6-bit value */
+{
+  if (value < 26)
+  {
+    return (uint8_t) (value + 'A');
+  }
+
+  if (value < 52)
+  {
+    return (uint8_t) (value - 26 + 'a');
+  }
+
+  if (value < 62)
+  {
+    return (uint8_t) (value - 52 + '0');
+  }
+
+  if (value == 62)
+  {
+    return (uint8_t) '+';
+  }
+
+  return (uint8_t) '/';
+} /* jerryx_to_base64_character */
+
+/**
+ * Encode a byte sequence into Base64 string.
+ */
+static void
+jerryx_to_base64 (const uint8_t *source_p, /**< source data */
+                 uint8_t *destination_p, /**< destination buffer */
+                 size_t length) /**< length of source, must be divisible by 3 */
+{
+  while (length >= 3)
+  {
+    uint8_t value = (source_p[0] >> 2);
+    destination_p[0] = jerryx_to_base64_character (value);
+
+    value = (uint8_t) (((source_p[0] << 4) | (source_p[1] >> 4)) & 0x3f);
+    destination_p[1] = jerryx_to_base64_character (value);
+
+    value = (uint8_t) (((source_p[1] << 2) | (source_p[2] >> 6)) & 0x3f);
+    destination_p[2] = jerryx_to_base64_character (value);
+
+    value = (uint8_t) (source_p[2] & 0x3f);
+    destination_p[3] = jerryx_to_base64_character (value);
+
+    source_p += 3;
+    destination_p += 4;
+    length -= 3;
+  }
+} /* jerryx_to_base64 */
+
+/**
+ * Process WebSocket handshake.
+ *
+ * @return true - if the handshake was completed successfully
+ *         false - otherwise
+ */
+static bool
+jerryx_process_handshake (uint8_t *request_buffer_p) /**< temporary buffer */
+{
+  size_t request_buffer_size = 1024;
+  uint8_t *request_end_p = request_buffer_p;
+
+  /* Buffer request text until the double newlines are received. */
+  while (true)
+  {
+    jerry_debugger_transport_receive_context_t context;
+    if (!jerry_debugger_transport_receive (&context))
+    {
+      JERRYX_ASSERT (!jerry_debugger_transport_is_connected ());
+      return false;
+    }
+
+    if (context.message_p == NULL)
+    {
+      jerry_debugger_transport_sleep ();
+      continue;
+    }
+
+    size_t length = request_buffer_size - 1u - (size_t) (request_end_p - request_buffer_p);
+
+    if (length < context.message_length)
+    {
+      JERRYX_ERROR_MSG ("Handshake buffer too small.\n");
+      return false;
+    }
+
+    /* Both stream and datagram packets are supported. */
+    memcpy (request_end_p, context.message_p, context.message_length);
+
+    jerry_debugger_transport_receive_completed (&context);
+
+    request_end_p += (size_t) context.message_length;
+    *request_end_p = 0;
+
+    if (request_end_p > request_buffer_p + 4
+        && memcmp (request_end_p - 4, "\r\n\r\n", 4) == 0)
+    {
+      break;
+    }
+  }
+
+  /* Check protocol. */
+  const char get_text[] = "GET /jerry-debugger";
+  size_t text_len = sizeof (get_text) - 1;
+
+  if ((size_t) (request_end_p - request_buffer_p) < text_len
+      || memcmp (request_buffer_p, get_text, text_len) != 0)
+  {
+    JERRYX_ERROR_MSG ("Invalid handshake format.\n");
+    return false;
+  }
+
+  uint8_t *websocket_key_p = request_buffer_p + text_len;
+
+  const char key_text[] = "Sec-WebSocket-Key:";
+  text_len = sizeof (key_text) - 1;
+
+  while (true)
+  {
+    if ((size_t) (request_end_p - websocket_key_p) < text_len)
+    {
+      JERRYX_ERROR_MSG ("Sec-WebSocket-Key not found.\n");
+      return false;
+    }
+
+    if (websocket_key_p[0] == 'S'
+        && websocket_key_p[-1] == '\n'
+        && websocket_key_p[-2] == '\r'
+        && memcmp (websocket_key_p, key_text, text_len) == 0)
+    {
+      websocket_key_p += text_len;
+      break;
+    }
+
+    websocket_key_p++;
+  }
+
+  /* String terminated by double newlines. */
+
+  while (*websocket_key_p == ' ')
+  {
+    websocket_key_p++;
+  }
+
+  uint8_t *websocket_key_end_p = websocket_key_p;
+
+  while (*websocket_key_end_p > ' ')
+  {
+    websocket_key_end_p++;
+  }
+
+  /* Since the request_buffer_p is not needed anymore it can
+   * be reused for storing the SHA-1 key and Base64 string. */
+
+  const size_t sha1_length = 20;
+
+  jerryx_debugger_compute_sha1 (websocket_key_p,
+                               (size_t) (websocket_key_end_p - websocket_key_p),
+                               (const uint8_t *) "258EAFA5-E914-47DA-95CA-C5AB0DC85B11",
+                               36,
+                               request_buffer_p);
+
+  /* The SHA-1 key is 20 bytes long but jerryx_to_base64 expects
+   * a length divisible by 3 so an extra 0 is appended at the end. */
+  request_buffer_p[sha1_length] = 0;
+
+  jerryx_to_base64 (request_buffer_p, request_buffer_p + sha1_length + 1, sha1_length + 1);
+
+  /* Last value must be replaced by equal sign. */
+
+  const uint8_t response_prefix[] =
+  "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: ";
+
+  if (!jerry_debugger_transport_send (response_prefix, sizeof (response_prefix) - 1)
+      || !jerry_debugger_transport_send (request_buffer_p + sha1_length + 1, 27))
+  {
+    return false;
+  }
+
+  const uint8_t response_suffix[] = "=\r\n\r\n";
+  return jerry_debugger_transport_send (response_suffix, sizeof (response_suffix) - 1);
+} /* jerryx_process_handshake */
+
+/**
+ * Close a tcp connection.
+ */
+static void
+jerryx_debugger_ws_close (jerry_debugger_transport_header_t *header_p) /**< tcp implementation */
+{
+  JERRYX_ASSERT (!jerry_debugger_transport_is_connected ());
+
+  jerry_heap_free ((void *) header_p, sizeof (jerry_debugger_transport_header_t));
+} /* jerryx_debugger_ws_close */
+
+/**
+ * Send data over a websocket connection.
+ *
+ * @return true - if the data has been sent successfully
+ *         false - otherwise
+ */
+static bool
+jerryx_debugger_ws_send (jerry_debugger_transport_header_t *header_p, /**< tcp implementation */
+                         uint8_t *message_p, /**< message to be sent */
+                         size_t message_length) /**< message length in bytes */
+{
+  JERRYX_ASSERT (message_length <= JERRYX_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX);
+
+  message_p[-2] = JERRYX_DEBUGGER_WEBSOCKET_FIN_BIT | JERRYX_DEBUGGER_WEBSOCKET_BINARY_FRAME;
+  message_p[-1] = (uint8_t) message_length;
+
+  return header_p->next_p->send (header_p->next_p, message_p - 2, message_length + 2);
+} /* jerryx_debugger_ws_send */
+
+/**
+ * Receive data from a websocket connection.
+ */
+static bool
+jerryx_debugger_ws_receive (jerry_debugger_transport_header_t *header_p, /**< tcp implementation */
+                            jerry_debugger_transport_receive_context_t *receive_context_p) /**< receive context */
+{
+  if (!header_p->next_p->receive (header_p->next_p, receive_context_p))
+  {
+    return false;
+  }
+
+  if (receive_context_p->message_p == NULL)
+  {
+    return true;
+  }
+
+  size_t message_total_length = receive_context_p->message_total_length;
+
+  if (message_total_length == 0)
+  {
+    /* Byte stream. */
+    if (receive_context_p->message_length < sizeof (jerryx_websocket_receive_header_t))
+    {
+      receive_context_p->message_p = NULL;
+      return true;
+    }
+  }
+  else
+  {
+    /* Datagram packet. */
+    JERRYX_ASSERT (receive_context_p->message_length >= sizeof (jerryx_websocket_receive_header_t));
+  }
+
+  uint8_t *message_p = receive_context_p->message_p;
+
+  if ((message_p[0] & ~JERRYX_DEBUGGER_WEBSOCKET_OPCODE_MASK) != JERRYX_DEBUGGER_WEBSOCKET_FIN_BIT
+      || (message_p[1] & JERRYX_DEBUGGER_WEBSOCKET_LENGTH_MASK) > JERRYX_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX
+      || !(message_p[1] & JERRYX_DEBUGGER_WEBSOCKET_MASK_BIT))
+  {
+    JERRYX_ERROR_MSG ("Unsupported Websocket message.\n");
+    jerry_debugger_transport_close ();
+    return false;
+  }
+
+  if ((message_p[0] & JERRYX_DEBUGGER_WEBSOCKET_OPCODE_MASK) != JERRYX_DEBUGGER_WEBSOCKET_BINARY_FRAME)
+  {
+    JERRYX_ERROR_MSG ("Unsupported Websocket opcode.\n");
+    jerry_debugger_transport_close ();
+    return false;
+  }
+
+  size_t message_length = (size_t) (message_p[1] & JERRYX_DEBUGGER_WEBSOCKET_LENGTH_MASK);
+
+  if (message_total_length == 0)
+  {
+    size_t new_total_length = message_length + sizeof (jerryx_websocket_receive_header_t);
+
+    /* Byte stream. */
+    if (receive_context_p->message_length < new_total_length)
+    {
+      receive_context_p->message_p = NULL;
+      return true;
+    }
+
+    receive_context_p->message_total_length = new_total_length;
+  }
+  else
+  {
+    /* Datagram packet. */
+    JERRYX_ASSERT (receive_context_p->message_length == (message_length + sizeof (jerryx_websocket_receive_header_t)));
+  }
+
+  message_p += sizeof (jerryx_websocket_receive_header_t);
+
+  receive_context_p->message_p = message_p;
+  receive_context_p->message_length = message_length;
+
+  /* Unmask data bytes. */
+  const uint8_t *mask_p = message_p - JERRYX_DEBUGGER_WEBSOCKET_MASK_SIZE;
+  const uint8_t *mask_end_p = message_p;
+  const uint8_t *message_end_p = message_p + message_length;
+
+  while (message_p < message_end_p)
+  {
+    /* Invert certain bits with xor operation. */
+    *message_p = *message_p ^ *mask_p;
+
+    message_p++;
+    mask_p++;
+
+    if (JERRY_UNLIKELY (mask_p >= mask_end_p))
+    {
+      mask_p -= JERRYX_DEBUGGER_WEBSOCKET_MASK_SIZE;
+    }
+  }
+
+  return true;
+} /* jerryx_debugger_ws_receive */
+
+/**
+ * Initialize the websocket transportation layer.
+ *
+ * @return true - if the connection succeeded
+ *         false - otherwise
+ */
+bool
+jerryx_debugger_ws_create (void)
+{
+  bool is_handshake_ok = false;
+
+  const size_t buffer_size = 1024;
+  uint8_t *request_buffer_p = (uint8_t *) jerry_heap_alloc (buffer_size);
+
+  if (!request_buffer_p)
+  {
+    return false;
+  }
+
+  is_handshake_ok = jerryx_process_handshake (request_buffer_p);
+
+  jerry_heap_free ((void *) request_buffer_p, buffer_size);
+
+  if (!is_handshake_ok && jerry_debugger_transport_is_connected ())
+  {
+    return false;
+  }
+
+  const size_t interface_size = sizeof (jerry_debugger_transport_header_t);
+  jerry_debugger_transport_header_t *header_p;
+  header_p = (jerry_debugger_transport_header_t *) jerry_heap_alloc (interface_size);
+
+  if (!header_p)
+  {
+    return false;
+  }
+
+  header_p->close = jerryx_debugger_ws_close;
+  header_p->send = jerryx_debugger_ws_send;
+  header_p->receive = jerryx_debugger_ws_receive;
+
+  jerry_debugger_transport_add (header_p,
+                                JERRYX_DEBUGGER_WEBSOCKET_HEADER_SIZE,
+                                JERRYX_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX,
+                                JERRYX_DEBUGGER_WEBSOCKET_HEADER_SIZE + JERRYX_DEBUGGER_WEBSOCKET_MASK_SIZE,
+                                JERRYX_DEBUGGER_WEBSOCKET_ONE_BYTE_LEN_MAX);
+
+  return true;
+} /* jerryx_debugger_ws_create */
+
+#else /* !JERRY_DEBUGGER */
+
+/**
+ * Dummy function when debugger is disabled.
+ *
+ * @return false
+ */
+bool
+jerryx_debugger_ws_create (void)
+{
+  return false;
+} /* jerryx_debugger_ws_create */
+
+#endif /* JERRY_DEBUGGER */
index 75254ab999e48c3f0c64e0ad080f070233773d3f..5cea2726085ddff670d043833b406693f4662565 100644 (file)
 #include "jerryscript-port.h"
 
 /**
- * Assert for scripts. The routine calls jerry_port_fatal on assertion failure.
+ * Hard assert for scripts. The routine calls jerry_port_fatal on assertion failure.
  *
  * @return true - if only one argument was passed and that argument was a boolean true.
  *         Note that the function does not return otherwise.
  */
 jerry_value_t
-jerryx_handler_assert (const jerry_value_t func_obj_val, /**< function object */
-                       const jerry_value_t this_p, /**< this arg */
-                       const jerry_value_t args_p[], /**< function arguments */
-                       const jerry_length_t args_cnt) /**< number of function arguments */
+jerryx_handler_assert_fatal (const jerry_value_t func_obj_val, /**< function object */
+                             const jerry_value_t this_p, /**< this arg */
+                             const jerry_value_t args_p[], /**< function arguments */
+                             const jerry_length_t args_cnt) /**< number of function arguments */
 {
   (void) func_obj_val; /* unused */
   (void) this_p; /* unused */
@@ -37,9 +37,47 @@ jerryx_handler_assert (const jerry_value_t func_obj_val, /**< function object */
   {
     return jerry_create_boolean (true);
   }
-  else
+
+  jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Script Error: assertion failed\n");
+  jerry_port_fatal (ERR_FAILED_INTERNAL_ASSERTION);
+} /* jerryx_handler_assert_fatal */
+
+/**
+ * Soft assert for scripts. The routine throws an error on assertion failure.
+ *
+ * @return true - if only one argument was passed and that argument was a boolean true.
+ *         error - otherwise.
+ */
+jerry_value_t
+jerryx_handler_assert_throw (const jerry_value_t func_obj_val, /**< function object */
+                             const jerry_value_t this_p, /**< this arg */
+                             const jerry_value_t args_p[], /**< function arguments */
+                             const jerry_length_t args_cnt) /**< number of function arguments */
+{
+  (void) func_obj_val; /* unused */
+  (void) this_p; /* unused */
+
+  if (args_cnt == 1
+      && jerry_value_is_boolean (args_p[0])
+      && jerry_get_boolean_value (args_p[0]))
   {
-    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Script Error: assertion failed\n");
-    jerry_port_fatal (ERR_FAILED_INTERNAL_ASSERTION);
+    return jerry_create_boolean (true);
   }
+
+  return jerry_create_error (JERRY_ERROR_COMMON, (jerry_char_t *) "assertion failed");
+} /* jerryx_handler_assert_throw */
+
+/**
+ * An alias to `jerryx_handler_assert_fatal`.
+ *
+ * @return true - if only one argument was passed and that argument was a boolean true.
+ *         Note that the function does not return otherwise.
+ */
+jerry_value_t
+jerryx_handler_assert (const jerry_value_t func_obj_val, /**< function object */
+                       const jerry_value_t this_p, /**< this arg */
+                       const jerry_value_t args_p[], /**< function arguments */
+                       const jerry_length_t args_cnt) /**< number of function arguments */
+{
+  return jerryx_handler_assert_fatal (func_obj_val, this_p, args_p, args_cnt);
 } /* jerryx_handler_assert */
index 65adbadd876b51dd7fa97ad12ddba72f10f85971..5f669b018863f354e88505ce895f5d09f1835f52 100644 (file)
@@ -28,9 +28,10 @@ jerryx_handler_gc (const jerry_value_t func_obj_val, /**< function object */
 {
   (void) func_obj_val; /* unused */
   (void) this_p; /* unused */
-  (void) args_p; /* unused */
-  (void) args_cnt; /* unused */
 
-  jerry_gc ();
+  jerry_gc_mode_t mode = ((args_cnt > 0 && jerry_value_to_boolean (args_p[0])) ? JERRY_GC_SEVERITY_HIGH
+                                                                               : JERRY_GC_SEVERITY_LOW);
+
+  jerry_gc (mode);
   return jerry_create_undefined ();
 } /* jerryx_handler_gc */
index dc5a2d5845493b4fb84c20b9001b7015104690b9..d1cdd306ceb95727371ffd1e20e564ac9771a716 100644 (file)
@@ -14,7 +14,7 @@
  */
 
 #include "jerryscript-ext/handler.h"
-#include "debugger.h"
+#include "jerryscript-debugger.h"
 
 /**
  * Provide a 'print' implementation for scripts.
@@ -44,64 +44,75 @@ jerryx_handler_print (const jerry_value_t func_obj_val, /**< function object */
   (void) func_obj_val; /* unused */
   (void) this_p; /* unused */
 
-  static const char *null_str = "\\u0000";
+  const char * const null_str = "\\u0000";
 
   jerry_value_t ret_val = jerry_create_undefined ();
 
-  for (jerry_length_t arg_index = 0;
-       jerry_value_is_undefined (ret_val) && arg_index < args_cnt;
-       arg_index++)
+  for (jerry_length_t arg_index = 0; arg_index < args_cnt; arg_index++)
   {
     jerry_value_t str_val = jerry_value_to_string (args_p[arg_index]);
 
-    if (!jerry_value_has_error_flag (str_val))
+    if (jerry_value_is_error (str_val))
     {
-      if (arg_index != 0)
+      /* There is no need to free the undefined value. */
+      ret_val = str_val;
+      break;
+    }
+
+    jerry_length_t length = jerry_get_utf8_string_length (str_val);
+    jerry_length_t substr_pos = 0;
+    jerry_char_t substr_buf[256];
+
+    do
+    {
+      jerry_size_t substr_size = jerry_substring_to_utf8_char_buffer (str_val,
+                                                                      substr_pos,
+                                                                      length,
+                                                                      substr_buf,
+                                                                      256 - 1);
+
+      jerry_char_t *buf_end_p = substr_buf + substr_size;
+
+      /* Update start position by the number of utf-8 characters. */
+      for (jerry_char_t *buf_p = substr_buf; buf_p < buf_end_p; buf_p++)
       {
-        jerryx_port_handler_print_char (' ');
+        /* Skip intermediate utf-8 octets. */
+        if ((*buf_p & 0xc0) != 0x80)
+        {
+          substr_pos++;
+        }
       }
 
-      jerry_size_t substr_size;
-      jerry_length_t substr_pos = 0;
-      jerry_char_t substr_buf[256];
+      if (substr_pos == length)
+      {
+        *buf_end_p++ = (arg_index < args_cnt - 1) ? ' ' : '\n';
+      }
 
-      while ((substr_size = jerry_substring_to_char_buffer (str_val,
-                                                            substr_pos,
-                                                            substr_pos + 256,
-                                                            substr_buf,
-                                                            256)) != 0)
+      for (jerry_char_t *buf_p = substr_buf; buf_p < buf_end_p; buf_p++)
       {
-#ifdef JERRY_DEBUGGER
-        jerry_debugger_send_output (substr_buf, substr_size, JERRY_DEBUGGER_OUTPUT_OK);
-#endif /* JERRY_DEBUGGER */
-        for (jerry_size_t chr_index = 0; chr_index < substr_size; chr_index++)
+        char chr = (char) *buf_p;
+
+        if (chr != '\0')
         {
-          char chr = (char) substr_buf[chr_index];
-          if (chr == '\0')
-          {
-            for (jerry_size_t null_index = 0; null_str[null_index] != 0; null_index++)
-            {
-              jerryx_port_handler_print_char (null_str[null_index]);
-            }
-          }
-          else
-          {
-            jerryx_port_handler_print_char (chr);
-          }
+          jerryx_port_handler_print_char (chr);
+          continue;
         }
 
-        substr_pos += substr_size;
+        for (jerry_size_t null_index = 0; null_str[null_index] != '\0'; null_index++)
+        {
+          jerryx_port_handler_print_char (null_str[null_index]);
+        }
       }
-
-      jerry_release_value (str_val);
-    }
-    else
-    {
-      ret_val = str_val;
     }
+    while (substr_pos < length);
+
+    jerry_release_value (str_val);
   }
 
-  jerryx_port_handler_print_char ('\n');
+  if (args_cnt == 0 || jerry_value_is_error (ret_val))
+  {
+    jerryx_port_handler_print_char ('\n');
+  }
 
   return ret_val;
 } /* jerryx_handler_print */
index 47a75f6a6f2dc155389e908234eca60cd43b7fa7..d1e4620f6c825792d2444393d161e6bf8af8e823 100644 (file)
@@ -94,7 +94,7 @@ typedef struct
         func = jerryx_arg_transform_ ## type; \
       } \
     } \
-    const jerryx_arg_int_option_t int_option = { .round = round_flag, .clamp = clamp_flag }; \
+    const jerryx_arg_int_option_t int_option = { .round = (uint8_t) round_flag, .clamp = (uint8_t) clamp_flag }; \
     return (jerryx_arg_t) \
     { \
       .func = func, \
diff --git a/deps/jerry/jerry-ext/include/jerryscript-ext/debugger.h b/deps/jerry/jerry-ext/include/jerryscript-ext/debugger.h
new file mode 100644 (file)
index 0000000..dd6cf93
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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 JERRYX_DEBUGGER_H
+#define JERRYX_DEBUGGER_H
+
+#include "jerryscript.h"
+#include "jerryscript-debugger-transport.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+void jerryx_debugger_after_connect (bool success);
+
+/*
+ * Message transmission interfaces.
+ */
+bool jerryx_debugger_tcp_create (uint16_t port);
+
+/*
+ * Message encoding interfaces.
+ */
+bool jerryx_debugger_ws_create (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* !JERRYX_HANDLER_H */
index 5c1bffb338cc85f7feb19e2e6ed74d13c5810426..0f0ff13fca6da9bfcf8c3f6f4db01aa7a0f742dd 100644 (file)
@@ -34,6 +34,10 @@ jerry_value_t jerryx_handler_register_global (const jerry_char_t *name_p,
  * Common external function handlers
  */
 
+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);
+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);
 jerry_value_t jerryx_handler_assert (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);
 jerry_value_t jerryx_handler_gc (const jerry_value_t func_obj_val, const jerry_value_t this_p,
index 21a644d5bd2068bc8bdd3193b30bb30892736c8f..1bb76def069ff06c52041cdabc71297ee24ab90b 100644 (file)
@@ -134,6 +134,13 @@ jerry_value_t jerryx_module_resolve (const jerry_value_t name,
                                      const jerryx_module_resolver_t **resolvers,
                                      size_t count);
 
+/**
+ * Delete a module from the cache or, if name has the JavaScript value of undefined, clear the entire cache.
+ */
+void jerryx_module_clear_cache (const jerry_value_t name,
+                                const jerryx_module_resolver_t **resolvers,
+                                size_t count);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 4cdde0275fb4f37b4176189f7851bb7fc87ec812..896b7caa99066d155d31543db6fb02eac632cc27 100644 (file)
@@ -35,10 +35,14 @@ jerryx_module_create_error (jerry_error_t error_type, /**< the type of error to
                             const jerry_value_t module_name) /**< the module name */
 {
   jerry_value_t ret = jerry_create_error (error_type, message);
+
+  jerry_value_t error_object = jerry_get_value_from_error (ret, false);
   jerry_value_t property_name = jerry_create_string (module_name_property_name);
 
-  jerry_release_value (jerry_set_property (ret, property_name, module_name));
+  jerry_release_value (jerry_set_property (error_object, property_name, module_name));
+
   jerry_release_value (property_name);
+  jerry_release_value (error_object);
   return ret;
 } /* jerryx_module_create_error */
 
@@ -116,14 +120,17 @@ jerryx_module_check_cache (jerry_value_t cache, /**< cache from which to attempt
   jerry_value_t js_has_property = jerry_has_property (cache, module_name);
 
   /* If we succeed in getting an answer, we examine the answer. */
-  if (!jerry_value_has_error_flag (js_has_property))
+  if (!jerry_value_is_error (js_has_property))
   {
     bool has_property = jerry_get_boolean_value (js_has_property);
 
     /* If the module is indeed in the cache, we return it. */
     if (has_property)
     {
-      (*result) = jerry_get_property (cache, module_name);
+      if (result != NULL)
+      {
+        (*result) = jerry_get_property (cache, module_name);
+      }
       ret = true;
     }
   }
@@ -146,7 +153,7 @@ jerryx_module_add_to_cache (jerry_value_t cache, /**< cache to which to add the
 {
   jerry_value_t ret = jerry_set_property (cache, module_name, module);
 
-  if (jerry_value_has_error_flag (ret))
+  if (jerry_value_is_error (ret))
   {
     jerry_release_value (module);
   }
@@ -173,7 +180,7 @@ jerryx_resolve_native_module (const jerry_value_t canonical_name, /**< canonical
   const jerryx_native_module_t *module_p = NULL;
 
   jerry_size_t name_size = jerry_get_utf8_string_size (canonical_name);
-  jerry_char_t name_string[name_size];
+  JERRY_VLA (jerry_char_t, name_string, name_size);
   jerry_string_to_utf8_char_buffer (canonical_name, name_string, name_size);
 
   /* Look for the module by its name in the list of module definitions. */
@@ -201,36 +208,27 @@ jerryx_module_resolver_t jerryx_module_native_resolver =
   .resolve_p = jerryx_resolve_native_module
 };
 
-/**
- * Resolve a single module using the module resolvers available in the section declared above and load it into the
- * current context.
- *
- * @p name - name of the module to resolve
- * @p resolvers - list of resolvers to invoke
- * @p count - number of resolvers in the list
- *
- * @return a jerry_value_t containing one of the followings:
- *   - the result of having loaded the module named @p name, or
- *   - the result of a previous successful load, or
- *   - an error indicating that something went wrong during the attempt to load the module.
- */
-jerry_value_t
-jerryx_module_resolve (const jerry_value_t name, /**< name of the module to load */
-                       const jerryx_module_resolver_t **resolvers_p, /**< list of resolvers */
-                       size_t resolver_count) /**< number of resolvers in @p resolvers */
+
+static void
+jerryx_module_resolve_local (const jerry_value_t name, /**< name of the module to load */
+                             const jerryx_module_resolver_t **resolvers_p, /**< list of resolvers */
+                             size_t resolver_count, /**< number of resolvers in @p resolvers */
+                             jerry_value_t *result) /**< location to store the result, or NULL to remove the module */
 {
   size_t index;
   size_t canonical_names_used = 0;
-  jerry_value_t ret;
   jerry_value_t instances;
-  jerry_value_t canonical_names[resolver_count];
+  JERRY_VLA (jerry_value_t, canonical_names, resolver_count);
   jerry_value_t (*get_canonical_name_p) (const jerry_value_t name);
   bool (*resolve_p) (const jerry_value_t canonical_name,
                      jerry_value_t *result);
 
   if (!jerry_value_is_string (name))
   {
-    ret = jerryx_module_create_error (JERRY_ERROR_COMMON, module_name_not_string, name);
+    if (result != NULL)
+    {
+      *result = jerryx_module_create_error (JERRY_ERROR_COMMON, module_name_not_string, name);
+    }
     goto done;
   }
 
@@ -246,28 +244,41 @@ jerryx_module_resolve (const jerry_value_t name, /**< name of the module to load
     canonical_names[index] = ((get_canonical_name_p == NULL) ? jerry_acquire_value (name)
                                                              : get_canonical_name_p (name));
     canonical_names_used++;
-    if (jerryx_module_check_cache (instances, canonical_names[index], &ret))
+    if (jerryx_module_check_cache (instances, canonical_names[index], result))
     {
+      /* A NULL for result indicates that we are to delete the module from the cache if found. Let's do that here.*/
+      if (result == NULL)
+      {
+        jerry_delete_property (instances, canonical_names[index]);
+      }
       goto done;
     }
   }
 
-  /* Try each resolver until one manages to find the module. */
+  if (result == NULL)
+  {
+    goto done;
+  }
+
+  /**
+   * Past this point we assume a module is wanted, and therefore result is not NULL. So, we try each resolver until one
+   * manages to resolve the module.
+   */
   for (index = 0; index < resolver_count; index++)
   {
     resolve_p = (resolvers_p[index] == NULL ? NULL : resolvers_p[index]->resolve_p);
-    if (resolve_p != NULL && resolve_p (canonical_names[index], &ret))
+    if (resolve_p != NULL && resolve_p (canonical_names[index], result))
     {
-      if (!jerry_value_has_error_flag (ret))
+      if (!jerry_value_is_error (*result))
       {
-        ret = jerryx_module_add_to_cache (instances, canonical_names[index], ret);
+        *result = jerryx_module_add_to_cache (instances, canonical_names[index], *result);
       }
       goto done;
     }
   }
 
   /* If none of the resolvers manage to find the module, complain with "Module not found" */
-  ret = jerryx_module_create_error (JERRY_ERROR_COMMON, module_not_found, name);
+  *result = jerryx_module_create_error (JERRY_ERROR_COMMON, module_not_found, name);
 
 done:
   /* Release the canonical names as returned by the various resolvers. */
@@ -275,5 +286,47 @@ done:
   {
     jerry_release_value (canonical_names[index]);
   }
+} /* jerryx_module_resolve_local */
+
+/**
+ * Resolve a single module using the module resolvers available in the section declared above and load it into the
+ * current context.
+ *
+ * @p name - name of the module to resolve
+ * @p resolvers - list of resolvers to invoke
+ * @p count - number of resolvers in the list
+ *
+ * @return a jerry_value_t containing one of the followings:
+ *   - the result of having loaded the module named @p name, or
+ *   - the result of a previous successful load, or
+ *   - an error indicating that something went wrong during the attempt to load the module.
+ */
+jerry_value_t
+jerryx_module_resolve (const jerry_value_t name, /**< name of the module to load */
+                       const jerryx_module_resolver_t **resolvers_p, /**< list of resolvers */
+                       size_t resolver_count) /**< number of resolvers in @p resolvers */
+{
+  /* Set to zero to circumvent fatal warning. */
+  jerry_value_t ret = 0;
+  jerryx_module_resolve_local (name, resolvers_p, resolver_count, &ret);
   return ret;
 } /* jerryx_module_resolve */
+
+void
+jerryx_module_clear_cache (const jerry_value_t name, /**< name of the module to remove, or undefined */
+                           const jerryx_module_resolver_t **resolvers_p, /**< list of resolvers */
+                           size_t resolver_count) /**< number of resolvers in @p resolvers */
+{
+  void *instances_p = jerry_get_context_data (&jerryx_module_manager);
+
+  if (jerry_value_is_undefined (name))
+  {
+    /* We were requested to clear the entire cache, so we bounce the context data in the most agnostic way possible. */
+    jerryx_module_manager.deinit_cb (instances_p);
+    jerryx_module_manager.init_cb (instances_p);
+    return;
+  }
+
+  /* Delete the requested module from the cache if it's there. */
+  jerryx_module_resolve_local (name, resolvers_p, resolver_count, NULL);
+} /* jerryx_module_clear_cache */
diff --git a/deps/jerry/jerry-libc/CMakeLists.txt b/deps/jerry/jerry-libc/CMakeLists.txt
deleted file mode 100644 (file)
index 08520c8..0000000
+++ /dev/null
@@ -1,45 +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.
-
-cmake_minimum_required (VERSION 2.8.12)
-set(JERRY_LIBC_NAME jerry-libc)
-project (${JERRY_LIBC_NAME} C ASM)
-
-# Checks the optional features
-# Enable init/fini arrays
-if(FEATURE_INIT_FINI)
-  set(DEFINES_LIBC ${DEFINES_LIBC} ENABLE_INIT_FINI)
-endif()
-
-# Include directories
-set(INCLUDE_LIBC "${CMAKE_CURRENT_SOURCE_DIR}")
-
-# Sources
-file(GLOB SOURCE_LIBC *.c)
-
-# Platform-specific
-# Linux
-if(DEFINED PLATFORM AND ((PLATFORM STREQUAL "LINUX") OR (PLATFORM STREQUAL "DARWIN")))
-  file(GLOB TARGET_SPECIFIC_LIBC_SOURCE target/posix/*.c target/posix/*.S)
-endif()
-
-add_library(${JERRY_LIBC_NAME} STATIC ${SOURCE_LIBC} ${TARGET_SPECIFIC_LIBC_SOURCE})
-
-target_compile_definitions(${JERRY_LIBC_NAME} PRIVATE ${DEFINES_LIBC})
-target_include_directories(${JERRY_LIBC_NAME} PRIVATE ${INCLUDE_LIBC})
-target_include_directories(${JERRY_LIBC_NAME} SYSTEM PUBLIC "${CMAKE_SOURCE_DIR}/jerry-libc/include")
-target_link_libraries(${JERRY_LIBC_NAME} -lgcc)
-
-install(TARGETS ${JERRY_LIBC_NAME} DESTINATION lib)
-install(DIRECTORY ${INCLUDE_LIBC}/include/ DESTINATION include/jerry-libc)
diff --git a/deps/jerry/jerry-libc/arch/arm-v7.h b/deps/jerry/jerry-libc/arch/arm-v7.h
deleted file mode 100644 (file)
index eb665a6..0000000
+++ /dev/null
@@ -1,192 +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 ASM_ARM_H
-#define ASM_ARM_H
-
-/*
- * mov syscall_no (%r0) -> %r7
- * svc #0
- */
-#define SYSCALL_0 \
-  push {r4-r12, lr}; \
-  \
-  mov r7, r0; \
-  \
-  svc #0; \
-  \
-  pop {r4-r12, pc};
-
-/*
- * mov syscall_no (%r0) -> %r7
- * mov arg1 (%r1) -> %r0
- * svc #0
- */
-#define SYSCALL_1 \
-  push {r4-r12, lr}; \
-  \
-  mov r7, r0; \
-  mov r0, r1; \
-  \
-  svc #0; \
-  \
-  pop {r4-r12, pc};
-
-/*
- * mov syscall_no (%r0) -> %r7
- * mov arg1 (%r1) -> %r0
- * mov arg2 (%r2) -> %r1
- * svc #0
- */
-#define SYSCALL_2 \
-  push {r4-r12, lr}; \
-  \
-  mov r7, r0; \
-  mov r0, r1; \
-  mov r1, r2; \
-  \
-  svc #0; \
-  \
-  pop {r4-r12, pc};
-
-/*
- * mov syscall_no (%r0) -> %r7
- * mov arg1 (%r1) -> %r0
- * mov arg2 (%r2) -> %r1
- * mov arg3 (%r3) -> %r2
- * svc #0
- */
-#define SYSCALL_3 \
-  push {r4-r12, lr}; \
-  \
-  mov r7, r0; \
-  mov r0, r1; \
-  mov r1, r2; \
-  mov r2, r3; \
-  \
-  svc #0; \
-  \
-  pop {r4-r12, pc};
-
-#ifdef ENABLE_INIT_FINI
-/*
- * bl libc_init_array
- */
-#define _INIT           \
-  bl libc_init_array;
-#else /* !ENABLE_INIT_FINI */
-#define _INIT
-#endif /* ENABLE_INIT_FINI */
-
-/*
- * bl libc_init_array
- *
- * ldr argc ([sp + 0x0]) -> r0
- * add argv (sp + 0x4) -> r1
- * bl main
- *
- * bl exit
- *
- * infinite loop
- */
-#define _START          \
-  _INIT;                \
-                        \
-  ldr r0, [sp, #0];     \
-  add r1, sp, #4;       \
-  bl main;              \
-                        \
-  bl exit;              \
-  1:                    \
-  b 1b;
-
-/**
- * If hard-float mode:
- *   store s16-s31 vfp registers to buffer, pointed with r0 register,
- *   and increase the register on size of stored data.
- */
-#if defined (__VFP_FP__) && !defined (__SOFTFP__)
-# define _STORE_VFP_S16_S31_IF_HARD_FLOAT \
-   vstm r0!, {s16 - s31};
-# define _LOAD_VFP_S16_S31_IF_HARD_FLOAT \
-   vldm r0!, {s16 - s31};
-#else /* !__VFP_FP__ || __SOFTFP__ */
-# define _STORE_VFP_S16_S31_IF_HARD_FLOAT
-# define _LOAD_VFP_S16_S31_IF_HARD_FLOAT
-#endif /* __VFP_FP__ && !__SOFTFP__ */
-
-/*
- * setjmp
- *
- * According to procedure call standard for the ARM architecture, the following
- * registers are callee-saved, and so need to be stored in context:
- *   - r4 - r11
- *   - sp
- *   - s16 - s31
- *
- * Also, we should store:
- *   - lr
- *
- * stmia {r4-r11, sp, lr} -> jmp_buf_0 (r0)!
- *
- * If hard-float build
- *   vstm  {s16-s31} -> jmp_buf_32 (r0)!
- *
- * mov r0, #0
- *
- * bx lr
- */
-#define _SETJMP \
-  stmia r0!, {r4 - r11, sp, lr};    \
-                                    \
-  _STORE_VFP_S16_S31_IF_HARD_FLOAT  \
-                                    \
-  mov r0, #0;                       \
-                                    \
-  bx lr;
-
-/*
- * longjmp
- *
- * See also:
- *          _SETJMP
- *
- * ldmia jmp_buf_0 (r0)! -> {r4-r11, sp, lr}
- *
- * If hard-float build
- *   vldm  jmp_buf_32 (r0)! -> {s16-s31}
- *
- * mov r1 -> r0
- * cmp r0, #0
- * bne 1f
- * mov #1 -> r0
- * 1:
- *
- * bx lr
- */
-#define _LONGJMP \
-  ldmia r0!, {r4 - r11, sp, lr};    \
-                                    \
-  _LOAD_VFP_S16_S31_IF_HARD_FLOAT   \
-                                    \
-  mov r0, r1;                       \
-  cmp r0, #0;                       \
-  bne 1f;                           \
-  mov r0, #1;                       \
-  1:                                \
-                                    \
-  bx lr;
-
-#endif /* !ASM_ARM_H */
diff --git a/deps/jerry/jerry-libc/arch/x86-32.h b/deps/jerry/jerry-libc/arch/x86-32.h
deleted file mode 100644 (file)
index c674f4a..0000000
+++ /dev/null
@@ -1,227 +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 ASM_X86_H
-#define ASM_X86_H
-
-/*
- * mov syscall_no -> %eax
- * int $0x80
- * mov %eax -> ret
- */
-#define SYSCALL_0 \
-  push %edi;               \
-  push %esi;               \
-  push %ebx;               \
-  mov 0x10 (%esp), %eax;   \
-  int $0x80;               \
-  pop %ebx;                \
-  pop %esi;                \
-  pop %edi;                \
-  ret;
-
-/*
- * mov syscall_no -> %eax
- * mov arg1 -> %ebx
- * int $0x80
- * mov %eax -> ret
- */
-#define SYSCALL_1 \
-  push %edi;               \
-  push %esi;               \
-  push %ebx;               \
-  mov 0x10 (%esp), %eax;   \
-  mov 0x14 (%esp), %ebx;   \
-  int $0x80;               \
-  pop %ebx;                \
-  pop %esi;                \
-  pop %edi;                \
-  ret;
-
-/*
- * mov syscall_no -> %eax
- * mov arg1 -> %ebx
- * mov arg2 -> %ecx
- * int $0x80
- * mov %eax -> ret
- */
-#define SYSCALL_2 \
-  push %edi;               \
-  push %esi;               \
-  push %ebx;               \
-  mov 0x10 (%esp), %eax;   \
-  mov 0x14 (%esp), %ebx;   \
-  mov 0x18 (%esp), %ecx;   \
-  int $0x80;               \
-  pop %ebx;                \
-  pop %esi;                \
-  pop %edi;                \
-  ret;
-
-/*
- * mov syscall_no -> %eax
- * mov arg1 -> %ebx
- * mov arg2 -> %ecx
- * mov arg3 -> %edx
- * int $0x80
- * mov %eax -> ret
- */
-#define SYSCALL_3 \
-  push %edi;               \
-  push %esi;               \
-  push %ebx;               \
-  mov 0x10 (%esp), %eax;   \
-  mov 0x14 (%esp), %ebx;   \
-  mov 0x18 (%esp), %ecx;   \
-  mov 0x1c (%esp), %edx;   \
-  int $0x80;               \
-  pop %ebx;                \
-  pop %esi;                \
-  pop %edi;               \
-  ret;
-
-#ifdef ENABLE_INIT_FINI
-/*
- * call libc_init_array
- */
-#define _INIT             \
-  call libc_init_array;
-#else /* !ENABLE_INIT_FINI */
-#define _INIT
-#endif /* ENABLE_INIT_FINI */
-
-/*
- * call libc_init_array
- *
- * push argv (%esp + 4)
- * push argc ([%esp + 0x4])
- *
- * call main
- *
- * push main_ret (%eax)
- * call exit
- *
- * infinite loop
- */
-#define _START            \
-  _INIT;                  \
-                          \
-  mov %esp, %eax;         \
-  add $4, %eax;           \
-  push %eax;              \
-  mov 0x4 (%esp), %eax;   \
-  push %eax;              \
-                          \
-  call main;              \
-                          \
-  push %eax;              \
-  call exit;              \
-                          \
-  1:                      \
-  jmp 1b;
-
-/*
- * setjmp
- *
- * According to x86_32 System V ABI, the following registers are
- * callee-saved, and so need to be stored in context:
- *   - %ebx
- *   - %esp
- *   - %ebp
- *   - %esi
- *   - %edi
- *   - x87 control word
- *
- * Also, we should store:
- *   - return address (to jump to upon longjmp)
- *
- * mov return_address ([%esp]) -> %eax
- *
- * mov env ([%esp + 0x4]) -> %edx
- *
- * mov %ebx -> jmp_buf_0  ([%edx + 0x0])
- * mov %esp -> jmp_buf_4  ([%edx + 0x4])
- * mov %ebp -> jmp_buf_8  ([%edx + 0x8])
- * mov %esi -> jmp_buf_12 ([%edx + 0xc])
- * mov %edi -> jmp_buf_16 ([%edx + 0x10])
- * mov %eax -> jmp_buf_20 ([%edx + 0x14])
- * fnstcw   -> jmp_buf_24 ([%edx + 0x18])
- *
- * ret
- */
-#define _SETJMP \
-  mov (%esp), %eax;       \
-  mov 0x4 (%esp), %edx;   \
-                          \
-  mov %ebx, 0x00 (%edx);  \
-  mov %esp, 0x04 (%edx);  \
-  mov %ebp, 0x08 (%edx);  \
-  mov %esi, 0x0c (%edx);  \
-  mov %edi, 0x10 (%edx);  \
-  mov %eax, 0x14 (%edx);  \
-  fnstcw 0x18 (%edx);     \
-                          \
-  xor %eax, %eax;         \
-                          \
-  ret
-
-/*
- * longjmp
- *
- * See also:
- *          _SETJMP
- *
- * mov env ([%esp + 0x4]) -> %edx
- * mov val ([%esp + 0x8]) -> %eax
- *
- * mov jmp_buf_0    ([%edx + 0x0])  -> %ebx
- * mov jmp_buf_4    ([%edx + 0x8])  -> %esp
- * mov jmp_buf_8    ([%edx + 0x10]) -> %ebp
- * mov jmp_buf_12   ([%edx + 0x18]) -> %esi
- * mov jmp_buf_16   ([%edx + 0x20]) -> %edi
- * mov jmp_buf_20   ([%edx + 0x28]) -> %ecx
- * fldcw jmp_buf_24 ([%edx + 0x30])
- *
- * mov return_address (%ecx) -> ([%esp])
- *
- * cmp (%eax), 0x0
- * jnz 1f
- * xor %eax, %eax
- * 1:
- *
- * ret
- */
-#define _LONGJMP \
-  mov 0x4 (%esp), %edx;   \
-  mov 0x8 (%esp), %eax;   \
-                          \
-  mov 0x0 (%edx), %ebx;   \
-  mov 0x4 (%edx), %esp;   \
-  mov 0x8 (%edx), %ebp;   \
-  mov 0xc (%edx), %esi;   \
-  mov 0x10 (%edx), %edi;  \
-  mov 0x14 (%edx), %ecx;  \
-  fldcw 0x18 (%edx);      \
-                          \
-  mov %ecx, (%esp);       \
-                          \
-  test %eax, %eax;        \
-  jnz 1f;                 \
-  xor %eax, %eax;         \
- 1:                       \
-                          \
-  ret
-
-#endif /* !ASM_X86_H */
diff --git a/deps/jerry/jerry-libc/arch/x86-64.h b/deps/jerry/jerry-libc/arch/x86-64.h
deleted file mode 100644 (file)
index 5a35d02..0000000
+++ /dev/null
@@ -1,202 +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 ASM_X64_H
-#define ASM_X64_H
-
-/*
- * mov syscall_no (%rdi) -> %rax
- * syscall
- */
-#define SYSCALL_0 \
-  mov %rdi, %rax; \
-  syscall; \
-  ret;
-
-/*
- * mov syscall_no (%rdi) -> %rax
- * mov arg1 (%rsi) -> %rdi
- * syscall
- */
-#define SYSCALL_1 \
-  mov %rdi, %rax; \
-  mov %rsi, %rdi; \
-  syscall; \
-  ret;
-
-/*
- * mov syscall_no (%rdi) -> %rax
- * mov arg1 (%rsi) -> %rdi
- * mov arg2 (%rdx) -> %rsi
- * syscall
- */
-#define SYSCALL_2 \
-  mov %rdi, %rax; \
-  mov %rsi, %rdi; \
-  mov %rdx, %rsi; \
-  syscall; \
-  ret;
-
-/*
- * mov syscall_no (%rdi) -> %rax
- * mov arg1 (%rsi) -> %rdi
- * mov arg2 (%rdx) -> %rsi
- * mov arg3 (%rcx) -> %rdx
- * syscall
- */
-#define SYSCALL_3 \
-  mov %rdi, %rax; \
-  mov %rsi, %rdi; \
-  mov %rdx, %rsi; \
-  mov %rcx, %rdx; \
-  syscall; \
-  ret;
-
-#ifdef ENABLE_INIT_FINI
-/*
- * call libc_init_array
- */
-#define _INIT             \
-  call libc_init_array;
-#else /* !ENABLE_INIT_FINI */
-#define _INIT
-#endif /* ENABLE_INIT_FINI */
-
-/*
- * call libc_init_array
- *
- * mov argc ([%rsp]) -> %rdi
- * mov argv (%rsp + 0x8) -> %rsi
- *
- * call main
- *
- * mov main_ret (%rax) -> %rdi
- * call exit
- *
- * infinite loop
- */
-#define _START            \
-  _INIT;                  \
-                          \
-  mov (%rsp), %rdi;       \
-  mov %rsp, %rsi;         \
-  add $8, %rsi;           \
-  callq main;             \
-                          \
-  mov %rax, %rdi;         \
-  callq exit;             \
-  1:                      \
-  jmp 1b;
-
-/*
- * setjmp
- *
- * According to x86_64 System V ABI, the following registers are
- * callee-saved, and so need to be stored in context:
- *   - %rbp
- *   - %rbx
- *   - %r12
- *   - %r13
- *   - %r14
- *   - %r15
- *   - x87 control word
- *
- * Also, we should store:
- *   - %rsp (stack pointer)
- *   - return address (to jump to upon longjmp)
- *
- * mov return_address ([%rsp]) -> %rax
- *
- * mov %rsp -> jmp_buf_0  ([%rdi + 0x0])
- * mov %rax -> jmp_buf_8  ([%rdi + 0x8])
- * mov %rbp -> jmp_buf_16 ([%rdi + 0x10])
- * mov %rbx -> jmp_buf_24 ([%rdi + 0x18])
- * mov %r12 -> jmp_buf_32 ([%rdi + 0x20])
- * mov %r13 -> jmp_buf_40 ([%rdi + 0x28])
- * mov %r14 -> jmp_buf_48 ([%rdi + 0x30])
- * mov %r15 -> jmp_buf_56 ([%rdi + 0x38])
- * fnstcw   -> jmp_buf_64 ([%rdi + 0x40])
- *
- * ret
- */
-#define _SETJMP \
-  mov (%rsp), %rax;      \
-                         \
-  mov %rsp, 0x00(%rdi);  \
-  mov %rax, 0x08(%rdi);  \
-  mov %rbp, 0x10(%rdi);  \
-  mov %rbx, 0x18(%rdi);  \
-  mov %r12, 0x20(%rdi);  \
-  mov %r13, 0x28(%rdi);  \
-  mov %r14, 0x30(%rdi);  \
-  mov %r15, 0x38(%rdi);  \
-  fnstcw 0x40(%rdi);     \
-                         \
-  xor %rax, %rax;        \
-                         \
-  ret;
-
-/*
- * longjmp
- *
- * See also:
- *          _SETJMP
- *
- * mov jmp_buf_0  ([%rdi + 0x0])  -> %rsp
- * mov jmp_buf_8  ([%rdi + 0x8])  -> %rax
- * mov jmp_buf_16 ([%rdi + 0x10]) -> %rbp
- * mov jmp_buf_24 ([%rdi + 0x18]) -> %rbx
- * mov jmp_buf_32 ([%rdi + 0x20]) -> %r12
- * mov jmp_buf_40 ([%rdi + 0x28]) -> %r13
- * mov jmp_buf_48 ([%rdi + 0x30]) -> %r14
- * mov jmp_buf_56 ([%rdi + 0x38]) -> %r15
- * fldcw jmp_buf_64 ([%rdi + 0x40])
- *
- * mov return_address (%rax) -> ([%rsp])
- *
- * mov val (%rsi) -> %rax
- *
- * test (%rax), (%rax)
- * jnz 1f
- * mov $1, %rax
- * 1:
- *
- * ret
- */
-#define _LONGJMP \
-  mov 0x00(%rdi), %rsp; \
-  mov 0x08(%rdi), %rax; \
-  mov 0x10(%rdi), %rbp; \
-  mov 0x18(%rdi), %rbx; \
-  mov 0x20(%rdi), %r12; \
-  mov 0x28(%rdi), %r13; \
-  mov 0x30(%rdi), %r14; \
-  mov 0x38(%rdi), %r15; \
-  fldcw 0x40(%rdi);     \
-                        \
-  mov %rax, (%rsp);     \
-                        \
-  mov %rsi, %rax;       \
-                        \
-  test %rax, %rax;      \
-  jnz 1f;               \
-  mov $1, %rax;         \
- 1:                     \
-                        \
-  ret
-
-
-
-#endif /* !ASM_X64_H */
diff --git a/deps/jerry/jerry-libc/include/assert.h b/deps/jerry/jerry-libc/include/assert.h
deleted file mode 100644 (file)
index 8e43849..0000000
+++ /dev/null
@@ -1,44 +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_LIBC_ASSERT_H
-#define JERRY_LIBC_ASSERT_H
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-#ifndef NDEBUG
-#define assert(x) \
-  do \
-  { \
-    if (!(x)) \
-    { \
-      fprintf (stderr, "%s:%d: %s: Assertion `%s' failed.", __FILE__, __LINE__, __func__, #x); \
-      abort (); \
-    } \
-  } while (0)
-#else /* NDEBUG */
-#define assert(x) ((void) 0)
-#endif /* !NDEBUG */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* !JERRY_LIBC_ASSERT_H */
diff --git a/deps/jerry/jerry-libc/include/setjmp.h b/deps/jerry/jerry-libc/include/setjmp.h
deleted file mode 100644 (file)
index ce5961c..0000000
+++ /dev/null
@@ -1,64 +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_LIBC_SETJMP_H
-#define JERRY_LIBC_SETJMP_H
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-/**
- * Storage for context, used for nonlocal goto
- *
- * x86_64 (8 * 8 + 2 bytes):
- *   0x00 - %rsp
- *   0x08 - return address
- *   0x10 - %rbp
- *   0x18 - %rbx
- *   0x20 - %r12
- *   0x28 - %r13
- *   0x30 - %r14
- *   0x38 - %r15
- *   0x40 - x87 control word
- *
- * x86_32 (6 * 4 + 2 bytes):
- *   - %ebx
- *   - %esp
- *   - %ebp
- *   - %esi
- *   - %edi
- *   - return address (to jump to upon longjmp)
- *   - x87 control word
- *
- * ARMv7 (10 * 4 + 16 * 4 bytes):
- *   - r4 - r11, sp, lr
- *   - s16 - s31 (if hardfp enabled)
- *
- * See also:
- *          setjmp, longjmp
- */
-typedef uint64_t jmp_buf[14];
-
-int setjmp (jmp_buf env);
-void longjmp (jmp_buf env, int val);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* !JERRY_LIBC_SETJMP_H */
diff --git a/deps/jerry/jerry-libc/include/stdio.h b/deps/jerry/jerry-libc/include/stdio.h
deleted file mode 100644 (file)
index 9ff331e..0000000
+++ /dev/null
@@ -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_LIBC_STDIO_H
-#define JERRY_LIBC_STDIO_H
-
-#include <stdarg.h>
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-/**
- * File descriptor type
- */
-typedef void FILE;
-
-/**
- * Standard file descriptors
- */
-extern FILE *stdin;
-extern FILE *stdout;
-extern FILE *stderr;
-
-/**
- * I/O routines
- */
-int vfprintf (FILE *stream, const char *format, va_list ap);
-FILE *fopen (const char *path, const char *mode);
-int fclose (FILE *fp);
-size_t fread (void *ptr, size_t size, size_t nmemb, FILE *stream);
-size_t fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream);
-int printf (const char *format, ...);
-int fprintf (FILE *stream, const char *format, ...);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* !JERRY_LIBC_STDIO_H */
diff --git a/deps/jerry/jerry-libc/include/stdlib.h b/deps/jerry/jerry-libc/include/stdlib.h
deleted file mode 100644 (file)
index 4682af8..0000000
+++ /dev/null
@@ -1,41 +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_LIBC_STDLIB_H
-#define JERRY_LIBC_STDLIB_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-/**
- * Maximum integer that could be returned by random number generator
- *
- * See also:
- *          rand
- */
-#define RAND_MAX (0x7fffffffu)
-
-void __attribute__ ((noreturn)) exit (int);
-void __attribute__ ((noreturn)) abort (void);
-int rand (void);
-void srand (unsigned int);
-long int strtol (const char *, char **, int);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* !JERRY_LIBC_STDLIB_H */
diff --git a/deps/jerry/jerry-libc/include/string.h b/deps/jerry/jerry-libc/include/string.h
deleted file mode 100644 (file)
index 0576540..0000000
+++ /dev/null
@@ -1,38 +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_LIBC_STRING_H
-#define JERRY_LIBC_STRING_H
-
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-void *memcpy (void *dest, const void *src, size_t n);
-void *memset (void *s, int c, size_t n);
-void *memmove (void *dest, const void *src, size_t n);
-int memcmp (const void *s1, const void *s2, size_t n);
-int strcmp (const char *s1, const char *s2);
-int strncmp (const char *s1, const char *s2, size_t n);
-char *strncpy (char *dest, const char *src, size_t n);
-size_t strlen (const char *s);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* !JERRY_LIBC_STRING_H */
diff --git a/deps/jerry/jerry-libc/include/sys/time.h b/deps/jerry/jerry-libc/include/sys/time.h
deleted file mode 100644 (file)
index a20cba0..0000000
+++ /dev/null
@@ -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.
- */
-
-#ifndef JERRY_LIBC_TIME_H
-#define JERRY_LIBC_TIME_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-/**
- * Time value structure
- */
-struct timeval
-{
-  unsigned long tv_sec;   /**< seconds */
-  unsigned long tv_usec;  /**< microseconds */
-};
-
-/**
- * Timezone structure
- */
-struct timezone
-{
-  int tz_minuteswest;     /**< minutes west of Greenwich */
-  int tz_dsttime;         /**< type of DST correction */
-};
-
-int gettimeofday (void *tp, void *tzp);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* !JERRY_LIBC_TIME_H */
diff --git a/deps/jerry/jerry-libc/jerry-libc-defs.h b/deps/jerry/jerry-libc/jerry-libc-defs.h
deleted file mode 100644 (file)
index 3a61a93..0000000
+++ /dev/null
@@ -1,37 +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 DEFS_H
-#define DEFS_H
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stddef.h>
-
-/**
- * Attributes
- */
-#define __attr_unused___   __attribute__((unused))
-#define __attr_used___     __attribute__((used))
-#define __attr_noreturn___ __attribute__((noreturn))
-#define __attr_noinline___ __attribute__((noinline))
-#define __attr_weak___     __attribute__((weak))
-
-#ifdef ENABLE_INIT_FINI
-void libc_init_array (void);
-void libc_fini_array (void);
-#endif /* ENABLE_INIT_FINI */
-
-#endif /* !DEFS_H */
diff --git a/deps/jerry/jerry-libc/jerry-libc-init.c b/deps/jerry/jerry-libc/jerry-libc-init.c
deleted file mode 100644 (file)
index 3d34666..0000000
+++ /dev/null
@@ -1,98 +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.
- *
- * This file is based on work under the following copyright and permission
- * notice:
- *
- *    Copyright (C) 2004 CodeSourcery, LLC
- *
- *    Permission to use, copy, modify, and distribute this file
- *    for any purpose is hereby granted without fee, provided that
- *    the above copyright notice and this notice appears in all
- *    copies.
- *
- *    This file is distributed WITHOUT ANY WARRANTY; without even the implied
- *    warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#include "jerry-libc-defs.h"
-
-#ifdef ENABLE_INIT_FINI
-
-/* These magic symbols are provided by the linker.  */
-typedef void (*libc_init_fn_t) (void);
-
-extern libc_init_fn_t __preinit_array_start[] __attr_weak___;
-extern libc_init_fn_t __preinit_array_end[] __attr_weak___;
-extern libc_init_fn_t __init_array_start[] __attr_weak___;
-extern libc_init_fn_t __init_array_end[] __attr_weak___;
-extern libc_init_fn_t __fini_array_start[] __attr_weak___;
-extern libc_init_fn_t __fini_array_end[] __attr_weak___;
-extern void _init (void);
-extern void _fini (void);
-
-
-/**
- * No-op default _init.
- */
-void __attr_weak___
-_init (void)
-{
-} /* _init */
-
-/**
- * No-op default _fini.
- */
-void __attr_weak___
-_fini (void)
-{
-} /* _fini */
-
-/**
- * Iterate over all the init routines.
- */
-void
-libc_init_array (void)
-{
-  size_t count = (size_t) (__preinit_array_end - __preinit_array_start);
-  for (size_t i = 0; i < count; i++)
-  {
-    __preinit_array_start[i] ();
-  }
-
-  _init ();
-
-  count = (size_t) (__init_array_end - __init_array_start);
-  for (size_t i = 0; i < count; i++)
-  {
-    __init_array_start[i] ();
-  }
-} /* libc_init_array */
-
-/**
- * Run all the cleanup routines.
- */
-void
-libc_fini_array (void)
-{
-  size_t count = (size_t) (__fini_array_end - __fini_array_start);
-  for (size_t i = count; i > 0; i--)
-  {
-    __fini_array_start[i - 1] ();
-  }
-
-  _fini ();
-} /* libc_fini_array */
-
-#endif /* ENABLE_INIT_FINI */
diff --git a/deps/jerry/jerry-libc/jerry-libc-printf.c b/deps/jerry/jerry-libc/jerry-libc-printf.c
deleted file mode 100644 (file)
index a786839..0000000
+++ /dev/null
@@ -1,756 +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.
- */
-
-/**
- * Jerry printf implementation
- */
-
-#include <assert.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "jerry-libc-defs.h"
-
-/**
- * printf's length type
- */
-typedef enum
-{
-  LIBC_PRINTF_ARG_LENGTH_TYPE_NONE, /**< (none) */
-  LIBC_PRINTF_ARG_LENGTH_TYPE_HH, /**< hh */
-  LIBC_PRINTF_ARG_LENGTH_TYPE_H, /**< h */
-  LIBC_PRINTF_ARG_LENGTH_TYPE_L, /**< l */
-  LIBC_PRINTF_ARG_LENGTH_TYPE_LL, /**< ll */
-  LIBC_PRINTF_ARG_LENGTH_TYPE_J, /**< j */
-  LIBC_PRINTF_ARG_LENGTH_TYPE_Z, /**< z */
-  LIBC_PRINTF_ARG_LENGTH_TYPE_T, /**< t */
-  LIBC_PRINTF_ARG_LENGTH_TYPE_HIGHL /**< L */
-} libc_printf_arg_length_type_t;
-
-/**
- * printf's flags mask
- */
-typedef uint8_t libc_printf_arg_flags_mask_t;
-
-/**
- * Left justification of field's contents
- */
-#define LIBC_PRINTF_ARG_FLAG_LEFT_JUSTIFY (1 << 0)
-
-/**
- * Force print of number's sign
- */
-#define LIBC_PRINTF_ARG_FLAG_PRINT_SIGN   (1 << 1)
-
-/**
- * If no sign is printed, print space before value
- */
-#define LIBC_PRINTF_ARG_FLAG_SPACE        (1 << 2)
-
-/**
- * For o, x, X preceed value with 0, 0x or 0X for non-zero values.
- */
-#define LIBC_PRINTF_ARG_FLAG_SHARP        (1 << 3)
-
-/**
- * Left-pad field with zeroes instead of spaces
- */
-#define LIBC_PRINTF_ARG_FLAG_ZERO_PADDING (1 << 4)
-
-/**
- * printf helper function that outputs a char
- */
-static void
-libc_printf_putchar (FILE *stream, /**< stream pointer */
-                     char character) /**< character */
-{
-  fwrite (&character, 1, sizeof (character), stream);
-} /* libc_printf_putchar */
-
-/**
- * printf helper function that outputs justified string
- */
-static void
-libc_printf_justified_string_output (FILE *stream, /**< stream pointer */
-                                     const char *string_p, /**< string */
-                                     size_t width, /**< minimum field width */
-                                     bool is_left_justify, /**< justify to left (true) or right (false) */
-                                     bool is_zero_padding) /**< left-pad with zeroes (true) or spaces (false) */
-{
-  const size_t str_length = strlen (string_p);
-
-  size_t outputted_length = 0;
-
-  if (!is_left_justify)
-  {
-    char padding_char = is_zero_padding ? '0' : ' ';
-
-    while (outputted_length + str_length < width)
-    {
-      libc_printf_putchar (stream, padding_char);
-      outputted_length++;
-    }
-  }
-
-  fwrite (string_p, 1, str_length * sizeof (*string_p), stream);
-  outputted_length += str_length;
-
-  if (is_left_justify)
-  {
-    while (outputted_length < width)
-    {
-      libc_printf_putchar (stream, ' ');
-      outputted_length++;
-    }
-  }
-} /* libc_printf_justified_string_output */
-
-/**
- * printf helper function that converts unsigned integer to string
- *
- * @return start of the string representation (within the output string buffer
- *         but not necessarily at its start)
- */
-static char *
-libc_printf_uint_to_string (uintmax_t value, /**< integer value */
-                            char *buffer_p, /**< buffer for output string */
-                            size_t buffer_size, /**< buffer size */
-                            const char *alphabet, /**< alphabet used for digits */
-                            uint32_t radix) /**< radix */
-{
-  char *str_buffer_end = buffer_p + buffer_size;
-  char *str_p = str_buffer_end;
-  *--str_p = '\0';
-
-  assert (radix >= 2);
-
-  if ((radix & (radix - 1)) != 0)
-  {
-    /*
-     * Radix is not power of 2. Only 32-bit numbers are supported in this mode.
-     */
-    assert ((value >> 32) == 0);
-
-    uint32_t value_lo = (uint32_t) value;
-
-    while (value_lo != 0)
-    {
-      assert (str_p != buffer_p);
-
-      *--str_p = alphabet[ value_lo % radix ];
-      value_lo /= radix;
-    }
-  }
-  else
-  {
-    uint32_t shift = 0;
-    while (!(radix & (1u << shift)))
-    {
-      shift++;
-
-      assert (shift <= 32);
-    }
-
-    uint32_t value_lo = (uint32_t) value;
-    uint32_t value_hi = (uint32_t) (value >> 32);
-
-    while (value_lo != 0
-           || value_hi != 0)
-    {
-      assert (str_p != buffer_p);
-
-      *--str_p = alphabet[ value_lo & (radix - 1) ];
-      value_lo >>= shift;
-      value_lo += (value_hi & (radix - 1)) << (32 - shift);
-      value_hi >>= shift;
-    }
-  }
-
-  if (*str_p == '\0')
-  {
-    *--str_p = '0';
-  }
-
-  assert (str_p >= buffer_p && str_p < str_buffer_end);
-
-  return str_p;
-} /* libc_printf_uint_to_string */
-
-/**
- * printf helper function that prints d and i arguments
- *
- * @return updated va_list
- */
-static void
-libc_printf_write_d_i (FILE *stream, /**< stream pointer */
-                       va_list *args_list_p, /**< args' list */
-                       libc_printf_arg_flags_mask_t flags, /**< field's flags */
-                       libc_printf_arg_length_type_t length, /**< field's length type */
-                       uint32_t width) /**< minimum field width to output */
-{
-  assert ((flags & LIBC_PRINTF_ARG_FLAG_SHARP) == 0);
-
-  bool is_signed = true;
-  uintmax_t value = 0;
-
-  /* true - positive, false - negative */
-  bool sign = true;
-  const size_t bits_in_byte = 8;
-  const uintmax_t value_sign_mask = ((uintmax_t) 1) << (sizeof (value) * bits_in_byte - 1);
-
-  switch (length)
-  {
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_NONE:
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_HH: /* char is promoted to int */
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_H: /* short int is promoted to int */
-    {
-      value = (uintmax_t) va_arg (*args_list_p, int);
-      break;
-    }
-
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_L:
-    {
-      value = (uintmax_t) va_arg (*args_list_p, long int);
-      break;
-    }
-
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_LL:
-    {
-      value = (uintmax_t) va_arg (*args_list_p, long long int);
-      break;
-    }
-
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_J:
-    {
-      value = (uintmax_t) va_arg (*args_list_p, intmax_t);
-      break;
-    }
-
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_Z:
-    {
-      is_signed = false;
-      value = (uintmax_t) va_arg (*args_list_p, size_t);
-      break;
-    }
-
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_T:
-    {
-      is_signed = false;
-      value = (uintmax_t) va_arg (*args_list_p, ptrdiff_t);
-      break;
-    }
-
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_HIGHL:
-    {
-      assert (false && "unsupported length field L");
-    }
-  }
-
-  if (is_signed)
-  {
-    sign = ((value & value_sign_mask) == 0);
-
-    if (!sign)
-    {
-      value = (uintmax_t) (-value);
-    }
-  }
-
-  char str_buffer[ 32 ];
-  char *string_p = libc_printf_uint_to_string (value,
-                                               str_buffer,
-                                               sizeof (str_buffer),
-                                               "0123456789",
-                                               10);
-
-  if (!sign
-      || (flags & LIBC_PRINTF_ARG_FLAG_PRINT_SIGN))
-  {
-    assert (string_p > str_buffer);
-    *--string_p = (sign ? '+' : '-');
-  }
-  else if (flags & LIBC_PRINTF_ARG_FLAG_SPACE)
-  {
-    /* no sign and space flag, printing one space */
-
-    libc_printf_putchar (stream, ' ');
-    if (width > 0)
-    {
-      width--;
-    }
-  }
-
-  libc_printf_justified_string_output (stream,
-                                       string_p,
-                                       width,
-                                       flags & LIBC_PRINTF_ARG_FLAG_LEFT_JUSTIFY,
-                                       flags & LIBC_PRINTF_ARG_FLAG_ZERO_PADDING);
-} /* libc_printf_write_d_i */
-
-/**
- * printf helper function that prints d and i arguments
- *
- * @return updated va_list
- */
-static void
-libc_printf_write_u_o_x_X (FILE *stream, /**< stream pointer */
-                           char specifier, /**< specifier (u, o, x, X) */
-                           va_list *args_list_p, /**< args' list */
-                           libc_printf_arg_flags_mask_t flags, /**< field's flags */
-                           libc_printf_arg_length_type_t length, /**< field's length type */
-                           uint32_t width) /**< minimum field width to output */
-{
-  uintmax_t value;
-
-  switch (length)
-  {
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_NONE:
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_HH: /* char is promoted to int */
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_H: /* short int is promoted to int */
-    {
-      value = (uintmax_t) va_arg (*args_list_p, unsigned int);
-      break;
-    }
-
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_L:
-    {
-      value = (uintmax_t) va_arg (*args_list_p, unsigned long int);
-      break;
-    }
-
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_LL:
-    {
-      value = (uintmax_t) va_arg (*args_list_p, unsigned long long int);
-      break;
-    }
-
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_J:
-    {
-      value = (uintmax_t) va_arg (*args_list_p, uintmax_t);
-      break;
-    }
-
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_Z:
-    {
-      value = (uintmax_t) va_arg (*args_list_p, size_t);
-      break;
-    }
-
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_T:
-    {
-      value = (uintmax_t) va_arg (*args_list_p, ptrdiff_t);
-      break;
-    }
-
-    case LIBC_PRINTF_ARG_LENGTH_TYPE_HIGHL:
-    {
-      assert (false && "unsupported length field L");
-      return;
-    }
-
-    default:
-    {
-      assert (false && "unexpected length field");
-      return;
-    }
-  }
-
-  if (flags & LIBC_PRINTF_ARG_FLAG_SHARP)
-  {
-    if (value != 0 && specifier != 'u')
-    {
-      libc_printf_putchar (stream, '0');
-
-      if (specifier == 'x')
-      {
-        libc_printf_putchar (stream, 'x');
-      }
-      else if (specifier == 'X')
-      {
-        libc_printf_putchar (stream, 'X');
-      }
-      else
-      {
-        assert (specifier == 'o');
-      }
-    }
-  }
-
-  uint32_t radix;
-  const char *alphabet;
-
-  switch (specifier)
-  {
-    case 'u':
-    {
-      alphabet = "0123456789";
-      radix = 10;
-      break;
-    }
-
-    case 'o':
-    {
-      alphabet = "01234567";
-      radix = 8;
-      break;
-    }
-
-    case 'x':
-    {
-      alphabet = "0123456789abcdef";
-      radix = 16;
-      break;
-    }
-
-    case 'X':
-    {
-      alphabet = "0123456789ABCDEF";
-      radix = 16;
-      break;
-    }
-
-    default:
-    {
-      assert (false && "unexpected type field");
-      return;
-    }
-  }
-
-  char str_buffer[ 32 ];
-  const char *string_p = libc_printf_uint_to_string (value,
-                                                     str_buffer,
-                                                     sizeof (str_buffer),
-                                                     alphabet,
-                                                     radix);
-
-  if (flags & LIBC_PRINTF_ARG_FLAG_PRINT_SIGN)
-  {
-    /* printing sign */
-
-    libc_printf_putchar (stream, '+');
-    if (width > 0)
-    {
-      width--;
-    }
-  }
-  else if (flags & LIBC_PRINTF_ARG_FLAG_SPACE)
-  {
-    /* no sign and space flag, printing one space */
-
-    libc_printf_putchar (stream, ' ');
-    if (width > 0)
-    {
-      width--;
-    }
-  }
-
-  libc_printf_justified_string_output (stream,
-                                       string_p,
-                                       width,
-                                       flags & LIBC_PRINTF_ARG_FLAG_LEFT_JUSTIFY,
-                                       flags & LIBC_PRINTF_ARG_FLAG_ZERO_PADDING);
-} /* libc_printf_write_u_o_x_X */
-
-/**
- * vfprintf
- *
- * @return number of characters printed
- */
-int __attr_weak___
-vfprintf (FILE *stream, /**< stream pointer */
-          const char *format, /**< format string */
-          va_list args) /**< arguments */
-{
-  va_list args_copy;
-
-  va_copy (args_copy, args);
-
-  const char *format_iter_p = format;
-
-  while (*format_iter_p)
-  {
-    if (*format_iter_p != '%')
-    {
-      libc_printf_putchar (stream, *format_iter_p);
-    }
-    else
-    {
-      libc_printf_arg_flags_mask_t flags = 0;
-      uint32_t width = 0;
-      libc_printf_arg_length_type_t length = LIBC_PRINTF_ARG_LENGTH_TYPE_NONE;
-
-      while (true)
-      {
-        format_iter_p++;
-
-        if (*format_iter_p == '-')
-        {
-          flags |= LIBC_PRINTF_ARG_FLAG_LEFT_JUSTIFY;
-        }
-        else if (*format_iter_p == '+')
-        {
-          flags |= LIBC_PRINTF_ARG_FLAG_PRINT_SIGN;
-        }
-        else if (*format_iter_p == ' ')
-        {
-          flags |= LIBC_PRINTF_ARG_FLAG_SPACE;
-        }
-        else if (*format_iter_p == '#')
-        {
-          flags |= LIBC_PRINTF_ARG_FLAG_SHARP;
-        }
-        else if (*format_iter_p == '0')
-        {
-          flags |= LIBC_PRINTF_ARG_FLAG_ZERO_PADDING;
-        }
-        else
-        {
-          break;
-        }
-      }
-
-      if (*format_iter_p == '*')
-      {
-        assert (false && "unsupported width field *");
-      }
-
-      /* If there is a number, recognize it as field width. */
-      while (*format_iter_p >= '0' && *format_iter_p <= '9')
-      {
-        width = width * 10u + (uint32_t) (*format_iter_p - '0');
-
-        format_iter_p++;
-      }
-
-      if (*format_iter_p == '.')
-      {
-        assert (false && "unsupported precision field");
-      }
-
-      switch (*format_iter_p)
-      {
-        case 'h':
-        {
-          format_iter_p++;
-          if (*format_iter_p == 'h')
-          {
-            format_iter_p++;
-
-            length = LIBC_PRINTF_ARG_LENGTH_TYPE_HH;
-          }
-          else
-          {
-            length = LIBC_PRINTF_ARG_LENGTH_TYPE_H;
-          }
-          break;
-        }
-
-        case 'l':
-        {
-          format_iter_p++;
-          if (*format_iter_p == 'l')
-          {
-            format_iter_p++;
-
-            length = LIBC_PRINTF_ARG_LENGTH_TYPE_LL;
-          }
-          else
-          {
-            length = LIBC_PRINTF_ARG_LENGTH_TYPE_L;
-          }
-          break;
-        }
-
-        case 'j':
-        {
-          format_iter_p++;
-          length = LIBC_PRINTF_ARG_LENGTH_TYPE_J;
-          break;
-        }
-
-        case 'z':
-        {
-          format_iter_p++;
-          length = LIBC_PRINTF_ARG_LENGTH_TYPE_Z;
-          break;
-        }
-
-        case 't':
-        {
-          format_iter_p++;
-          length = LIBC_PRINTF_ARG_LENGTH_TYPE_T;
-          break;
-        }
-
-        case 'L':
-        {
-          format_iter_p++;
-          length = LIBC_PRINTF_ARG_LENGTH_TYPE_HIGHL;
-          break;
-        }
-      }
-
-      switch (*format_iter_p)
-      {
-        case 'd':
-        case 'i':
-        {
-          libc_printf_write_d_i (stream, &args_copy, flags, length, width);
-          break;
-        }
-
-        case 'u':
-        case 'o':
-        case 'x':
-        case 'X':
-        {
-          libc_printf_write_u_o_x_X (stream, *format_iter_p, &args_copy, flags, length, width);
-          break;
-        }
-
-        case 'f':
-        case 'F':
-        case 'e':
-        case 'E':
-        case 'g':
-        case 'G':
-        case 'a':
-        case 'A':
-        {
-          assert (false && "unsupported double type field");
-          break;
-        }
-
-        case 'c':
-        {
-          if (length & LIBC_PRINTF_ARG_LENGTH_TYPE_L)
-          {
-            assert (false && "unsupported length field L");
-          }
-          else
-          {
-            char str[2] =
-            {
-              (char) va_arg (args_copy, int), /* char is promoted to int */
-              '\0'
-            };
-
-            libc_printf_justified_string_output (stream,
-                                                 str,
-                                                 width,
-                                                 flags & LIBC_PRINTF_ARG_FLAG_LEFT_JUSTIFY,
-                                                 flags & LIBC_PRINTF_ARG_FLAG_ZERO_PADDING);
-          }
-          break;
-        }
-
-        case 's':
-        {
-          if (length & LIBC_PRINTF_ARG_LENGTH_TYPE_L)
-          {
-            assert (false && "unsupported length field L");
-          }
-          else
-          {
-            char *str_p = va_arg (args_copy, char *);
-
-            libc_printf_justified_string_output (stream,
-                                                 str_p,
-                                                 width,
-                                                 flags & LIBC_PRINTF_ARG_FLAG_LEFT_JUSTIFY,
-                                                 flags & LIBC_PRINTF_ARG_FLAG_ZERO_PADDING);
-          }
-          break;
-        }
-
-        case 'p':
-        {
-          va_list args_copy2;
-          va_copy (args_copy2, args_copy);
-          void *value = va_arg (args_copy2, void *);
-          va_end (args_copy2);
-
-          if (value == NULL)
-          {
-            printf ("(nil)");
-          }
-          else
-          {
-            libc_printf_write_u_o_x_X (stream,
-                                       'x',
-                                       &args_copy,
-                                       flags | LIBC_PRINTF_ARG_FLAG_SHARP,
-                                       LIBC_PRINTF_ARG_LENGTH_TYPE_Z,
-                                       width);
-          }
-          break;
-        }
-
-        case 'n':
-        {
-          assert (false && "unsupported type field n");
-        }
-      }
-    }
-
-    format_iter_p++;
-  }
-
-  va_end (args_copy);
-
-  return 0;
-} /* vfprintf */
-
-/**
- * fprintf
- *
- * @return number of characters printed
- */
-int __attr_weak___
-fprintf (FILE *stream, /**< stream pointer */
-         const char *format, /**< format string */
-         ...) /**< parameters' values */
-{
-  va_list args;
-
-  va_start (args, format);
-
-  int ret = vfprintf (stream, format, args);
-
-  va_end (args);
-
-  return ret;
-} /* fprintf */
-
-/**
- * printf
- *
- * @return number of characters printed
- */
-int __attr_weak___
-printf (const char *format, /**< format string */
-        ...) /**< parameters' values */
-{
-  va_list args;
-
-  va_start (args, format);
-
-  int ret = vfprintf (stdout, format, args);
-
-  va_end (args);
-
-  return ret;
-} /* printf */
diff --git a/deps/jerry/jerry-libc/jerry-libc.c b/deps/jerry/jerry-libc/jerry-libc.c
deleted file mode 100644 (file)
index 45c44c3..0000000
+++ /dev/null
@@ -1,384 +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.
- */
-
-/**
- * Jerry libc's common functions implementation
- */
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "jerry-libc-defs.h"
-
-/**
- * State of pseudo-random number generator
- */
-static uint32_t libc_random_gen_state[4] = { 1455997910, 1999515274, 1234451287, 1949149569 };
-
-/**
- * Standard file descriptors
- */
-FILE *stdin  = (FILE *) 0;
-FILE *stdout = (FILE *) 1;
-FILE *stderr = (FILE *) 2;
-
-#ifdef __GNUC__
-/*
- * Making GCC not to replace:
- *   - memcpy  -> call to memcpy;
- *   - memset  -> call to memset;
- *   - memmove -> call to memmove.
- */
-#define CALL_PRAGMA(x) _Pragma (#x)
-
-CALL_PRAGMA (GCC diagnostic push)
-CALL_PRAGMA (GCC diagnostic ignored "-Wpragmas")
-CALL_PRAGMA (GCC push_options)
-CALL_PRAGMA (GCC optimize ("-fno-tree-loop-distribute-patterns"))
-#endif /* __GNUC__ */
-
-/**
- * memset
- *
- * @return @a s
- */
-void * __attr_weak___ __attr_used___
-memset (void *s, /**< area to set values in */
-        int c, /**< value to set */
-        size_t n) /**< area size */
-{
-  uint8_t *area_p = (uint8_t *) s;
-  while (n--)
-  {
-    *area_p++ = (uint8_t) c;
-  }
-
-  return s;
-} /* memset */
-
-/**
- * memcmp
- *
- * @return 0, if areas are equal;
- *         <0, if first area's content is lexicographically less, than second area's content;
- *         >0, otherwise
- */
-int __attr_weak___
-memcmp (const void *s1, /**< first area */
-        const void *s2, /**< second area */
-        size_t n) /**< area size */
-{
-  const uint8_t *area1_p = (uint8_t *) s1, *area2_p = (uint8_t *) s2;
-  while (n--)
-  {
-    int diff = ((int) *area1_p++) - ((int) *area2_p++);
-    if (diff)
-    {
-      return diff;
-    }
-  }
-
-  return 0;
-} /* memcmp */
-
-/**
- * memcpy
- *
- * @return the dest pointer's value
- */
-void * __attr_weak___ __attr_used___
-memcpy (void *s1, /**< destination */
-        const void *s2, /**< source */
-        size_t n) /**< bytes number */
-{
-  uint8_t *dst_p = (uint8_t *) s1;
-  const uint8_t *src_p = (const uint8_t *) s2;
-
-  /* Aligned fast case. */
-  if (n >= 4 && !(((uintptr_t) s1) & 0x3) && !(((uintptr_t) s2) & 0x3))
-  {
-    size_t chunks = (n >> 2);
-    uint32_t *u32_dst_p = (uint32_t *) dst_p;
-    const uint32_t *u32_src_p = (const uint32_t *) src_p;
-
-    do
-    {
-      *u32_dst_p++ = *u32_src_p++;
-    }
-    while (--chunks);
-
-    n &= 0x3;
-    dst_p = (uint8_t *) u32_dst_p;
-    src_p = (const uint8_t *) u32_src_p;
-  }
-
-  while (n--)
-  {
-    *dst_p++ = *src_p++;
-  }
-
-  return s1;
-} /* memcpy */
-
-/**
- * memmove
- *
- * @return the dest pointer's value
- */
-void * __attr_weak___ __attr_used___
-memmove (void *s1, /**< destination */
-         const void *s2, /**< source */
-         size_t n) /**< bytes number */
-{
-  uint8_t *dest_p;
-  const uint8_t *src_p;
-
-  if (s1 < s2)
-  { /* from begin to end */
-    dest_p = (uint8_t *) s1;
-    src_p = (const uint8_t *) s2;
-
-    while (n--)
-    {
-      *dest_p++ = *src_p++;
-    }
-  }
-  else if (s1 > s2)
-  { /* from end to begin */
-    dest_p = ((uint8_t *) s1) + n - 1;
-    src_p = ((const uint8_t *) s2) + n - 1;
-
-    while (n--)
-    {
-      *dest_p-- = *src_p--;
-    }
-  }
-
-  return s1;
-} /* memmove */
-
-#ifdef __GNUC__
-CALL_PRAGMA (GCC pop_options)
-CALL_PRAGMA (GCC diagnostic pop)
-#endif /* __GNUC__ */
-
-/**
- * Compare two strings.
- *
- * @return an integer less than, equal to, or greater than zero if s1 is found, respectively,
- *         to be less than, to match, or be greater than s2.
- */
-int __attr_weak___
-strcmp (const char *s1, /**< first string */
-        const char *s2) /**< second string */
-{
-  while (1)
-  {
-    int c1 = (unsigned char) *s1++;
-    int c2 = (unsigned char) *s2++;
-    int diff = c1 - c2;
-
-    if (!c1 || diff)
-    {
-      return diff;
-    }
-  }
-} /* strcmp */
-
-/**
- * Compare two strings.
- *
- * @return an integer less than, equal to, or greater than zero if the first n character of s1 is found, respectively,
- *         to be less than, to match, or be greater than the first n character of s2.
- */
-int __attr_weak___
-strncmp (const char *s1, /**< first string */
-         const char *s2, /**< second string */
-         size_t n) /**< maximum number of characters to compare */
-{
-  while (n--)
-  {
-    int c1 = (unsigned char) *s1++;
-    int c2 = (unsigned char) *s2++;
-    int diff = c1 - c2;
-
-    if (!c1 || diff)
-    {
-      return diff;
-    }
-  }
-
-  return 0;
-} /* strncmp */
-
-/**
- * Copy a string. At most n bytes of src are copied.
- *
- * Note:
- *      If there is no null byte among the first n bytes of src, the string
- *      placed in dest will not be null-terminated.
- *
- * @return a pointer to the destination string dest.
- */
-char * __attr_weak___ __attr_used___
-strncpy (char *dest, /**< destination string */
-         const char *src, /**< source string */
-         size_t n) /**< maximum number of characters to copy */
-{
-  while (n--)
-  {
-    char c = *src++;
-    *dest++ = c;
-
-    if (!c)
-    {
-      break;
-    }
-  }
-
-  return dest;
-} /* strncpy */
-
-/**
- * Calculate the length of a string.
- *
- * @return the length.
- */
-size_t __attr_weak___
-strlen (const char *s) /**< string */
-{
-  size_t i = 0;
-  while (s[i])
-  {
-    i++;
-  }
-
-  return i;
-} /* strlen */
-
-/**
- * Generate pseudo-random integer
- *
- * Note:
- *      The function implements George Marsaglia's XorShift random number generator
- *
- * @return integer in range [0; RAND_MAX]
- */
-int __attr_weak___
-rand (void)
-{
-  uint32_t intermediate = libc_random_gen_state[0] ^ (libc_random_gen_state[0] << 11);
-  intermediate ^= intermediate >> 8;
-
-  libc_random_gen_state[0] = libc_random_gen_state[1];
-  libc_random_gen_state[1] = libc_random_gen_state[2];
-  libc_random_gen_state[2] = libc_random_gen_state[3];
-
-  libc_random_gen_state[3] ^= libc_random_gen_state[3] >> 19;
-  libc_random_gen_state[3] ^= intermediate;
-
-  return (int) (libc_random_gen_state[3] % (RAND_MAX + 1));
-} /* rand */
-
-/**
- * Initialize pseudo-random number generator with the specified seed value
- */
-void __attr_weak___
-srand (unsigned int seed) /**< new seed */
-{
-  libc_random_gen_state[0] = (uint32_t) ((seed * 14316555781)
-                                         + (seed * 1183186591)
-                                         + (seed * 622729787)
-                                         + (seed * 338294347));
-
-  libc_random_gen_state[1] = 842502087;
-  libc_random_gen_state[2] = 3579807591;
-  libc_random_gen_state[3] = 273326509;
-} /* srand */
-
-/**
- * Convert a string to a long integer.
- *
- * The function first discards leading whitespace characters. Then takes an
- * optional sign followed by as many digits as possible and interprets them as a
- * numerical value. Additional characters after those that form the number are
- * ignored.
- *
- * Note:
- *      If base is not 10, the behaviour is undefined.
- *      If the value read is out-of-range, the behaviour is undefined.
- *      The implementation never sets errno.
- *
- * @return the integer value of str.
- */
-long int __attr_weak___
-strtol (const char *nptr, /**< string representation of an integer number */
-        char **endptr, /**< [out] the address of the first non-number character */
-        int base) /**< numerical base or radix (MUST be 10) */
-{
-  assert (base == 10);
-  (void) base; /* Unused. */
-
-  const char *str = nptr;
-
-  /* Skip leading whitespaces. */
-  while (*str == ' ' || *str == '\t' || *str == '\r' || *str == '\n')
-  {
-    str++;
-  }
-
-  bool digits = false;
-  bool positive = true;
-  long int num = 0;
-
-  /* Process optional sign. */
-  if (*str == '-')
-  {
-    positive = false;
-    str++;
-  }
-  else if (*str == '+')
-  {
-    str++;
-  }
-
-  /* Process base-10 digits. */
-  while (*str >= '0' && *str <= '9')
-  {
-    num = num * 10 + (*str - '0');
-    digits = true;
-    str++;
-  }
-
-  /* Set endptr and return result*/
-  if (digits)
-  {
-    if (endptr)
-    {
-      *endptr = (char *) str;
-    }
-    return positive ? num : -num;
-  }
-  else
-  {
-    if (endptr)
-    {
-      *endptr = (char *) nptr;
-    }
-    return 0L;
-  }
-} /* strtol */
diff --git a/deps/jerry/jerry-libc/target/posix/jerry-asm.S b/deps/jerry/jerry-libc/target/posix/jerry-asm.S
deleted file mode 100644 (file)
index 9deb0b1..0000000
+++ /dev/null
@@ -1,91 +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.
- */
-
-#if defined (__x86_64__)
-#include "arch/x86-64.h"
-#elif defined (__i386__)
-#include "arch/x86-32.h"
-#elif defined (__ARM_ARCH_7A__)
-#include "arch/arm-v7.h"
-#else /* !__x86_64__ && !__i386__ && !__ARM_ARCH_7A__ */
-#error "Unsupported architecture"
-#endif /* __x86_64__ */
-
-#if defined (__linux__)
-.macro func _name
-.global \_name
-.type \_name, %function
-\_name:
-.endm
-.macro endfunc _name
-.size \_name, .-\_name
-.endm
-#elif defined (__APPLE__) && defined (__MACH__)
-.macro func _name
-.global \_name
-\_name:
-.endm
-.macro endfunc _name
-.endm
-#else /* !__linux && !(__APPLE__ && __MACH__) */
-#error "Unsupported OS"
-#endif /* __linux__ */
-
-func _start
-  _START
-endfunc _start
-
-func syscall_0
-  SYSCALL_0
-endfunc syscall_0
-
-func syscall_1
-  SYSCALL_1
-endfunc syscall_1
-
-func syscall_2
-  SYSCALL_2
-endfunc syscall_2
-
-func syscall_3
-  SYSCALL_3
-endfunc syscall_3
-
-/**
- * setjmp (jmp_buf env)
- *
- * See also:
- *          longjmp
- *
- * @return 0 - if returns from direct call,
- *         nonzero - if returns after longjmp.
- */
-func setjmp
-  _SETJMP
-endfunc setjmp
-
-/**
- * longjmp (jmp_buf env, int val)
- *
- * Note:
- *      if val is not 0, then it would be returned from setjmp,
- *      otherwise - 0 would be returned.
- *
- * See also:
- *          setjmp
- */
-func longjmp
-  _LONGJMP
-endfunc longjmp
diff --git a/deps/jerry/jerry-libc/target/posix/jerry-libc-target.c b/deps/jerry/jerry-libc/target/posix/jerry-libc-target.c
deleted file mode 100644 (file)
index d0a628c..0000000
+++ /dev/null
@@ -1,279 +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.
- */
-
-/**
- * Jerry libc platform-specific functions posix implementation
- */
-
-#include <assert.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#if defined (__linux__)
-#define SYSCALL_NO(NAME) __NR_ ## NAME
-#elif defined (__APPLE__) && defined (__MACH__)
-#define SYS_exit_group SYS_exit
-#define SYSCALL_NO(NAME) SYS_ ## NAME
-#else /* !__linux && !(__APPLE__ && __MACH__) */
-#error "Unsupported OS"
-#endif /* __linux__ */
-
-#include "jerry-libc-defs.h"
-
-long int syscall_0 (long int syscall_no);
-long int syscall_1 (long int syscall_no, long int arg1);
-long int syscall_2 (long int syscall_no, long int arg1, long int arg2);
-long int syscall_3 (long int syscall_no, long int arg1, long int arg2, long int arg3);
-
-/**
- * Exit - cause normal process termination with specified status code
- */
-void __attr_weak___ __attr_noreturn___ __attr_used___
-exit (int status) /**< status code */
-{
-#ifdef ENABLE_INIT_FINI
-  libc_fini_array ();
-#endif /* ENABLE_INIT_FINI */
-
-  syscall_1 (SYSCALL_NO (close), (long int) stdin);
-  syscall_1 (SYSCALL_NO (close), (long int) stdout);
-  syscall_1 (SYSCALL_NO (close), (long int) stderr);
-
-  syscall_1 (SYSCALL_NO (exit_group), status);
-
-  while (true)
-  {
-    /* unreachable */
-  }
-} /* exit */
-
-/**
- * Abort current process, producing an abnormal program termination.
- * The function raises the SIGABRT signal.
- */
-void __attr_weak___ __attr_noreturn___ __attr_used___
-abort (void)
-{
-  syscall_1 (SYSCALL_NO (close), (long int) stdin);
-  syscall_1 (SYSCALL_NO (close), (long int) stdout);
-  syscall_1 (SYSCALL_NO (close), (long int) stderr);
-
-  raise (SIGABRT);
-
-  while (true)
-  {
-    /* unreachable */
-  }
-} /* abort */
-
-/**
- * Send a signal to the current process.
- *
- * @return 0 - upon successful completion,
- *         non-zero value - otherwise.
- */
-int __attr_weak___ __attr_used___
-raise (int sig) /**< signal number */
-{
-  return (int) syscall_2 (SYSCALL_NO (kill), syscall_0 (SYSCALL_NO (getpid)), sig);
-} /* raise */
-
-/**
- * fopen
- *
- * @return FILE pointer - upon successful completion,
- *         NULL - otherwise.
- */
-FILE * __attr_weak___
-fopen (const char *path, /**< file path */
-       const char *mode) /**< file open mode */
-{
-  bool may_read = false;
-  bool may_write = false;
-  bool truncate = false;
-  bool create_if_not_exist = false;
-  bool position_at_end = false;
-
-  assert (path != NULL && mode != NULL);
-  assert (mode[1] == '+' || mode[1] == '\0');
-
-  switch (mode[0])
-  {
-    case 'r':
-    {
-      may_read = true;
-      may_write = (mode[1] == '+');
-      break;
-    }
-    case 'w':
-    {
-      may_write = true;
-      truncate = true;
-      create_if_not_exist = true;
-      may_read = (mode[1] == '+');
-      break;
-    }
-    case 'a':
-    {
-      may_write = true;
-      position_at_end = true;
-      create_if_not_exist = true;
-      if (mode[1] == '+')
-      {
-        assert (false && "unsupported mode a+");
-      }
-      break;
-    }
-    default:
-    {
-      assert (false && "unsupported mode");
-    }
-  }
-
-  int flags = 0;
-  int access = S_IRUSR | S_IWUSR;
-  if (may_read && !may_write)
-  {
-    flags = O_RDONLY;
-  }
-  else if (!may_read && may_write)
-  {
-    flags = O_WRONLY;
-  }
-  else
-  {
-    assert (may_read && may_write);
-
-    flags = O_RDWR;
-  }
-
-  if (truncate)
-  {
-    flags |= O_TRUNC;
-  }
-
-  if (create_if_not_exist)
-  {
-    flags |= O_CREAT;
-  }
-
-  if (position_at_end)
-  {
-    flags |= O_APPEND;
-  }
-
-  long int ret = syscall_3 (SYSCALL_NO (open), (long int) path, flags, access);
-
-  return ((ret < 0) ? NULL : (void *) (uintptr_t) (ret));
-} /* fopen */
-
-/**
- * fclose
- *
- * @return 0 - upon successful completion,
- *         non-zero value - otherwise.
- */
-int __attr_weak___
-fclose (FILE *fp) /**< stream pointer */
-{
-  syscall_2 (SYSCALL_NO (close), (long int) fp, 0);
-
-  return 0;
-} /* fclose */
-
-/**
- * fread
- *
- * @return number of elements read
- */
-size_t __attr_weak___
-fread (void *ptr, /**< address of buffer to read to */
-       size_t size, /**< size of elements to read */
-       size_t nmemb, /**< number of elements to read */
-       FILE *stream) /**< stream pointer */
-{
-  long int ret;
-  size_t bytes_read = 0;
-
-  if (size == 0)
-  {
-    return 0;
-  }
-
-  do
-  {
-    ret = syscall_3 (SYSCALL_NO (read),
-                     (long int) stream,
-                     (long int) ((uint8_t *) ptr + bytes_read),
-                     (long int) (size * nmemb - bytes_read));
-
-    bytes_read += (size_t) ret;
-  }
-  while (bytes_read != size * nmemb && ret != 0);
-
-  return bytes_read / size;
-} /* fread */
-
-/**
- * fwrite
- *
- * @return number of elements written
- */
-size_t __attr_weak___
-fwrite (const void *ptr, /**< data to write */
-        size_t size, /**< size of elements to write */
-        size_t nmemb, /**< number of elements */
-        FILE *stream) /**< stream pointer */
-{
-  size_t bytes_written = 0;
-
-  if (size == 0)
-  {
-    return 0;
-  }
-
-  do
-  {
-    long int ret = syscall_3 (SYSCALL_NO (write),
-                              (long int) stream,
-                              (long int) ((uint8_t *) ptr + bytes_written),
-                              (long int) (size * nmemb - bytes_written));
-
-    bytes_written += (size_t) ret;
-  }
-  while (bytes_written != size * nmemb);
-
-  return bytes_written / size;
-} /* fwrite */
-
-/**
- * This function can get the time as well as a timezone.
- *
- * @return 0 if success, -1 otherwise
- */
-int __attr_weak___
-gettimeofday (void *tp,  /**< struct timeval */
-              void *tzp) /**< struct timezone */
-{
-  return (int) syscall_2 (SYSCALL_NO (gettimeofday), (long int) tp, (long int) tzp);
-} /* gettimeofday */
index 4a79fe1366e8893989c12dd1c8a31735758c55b1..abc182cde0f6bace51a54850a844242bcc1a76c9 100644 (file)
@@ -30,7 +30,7 @@ set(INCLUDE_LIBM "${CMAKE_CURRENT_SOURCE_DIR}/include")
 # Source directories
 file(GLOB SOURCE_LIBM *.c)
 
-add_library(${JERRY_LIBM_NAME} STATIC ${SOURCE_LIBM})
+add_library(${JERRY_LIBM_NAME} ${SOURCE_LIBM})
 set_property(TARGET ${JERRY_LIBM_NAME}
              PROPERTY COMPILE_FLAGS "${COMPILE_FLAGS_LIBM}")
 
index f7dcfc7591d14324462d01b703b752553a7bc610..4b24ef5871ada124c948d4d877bd1a45c8c719f9 100644 (file)
@@ -19,7 +19,7 @@ project (jerry-main C)
 set(ENABLE_LINK_MAP OFF CACHE BOOL "Enable generating a link map file?")
 
 # Status messages
-message(STATUS "ENABLE_LINK_MAP           " ${ENABLE_LINK_MAP})
+message(STATUS "ENABLE_LINK_MAP             " ${ENABLE_LINK_MAP})
 
 # Generate map file
 if(ENABLE_LINK_MAP)
@@ -54,10 +54,6 @@ macro(jerry_create_executable JERRY_NAME)
   install(TARGETS ${JERRY_NAME} DESTINATION bin)
 endmacro()
 
-if(JERRY_LIBC AND FEATURE_EXTERNAL_CONTEXT)
-  MESSAGE(FATAL_ERROR "This configuration is not supported for jerry-main. Please build against your system libc to enable the external context.")
-endif()
-
 # Jerry standalones
 if(JERRY_CMDLINE)
   jerry_create_executable("jerry" "main-unix.c" "cli.c")
index 0e8e151a700efa8fb77256bdf1b42abfb8c19fc6..28546566bbeb51c3795798fa95deb1e19633b893 100644 (file)
@@ -21,7 +21,7 @@
  * implementations.
  */
 
- #ifdef __GNUC__
+#ifdef __GNUC__
 /*
  * Note:
  *      This is nasty and dangerous. However, we only need the timeval structure
index 77a7c755cc2efd32bff965849455911398f2694e..1f8c878f78b2477c96401634521fdff5fb1d51a7 100644 (file)
@@ -362,7 +362,7 @@ cli_print_help (const char *help) /**< the help message to print */
     cli_print_prefix (help, length);
 
     help += length;
-    while (*help == ' ' && *help != 0)
+    while (*help == ' ')
     {
       help++;
     }
index ce425bf774dbcd053728a1091c4080e735b94993..62a5fa31bef36c31362ae78e69eab338738cebdf 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <assert.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include "jerryscript.h"
  */
 #define JERRY_BUFFER_SIZE (1048576)
 
+/**
+ * Maximum number of loaded literals
+ */
+#define JERRY_LITERAL_LENGTH (4096)
+
 /**
  * Standalone Jerry exit codes
  */
 #define JERRY_STANDALONE_EXIT_CODE_OK   (0)
 #define JERRY_STANDALONE_EXIT_CODE_FAIL (1)
 
-static uint8_t input_buffer[ JERRY_BUFFER_SIZE ];
-static uint32_t output_buffer[ JERRY_BUFFER_SIZE / 4 ];
+static uint8_t input_buffer[JERRY_BUFFER_SIZE];
+static uint32_t output_buffer[JERRY_BUFFER_SIZE / 4];
+static jerry_char_t literal_buffer[JERRY_BUFFER_SIZE];
 static const char *output_file_name_p = "js.snapshot";
+static jerry_length_t magic_string_lengths[JERRY_LITERAL_LENGTH];
+static const jerry_char_t *magic_string_items[JERRY_LITERAL_LENGTH];
 
 /**
  * Check whether JerryScript has a requested feature enabled or not. If not,
@@ -92,7 +101,7 @@ static size_t
 read_file (uint8_t *input_pos_p, /**< next position in the input buffer */
            const char *file_name) /**< file name */
 {
-  FILE *file = fopen (file_name, "r");
+  FILE *file = fopen (file_name, "rb");
 
   if (file == NULL)
   {
@@ -117,7 +126,7 @@ read_file (uint8_t *input_pos_p, /**< next position in the input buffer */
     return 0;
   }
 
-  printf ("Input file '%s' (%d bytes) loaded.\n", file_name, (int) bytes_read);
+  printf ("Input file '%s' (%lu bytes) loaded.\n", file_name, bytes_read);
   return bytes_read;
 } /* read_file */
 
@@ -127,11 +136,11 @@ read_file (uint8_t *input_pos_p, /**< next position in the input buffer */
 static void
 print_unhandled_exception (jerry_value_t error_value) /**< error value */
 {
-  assert (!jerry_value_has_error_flag (error_value));
+  assert (!jerry_value_is_error (error_value));
 
   jerry_value_t err_str_val = jerry_value_to_string (error_value);
 
-  if (jerry_value_has_error_flag (err_str_val))
+  if (jerry_value_is_error (err_str_val))
   {
     /* Avoid recursive error throws. */
     jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Snapshot error: [value cannot be converted to string]\n");
@@ -164,10 +173,9 @@ typedef enum
 {
   OPT_GENERATE_HELP,
   OPT_GENERATE_STATIC,
-  OPT_GENERATE_LITERAL_LIST,
-  OPT_GENERATE_LITERAL_C,
   OPT_GENERATE_SHOW_OP,
   OPT_GENERATE_OUT,
+  OPT_IMPORT_LITERAL_LIST
 } generate_opt_id_t;
 
 /**
@@ -179,18 +187,15 @@ static const cli_opt_t generate_opts[] =
                .help = "print this help and exit"),
   CLI_OPT_DEF (.id = OPT_GENERATE_STATIC, .opt = "s", .longopt = "static",
                .help = "generate static snapshot"),
-  CLI_OPT_DEF (.id = OPT_GENERATE_LITERAL_LIST, .longopt = "save-literals-list-format",
+  CLI_OPT_DEF (.id = OPT_IMPORT_LITERAL_LIST, .longopt = "load-literals-list-format",
                .meta = "FILE",
-               .help = "export literals found in parsed JS input (in list format)"),
-  CLI_OPT_DEF (.id = OPT_GENERATE_LITERAL_C, .longopt = "save-literals-c-format",
-               .meta = "FILE",
-               .help = "export literals found in parsed JS input (in C source format)"),
+               .help = "import literals from list format (for static snapshots)"),
   CLI_OPT_DEF (.id = OPT_GENERATE_SHOW_OP, .longopt = "show-opcodes",
                .help = "print generated opcodes"),
   CLI_OPT_DEF (.id = OPT_GENERATE_OUT, .opt = "o",  .meta="FILE",
                .help = "specify output file name (default: js.snapshot)"),
   CLI_OPT_DEF (.id = CLI_OPT_DEFAULT, .meta = "FILE",
-               .help = "input snapshot file")
+               .help = "input source file")
 };
 
 /**
@@ -205,14 +210,13 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
 {
   (void) argc;
 
-  bool is_save_literals_mode_in_c_format = false;
   uint32_t snapshot_flags = 0;
   jerry_init_flag_t flags = JERRY_INIT_EMPTY;
 
   const char *file_name_p = NULL;
   uint8_t *source_p = input_buffer;
   size_t source_length = 0;
-  const char *save_literals_file_name_p = NULL;
+  const char *literals_file_name_p = NULL;
 
   cli_change_opts (cli_state_p, generate_opts);
 
@@ -230,17 +234,9 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
         snapshot_flags |= JERRY_SNAPSHOT_SAVE_STATIC;
         break;
       }
-      case OPT_GENERATE_LITERAL_LIST:
-      case OPT_GENERATE_LITERAL_C:
+      case OPT_IMPORT_LITERAL_LIST:
       {
-        if (save_literals_file_name_p != NULL)
-        {
-          jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: literal file name already specified");
-          return JERRY_STANDALONE_EXIT_CODE_FAIL;
-        }
-
-        is_save_literals_mode_in_c_format = (id == OPT_GENERATE_LITERAL_C);
-        save_literals_file_name_p = cli_consume_string (cli_state_p);
+        literals_file_name_p = cli_consume_string (cli_state_p);
         break;
       }
       case OPT_GENERATE_SHOW_OP:
@@ -303,11 +299,44 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
   if (!jerry_is_valid_utf8_string (source_p, (jerry_size_t) source_length))
   {
     jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Input must be a valid UTF-8 string.\n");
+    jerry_cleanup ();
     return JERRY_STANDALONE_EXIT_CODE_FAIL;
   }
 
-  jerry_value_t snapshot_result;
+  if (literals_file_name_p != NULL)
+  {
+    /* Import literal list */
+    uint8_t *sp_buffer_start_p = source_p + source_length + 1;
+    size_t sp_buffer_size = read_file (sp_buffer_start_p, literals_file_name_p);
+
+    if (sp_buffer_size > 0)
+    {
+      const char *sp_buffer_p = (const char *) sp_buffer_start_p;
+      uint32_t num_of_lit = 0;
+
+      do
+      {
+        char *sp_buffer_end_p = NULL;
+        jerry_length_t mstr_size = (jerry_length_t) strtol (sp_buffer_p, &sp_buffer_end_p, 10);
+        if (mstr_size > 0)
+        {
+          magic_string_items[num_of_lit] = (jerry_char_t *) (sp_buffer_end_p + 1);
+          magic_string_lengths[num_of_lit] = mstr_size;
+          num_of_lit++;
+        }
+        sp_buffer_p = sp_buffer_end_p + mstr_size + 1;
+      }
+      while ((size_t) (sp_buffer_p - (char *) sp_buffer_start_p) < sp_buffer_size);
 
+      if (num_of_lit > 0)
+      {
+        jerry_register_magic_strings (magic_string_items, num_of_lit,
+                                      magic_string_lengths);
+      }
+    }
+  }
+
+  jerry_value_t snapshot_result;
   snapshot_result = jerry_generate_snapshot ((jerry_char_t *) file_name_p,
                                              (size_t) strlen (file_name_p),
                                              (jerry_char_t *) source_p,
@@ -316,25 +345,27 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
                                              output_buffer,
                                              sizeof (output_buffer) / sizeof (uint32_t));
 
-  if (jerry_value_has_error_flag (snapshot_result))
+  if (jerry_value_is_error (snapshot_result))
   {
     jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Generating snapshot failed!\n");
 
-    jerry_value_clear_error_flag (&snapshot_result);
+    snapshot_result = jerry_get_value_from_error (snapshot_result, true);
 
     print_unhandled_exception (snapshot_result);
 
     jerry_release_value (snapshot_result);
+    jerry_cleanup ();
     return JERRY_STANDALONE_EXIT_CODE_FAIL;
   }
 
   size_t snapshot_size = (size_t) jerry_get_number_value (snapshot_result);
   jerry_release_value (snapshot_result);
 
-  FILE *snapshot_file_p = fopen (output_file_name_p, "w");
+  FILE *snapshot_file_p = fopen (output_file_name_p, "wb");
   if (snapshot_file_p == NULL)
   {
     jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Unable to write snapshot file: '%s'\n", output_file_name_p);
+    jerry_cleanup ();
     return JERRY_STANDALONE_EXIT_CODE_FAIL;
   }
 
@@ -343,36 +374,197 @@ process_generate (cli_state_t *cli_state_p, /**< cli state */
 
   printf ("Created snapshot file: '%s' (%lu bytes)\n", output_file_name_p, (unsigned long) snapshot_size);
 
-  if (save_literals_file_name_p != NULL)
+  jerry_cleanup ();
+  return JERRY_STANDALONE_EXIT_CODE_OK;
+} /* process_generate */
+
+/**
+ * Literal dump command line option IDs
+ */
+typedef enum
+{
+  OPT_LITERAL_DUMP_HELP,
+  OPT_LITERAL_DUMP_FORMAT,
+  OPT_LITERAL_DUMP_OUT,
+} literal_dump_opt_id_t;
+
+/**
+ * Literal dump command line options
+ */
+static const cli_opt_t literal_dump_opts[] =
+{
+  CLI_OPT_DEF (.id = OPT_LITERAL_DUMP_HELP, .opt = "h", .longopt = "help",
+               .help = "print this help and exit"),
+  CLI_OPT_DEF (.id = OPT_LITERAL_DUMP_FORMAT, .longopt = "format",
+               .meta = "[c|list]",
+               .help = "specify output format (default: list)"),
+  CLI_OPT_DEF (.id = OPT_LITERAL_DUMP_OUT, .opt = "o",
+               .help = "specify output file name (default: literals.[h|list])"),
+  CLI_OPT_DEF (.id = CLI_OPT_DEFAULT, .meta = "FILE(S)",
+               .help = "input snapshot files")
+};
+
+/**
+ * Process 'litdump' command.
+ *
+ * @return error code (0 - no error)
+ */
+static int
+process_literal_dump (cli_state_t *cli_state_p, /**< cli state */
+                      int argc, /**< number of arguments */
+                      char *prog_name_p) /**< program name */
+{
+  uint8_t *input_pos_p = input_buffer;
+
+  cli_change_opts (cli_state_p, literal_dump_opts);
+
+  JERRY_VLA (const uint32_t *, snapshot_buffers, argc);
+  JERRY_VLA (size_t, snapshot_buffer_sizes, argc);
+  uint32_t number_of_files = 0;
+  const char *literals_file_name_p = NULL;
+  bool is_c_format = false;
+
+  for (int id = cli_consume_option (cli_state_p); id != CLI_OPT_END; id = cli_consume_option (cli_state_p))
   {
-    const size_t literal_buffer_size = jerry_parse_and_save_literals ((jerry_char_t *) source_p,
-                                                                      source_length,
-                                                                      false,
-                                                                      output_buffer,
-                                                                      sizeof (output_buffer) / sizeof (uint32_t),
-                                                                      is_save_literals_mode_in_c_format);
-    if (literal_buffer_size == 0)
+    switch (id)
     {
-      jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Literal saving failed!\n");
-      return JERRY_STANDALONE_EXIT_CODE_FAIL;
+      case OPT_LITERAL_DUMP_HELP:
+      {
+        cli_help (prog_name_p, "litdump", literal_dump_opts);
+        return JERRY_STANDALONE_EXIT_CODE_OK;
+      }
+      case OPT_LITERAL_DUMP_FORMAT:
+      {
+        const char *fromat_str_p = cli_consume_string (cli_state_p);
+        if (!strcmp ("c", fromat_str_p))
+        {
+          is_c_format = true;
+        }
+        else if (!strcmp ("list", fromat_str_p))
+        {
+          is_c_format = false;
+        }
+        else
+        {
+          jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Unsupported literal dump format.");
+          return JERRY_STANDALONE_EXIT_CODE_FAIL;
+        }
+        break;
+      }
+      case OPT_LITERAL_DUMP_OUT:
+      {
+        literals_file_name_p = cli_consume_string (cli_state_p);
+        break;
+      }
+      case CLI_OPT_DEFAULT:
+      {
+        const char *file_name_p = cli_consume_string (cli_state_p);
+
+        if (cli_state_p->error == NULL)
+        {
+          size_t size = read_file (input_pos_p, file_name_p);
+
+          if (size == 0)
+          {
+            return JERRY_STANDALONE_EXIT_CODE_FAIL;
+          }
+
+          snapshot_buffers[number_of_files] = (const uint32_t *) input_pos_p;
+          snapshot_buffer_sizes[number_of_files] = size;
+
+          number_of_files++;
+          const uintptr_t mask = sizeof (uint32_t) - 1;
+          input_pos_p = (uint8_t *) ((((uintptr_t) input_pos_p) + size + mask) & ~mask);
+        }
+        break;
+      }
+      default:
+      {
+        cli_state_p->error = "Internal error";
+        break;
+      }
     }
+  }
+
+  if (check_cli_error (cli_state_p))
+  {
+    return JERRY_STANDALONE_EXIT_CODE_FAIL;
+  }
+
+  if (number_of_files < 1)
+  {
+    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: at least one input file must be specified.\n");
+    return JERRY_STANDALONE_EXIT_CODE_FAIL;
+  }
 
-    FILE *literal_file_p = fopen (save_literals_file_name_p, "w");
+  jerry_init (JERRY_INIT_EMPTY);
 
-    if (literal_file_p == NULL)
+  size_t lit_buf_sz = 0;
+  if (number_of_files == 1)
+  {
+    lit_buf_sz = jerry_get_literals_from_snapshot (snapshot_buffers[0],
+                                                   snapshot_buffer_sizes[0],
+                                                   literal_buffer,
+                                                   JERRY_BUFFER_SIZE,
+                                                   is_c_format);
+  }
+  else
+  {
+    /* The input contains more than one input snapshot file, so we must merge them first. */
+    const char *error_p = NULL;
+    size_t merged_snapshot_size = jerry_merge_snapshots (snapshot_buffers,
+                                                         snapshot_buffer_sizes,
+                                                         number_of_files,
+                                                         output_buffer,
+                                                         JERRY_BUFFER_SIZE,
+                                                         &error_p);
+
+    if (merged_snapshot_size == 0)
     {
-      jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Unable to write literal file: '%s'\n", save_literals_file_name_p);
+      jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", error_p);
+      jerry_cleanup ();
       return JERRY_STANDALONE_EXIT_CODE_FAIL;
     }
 
-    fwrite (output_buffer, sizeof (uint8_t), literal_buffer_size, literal_file_p);
-    fclose (literal_file_p);
+    printf ("Successfully merged the input snapshots (%lu bytes).\n", merged_snapshot_size);
 
-    printf ("Created literal file: '%s' (%lu bytes)\n", save_literals_file_name_p, (unsigned long) literal_buffer_size);
+    lit_buf_sz = jerry_get_literals_from_snapshot (output_buffer,
+                                                   merged_snapshot_size,
+                                                   literal_buffer,
+                                                   JERRY_BUFFER_SIZE,
+                                                   is_c_format);
   }
 
-  return 0;
-} /* process_generate */
+  if (lit_buf_sz == 0)
+  {
+    jerry_port_log (JERRY_LOG_LEVEL_ERROR,
+                    "Error: Literal saving failed! No literals were found in the input snapshot(s).\n");
+    jerry_cleanup ();
+    return JERRY_STANDALONE_EXIT_CODE_FAIL;
+  }
+
+  if (literals_file_name_p == NULL)
+  {
+    literals_file_name_p = is_c_format ? "literals.h" : "literals.list";
+  }
+
+  FILE *file_p = fopen (literals_file_name_p, "wb");
+
+  if (file_p == NULL)
+  {
+    jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: cannot open file: '%s'\n", literals_file_name_p);
+    jerry_cleanup ();
+    return JERRY_STANDALONE_EXIT_CODE_FAIL;
+  }
+
+  fwrite (literal_buffer, sizeof (uint8_t), lit_buf_sz, file_p);
+  fclose (file_p);
+
+  printf ("Literals are saved into '%s' (%lu bytes).\n", literals_file_name_p, lit_buf_sz);
+
+  jerry_cleanup ();
+  return JERRY_STANDALONE_EXIT_CODE_OK;
+} /* process_literal_dump */
 
 /**
  * Merge command line option IDs
@@ -406,14 +598,12 @@ process_merge (cli_state_t *cli_state_p, /**< cli state */
                int argc, /**< number of arguments */
                char *prog_name_p) /**< program name */
 {
-  jerry_init (JERRY_INIT_EMPTY);
-
   uint8_t *input_pos_p = input_buffer;
 
   cli_change_opts (cli_state_p, merge_opts);
 
-  const uint32_t *merge_buffers[argc];
-  size_t merge_buffer_sizes[argc];
+  JERRY_VLA (const uint32_t *, merge_buffers, argc);
+  JERRY_VLA (size_t, merge_buffer_sizes, argc);
   uint32_t number_of_files = 0;
 
   for (int id = cli_consume_option (cli_state_p); id != CLI_OPT_END; id = cli_consume_option (cli_state_p))
@@ -468,36 +658,43 @@ process_merge (cli_state_t *cli_state_p, /**< cli state */
   if (number_of_files < 2)
   {
     jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: at least two input files must be passed.\n");
-
     return JERRY_STANDALONE_EXIT_CODE_FAIL;
   }
 
-  const char *error_p;
-  size_t size = jerry_merge_snapshots (merge_buffers,
-                                       merge_buffer_sizes,
-                                       number_of_files,
-                                       output_buffer,
-                                       JERRY_BUFFER_SIZE,
-                                       &error_p);
+  jerry_init (JERRY_INIT_EMPTY);
+
+  const char *error_p = NULL;
+  size_t merged_snapshot_size = jerry_merge_snapshots (merge_buffers,
+                                                       merge_buffer_sizes,
+                                                       number_of_files,
+                                                       output_buffer,
+                                                       JERRY_BUFFER_SIZE,
+                                                       &error_p);
 
-  if (size == 0)
+  if (merged_snapshot_size == 0)
   {
     jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: %s\n", error_p);
+    jerry_cleanup ();
     return JERRY_STANDALONE_EXIT_CODE_FAIL;
   }
 
-  FILE *file_p = fopen (output_file_name_p, "w");
+  FILE *file_p = fopen (output_file_name_p, "wb");
 
-  if (file_p != NULL)
-  {
-    fwrite (output_buffer, 1u, size, file_p);
-    fclose (file_p);
-  }
-  else
+  if (file_p == NULL)
   {
     jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: cannot open file: '%s'\n", output_file_name_p);
+    jerry_cleanup ();
+    return JERRY_STANDALONE_EXIT_CODE_FAIL;
   }
 
+  fwrite (output_buffer, 1u, merged_snapshot_size, file_p);
+  fclose (file_p);
+
+  printf ("Merge is completed. Merged snapshot is saved into '%s' (%lu bytes).\n",
+          output_file_name_p,
+          merged_snapshot_size);
+
+  jerry_cleanup ();
   return JERRY_STANDALONE_EXIT_CODE_OK;
 } /* process_merge */
 
@@ -530,6 +727,7 @@ print_commands (char *prog_name_p) /**< program name */
 
   printf ("\nAvailable commands:\n"
           "  generate\n"
+          "  litdump\n"
           "  merge\n"
           "\nPassing -h or --help after a command displays its help.\n");
 } /* print_commands */
@@ -567,6 +765,10 @@ main (int argc, /**< number of arguments */
         {
           return process_merge (&cli_state, argc, argv[0]);
         }
+        else if (!strcmp ("litdump", command_p))
+        {
+          return process_literal_dump (&cli_state, argc, argv[0]);
+        }
         else if (!strcmp ("generate", command_p))
         {
           return process_generate (&cli_state, argc, argv[0]);
index a67eb3ed2da166ed9fc75708c9d5af17b9f76403..3db77b950e5c7363ae1258cc4749ae26be64cb1e 100644 (file)
@@ -36,7 +36,7 @@ static const uint8_t *
 read_file (const char *file_name,
            size_t *out_size_p)
 {
-  FILE *file = fopen (file_name, "r");
+  FILE *file = fopen (file_name, "rb");
   if (file == NULL)
   {
     jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to open file: %s\n", file_name);
@@ -98,7 +98,7 @@ main (int argc,
     {
       ret_value = jerry_parse (NULL, 0, source_p, source_size, JERRY_PARSE_NO_OPTS);
 
-      if (!jerry_value_has_error_flag (ret_value))
+      if (!jerry_value_is_error (ret_value))
       {
         jerry_value_t func_val = ret_value;
         ret_value = jerry_run (func_val);
@@ -106,7 +106,7 @@ main (int argc,
       }
     }
 
-    if (jerry_value_has_error_flag (ret_value))
+    if (jerry_value_is_error (ret_value))
     {
       break;
     }
@@ -117,7 +117,7 @@ main (int argc,
 
   int ret_code = JERRY_STANDALONE_EXIT_CODE_OK;
 
-  if (jerry_value_has_error_flag (ret_value))
+  if (jerry_value_is_error (ret_value))
   {
     jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Unhandled exception: Script Error!\n");
     ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL;
index 260cc190b39c677c0d037dfb1a62ed1a50e09959..b8e5801614ac5cd2b8f4e6a83fc158c491fe6fed 100644 (file)
@@ -19,6 +19,7 @@
 #include <string.h>
 
 #include "jerryscript.h"
+#include "jerryscript-ext/debugger.h"
 #include "jerryscript-ext/handler.h"
 #include "jerryscript-port.h"
 #include "jerryscript-port-default.h"
@@ -59,7 +60,7 @@ read_file (const char *file_name,
   }
   else
   {
-    file = fopen (file_name, "r");
+    file = fopen (file_name, "rb");
     if (file == NULL)
     {
       jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: failed to open file: %s\n", file_name);
@@ -87,7 +88,7 @@ read_file (const char *file_name,
 static void
 print_unhandled_exception (jerry_value_t error_value) /**< error value */
 {
-  assert (!jerry_value_has_error_flag (error_value));
+  assert (!jerry_value_is_error (error_value));
 
   jerry_char_t err_str_buf[256];
 
@@ -97,7 +98,7 @@ print_unhandled_exception (jerry_value_t error_value) /**< error value */
     jerry_value_t backtrace_val = jerry_get_property (error_value, stack_str);
     jerry_release_value (stack_str);
 
-    if (!jerry_value_has_error_flag (backtrace_val)
+    if (!jerry_value_is_error (backtrace_val)
         && jerry_value_is_array (backtrace_val))
     {
       printf ("Exception backtrace:\n");
@@ -114,14 +115,14 @@ print_unhandled_exception (jerry_value_t error_value) /**< error value */
       {
         jerry_value_t item_val = jerry_get_property_by_index (backtrace_val, i);
 
-        if (!jerry_value_has_error_flag (item_val)
+        if (!jerry_value_is_error (item_val)
             && jerry_value_is_string (item_val))
         {
           jerry_size_t str_size = jerry_get_string_size (item_val);
 
           if (str_size >= 256)
           {
-            printf ("%3d: [Backtrace string too long]\n", i);
+            printf ("%3u: [Backtrace string too long]\n", i);
           }
           else
           {
@@ -129,7 +130,7 @@ print_unhandled_exception (jerry_value_t error_value) /**< error value */
             assert (string_end == str_size);
             err_str_buf[string_end] = 0;
 
-            printf ("%3d: %s\n", i, err_str_buf);
+            printf ("%3u: %s\n", i, err_str_buf);
           }
         }
 
@@ -262,10 +263,10 @@ register_js_function (const char *name_p, /**< name of the function */
 {
   jerry_value_t result_val = jerryx_handler_register_global ((const jerry_char_t *) name_p, handler_p);
 
-  if (jerry_value_has_error_flag (result_val))
+  if (jerry_value_is_error (result_val))
   {
     jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Warning: failed to register '%s' method.", name_p);
-    jerry_value_clear_error_flag (&result_val);
+    result_val = jerry_get_value_from_error (result_val, true);
     print_unhandled_exception (result_val);
   }
 
@@ -283,15 +284,16 @@ wait_for_source_callback (const jerry_char_t *resource_name_p, /**< resource nam
                           size_t resource_name_size, /**< size of resource name */
                           const jerry_char_t *source_p, /**< source code */
                           size_t source_size, /**< source code size */
-                          void *user_p __attribute__((unused))) /**< user pointer */
+                          void *user_p) /**< user pointer */
 {
+  (void) user_p; /* unused */
   jerry_value_t ret_val = jerry_parse (resource_name_p,
                                        resource_name_size,
                                        source_p,
                                        source_size,
                                        JERRY_PARSE_NO_OPTS);
 
-  if (!jerry_value_has_error_flag (ret_val))
+  if (!jerry_value_is_error (ret_val))
   {
     jerry_value_t func_val = ret_val;
     ret_val = jerry_run (func_val);
@@ -399,29 +401,50 @@ check_usage (bool condition, /**< the condition that must hold */
 #ifdef JERRY_ENABLE_EXTERNAL_CONTEXT
 
 /**
- * The alloc function passed to jerry_create_instance
+ * The alloc function passed to jerry_create_context
  */
 static void *
-instance_alloc (size_t size,
-                void *cb_data_p __attribute__((unused)))
+context_alloc (size_t size,
+               void *cb_data_p)
 {
+  (void) cb_data_p; /* unused */
   return malloc (size);
-} /* instance_alloc */
+} /* context_alloc */
 
 #endif /* JERRY_ENABLE_EXTERNAL_CONTEXT */
 
+/**
+ * Inits the engine and the debugger
+ */
+static void
+init_engine (jerry_init_flag_t flags, /**< initialized flags for the engine */
+             bool debug_server, /**< enable the debugger init or not */
+             uint16_t debug_port) /**< the debugger port */
+{
+  jerry_init (flags);
+  if (debug_server)
+  {
+    jerryx_debugger_after_connect (jerryx_debugger_tcp_create (debug_port)
+                                   && jerryx_debugger_ws_create ());
+  }
+
+  register_js_function ("assert", jerryx_handler_assert);
+  register_js_function ("gc", jerryx_handler_gc);
+  register_js_function ("print", jerryx_handler_print);
+} /* init_engine */
+
 int
 main (int argc,
       char **argv)
 {
   srand ((unsigned) jerry_port_get_current_time ());
-  const char *file_names[argc];
+  JERRY_VLA (const char *, file_names, argc);
   int files_counter = 0;
 
   jerry_init_flag_t flags = JERRY_INIT_EMPTY;
 
-  const char *exec_snapshot_file_names[argc];
-  uint32_t exec_snapshot_file_indices[argc];
+  JERRY_VLA (const char *, exec_snapshot_file_names, argc);
+  JERRY_VLA (uint32_t, exec_snapshot_file_indices, argc);
   int exec_snapshots_count = 0;
 
   bool is_parse_only = false;
@@ -584,20 +607,12 @@ main (int argc,
 
 #ifdef JERRY_ENABLE_EXTERNAL_CONTEXT
 
-  jerry_instance_t *instance_p = jerry_create_instance (512*1024, instance_alloc, NULL);
-  jerry_port_default_set_instance (instance_p);
+  jerry_context_t *context_p = jerry_create_context (512*1024, context_alloc, NULL);
+  jerry_port_default_set_current_context (context_p);
 
 #endif /* JERRY_ENABLE_EXTERNAL_CONTEXT */
 
-  jerry_init (flags);
-  if (start_debug_server)
-  {
-    jerry_debugger_init (debug_port);
-  }
-
-  register_js_function ("assert", jerryx_handler_assert);
-  register_js_function ("gc", jerryx_handler_gc);
-  register_js_function ("print", jerryx_handler_print);
+  init_engine (flags, start_debug_server, debug_port);
 
   jerry_value_t ret_value = jerry_create_undefined ();
 
@@ -620,106 +635,148 @@ main (int argc,
                                          JERRY_SNAPSHOT_EXEC_COPY_DATA);
       }
 
-      if (jerry_value_has_error_flag (ret_value))
+      if (jerry_value_is_error (ret_value))
       {
         break;
       }
     }
   }
 
-  if (!jerry_value_has_error_flag (ret_value))
+  while (true)
   {
-    for (int i = 0; i < files_counter; i++)
-    {
-      size_t source_size;
-      const jerry_char_t *source_p = (jerry_char_t *) read_file (file_names[i], &source_size);
 
-      if (source_p == NULL)
+    if (!jerry_value_is_error (ret_value))
+    {
+      for (int i = 0; i < files_counter; i++)
       {
-        ret_value = jerry_create_error (JERRY_ERROR_COMMON, (jerry_char_t *) "Source file load error");
-        break;
-      }
+        size_t source_size;
+        const jerry_char_t *source_p = (jerry_char_t *) read_file (file_names[i], &source_size);
 
-      if (!jerry_is_valid_utf8_string (source_p, (jerry_size_t) source_size))
-      {
-        ret_value = jerry_create_error (JERRY_ERROR_COMMON, (jerry_char_t *) ("Input must be a valid UTF-8 string."));
-        break;
-      }
+        if (source_p == NULL)
+        {
+          ret_value = jerry_create_error (JERRY_ERROR_COMMON, (jerry_char_t *) "Source file load error");
+          break;
+        }
 
-      ret_value = jerry_parse ((jerry_char_t *) file_names[i],
-                               strlen (file_names[i]),
-                               source_p,
-                               source_size,
-                               JERRY_PARSE_NO_OPTS);
+        if (!jerry_is_valid_utf8_string (source_p, (jerry_size_t) source_size))
+        {
+          ret_value = jerry_create_error (JERRY_ERROR_COMMON, (jerry_char_t *) ("Input must be a valid UTF-8 string."));
+          break;
+        }
 
-      if (!jerry_value_has_error_flag (ret_value) && !is_parse_only)
-      {
-        jerry_value_t func_val = ret_value;
-        ret_value = jerry_run (func_val);
-        jerry_release_value (func_val);
-      }
+        ret_value = jerry_parse ((jerry_char_t *) file_names[i],
+                                 strlen (file_names[i]),
+                                 source_p,
+                                 source_size,
+                                 JERRY_PARSE_NO_OPTS);
 
-      if (jerry_value_has_error_flag (ret_value))
-      {
-        break;
-      }
+        if (!jerry_value_is_error (ret_value) && !is_parse_only)
+        {
+          jerry_value_t func_val = ret_value;
+          ret_value = jerry_run (func_val);
+          jerry_release_value (func_val);
+        }
 
-      jerry_release_value (ret_value);
-      ret_value = jerry_create_undefined ();
-    }
-  }
+        if (jerry_value_is_error (ret_value))
+        {
+          break;
+        }
 
-  if (is_wait_mode)
-  {
-    is_repl_mode = false;
+        jerry_release_value (ret_value);
+        ret_value = jerry_create_undefined ();
+      }
+    }
 
-    if (jerry_is_feature_enabled (JERRY_FEATURE_DEBUGGER))
+    if (is_wait_mode)
     {
-      while (true)
-      {
-        jerry_debugger_wait_for_source_status_t receive_status;
+      is_repl_mode = false;
 
-        do
+      if (jerry_is_feature_enabled (JERRY_FEATURE_DEBUGGER))
+      {
+        while (true)
         {
-          jerry_value_t run_result;
+          jerry_debugger_wait_for_source_status_t receive_status;
 
-          receive_status = jerry_debugger_wait_for_client_source (wait_for_source_callback,
-                                                                  NULL,
-                                                                  &run_result);
-
-          if (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED)
+          do
           {
-            ret_value = jerry_create_error (JERRY_ERROR_COMMON,
-                                            (jerry_char_t *) "Connection aborted before source arrived.");
+            jerry_value_t run_result;
+
+            receive_status = jerry_debugger_wait_for_client_source (wait_for_source_callback,
+                                                                    NULL,
+                                                                    &run_result);
+
+            if (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVE_FAILED)
+            {
+              ret_value = jerry_create_error (JERRY_ERROR_COMMON,
+                                              (jerry_char_t *) "Connection aborted before source arrived.");
+            }
+
+            if (receive_status == JERRY_DEBUGGER_SOURCE_END)
+            {
+              jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "No more client source.\n");
+            }
+
+            if (jerry_value_is_abort (run_result))
+            {
+              ret_value = jerry_acquire_value (run_result);
+            }
+
+            jerry_release_value (run_result);
           }
+          while (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVED);
 
-          if (receive_status == JERRY_DEBUGGER_SOURCE_END)
+          if (receive_status != JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED)
           {
-            jerry_port_log (JERRY_LOG_LEVEL_DEBUG, "No more client source.\n");
+            break;
           }
 
-          jerry_release_value (run_result);
-        }
-        while (receive_status == JERRY_DEBUGGER_SOURCE_RECEIVED);
+          init_engine (flags, true, debug_port);
 
-        if (receive_status != JERRY_DEBUGGER_CONTEXT_RESET_RECEIVED)
-        {
-          break;
+          ret_value = jerry_create_undefined ();
         }
+      }
 
-        jerry_cleanup ();
+    }
 
-        jerry_init (flags);
-        jerry_debugger_init (debug_port);
+    bool restart = false;
 
-        register_js_function ("assert", jerryx_handler_assert);
-        register_js_function ("gc", jerryx_handler_gc);
-        register_js_function ("print", jerryx_handler_print);
+    if (jerry_is_feature_enabled (JERRY_FEATURE_DEBUGGER) && jerry_value_is_abort (ret_value))
+    {
+      jerry_value_t abort_value = jerry_get_value_from_error (ret_value, false);
+      if (jerry_value_is_string (abort_value))
+      {
+        static const char restart_str[] = "r353t";
 
-        ret_value = jerry_create_undefined ();
+        jerry_value_t str_val = jerry_value_to_string (abort_value);
+        jerry_size_t str_size = jerry_get_string_size (str_val);
+
+        if (str_size == sizeof (restart_str) - 1)
+        {
+          JERRY_VLA (jerry_char_t, str_buf, str_size);
+          jerry_string_to_char_buffer (str_val, str_buf, str_size);
+          if (memcmp (restart_str, (char *) (str_buf), str_size) == 0)
+          {
+            jerry_release_value (ret_value);
+            restart = true;
+          }
+        }
+
+        jerry_release_value (str_val);
       }
+
+      jerry_release_value (abort_value);
+    }
+
+    if (!restart)
+    {
+      break;
     }
 
+    jerry_cleanup ();
+
+    init_engine (flags, true, debug_port);
+
+    ret_value = jerry_create_undefined ();
   }
 
   if (is_repl_mode)
@@ -753,10 +810,16 @@ main (int argc,
 
       if (len > 0)
       {
+        if (!jerry_is_valid_utf8_string (buffer, (jerry_size_t) len))
+        {
+          jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Error: Input must be a valid UTF-8 string.\n");
+          return JERRY_STANDALONE_EXIT_CODE_FAIL;
+        }
+
         /* Evaluate the line */
-        jerry_value_t ret_val_eval = jerry_eval (buffer, len, false);
+        jerry_value_t ret_val_eval = jerry_eval (buffer, len, JERRY_PARSE_NO_OPTS);
 
-        if (!jerry_value_has_error_flag (ret_val_eval))
+        if (!jerry_value_is_error (ret_val_eval))
         {
           /* Print return value */
           const jerry_value_t args[] = { ret_val_eval };
@@ -768,15 +831,15 @@ main (int argc,
           jerry_release_value (ret_val_eval);
           ret_val_eval = jerry_run_all_enqueued_jobs ();
 
-          if (jerry_value_has_error_flag (ret_val_eval))
+          if (jerry_value_is_error (ret_val_eval))
           {
-            jerry_value_clear_error_flag (&ret_val_eval);
+            ret_val_eval = jerry_get_value_from_error (ret_val_eval, true);
             print_unhandled_exception (ret_val_eval);
           }
         }
         else
         {
-          jerry_value_clear_error_flag (&ret_val_eval);
+          ret_val_eval = jerry_get_value_from_error (ret_val_eval, true);
           print_unhandled_exception (ret_val_eval);
         }
 
@@ -787,9 +850,9 @@ main (int argc,
 
   int ret_code = JERRY_STANDALONE_EXIT_CODE_OK;
 
-  if (jerry_value_has_error_flag (ret_value))
+  if (jerry_value_is_error (ret_value))
   {
-    jerry_value_clear_error_flag (&ret_value);
+    ret_value = jerry_get_value_from_error (ret_value, true);
     print_unhandled_exception (ret_value);
 
     ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL;
@@ -799,9 +862,9 @@ main (int argc,
 
   ret_value = jerry_run_all_enqueued_jobs ();
 
-  if (jerry_value_has_error_flag (ret_value))
+  if (jerry_value_is_error (ret_value))
   {
-    jerry_value_clear_error_flag (&ret_value);
+    ret_value = jerry_get_value_from_error (ret_value, true);
     print_unhandled_exception (ret_value);
     ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL;
   }
@@ -810,7 +873,7 @@ main (int argc,
 
   jerry_cleanup ();
 #ifdef JERRY_ENABLE_EXTERNAL_CONTEXT
-  free (instance_p);
+  free (context_p);
 #endif /* JERRY_ENABLE_EXTERNAL_CONTEXT */
   return ret_code;
 } /* main */
index b9df5e5e1ee751621bce0ea1e8410056e3472efd..35bca5d877926188869c38e65958211cc7980712 100644 (file)
@@ -26,14 +26,37 @@ file(GLOB SOURCE_PORT_DEFAULT *.c)
 # (should only be necessary if we used compiler default libc but not checking that)
 set(DEFINES_PORT_DEFAULT _BSD_SOURCE _DEFAULT_SOURCE)
 
+INCLUDE (CheckStructHasMember)
+# CHECK_STRUCT_HAS_MEMBER works by trying to compile some C code that accesses the
+# given field of the given struct. However, our default compiler options break this
+# C code, so turn a couple of them off for this.
+set(CMAKE_REQUIRED_FLAGS "-Wno-error=strict-prototypes -Wno-error=old-style-definition")
+# tm.tm_gmtoff is non-standard, so glibc doesn't expose it in c99 mode
+# (our default). Define some macros to expose it anyway.
+set(CMAKE_REQUIRED_DEFINITIONS "-D_BSD_SOURCE -D_DEFAULT_SOURCE")
+CHECK_STRUCT_HAS_MEMBER ("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF)
+if(HAVE_TM_GMTOFF)
+  set(DEFINES_PORT_DEFAULT ${DEFINES_PORT_DEFAULT} HAVE_TM_GMTOFF)
+endif()
+
+# Sleep function availability check
+INCLUDE (CheckIncludeFiles)
+CHECK_INCLUDE_FILES (time.h HAVE_TIME_H)
+CHECK_INCLUDE_FILES (unistd.h HAVE_UNISTD_H)
+if(HAVE_TIME_H)
+  set(DEFINES_PORT_DEFAULT ${DEFINES_PORT_DEFAULT} HAVE_TIME_H)
+elseif(HAVE_UNISTD_H)
+  set(DEFINES_PORT_DEFAULT ${DEFINES_PORT_DEFAULT} HAVE_UNISTD_H)
+endif()
+
 # Default Jerry port implementation library variants:
 #   - default
 #   - default-minimal (no extra termination and log APIs)
 foreach(JERRY_PORT_LIBRARY_NAME ${JERRY_PORT_DEFAULT_NAME} ${JERRY_PORT_DEFAULT_NAME}-minimal)
-  add_library(${JERRY_PORT_LIBRARY_NAME} STATIC ${SOURCE_PORT_DEFAULT})
+  add_library(${JERRY_PORT_LIBRARY_NAME} ${SOURCE_PORT_DEFAULT})
   target_include_directories(${JERRY_PORT_LIBRARY_NAME} PUBLIC ${INCLUDE_PORT_DEFAULT})
-  target_include_directories(${JERRY_PORT_LIBRARY_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/jerry-core/include)
-  target_include_directories(${JERRY_PORT_LIBRARY_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/jerry-ext/include)
+  target_include_directories(${JERRY_PORT_LIBRARY_NAME} PRIVATE ${INCLUDE_CORE_PUBLIC})
+  target_include_directories(${JERRY_PORT_LIBRARY_NAME} PRIVATE ${INCLUDE_EXT_PUBLIC})
   target_compile_definitions(${JERRY_PORT_LIBRARY_NAME} PRIVATE ${DEFINES_PORT_DEFAULT})
   target_link_libraries(${JERRY_PORT_LIBRARY_NAME} jerry-core) # FIXME: remove this dependency as soon as possible
 endforeach()
index 0d5ebed5910158bd61ffddb5f22fa4cce297325d..70213437114859edbf6e4ce2762c5fd14509de38 100644 (file)
  * limitations under the License.
  */
 
+#ifdef HAVE_TM_GMTOFF
+#include <time.h>
+#endif /* HAVE_TM_GMTOFF */
 #ifdef __GNUC__
 #include <sys/time.h>
-#endif
+#endif /* __GNUC__ */
 
 #include "jerryscript-port.h"
 #include "jerryscript-port-default.h"
 
 /**
- * Default implementation of jerry_port_get_time_zone. Uses 'gettimeofday' if
- * available on the system, does nothing otherwise.
+ * Default implementation of jerry_port_get_local_time_zone_adjustment. Uses the 'tm_gmtoff' field
+ * of 'struct tm' (a GNU extension) filled by 'localtime_r' if available on the
+ * system, does nothing otherwise.
  *
- * @return true - if 'gettimeofday' is available and executed successfully,
- *         false - otherwise.
+ * @return offset between UTC and local time at the given unix timestamp, if
+ *         available. Otherwise, returns 0, assuming UTC time.
  */
-bool jerry_port_get_time_zone (jerry_time_zone_t *tz_p) /**< [out] time zone structure to fill */
+double jerry_port_get_local_time_zone_adjustment (double unix_ms,  /**< ms since unix epoch */
+                                                  bool is_utc)  /**< is the time above in UTC? */
 {
-#ifdef __GNUC__
-  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)
+#ifdef HAVE_TM_GMTOFF
+  struct tm tm;
+  time_t now = (time_t) (unix_ms / 1000);
+  localtime_r (&now, &tm);
+  if (!is_utc)
   {
-    return false;
+    now -= tm.tm_gmtoff;
+    localtime_r (&now, &tm);
   }
-
-  tz_p->offset = tz.tz_minuteswest;
-  tz_p->daylight_saving_time = tz.tz_dsttime > 0 ? 1 : 0;
-
-  return true;
-#else /* !__GNUC__ */
-  return false;
-#endif /* __GNUC__ */
-} /* jerry_port_get_time_zone */
+  return ((double) tm.tm_gmtoff) * 1000;
+#else /* !HAVE_TM_GMTOFF */
+  (void) unix_ms;
+  (void) is_utc;
+  return 0.0;
+#endif /* HAVE_TM_GMTOFF */
+} /* jerry_port_get_local_time_zone_adjustment */
 
 /**
  * Default implementation of jerry_port_get_current_time. Uses 'gettimeofday' if
@@ -64,13 +64,11 @@ double jerry_port_get_current_time (void)
 #ifdef __GNUC__
   struct timeval tv;
 
-  if (gettimeofday (&tv, NULL) != 0)
+  if (gettimeofday (&tv, NULL) == 0)
   {
-    return 0.0;
+    return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0;
   }
+#endif /* __GNUC__ */
 
-  return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0;
-#else /* __!GNUC__ */
   return 0.0;
-#endif /* __GNUC__ */
 } /* jerry_port_get_current_time */
index d1b991ddca29ae9d2b0ce92e6d364b427dd7e27c..e32d66114484d5fead60c67c90984e1560e53095 100644 (file)
  * limitations under the License.
  */
 
-#include "jerryscript-port.h"
-#include "jerryscript-port-default.h"
+#if !defined (_XOPEN_SOURCE) || _XOPEN_SOURCE < 500
+#undef _XOPEN_SOURCE
+/* Required macro for sleep functions (nanosleep or usleep) */
+#define _XOPEN_SOURCE 500
+#endif
 
 #ifdef HAVE_TIME_H
 #include <time.h>
 #include <unistd.h>
 #endif /* HAVE_TIME_H */
 
-#ifdef JERRY_DEBUGGER
-void jerry_port_sleep (uint32_t sleep_time)
+#include "jerryscript-port.h"
+#include "jerryscript-port-default.h"
+
+/**
+ * Default implementation of jerry_port_sleep. Uses 'nanosleep' or 'usleep' if
+ * available on the system, does nothing otherwise.
+ */
+void jerry_port_sleep (uint32_t sleep_time) /**< milliseconds to sleep */
 {
 #ifdef HAVE_TIME_H
-  nanosleep (&(const struct timespec)
-  {
-    sleep_time / 1000, (sleep_time % 1000) * 1000000L /* Seconds, nanoseconds */
-  }
-  , NULL);
+  struct timespec sleep_timespec;
+  sleep_timespec.tv_sec = (time_t) sleep_time / 1000;
+  sleep_timespec.tv_nsec = ((long int) sleep_time % 1000) * 1000000L;
+
+  nanosleep (&sleep_timespec, NULL);
 #elif defined (HAVE_UNISTD_H)
   usleep ((useconds_t) sleep_time * 1000);
-#endif /* HAVE_TIME_H */
+#else
   (void) sleep_time;
+#endif /* HAVE_TIME_H */
 } /* jerry_port_sleep */
-#endif /* JERRY_DEBUGGER */
index 11c7fbab02483f7cb06782a2b1b2406c03e0dc1c..1d537716183703fb72ac85fe659324d86ea362ab 100644 (file)
 #include "jerryscript-port-default.h"
 
 /**
- * Pointer to the current instance.
+ * Pointer to the current context.
  * Note that it is a global variable, and is not a thread safe implementation.
  */
-static jerry_instance_t *current_instance_p = NULL;
+static jerry_context_t *current_context_p = NULL;
 
 /**
- * Set the current_instance_p as the passed pointer.
+ * Set the current_context_p as the passed pointer.
  */
 void
-jerry_port_default_set_instance (jerry_instance_t *instance_p) /**< points to the created instance */
+jerry_port_default_set_current_context (jerry_context_t *context_p) /**< points to the created context */
 {
-  current_instance_p = instance_p;
-} /* jerry_port_default_set_instance */
+  current_context_p = context_p;
+} /* jerry_port_default_set_current_context */
 
 /**
- * Get the current instance.
+ * Get the current context.
  *
- * @return the pointer to the current instance
+ * @return the pointer to the current context
  */
-jerry_instance_t *
-jerry_port_get_current_instance (void)
+jerry_context_t *
+jerry_port_get_current_context (void)
 {
-  return current_instance_p;
-} /* jerry_port_get_current_instance */
+  return current_context_p;
+} /* jerry_port_get_current_context */
index 3577c38765675f13f4eff811de6eea3808121a91..53862d10a4698904d5e907a209d7a918dc2f3cda 100644 (file)
@@ -61,20 +61,16 @@ bool jerry_port_default_is_abort_on_fail (void)
  *      The "abort-on-fail" behaviour is only available if the port
  *      implementation library is compiled without the DISABLE_EXTRA_API macro.
  */
-void jerry_port_fatal (jerry_fatal_code_t code)
+void jerry_port_fatal (jerry_fatal_code_t code) /**< cause of error */
 {
 #ifndef DISABLE_EXTRA_API
   if (code != 0
       && code != ERR_OUT_OF_MEMORY
-      && jerry_port_default_is_abort_on_fail ())
+      && abort_on_fail)
   {
     abort ();
   }
-  else
-  {
-#endif /* !DISABLE_EXTRA_API */
-    exit (code);
-#ifndef DISABLE_EXTRA_API
-  }
 #endif /* !DISABLE_EXTRA_API */
+
+  exit ((int) code);
 } /* jerry_port_fatal */
index 1e2f0322585360af9962e4dae37862bef338a331..72dea34e766f7a27268f97a7deb32a3ee55ee0a8 100644 (file)
@@ -17,7 +17,7 @@
 
 #include "jerryscript-port.h"
 #include "jerryscript-port-default.h"
-#include "debugger.h"
+#include "jerryscript-debugger.h"
 
 #ifndef DISABLE_EXTRA_API
 
@@ -61,10 +61,12 @@ jerry_port_default_set_log_level (jerry_log_level_t level) /**< log level */
 #endif /* !DISABLE_EXTRA_API */
 
 /**
- * Default implementation of jerry_port_log. Prints log message to a buffer
- * then prints the buffer to the standard error with 'fprintf' if message
- * level is less than or equal to the set log level.
- * Additionally, sends the message to the debugger client.
+ * Default implementation of jerry_port_log. Prints log message to the standard
+ * error with 'vfprintf' if message log level is less than or equal to the
+ * current log level.
+ *
+ * If debugger support is enabled, printing happens first to an in-memory buffer,
+ * which is then sent both to the standard error and to the debugger client.
  *
  * Note:
  *      Changing the log level from JERRY_LOG_LEVEL_ERROR is only possible if
@@ -72,7 +74,7 @@ jerry_port_default_set_log_level (jerry_log_level_t level) /**< log level */
  *      DISABLE_EXTRA_API macro.
  */
 void
-jerry_port_log (jerry_log_level_t level, /**< log level */
+jerry_port_log (jerry_log_level_t level, /**< message log level */
                 const char *format, /**< format string */
                 ...)  /**< parameters */
 {
@@ -81,13 +83,15 @@ jerry_port_log (jerry_log_level_t level, /**< log level */
     va_list args;
     va_start (args, format);
 #ifdef JERRY_DEBUGGER
-    char buffer[256];
-    int length = 0;
-    length = vsnprintf (buffer, 255, format, args);
-    buffer[length] = '\0';
+    int length = vsnprintf (NULL, 0, format, args);
+    va_end (args);
+    va_start (args, format);
+
+    char buffer[length + 1];
+    vsnprintf (buffer, (size_t) length + 1, format, args);
+
     fprintf (stderr, "%s", buffer);
-    jerry_char_t *jbuffer = (jerry_char_t *) buffer;
-    jerry_debugger_send_output (jbuffer, (jerry_size_t) length, (uint8_t) (level + 2));
+    jerry_debugger_send_log (level, (jerry_char_t *) buffer, (jerry_size_t) length);
 #else /* If jerry-debugger isn't defined, libc is turned on */
     vfprintf (stderr, format, args);
 #endif /* JERRY_DEBUGGER */
index 0ded3eed4c5cf473ccb59f229a524338c0fbc67a..8e9c93934a247dfb18855a9aa98d363484e3f33b 100644 (file)
 
 #include "jerryscript-ext/handler.h"
 
+#ifdef JERRY_DEBUGGER
+
+#define DEBUG_BUFFER_SIZE (256)
+static char debug_buffer[DEBUG_BUFFER_SIZE];
+static int debug_buffer_index = 0;
+
+#endif /* JERRY_DEBUGGER */
+
 /**
  * Default implementation of jerryx_port_handler_print_char. Uses 'printf' to
  * print a single character to standard output.
@@ -25,4 +33,14 @@ void
 jerryx_port_handler_print_char (char c) /**< the character to print */
 {
   printf ("%c", c);
+
+#ifdef JERRY_DEBUGGER
+  debug_buffer[debug_buffer_index++] = c;
+
+  if ((debug_buffer_index == DEBUG_BUFFER_SIZE) || (c == '\n'))
+  {
+    jerry_debugger_send_output ((jerry_char_t *) debug_buffer, (jerry_size_t) debug_buffer_index);
+    debug_buffer_index = 0;
+  }
+#endif /* JERRY_DEBUGGER */
 } /* jerryx_port_handler_print_char */
index 6d66cb9d73b5c7a297200ccb6541f86f7bb3d77d..0789042424b335c6b5f6ff8d207d54279a60a322 100644 (file)
 #ifndef JERRYSCRIPT_PORT_DEFAULT_H
 #define JERRYSCRIPT_PORT_DEFAULT_H
 
+#include <stdbool.h>
+
 #include "jerryscript.h"
 #include "jerryscript-port.h"
 
-#include <stdbool.h>
-
 #ifdef __cplusplus
 extern "C"
 {
@@ -37,7 +37,7 @@ bool jerry_port_default_is_abort_on_fail (void);
 jerry_log_level_t jerry_port_default_get_log_level (void);
 void jerry_port_default_set_log_level (jerry_log_level_t level);
 
-void jerry_port_default_set_instance (jerry_instance_t *instance_p);
+void jerry_port_default_set_current_context (jerry_context_t *context_p);
 
 /**
  * @}
diff --git a/deps/jerry/sonar-project.properties b/deps/jerry/sonar-project.properties
new file mode 100644 (file)
index 0000000..db384bb
--- /dev/null
@@ -0,0 +1,19 @@
+# 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.
+
+sonar.projectName=JerryScript
+sonar.projectKey=jerryscript
+sonar.organization=jerryscript-project
+sonar.sources=jerry-core,jerry-ext,jerry-main,jerry-port
+sonar.cfamily.build-wrapper-output=bw-output
index d9984633da3d9820db2876cb025c13c77ff591e7..b14b532c9d881815e1f2f37bf9d661641b3e2486 100644 (file)
@@ -44,9 +44,9 @@ jerry_value_t print_function;
 
 void jerry_resolve_error (jerry_value_t ret_value)
 {
-  if (jerry_value_has_error_flag (ret_value))
+  if (jerry_value_is_error (ret_value))
   {
-    jerry_value_clear_error_flag (&ret_value);
+    ret_value = jerry_get_value_from_error (ret_value, true);
     jerry_value_t err_str_val = jerry_value_to_string (ret_value);
     jerry_size_t err_str_size = jerry_get_string_size (err_str_val);
     jerry_char_t *err_str_buf = (jerry_char_t *) balloc (err_str_size, NULL);
@@ -111,9 +111,9 @@ void eval_jerry_script (int argc, char *argv[], struct tcmd_handler_ctx *ctx)
     }
     *p = '\0';
 
-    jerry_value_t eval_ret = jerry_eval (buffer, str_total_length - 1, false);
+    jerry_value_t eval_ret = jerry_eval (buffer, str_total_length - 1, JERRY_PARSE_NO_OPTS);
 
-    if (jerry_value_has_error_flag (eval_ret))
+    if (jerry_value_is_error (eval_ret))
     {
       jerry_resolve_error (eval_ret);
       TCMD_RSP_ERROR (ctx, NULL);
index 97cb896c4284a595c51746c16f44f0190425a824..1def05e2ec207ae31e3cabe36c6becbd26616a67 100644 (file)
@@ -52,16 +52,13 @@ void jerry_port_fatal (jerry_fatal_code_t code)
 } /* jerry_port_fatal */
 
 /**
- * Curie BSP implementation of jerry_port_get_time_zone.
+ * Curie BSP implementation of jerry_port_get_local_time_zone_adjustment.
  */
-bool jerry_port_get_time_zone (jerry_time_zone_t *tz_p)
+double jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc)
 {
   //EMPTY implementation
-  tz_p->offset = 0;
-  tz_p->daylight_saving_time = 0;
-
-  return true;
-} /* jerry_port_get_time_zone */
+  return 0;
+} /* jerry_port_get_local_time_zone_adjustment */
 
 /**
  * Curie BSP implementation of jerry_port_get_current_time.
index 804192c13dc4a499e4b97b3593b060ee79487fb5..34dcf71ebea3e76d09f9813d901d4da064615b5d 100644 (file)
@@ -50,7 +50,6 @@ jerry:
         -DCMAKE_C_COMPILER_WORKS=TRUE \
         -DENABLE_LTO=OFF \
         -DENABLE_ALL_IN_ONE=ON \
-        -DJERRY_LIBC=OFF \
         -DJERRY_CMDLINE=OFF \
         -DEXTERNAL_COMPILE_FLAGS="$(ESP_CFLAGS)" \
         -DMEM_HEAP_SIZE_KB=$(JERRYHEAP)
index da5b61cad0bb079e22935173f407c283e603b7e3..aa182c118bee27cfcca5e0452bf07549c2b5c3f6 100644 (file)
@@ -41,7 +41,8 @@ install-espressif-sdk:
        wget https://github.com/esp8266/esp8266-wiki/raw/master/libs/libhal.a -O ../ESP8266_SDK/lib/libhal.a
 
 # Perform all the necessary (JerryScript-independent) installation steps.
-install: install-apt-get-deps install-xtensa-kx106-gcc install-espressif-sdk
+install-noapt: install-xtensa-kx106-gcc install-espressif-sdk
+install: install-apt-get-deps install-noapt
 
 
 ## Targets for building ESP8266 with JerryScript.
index 62e61e469c175bdf9d89718629e4ee2a853b1175..8b5afb0889ab5a0e04df5a82e6c5b03d465e9bc0 100644 (file)
@@ -166,7 +166,7 @@ register_native_function (const char* name,
   jerry_release_value (global_obj_val);
   jerry_release_value (prop_name_val);
 
-  if (jerry_value_has_error_flag (res))
+  if (jerry_value_is_error (res))
   {
     printf ("!!! register_native_function failed: [%s]\r\n", name);
     jerry_release_value (res);
index 7ba25e43ada9774aad44ac896c4ea5547cbaf958..f4d58769736ba5bc9341d56466e0181e5567d33a 100644 (file)
@@ -61,16 +61,13 @@ jerry_port_get_current_time (void)
 } /* jerry_port_get_current_time */
 
 /**
- * Dummy function to get the time zone.
+ * Dummy function to get the time zone adjustment.
  *
- * @return true
+ * @return 0
  */
-bool
-jerry_port_get_time_zone (jerry_time_zone_t *tz_p)
+double
+jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc)
 {
   /* We live in UTC. */
-  tz_p->offset = 0;
-  tz_p->daylight_saving_time = 0;
-
-  return true;
-} /* jerry_port_get_time_zone */
+  return 0;
+} /* jerry_port_get_local_time_zone_adjustment */
index 108e5488f041264ed1726c5ac8e8ba9d3d199a54..ab70ff766ec978fd4703c11e9b3e1655c8aad24c 100644 (file)
@@ -36,8 +36,8 @@ int js_eval (const char *source_p, const size_t source_size)
 {
   jerry_value_t res = jerry_eval ((jerry_char_t *) source_p,
                                   source_size,
-                                  false);
-  if (jerry_value_has_error_flag (res)) {
+                                  JERRY_PARSE_NO_OPTS);
+  if (jerry_value_is_error (res)) {
     jerry_release_value (res);
     return -1;
   }
@@ -54,7 +54,7 @@ int js_loop (uint32_t ticknow)
   jerry_value_t sysloop_func = jerry_get_property (global_obj_val, prop_name_val);
   jerry_release_value (prop_name_val);
 
-  if (jerry_value_has_error_flag (sysloop_func)) {
+  if (jerry_value_is_error (sysloop_func)) {
     printf ("Error: '%s' not defined!!!\r\n", fn_sys_loop_name);
     jerry_release_value (sysloop_func);
     jerry_release_value (global_obj_val);
@@ -83,7 +83,7 @@ int js_loop (uint32_t ticknow)
   jerry_release_value (sysloop_func);
   jerry_release_value (global_obj_val);
 
-  if (jerry_value_has_error_flag (res)) {
+  if (jerry_value_is_error (res)) {
     jerry_release_value (res);
     return -3;
   }
diff --git a/deps/jerry/targets/mbed/Makefile.mbed b/deps/jerry/targets/mbed/Makefile.mbed
deleted file mode 100644 (file)
index 29529c9..0000000
+++ /dev/null
@@ -1,96 +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.
-
-# use TAB-8
-
-TARGET_LIST     = k64f stm32f4 stm32f429i nucleo
-JERRYHEAP      ?= 16
-
-ifneq ($(filter $(board), $(TARGET_LIST)),)
-       TARGET        = $(board)
-ifeq ($(TARGET), k64f)
-       YOTTA_TARGET  = frdm-k64f-gcc
-       TARGET_DIR   ?= /media/$(USER)/MBED
-else ifeq ($(TARGET), stm32f4)
-       YOTTA_TARGET  = stm32f4-disco-gcc
-else ifeq ($(TARGET), stm32f429i)
-       YOTTA_TARGET  = stm32f429i-disco-gcc
-else ifeq ($(TARGET), nucleo)
-       YOTTA_TARGET  = st-nucleo-f401re-gcc
-       TARGET_DIR   ?= /media/$(USER)/NODE_F401RE
-endif
-
-BUILD_DIR      ?= build/mbed
-UPPERC_TARGET  ?= $(shell echo $(TARGET) | tr a-z A-Z)
-COPYTARGET     ?= targets/mbed/libjerry
-
-else
-  $(error This board ($(board)) is not supported!)
-endif
-
-EXT_CFLAGS := -D__TARGET_MBED_$(UPPERC_TARGET)
-EXT_CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m4
-EXT_CFLAGS += -Wno-error=format=
-
-EXT_PORT_DIR := ""
-
-.PHONY: jerry js2c yotta flash clean
-
-all: jerry js2c yotta
-
-jerry:
-       mkdir -p $(COPYTARGET)
-       mkdir -p $(BUILD_DIR)
-       cmake -B$(BUILD_DIR) -H./ \
-        -DCMAKE_SYSTEM_NAME=Mbed \
-        -DCMAKE_SYSTEM_PROCESSOR=armv7l-hf \
-        -DCMAKE_C_COMPILER=arm-none-eabi-gcc \
-        -DCMAKE_C_COMPILER_WORKS=TRUE \
-        -DENABLE_LTO=OFF \
-        -DENABLE_ALL_IN_ONE=OFF \
-        -DJERRY_LIBC=OFF \
-        -DJERRY_CMDLINE=OFF \
-        -DEXTERNAL_COMPILE_FLAGS="$(EXT_CFLAGS)" \
-        -DMEM_HEAP_SIZE_KB=$(JERRYHEAP) \
-
-       make -C$(BUILD_DIR) jerry-core
-       make -C$(BUILD_DIR) jerry-libm
-       cp $(BUILD_DIR)/lib/libjerry-core.a $(COPYTARGET)/libjerrycore.a
-       cp $(BUILD_DIR)/lib/libjerry-libm.a $(COPYTARGET)/libjerrylibm.a
-
-js2c:
-       cd targets/mbed; ../../tools/js2c.py;
-
-yotta:
-       cd targets/mbed; \
-        yotta target $(YOTTA_TARGET); \
-        yotta build
-
-flash:
-  ifndef TARGET_DIR
-       st-flash write targets/mbed/build/$(YOTTA_TARGET)/source/jerry.bin 0x08000000
-  else
-         @if [ ! -d "${TARGET_DIR}" ] ; then \
-          echo "The board not mounted at ${TARGET_DIR}"; \
-          exit 1; \
-         fi
-         cp targets/mbed/build/$(YOTTA_TARGET)/source/jerry.bin \
-          "$(TARGET_DIR)/."
-  endif
-       @echo "Wait till LED flashing stops..."
-
-clean:
-       rm -rf $(COPYTARGET)
-       rm -rf $(OUTPUT)
-       rm -rf targets/mbed/build
diff --git a/deps/jerry/targets/mbed/Makefile.travis b/deps/jerry/targets/mbed/Makefile.travis
deleted file mode 100644 (file)
index 96b1d81..0000000
+++ /dev/null
@@ -1,42 +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.
-
-
-# Default target for running the build test outside the Travis CI environment.
-all:
-       $(MAKE) install
-       $(MAKE) script
-
-
-## Targets for installing build dependencies of the Mbed JerryScript target.
-
-# Install tools via apt.
-install-apt-get-deps:
-       sudo apt-get install -q -y ninja-build libffi-dev libssl-dev
-
-# Install yotta
-install-yotta:
-       pyenv global 2.7.13 # force the python version to a newer one
-       pip install --user "pyOpenSSL<17.5" # fix for failures with pyOpenSSL 17.5
-       pip install --user yotta
-
-# Perform all the necessary (JerryScript-independent) installation steps.
-install: install-apt-get-deps install-yotta
-
-
-## Targets for building Mbed with JerryScript.
-
-# Build the firmware (Mbed with JerryScript).
-script:
-       $(MAKE) -f targets/mbed/Makefile.mbed board=k64f
diff --git a/deps/jerry/targets/mbed/js/blink.js b/deps/jerry/targets/mbed/js/blink.js
deleted file mode 100644 (file)
index ad43888..0000000
+++ /dev/null
@@ -1,25 +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.
- */
-
-var check = 1;
-
-function blink ()
-{
-  var blk = (check > 8) ? 1 : 0;
-  led (0, blk);
-  check = (check >= 10) ? 1 : check + 1;
-}
-
-print ("blink js OK");
diff --git a/deps/jerry/targets/mbed/js/main.js b/deps/jerry/targets/mbed/js/main.js
deleted file mode 100644 (file)
index d5d1045..0000000
+++ /dev/null
@@ -1,21 +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.
- */
-
-function sysloop (ticknow)
-{
-  blink ();
-}
-
-print ("main js OK");
diff --git a/deps/jerry/targets/mbed/module.json b/deps/jerry/targets/mbed/module.json
deleted file mode 100644 (file)
index 5d73d51..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  "name": "jerry",
-  "version": "0.0.1",
-  "bin": "./source",
-  "private": true,
-  "description": "JerryScript in mbed",
-  "author": "",
-  "license": "Apache-2.0",
-  "dependencies": {
-    "mbed-drivers": "^1.5.0"
-  }
-}
diff --git a/deps/jerry/targets/mbed/readme.md b/deps/jerry/targets/mbed/readme.md
deleted file mode 100644 (file)
index c3167f9..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-This folder contains files to run JerryScript in mbed / for:
-
-* Freedom-K64F (k64)
-* Discovery-STM32F4 (stm32f4)
-* Discovery-STM32F429ZI (stm32f429i)
-* Nucleo-F401RE (nucleo)
-
-####Yotta
-You need to install yotta before proceeding. Please visit [Yotta docs page](http://yottadocs.mbed.com/#installing-on-linux).
-
-####Cross-compiler
-For cross-compilation the GCC 5.2.1 is suggested to be used. All the supported targets were tested with this version. If you don't have any GCC compiler installed, please visit [this](https://launchpad.net/gcc-arm-embedded/+download) page to download GCC 5.2.1.
-
-####How to build a target
-Navigate to your JerryScript root folder (after you cloned this repository into the targets folder) and use the following command:
-
-```
-make -f targets/mbed/Makefile.mbed board=$(TARGET)
-```
-Where the `$(TARGET)` is one of the following options: `k64f`, `stm32f4`, `stm32f429i` or `nucleo`.
-This command will create a new folder for your target and build the jerryscript and mbed OS into that folder.
-
-####How to build a completely new target
-If you want to build a new target (which is not available in this folder) you have to modify the makefile.
-You have to add the new board name to the `TARGET_LIST` and you have to add a new branch with the new `YOTTA_TARGET` and a new `TARGET_DIR` path (if it neccessary) to the if at the top in the Makefile (just as you see right now).
-There is a little code snippet: 
-
-```
-ifeq ($(TARGET), k64f)
-  YOTTA_TARGET  = frdm-k64f-gcc
-  TARGET_DIR   ?= /media/$(USER)/MBED
-else ifeq ($(TARGET), stm32f4)
-  YOTTA_TARGET  = 
-```
-
-Basically, you can create a new target in this way (If the mbed OS support your board).
-
-#####Let's get into the details!
-1. The next rule is the `jerry` rule. This rule builds the JerryScript and copy the output files into the target libjerry folder. Two files will be generated at `targets/mbed/libjerry`:
-  * libjerrycore.a
-  * libfdlibm.a
-
-  You can run this rule with the following command: 
-  - `make -f targets/mbed/Makefile.mbed board=$(TARGET) jerry`
-
-2. The next rule is the `js2c`. This rule calls a `js2c.py` python script from the `jerryscript/targets/tools` and creates the JavaScript builtin file into the `targets/mbed/source/` folder. This file is the `jerry-targetjs.h`. You can run this rule with the follwoing command:
-
-  - `make -f targets/mbed/Makefile.mbed board=$(TARGET) js2c`
-
-3. The last rule is the `yotta`. This rule sets the yotta target and install the mbed-drivers module, install the dependencies for the mbed OS and finaly creates the mbed binary file. The binary file will be genrated at `targets/mbed/build/$(YOTTA_TARGET)/source/jerry.bin`. You can run this rule with the following command: 
-
-  - `make -f targets/mbed/Makefile.mbed board=$(TARGET) yotta`
-
-4. Optional rule: `clean`. It removes the build folder from the mbed and jerry. You can run this rule with this command:
-
-  - `make -f targets/mbed/Makefile.mbed board=$(TARGET) clean`
-
-#####Flashing
-When the build is finished you can flash the binary into your board if you want. In case of ST boards you have to install the `st-link` software. Please visit [this page](https://github.com/texane/stlink) to install STLink-v2.
-You can flash your binary into your board with the following command:
-```
-make -f targets/mbed/Makefile.mbed board=$(TARGET) flash
-```
-The flash rule grabs the binary and copies it to the mounted board or use the STLink-v2 to flash.
-When the status LED of the board stops blinking, press RESET button on the board to execute JerryScript led flashing sample program in js folder.
-
-###Note
-If you use an STM32F4 board your build will stop with missing header errors. To fix this error please visit to [this page](http://browser.sed.hu/blog/20160407/how-run-javascripts-jerryscript-mbed) and read about the fix in the `New target for STM32F4` block.
diff --git a/deps/jerry/targets/mbed/source/jerry_extapi.cpp b/deps/jerry/targets/mbed/source/jerry_extapi.cpp
deleted file mode 100644 (file)
index 8c2c92c..0000000
+++ /dev/null
@@ -1,148 +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 <stdlib.h>
-#include <stdio.h>
-
-#include "jerry-core/include/jerryscript.h"
-#include "jerry_extapi.h"
-
-#include "native_mbed.h"
-
-#ifndef MIN
-#define MIN(A,B) ((A)<(B)?(A):(B))
-#endif
-
-//-----------------------------------------------------------------------------
-
-#define __UNSED__ __attribute__((unused))
-
-#define DECLARE_HANDLER(NAME) \
-static jerry_value_t \
-NAME ## _handler (const jerry_value_t func_value __UNSED__, \
-                  const jerry_value_t this_value __UNSED__, \
-                  const jerry_value_t args[], \
-                  const jerry_length_t args_cnt )
-
-#define REGISTER_HANDLER(NAME) \
-  register_native_function ( # NAME, NAME ## _handler)
-
-//-----------------------------------------------------------------------------
-
-DECLARE_HANDLER(assert)
-{
-  if (args_cnt == 1
-      && jerry_value_is_boolean (args[0])
-      && jerry_get_boolean_value (args[0]))
-  {
-    printf (">> Jerry assert true\r\n");
-    return jerry_create_boolean (true);
-  }
-  printf ("ERROR: Script assertion failed\n");
-  exit (JERRY_STANDALONE_EXIT_CODE_FAIL);
-  return jerry_create_boolean (false);
-}
-
-DECLARE_HANDLER(led)
-{
-  jerry_value_t ret_val;
-
-  if (args_cnt < 2)
-  {
-    ret_val = jerry_create_boolean (false);
-    printf ("Error: invalid arguments number!\r\n");
-    return ret_val;
-  }
-
-  if (!(jerry_value_is_number (args[0])
-        && jerry_value_is_number (args[1])))
-  {
-    ret_val = jerry_create_boolean (false);
-    printf ("Error: arguments must be numbers!\r\n");
-    return ret_val;
-  }
-
-  int port, value;
-  port = (int) jerry_get_number_value (args[0]);
-  value = (int) jerry_get_number_value (args[1]);
-
-  if (port >= 0 && port <= 3)
-  {
-    native_led (port, value);
-    ret_val = jerry_create_boolean (true);
-  }
-  else
-  {
-    ret_val = jerry_create_boolean (false);
-  }
-  return ret_val;
-}
-
-//-----------------------------------------------------------------------------
-
-static bool
-register_native_function (const char* name,
-                          jerry_external_handler_t handler)
-{
-  jerry_value_t global_object_val = jerry_get_global_object ();
-  jerry_value_t reg_function = jerry_create_external_function (handler);
-
-  bool is_ok = true;
-
-  if (!(jerry_value_is_function (reg_function)
-        && jerry_value_is_constructor (reg_function)))
-  {
-    is_ok = false;
-    printf ("Error: create_external_function failed !!!\r\n");
-    jerry_release_value (global_object_val);
-    jerry_release_value (reg_function);
-    return is_ok;
-  }
-
-  if (jerry_value_has_error_flag (reg_function))
-  {
-    is_ok = false;
-    printf ("Error: create_external_function has error flag! \n\r");
-    jerry_release_value (global_object_val);
-    jerry_release_value (reg_function);
-    return is_ok;
-  }
-
-  jerry_value_t jerry_name = jerry_create_string ((jerry_char_t *) name);
-
-  jerry_value_t set_result = jerry_set_property (global_object_val,
-                                                 jerry_name,
-                                                 reg_function);
-
-
-  if (jerry_value_has_error_flag (set_result))
-  {
-    is_ok = false;
-    printf ("Error: register_native_function failed: [%s]\r\n", name);
-  }
-
-  jerry_release_value (jerry_name);
-  jerry_release_value (global_object_val);
-  jerry_release_value (reg_function);
-  jerry_release_value (set_result);
-
-  return is_ok;
-}
-
-void js_register_functions (void)
-{
-  REGISTER_HANDLER (assert);
-  REGISTER_HANDLER (led);
-}
diff --git a/deps/jerry/targets/mbed/source/jerry_extapi.h b/deps/jerry/targets/mbed/source/jerry_extapi.h
deleted file mode 100644 (file)
index 8c365b1..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Copyright JS Foundation and other contributors, http://js.foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __JERRY_EXTAPI_H__
-#define __JERRY_EXTAPI_H__
-
-#define JERRY_STANDALONE_EXIT_CODE_OK   (0)
-#define JERRY_STANDALONE_EXIT_CODE_FAIL (1)
-
-void js_register_functions (void);
-
-#endif
diff --git a/deps/jerry/targets/mbed/source/jerry_run.cpp b/deps/jerry/targets/mbed/source/jerry_run.cpp
deleted file mode 100644 (file)
index 2e6f3b8..0000000
+++ /dev/null
@@ -1,127 +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 <stdlib.h>
-#include <stdio.h>
-
-#include "jerry-core/include/jerryscript.h"
-#include "jerry_extapi.h"
-#include "jerry_run.h"
-
-static const char* fn_sys_loop_name = "sysloop";
-
-int js_entry (const char *source_p, const size_t source_size)
-{
-  const jerry_char_t *jerry_src = (const jerry_char_t *) source_p;
-  jerry_init (JERRY_INIT_EMPTY);
-  uint8_t ret_code = 0;
-
-  js_register_functions ();
-
-  jerry_value_t parsed_code = jerry_parse (NULL, 0, jerry_src, source_size, JERRY_PARSE_NO_OPTS);
-
-  if (!jerry_value_has_error_flag (parsed_code))
-  {
-    jerry_value_t ret_value = jerry_run (parsed_code);
-
-    if (jerry_value_has_error_flag (ret_value))
-      {
-      printf ("Error: ret_value has an error flag!\r\n");
-      return ret_code = -1;
-      }
-
-    jerry_release_value (ret_value);
-  }
-  else
-  {
-    printf ("Error: jerry_parse failed!\r\n");
-    ret_code = -1;
-  }
-
-  jerry_release_value (parsed_code);
-
-  return ret_code;
-}
-
-int js_eval (const char *source_p, const size_t source_size)
-{
-  int status = 0;
-
-  jerry_value_t ret_val = jerry_eval ((jerry_char_t *) source_p,
-                                      source_size,
-                                      false);
-
-  if (jerry_value_has_error_flag (ret_val))
-  {
-    printf ("Error: jerry_eval failed!\r\n");
-    status = -1;
-  }
-
-  jerry_release_value (ret_val);
-
-  return status;
-}
-
-int js_loop (uint32_t ticknow)
-{
-  int status = 0;
-  jerry_value_t global_obj = jerry_get_global_object ();
-  jerry_value_t sys_name = jerry_create_string ((const jerry_char_t *) fn_sys_loop_name);
-  jerry_value_t sysloop_func = jerry_get_property (global_obj, sys_name);
-
-  jerry_release_value (sys_name);
-
-  if (jerry_value_has_error_flag (sysloop_func))
-  {
-    printf ("Error: '%s' not defined!!!\r\n", fn_sys_loop_name);
-    jerry_release_value (global_obj);
-    jerry_release_value (sysloop_func);
-    return -1;
-  }
-
-  if (!jerry_value_is_function (sysloop_func))
-  {
-    printf ("Error: '%s' is not a function!!!\r\n", fn_sys_loop_name);
-    jerry_release_value (global_obj);
-    jerry_release_value (sysloop_func);
-    return -2;
-  }
-
-  jerry_value_t val_args[1];
-  uint16_t val_argv = 1;
-
-  val_args[0] = jerry_create_number (ticknow);
-
-  jerry_value_t ret_val_sysloop = jerry_call_function (sysloop_func,
-                                                       global_obj,
-                                                       val_args,
-                                                       val_argv);
-  if (jerry_value_has_error_flag (ret_val_sysloop))
-  {
-    status = -3;
-  }
-
-  jerry_release_value (global_obj);
-  jerry_release_value (ret_val_sysloop);
-  jerry_release_value (sysloop_func);
-  jerry_release_value (val_args[0]);
-
-  return status;
-}
-
-void js_exit (void)
-{
-  jerry_cleanup ();
-}
diff --git a/deps/jerry/targets/mbed/source/jerry_run.h b/deps/jerry/targets/mbed/source/jerry_run.h
deleted file mode 100644 (file)
index 669beff..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Copyright JS Foundation and other contributors, http://js.foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __JERRY_RUN_H__
-#define __JERRY_RUN_H__
-
-int js_entry (const char *source_p, const size_t source_size);
-int js_eval (const char *source_p, const size_t source_size);
-int js_loop (uint32_t ticknow);
-void js_exit (void);
-
-#endif
diff --git a/deps/jerry/targets/mbed/source/main.cpp b/deps/jerry/targets/mbed/source/main.cpp
deleted file mode 100644 (file)
index a3940f2..0000000
+++ /dev/null
@@ -1,74 +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 "mbed-drivers/mbed.h"
-
-#include "jerry-core/include/jerryscript.h"
-#include "jerry-core/include/jerryscript-port.h"
-#include "jerry_run.h"
-
-#include "jerry-targetjs.h"
-
-static Serial pc (USBTX, USBRX); //tx, rx
-
-static int jerry_task_init (void)
-{
-  srand ((unsigned) jerry_port_get_current_time ());
-  int retcode;
-
-  DECLARE_JS_CODES;
-
-  /* run main.js */
-  retcode = js_entry (js_codes[0].source, js_codes[0].length);
-  if (retcode != 0)
-  {
-    printf ("js_entry failed code(%d) [%s]\r\n", retcode, js_codes[0].name);
-    js_exit ();
-    return -1;
-  }
-  /* run rest of the js files */
-  for (int src = 1; js_codes[src].source; src++)
-  {
-    retcode = js_eval (js_codes[src].source, js_codes[src].length);
-    if (retcode != 0)
-    {
-      printf ("js_eval failed code(%d) [%s]\r\n", retcode, js_codes[src].name);
-      js_exit ();
-      return -2;
-    }
-  }
-  return 0;
-}
-
-static void jerry_loop (void)
-{
-  static uint32_t _jcount = 0;
-
-  js_loop (_jcount++);
-}
-
-void app_start (int, char**)
-{
-  /* set 9600 baud rate for stdout */
-  pc.baud (9600);
-
-  printf ("\r\nJerryScript in mbed\r\n");
-  printf ("Version: \t%d.%d\n\n", JERRY_API_MAJOR_VERSION, JERRY_API_MINOR_VERSION);
-
-  if (jerry_task_init () == 0)
-  {
-    minar::Scheduler::postCallback(jerry_loop).period(minar::milliseconds(100));
-  }
-}
diff --git a/deps/jerry/targets/mbed/source/makejerry.cmake b/deps/jerry/targets/mbed/source/makejerry.cmake
deleted file mode 100644 (file)
index 36abec8..0000000
+++ /dev/null
@@ -1,30 +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.
-
-# application name
-set(MBEDMODULE "jerry")
-
-# add include jerry-core
-set(LJCORE ${CMAKE_CURRENT_LIST_DIR}/../../../)
-include_directories(${LJCORE})
-
-# compile flags
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlittle-endian -mthumb -mcpu=cortex-m4" )
-
-# link jerryscript
-set(LJPATH ${CMAKE_CURRENT_LIST_DIR}/../libjerry)
-set(LJFILES "")
-set(LJFILES ${LJFILES} ${LJPATH}/libjerrylibm.a)
-set(LJFILES ${LJFILES} ${LJPATH}/libjerrycore.a)
-target_link_libraries(${MBEDMODULE} ${LJFILES})
diff --git a/deps/jerry/targets/mbed/source/native_mbed.cpp b/deps/jerry/targets/mbed/source/native_mbed.cpp
deleted file mode 100644 (file)
index cc81e0e..0000000
+++ /dev/null
@@ -1,25 +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 "mbed-drivers/mbed.h"
-
-#include "native_mbed.h"
-
-void native_led (int port, int val)
-{
-  static const PinName portmap[] = { LED1, LED2, LED3, LED4 };
-  static DigitalOut led (portmap[port]);
-  led = val;
-}
diff --git a/deps/jerry/targets/mbed/source/native_mbed.h b/deps/jerry/targets/mbed/source/native_mbed.h
deleted file mode 100644 (file)
index 9f44010..0000000
+++ /dev/null
@@ -1,21 +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 __NATIVE_MBED_H__
-#define __NATIVE_MBED_H__
-
-void native_led (int port, int val);
-
-#endif /* !__NATIVE_MBED_H__ */
diff --git a/deps/jerry/targets/mbed/source/port/jerry_port.c b/deps/jerry/targets/mbed/source/port/jerry_port.c
deleted file mode 100644 (file)
index 496ee86..0000000
+++ /dev/null
@@ -1,74 +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.
- */
-
-#define _BSD_SOURCE
-#include <stdarg.h>
-#include <stdlib.h>
-#include <sys/time.h>
-
-#include "jerry-core/include/jerryscript-port.h"
-
-#include "mbed-hal/us_ticker_api.h"
-
-/**
- * Provide log message implementation for the engine.
- */
-void
-jerry_port_log (jerry_log_level_t level, /**< log level */
-                const char *format, /**< format string */
-                ...)  /**< parameters */
-{
-  (void) level; /* ignore log level */
-
-  va_list args;
-  va_start (args, format);
-  vfprintf (stderr, format, args);
-  va_end (args);
-} /* jerry_port_log */
-
-/**
- * Implementation of jerry_port_fatal.
- */
-void
-jerry_port_fatal (jerry_fatal_code_t code) /**< fatal code enum item */
-{
-  exit (code);
-} /* jerry_port_fatal */
-
-/**
- * Implementation of jerry_port_get_time_zone.
- *
- * @return true - if success
- */
-bool
-jerry_port_get_time_zone (jerry_time_zone_t *tz_p) /**< timezone pointer */
-{
-  tz_p->offset = 0;
-  tz_p->daylight_saving_time = 0;
-  return true;
-} /* jerry_port_get_time_zone */
-
-/**
- * Implementation of jerry_port_get_current_time.
- *
- * @return current timer's counter value in milliseconds
- */
-double
-jerry_port_get_current_time (void)
-{
-  /* Note: if the target has its own RTC, this value should be extended by the
-   * RTC's one. */
-  return (double) us_ticker_read () / 1000;
-} /* jerry_port_get_current_time */
index a0ef7d28cdece1e4e8247957fc57c5b4bb0fd6c0..ed77d265884fa78ad87a680c91dee50e995b1714 100644 (file)
@@ -25,6 +25,7 @@ all:
 install:
        pip install --user mbed-cli
        cd targets/mbedos5 && mbed deploy
+       pip install --user mbed-host-tests==1.4.2 # FIXME: mbed-host-tests 1.4.4 requires pyocd>=0.14.0, which cannot be satisfied for whatever reason
        pip install --user -r targets/mbedos5/mbed-os/requirements.txt
 
 
index 395dcfa8894195805612ac6e373a5dc0d0ef6914..33ae1ee9c5b2e0e6980e7ad3a18c0c135e36af06 100644 (file)
@@ -34,7 +34,7 @@ DECLARE_GLOBAL_FUNCTION(setInterval) {
 
     jerry_value_t result = jerry_set_property_by_index(function_obj_p, id, args[0]);
 
-    if (jerry_value_has_error_flag(result)) {
+    if (jerry_value_is_error(result)) {
         jerry_release_value(result);
         mbed::js::EventLoop::getInstance().getQueue().cancel(id);
 
index edccc536c0c4dcab5fd3f441c63222fa98c8eebd..adbaca3f394827e8c776051c0b862c74a7737c5f 100644 (file)
@@ -34,7 +34,7 @@ DECLARE_GLOBAL_FUNCTION(setTimeout) {
 
     jerry_value_t result = jerry_set_property_by_index(function_obj_p, id, args[0]);
 
-    if (jerry_value_has_error_flag(result)) {
+    if (jerry_value_is_error(result)) {
         jerry_release_value(result);
         mbed::js::EventLoop::getInstance().getQueue().cancel(id);
 
index c51143b7c9e42aff68c68c1f2519a5deae3c9198..1acf2f169967d67969777d600ffab16478e63bd5 100644 (file)
@@ -44,7 +44,7 @@ static int load_javascript() {
 
         jerry_value_t parsed_code = jerry_parse(NULL, 0, code, length, JERRY_PARSE_NO_OPTS);
 
-        if (jerry_value_has_error_flag(parsed_code)) {
+        if (jerry_value_is_error(parsed_code)) {
             LOG_PRINT_ALWAYS("jerry_parse failed [%s]\r\n", js_codes[src].name);
             jerry_release_value(parsed_code);
             jsmbed_js_exit();
@@ -54,7 +54,7 @@ static int load_javascript() {
         jerry_value_t returned_value = jerry_run(parsed_code);
         jerry_release_value(parsed_code);
 
-        if (jerry_value_has_error_flag(returned_value)) {
+        if (jerry_value_is_error(returned_value)) {
             LOG_PRINT_ALWAYS("jerry_run failed [%s]\r\n", js_codes[src].name);
             jerry_release_value(returned_value);
             jsmbed_js_exit();
index 376e0864185a933849e7b1b562b77af8a82f0e42..6aa282efd8f269fda3ac00e4b588c11fd3b94d83 100644 (file)
@@ -21,7 +21,7 @@
 extern uint32_t jsmbed_js_magic_string_count;
 extern uint32_t jsmbed_js_magic_string_values[];
 
-extern const jerry_char_ptr_t jsmbed_js_magic_strings[];
+extern const jerry_char_t *jsmbed_js_magic_strings[];
 extern const jerry_length_t jsmbed_js_magic_string_lengths[];
 
 void jsmbed_js_load_magic_strings() {
index bb600a75bed885a9dcc74dbab8773c99bd010769..1fe7ab279bdca0e5f71cad591e867ebccb1183cc 100644 (file)
@@ -32,7 +32,7 @@ bool jsmbed_wrap_register_global_function(const char* name, jerry_external_handl
         return is_ok;
     }
 
-    if (jerry_value_has_error_flag(reg_function)) {
+    if (jerry_value_is_error(reg_function)) {
         is_ok = false;
         LOG_PRINT_ALWAYS("Error: jerry_create_external_function has error flag! \r\n");
         jerry_release_value(global_object_val);
@@ -45,7 +45,7 @@ bool jsmbed_wrap_register_global_function(const char* name, jerry_external_handl
     jerry_value_t set_result = jerry_set_property(global_object_val, jerry_name, reg_function);
 
 
-    if (jerry_value_has_error_flag(set_result)) {
+    if (jerry_value_is_error(set_result)) {
         is_ok = false;
         LOG_PRINT_ALWAYS("Error: jerry_create_external_function failed: [%s]\r\n", name);
     }
index 3e225b01369c6ba8f161e53af7f56066e6b2743a..357264715758a6b180a244aaaac7b9c3e2e543a6 100644 (file)
@@ -46,17 +46,15 @@ jerry_port_log (jerry_log_level_t level, /**< log level */
 #endif /* JSMBED_OVERRIDE_JERRY_PORT_LOG */
 
 /**
- * Implementation of jerry_port_get_time_zone.
+ * Implementation of jerry_port_get_local_time_zone_adjustment.
  *
- * @return true - if success
+ * @return 0, as we live in UTC.
  */
-bool
-jerry_port_get_time_zone (jerry_time_zone_t *tz_p) /**< timezone pointer */
+double
+jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc)
 {
-  tz_p->offset = 0;
-  tz_p->daylight_saving_time = 0;
-  return true;
-} /* jerry_port_get_time_zone */
+  return 0;
+} /* jerry_port_get_local_time_zone_adjustment */
 
 /**
  * Implementation of jerry_port_get_current_time.
index 6b979c98f49cb71b77bdd876f55884179440112a..f6c45e65f9aa6f445bbc95158e4359d883ac3bf7 100644 (file)
@@ -1,6 +1,5 @@
 cmake/*
 docs/*
-jerry-libc/*
 jerry-libm/*
 jerry-main/*
 jerry-port/default/default-date.c
index ccba0624c6cb61ab9d0f438cb8c22a0e87826b0d..10a6889351e026b56586c8791717356bcc2758f1 100644 (file)
@@ -14,7 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 """
-Generate pins.js for a specified target, using target definitions from the
+Generate pins.cpp for a specified target, using target definitions from the
 mbed OS source tree.
 
 It's expecting to be run from the targets/mbedos5 directory.
@@ -28,9 +28,8 @@ import ast
 import sys
 import os
 
-from simpleeval import SimpleEval, DEFAULT_OPERATORS
 from pycparserext.ext_c_parser import GnuCParser
-from pycparser import parse_file, c_ast, c_generator
+from pycparser import parse_file, c_ast
 
 # import mbed tools
 sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'mbed-os'))
@@ -113,27 +112,7 @@ class TypeDeclVisitor(c_ast.NodeVisitor):
         Visit a node.
         """
         if node.declname in self.names:
-            c_gen = c_generator.CGenerator()
-            pins = {}
-
-            operators = DEFAULT_OPERATORS
-            operators[ast.BitOr] = lambda a, b: a | b
-            operators[ast.LShift] = lambda a, b: a << b
-            operators[ast.RShift] = lambda a, b: a << b
-            evaluator = SimpleEval(DEFAULT_OPERATORS)
-
-            for pin in node.type.values.enumerators:
-                expr = c_gen.visit(pin.value)
-
-                if "(int)" in expr:
-                    expr = expr.replace('(int)', '')
-
-                if expr in pins:
-                    pins[pin.name] = pins[expr]
-                else:
-                    pins[pin.name] = evaluator.eval(expr.strip())
-
-            return pins
+            return [pin.name for pin in node.type.values.enumerators]
 
 
 def enumerate_pins(c_source_file, include_dirs, definitions):
@@ -158,39 +137,39 @@ def enumerate_pins(c_source_file, include_dirs, definitions):
     return visitor.visit(parsed_ast)
 
 
-def write_pins_to_files(pins, out_js_file, out_cpp_file):
+def write_pins_to_file(pins, pins_file, out_cpp_file):
     """
-    Write the generated pins for a specified mbed board into the output JS and C++ files.
+    Write the generated pins for a specified mbed board into the output C++ file.
     """
-    out_js = '\r\n'.join(['var %s = %s;' % pin for pin in pins])
-    out_js_file.write(out_js)
+
+    include = '\n#include "../{}"'.format(pins_file)
 
     count = '''
 unsigned int jsmbed_js_magic_string_count = {};
     '''.format(len(pins))
 
-    lengths = ',\n    '.join(str(len(pin[0])) for pin in pins)
+    lengths = ',\n    '.join(str(len(pin)) for pin in pins)
     lenghts_source = '''
 unsigned int jsmbed_js_magic_string_lengths[] = {
     %s
 };
     ''' % lengths
 
-    magic_values = ',\n    '.join(str(pin[1]) for pin in pins)
+    magic_values = ',\n    '.join(pins)
     magic_source = '''
 unsigned int jsmbed_js_magic_string_values[] = {
     %s
 };
     ''' % magic_values
 
-    magic_strings = ',\n    '.join('"' + pin[0] + '"' for pin in pins)
+    magic_strings = ',\n    '.join('"' + pin + '"' for pin in pins)
     magic_string_source = '''
 const char * jsmbed_js_magic_strings[] = {
     %s
 };
     ''' % magic_strings
 
-    out_cpp_file.write(LICENSE + count + lenghts_source + magic_source + magic_string_source)
+    out_cpp_file.write(LICENSE + include + count + lenghts_source + magic_source + magic_string_source)
 
 
 def main():
@@ -203,17 +182,13 @@ def main():
         sys.exit(1)
 
     description = """
-    Generate pins.js for a specified mbed board, using target definitions from the
+    Generate pins.cpp for a specified mbed board, using target definitions from the
     mbed OS source tree.
     """
 
     parser = argparse.ArgumentParser(description=description)
 
     parser.add_argument('board', help='mbed board name')
-    parser.add_argument('-o',
-                        help='Output JavaScript file (default: %(default)s)',
-                        default='js/pins.js',
-                        type=argparse.FileType('w'))
     parser.add_argument('-c',
                         help='Output C++ file (default: %(default)s)',
                         default='source/pins.cpp',
@@ -237,10 +212,9 @@ def main():
     pins = enumerate_pins(pins_file, ['./tools'] + list(includes), defines)
 
     # first sort alphabetically, then by length.
-    pins = [(x, pins[x]) for x in pins]  # turn dict into tuples, which can be sorted
-    pins = sorted(pins, key=lambda x: (len(x[0]), x[0].lower()))
+    pins = sorted(pins, key=lambda x: (len(x), x.lower()))
 
-    write_pins_to_files(pins, args.o, args.c)
+    write_pins_to_file(pins, pins_file, args.c)
 
 
 if __name__ == "__main__":
index 81b6a8f9a7568b14e2496dd406e23766766a323b..c6aa8813c6d5c52ca1154d49a6689af605b5e659 100644 (file)
@@ -43,14 +43,15 @@ install-clone-nuttx:
        git clone https://bitbucket.org/nuttx/nuttx.git ../nuttx -b nuttx-7.22
 
 # Perform all the necessary (JerryScript-independent) installation steps.
-install: install-apt-get-deps install-kconfig install-clone-nuttx
+install-noapt: install-kconfig install-clone-nuttx
+install: install-apt-get-deps install-noapt
 
 
 ## Targets for building NuttX with JerryScript.
 
 # Build JerryScript.
 script-build-jerryscript:
-       tools/build.py --clean --toolchain cmake/toolchain_mcu_stm32f4.cmake --profile=es2015-subset --jerry-cmdline OFF --jerry-libc OFF --lto OFF --jerry-libm ON --all-in-one ON --mem-heap 70 --compile-flag='--sysroot=../nuttx'
+       tools/build.py --clean --toolchain cmake/toolchain_mcu_stm32f4.cmake --profile=es2015-subset --jerry-cmdline OFF --lto OFF --jerry-libm ON --all-in-one ON --mem-heap 70 --compile-flag='--sysroot=../nuttx'
 
 # Link in the NuttX JerryScript target directory under the NuttX apps tree.
 script-add-jerryscript-app:
index 84dfd8454763708acc2ea7b9081fb863d4440ba6..879845c338a219908c9445a53c8d71afefe0ed70 100644 (file)
@@ -41,7 +41,6 @@ jerryscript/tools/build.py \
     --clean \
     --lto=OFF \
     --jerry-cmdline=OFF \
-    --jerry-libc=OFF \
     --jerry-libm=ON \
     --all-in-one=ON \
     --mem-heap=70 \
index 1775e3264b9933fdf4fc728445977be119864338..61419b99b9a6b35bb652c188820a57ae72593fcc 100644 (file)
@@ -18,6 +18,7 @@
 #include <stdlib.h>
 
 #include "jerryscript.h"
+#include "jerryscript-ext/debugger.h"
 #include "jerryscript-ext/handler.h"
 #include "jerryscript-port.h"
 #include "setjmp.h"
@@ -150,9 +151,9 @@ static void
 print_unhandled_exception (jerry_value_t error_value, /**< error value */
                            const jerry_char_t *source_p) /**< source_p */
 {
-  assert (jerry_value_has_error_flag (error_value));
+  assert (jerry_value_is_error (error_value));
 
-  error_value = jerry_get_value_without_error_flag (error_value);
+  error_value = jerry_get_value_from_error (error_value, false);
   jerry_value_t err_str_val = jerry_value_to_string (error_value);
   jerry_size_t err_str_size = jerry_get_string_size (err_str_val);
   jerry_char_t err_str_buf[256];
@@ -279,7 +280,7 @@ register_js_function (const char *name_p, /**< name of the function */
 {
   jerry_value_t result_val = jerryx_handler_register_global ((const jerry_char_t *) name_p, handler_p);
 
-  if (jerry_value_has_error_flag (result_val))
+  if (jerry_value_is_error (result_val))
   {
     jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Warning: failed to register '%s' method.", name_p);
   }
@@ -380,7 +381,8 @@ int jerry_main (int argc, char *argv[])
 
   if (start_debug_server)
   {
-    jerry_debugger_init (debug_port);
+    jerryx_debugger_after_connect (jerryx_debugger_tcp_create (debug_port)
+                                   && jerryx_debugger_ws_create ());
   }
 
   register_js_function ("assert", jerryx_handler_assert);
@@ -393,11 +395,10 @@ int jerry_main (int argc, char *argv[])
   {
     printf ("No input files, running a hello world demo:\n");
     const jerry_char_t script[] = "var str = 'Hello World'; print(str + ' from JerryScript')";
-    size_t script_size = strlen ((const char *) script);
 
-    ret_value = jerry_parse (NULL, 0, script, script_size, JERRY_PARSE_NO_OPTS);
+    ret_value = jerry_parse (NULL, 0, script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
 
-    if (!jerry_value_has_error_flag (ret_value))
+    if (!jerry_value_is_error (ret_value))
     {
       ret_value = jerry_run (ret_value);
     }
@@ -421,14 +422,14 @@ int jerry_main (int argc, char *argv[])
                                source_size,
                                JERRY_PARSE_NO_OPTS);
 
-      if (!jerry_value_has_error_flag (ret_value))
+      if (!jerry_value_is_error (ret_value))
       {
         jerry_value_t func_val = ret_value;
         ret_value = jerry_run (func_val);
         jerry_release_value (func_val);
       }
 
-      if (jerry_value_has_error_flag (ret_value))
+      if (jerry_value_is_error (ret_value))
       {
         print_unhandled_exception (ret_value, source_p);
         free ((void*) source_p);
@@ -445,7 +446,7 @@ int jerry_main (int argc, char *argv[])
 
   int ret_code = JERRY_STANDALONE_EXIT_CODE_OK;
 
-  if (jerry_value_has_error_flag (ret_value))
+  if (jerry_value_is_error (ret_value))
   {
     ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL;
   }
@@ -454,7 +455,7 @@ int jerry_main (int argc, char *argv[])
 
   ret_value = jerry_run_all_enqueued_jobs ();
 
-  if (jerry_value_has_error_flag (ret_value))
+  if (jerry_value_is_error (ret_value))
   {
     ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL;
   }
@@ -491,19 +492,16 @@ jerry_port_log (jerry_log_level_t level, /**< log level */
 } /* jerry_port_log */
 
 /**
- * Dummy function to get the time zone.
+ * Dummy function to get the time zone adjustment.
  *
- * @return true
+ * @return 0
  */
-bool
-jerry_port_get_time_zone (jerry_time_zone_t *tz_p)
+double
+jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc)
 {
   /* We live in UTC. */
-  tz_p->offset = 0;
-  tz_p->daylight_saving_time = 0;
-
-  return true;
-} /* jerry_port_get_time_zone */
+  return 0;
+} /* jerry_port_get_local_time_zone_adjustment */
 
 /**
  * Dummy function to get the current time.
index 28fb08cb3d2c92ad2e89cee2d0057761e8378acd..f51bbc080693868c239c544a64a5bd53c63dbdb1 100644 (file)
@@ -87,13 +87,9 @@ Please check if the `STAGING_DIR` is configured correctly and that the toolchain
 
 ```
 $ ./tools/build.py --toolchain cmake/toolchain_openwrt_mips.cmake \
-                   --jerry-libc OFF \
                    --lto OFF
 ```
 
-Currenlty the JerryScript libc does not supports the mips platform, that's why the `--jerry-libc OFF` argument
-is passed during build.
-
 ### 2. Copy the binary
 
 After a successful build the `build/bin/jerry` binary file can be copied to the target device.
index 7c5cea8eebe4bdd0ad41b0a291dfc245ff5fd692..30b1a8e8adc01e810c02c359b8e469e1d90432c5 100644 (file)
@@ -45,7 +45,6 @@ jerrycore:
         -DCMAKE_C_COMPILER_WORKS=TRUE \
         -DENABLE_LTO=ON \
         -DENABLE_ALL_IN_ONE=OFF \
-        -DJERRY_LIBC=OFF \
         -DJERRY_LIBM=OFF \
         -DJERRY_CMDLINE=OFF \
         -DFEATURE_PROFILE=minimal \
index f8463c01e117394d4b85b7a94a667de0bd9d972d..0c5e799e686ee0dff37136b831582e2f7d3a2b94 100644 (file)
@@ -114,9 +114,7 @@ test_jerry ()
     test.delay(250); \
   ";
 
-  size_t script_size = strlen ((const char *) script);
-
-  jerry_value_t eval_ret = jerry_eval (script, script_size, false);
+  jerry_value_t eval_ret = jerry_eval (script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
 
   /* Free JavaScript value, returned by eval */
   jerry_release_value (eval_ret);
index a1ce8083f79f7111c651340cf91b022af3875d28..2cd9631ec6eb5dc5d0ad3fb22d435ab62201b7fa 100644 (file)
@@ -18,6 +18,9 @@ APPLICATION = riot_jerry
 # default BOARD enviroment
 BOARD ?= stm32f4discovery
 
+# LLVM/Clang-based toolchain
+TOOLCHAIN ?= llvm
+
 # path to the RIOT base directory
 RIOTBASE ?= $(CURDIR)/../RIOT
 # path to the JERRYSCRIPT directory
@@ -29,11 +32,6 @@ APPDIR ?= $(JERRYDIR)/targets/riot-stm32f4/source
 # path to the binary directory
 BINDIR ?= $(JERRYDIR)/targets/riot-stm32f4/bin/
 
-# Comment this out to disable code in RIOT that does safety checking
-# which is not needed in a production environment but helps in the
-# development process:
-CFLAGS += -DDEVELHELP
-
 # Change this to 0 show compiler invocation lines by default:
 QUIET ?= 1
 
@@ -44,7 +42,7 @@ USEMODULE += shell
 USEMODULE += shell_commands
 
 # Add the jerry libs
-USEMODULE += libjerrycore libjerryport-minimal libjerryext
+USEMODULE += libjerry-core libjerry-port-default-minimal libjerry-ext
 
 
 include $(RIOTBASE)/Makefile.include
index 81d9392a0a8d30e83b7f19c251d46347333ba009..d9cb5cca3df2fb70aab40e84ca508ec7c021507b 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+# Build and output directories
 BUILD_DIR  ?= build/riotstm32f4
 COPYTARGET ?= targets/riot-stm32f4/bin
 
+# JerryScript configuration
 JERRYHEAP  ?= 16
 
-EXT_CFLAGS := -D__TARGET_RIOT_STM32F4
+# To be defined on the command line of make if Clang is available via a
+# different name (e.g., clang-N.M)
+CC ?= clang
+
+# Cross-compilation settings for Clang
+EXT_CFLAGS := -target arm-none-eabi
 EXT_CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m4
-EXT_CFLAGS += -Wno-error=format=
+EXT_CFLAGS += -isystem /usr/arm-none-eabi/include
+EXT_CFLAGS += $(addprefix -isystem $(lastword $(sort $(wildcard /usr/lib/gcc/arm-none-eabi/*/))), include include-fixed)
+EXT_CFLAGS += -nostdinc
+
+# For ABI compatibility with RIOT-OS
+EXT_CFLAGS += -fshort-enums
+
 
 .PHONY: libjerry riot-jerry flash clean
 
@@ -27,25 +40,23 @@ all: libjerry riot-jerry
 
 libjerry:
        mkdir -p $(BUILD_DIR)
-       mkdir -p $(COPYTARGET)
        cmake -B$(BUILD_DIR) -H./ \
         -DCMAKE_SYSTEM_NAME=RIOT \
         -DCMAKE_SYSTEM_PROCESSOR=armv7l \
-        -DCMAKE_C_COMPILER=arm-none-eabi-gcc \
+        -DCMAKE_C_COMPILER=$(CC) \
         -DCMAKE_C_COMPILER_WORKS=TRUE \
         -DENABLE_LTO=OFF \
         -DENABLE_ALL_IN_ONE=OFF \
-        -DJERRY_LIBC=OFF \
         -DJERRY_LIBM=OFF \
         -DJERRY_CMDLINE=OFF \
         -DEXTERNAL_COMPILE_FLAGS="$(EXT_CFLAGS)" \
         -DMEM_HEAP_SIZE_KB=$(JERRYHEAP)
-
        make -C$(BUILD_DIR) jerry-core jerry-port-default-minimal jerry-ext
-       cp $(BUILD_DIR)/lib/libjerry-core.a $(COPYTARGET)/libjerrycore.a
-       cp $(BUILD_DIR)/lib/libjerry-port-default-minimal.a $(COPYTARGET)/libjerryport-minimal.a
-       cp $(BUILD_DIR)/lib/libjerry-ext.a $(COPYTARGET)/libjerryext.a
 
+       mkdir -p $(COPYTARGET)
+       cp $(BUILD_DIR)/lib/libjerry-core.a $(COPYTARGET)
+       cp $(BUILD_DIR)/lib/libjerry-port-default-minimal.a $(COPYTARGET)
+       cp $(BUILD_DIR)/lib/libjerry-ext.a $(COPYTARGET)
 
 riot-jerry: libjerry
        make -f ./targets/riot-stm32f4/Makefile
index 5a7204833be44c13439ae38846e5cf391571597e..ca3f80a438b2c0d3dcb84ba88dfb0df93038e5a3 100644 (file)
@@ -23,14 +23,15 @@ all:
 
 # Install cross-compiler via apt.
 install-apt-get-deps:
-       sudo apt-get install -q -y gcc-arm-none-eabi
+       sudo apt-get install -q -y clang-3.9 gcc-arm-embedded gcc-multilib
 
 # Fetch RIOT OS repository.
 install-clone-riot:
-       git clone git://github.com/RIOT-OS/RIOT.git ../RIOT -b 2017.10
+       git clone git://github.com/RIOT-OS/RIOT.git ../RIOT -b 2018.07
 
 # Perform all the necessary (JerryScript-independent) installation steps.
-install: install-apt-get-deps install-clone-riot
+install-noapt: install-clone-riot
+install: install-apt-get-deps install-noapt
 
 
 ## Targets for building RIOT with JerryScript.
index ab419e7cca076f8a0180edd741da958f8e49f374..d77aa274b00c91f6ca89b1706389ed22e8159704 100644 (file)
@@ -36,7 +36,7 @@ register_js_function (const char *name_p, /**< name of the function */
 {
   jerry_value_t result_val = jerryx_handler_register_global ((const jerry_char_t *) name_p, handler_p);
 
-  if (jerry_value_has_error_flag (result_val))
+  if (jerry_value_is_error (result_val))
   {
     printf ("Warning: failed to register '%s' method.", name_p);
   }
@@ -56,7 +56,6 @@ int test_jerry (int argc, char **argv)
   jerry_value_t ret_value = jerry_create_undefined ();
 
   const jerry_char_t script[] = "print ('Hello, World!');";
-  size_t script_size = strlen ((const char *) script);
   printf ("This test run the following script code: [%s]\n\n", script);
 
   /* Initialize engine */
@@ -66,9 +65,9 @@ int test_jerry (int argc, char **argv)
   register_js_function ("print", jerryx_handler_print);
 
   /* Setup Global scope code */
-  ret_value = jerry_parse (NULL, 0, script, script_size, JERRY_PARSE_NO_OPTS);
+  ret_value = jerry_parse (NULL, 0, script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
 
-  if (!jerry_value_has_error_flag (ret_value))
+  if (!jerry_value_is_error (ret_value))
   {
     /* Execute the parsed source code in the Global scope */
     ret_value = jerry_run (ret_value);
@@ -76,7 +75,7 @@ int test_jerry (int argc, char **argv)
 
   int ret_code = JERRY_STANDALONE_EXIT_CODE_OK;
 
-  if (jerry_value_has_error_flag (ret_value))
+  if (jerry_value_is_error (ret_value))
   {
     printf ("Script Error!");
 
index a1a1f923797bf802bdf1ac38f06aea9b663892d2..eaa3406ee7c7beef02ff0fc16164781ae3c71e4a 100644 (file)
@@ -25,7 +25,6 @@ libjerry:
        cmake -B$(BUILD_DIR) -H./ \
         -DENABLE_LTO=OFF \
         -DENABLE_ALL_IN_ONE=OFF \
-        -DJERRY_LIBC=OFF \
         -DJERRY_CMDLINE=OFF \
         -DEXTERNAL_COMPILE_FLAGS="$(EXT_CFLAGS)" \
         -DMEM_HEAP_SIZE_KB=$(JERRYHEAP) \
index 32e5dd1b53c5e7fe3dca058d327fcf74635847de..ab9107cf8b92a41e078d171eb16be90480cfb40e 100644 (file)
@@ -10,7 +10,7 @@ If you are in a hurry, run following commands:
 
 ```
 $ sudo apt-add-repository -y "ppa:team-gcc-arm-embedded/ppa"
-$ sudo apt-get update 
+$ sudo apt-get update
 $ sudo apt-get install gcc-arm-embedded
 $ git clone https://github.com/jerryscript-project/jerryscript.git jerryscript
 $ cd jerryscript
@@ -87,7 +87,6 @@ jerryscript/tools/build.py \
     --clean \
     --lto=OFF \
     --jerry-cmdline=OFF \
-    --jerry-libc=OFF \
     --all-in-one=OFF \
     --mem-heap=70 \
     --profile=es2015-subset \
@@ -151,4 +150,4 @@ Without argument it prints:
 TASH>>jerry                                                                        
 No input files, running a hello world demo:                                        
 Hello World from JerryScript
-```
\ No newline at end of file
+```
index 592ea132b89c20197bfb2afcfed8cf98be24b4b2..fcf0787f44d0d6afd2c8f1318d2b42367fc90773 100644 (file)
@@ -103,12 +103,12 @@ ifneq ($(CONFIG_BUILD_KERNEL),y)
 endif
 
 ifeq ($(CONFIG_WINDOWS_NATIVE),y)
-  BIN = ..\..\libapps$(LIBEXT)
+  BIN = $(APPDIR)\libapps$(LIBEXT)
 else
 ifeq ($(WINTOOL),y)
-  BIN = ..\\..\\libapps$(LIBEXT)
+  BIN = $(APPDIR)\\libapps$(LIBEXT)
 else
-  BIN = ../../libapps$(LIBEXT)
+  BIN = $(APPDIR)/libapps$(LIBEXT)
 endif
 endif
 
index 53d365a925bfe79d3ef6417726013b14988634c2..2774c5819303635dcab10967a16f61c8c721e338 100644 (file)
@@ -19,6 +19,7 @@
 #include <tinyara/fs/fs_utils.h>
 
 #include "jerryscript.h"
+#include "jerryscript-ext/debugger.h"
 #include "jerryscript-ext/handler.h"
 #include "jerryscript-port.h"
 #include "setjmp.h"
@@ -128,9 +129,9 @@ static void
 print_unhandled_exception (jerry_value_t error_value, /**< error value */
                            const jerry_char_t *source_p) /**< source_p */
 {
-  assert (jerry_value_has_error_flag (error_value));
+  assert (jerry_value_is_error (error_value));
 
-  error_value = jerry_get_value_without_error_flag (error_value);
+  error_value = jerry_get_value_from_error (error_value, false);
   jerry_value_t err_str_val = jerry_value_to_string (error_value);
   jerry_size_t err_str_size = jerry_get_string_size (err_str_val);
   jerry_char_t err_str_buf[256];
@@ -257,7 +258,7 @@ register_js_function (const char *name_p, /**< name of the function */
 {
   jerry_value_t result_val = jerryx_handler_register_global ((const jerry_char_t *) name_p, handler_p);
 
-  if (jerry_value_has_error_flag (result_val))
+  if (jerry_value_is_error (result_val))
   {
     jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Warning: failed to register '%s' method.", name_p);
   }
@@ -356,7 +357,8 @@ jerry_cmd_main (int argc, char *argv[])
 
   if (start_debug_server)
   {
-    jerry_debugger_init (debug_port);
+    jerryx_debugger_after_connect (jerryx_debugger_tcp_create (debug_port)
+                                   && jerryx_debugger_ws_create ());
   }
 
   register_js_function ("assert", jerryx_handler_assert);
@@ -369,11 +371,10 @@ jerry_cmd_main (int argc, char *argv[])
   {
     printf ("No input files, running a hello world demo:\n");
     const jerry_char_t script[] = "var str = 'Hello World'; print(str + ' from JerryScript')";
-    size_t script_size = strlen ((const char *) script);
 
-    ret_value = jerry_parse (NULL, 0, script, script_size, JERRY_PARSE_NO_OPTS);
+    ret_value = jerry_parse (NULL, 0, script, sizeof (script) - 1, JERRY_PARSE_NO_OPTS);
 
-    if (!jerry_value_has_error_flag (ret_value))
+    if (!jerry_value_is_error (ret_value))
     {
       ret_value = jerry_run (ret_value);
     }
@@ -397,14 +398,14 @@ jerry_cmd_main (int argc, char *argv[])
                                source_size,
                                JERRY_PARSE_NO_OPTS);
 
-      if (!jerry_value_has_error_flag (ret_value))
+      if (!jerry_value_is_error (ret_value))
       {
         jerry_value_t func_val = ret_value;
         ret_value = jerry_run (func_val);
         jerry_release_value (func_val);
       }
 
-      if (jerry_value_has_error_flag (ret_value))
+      if (jerry_value_is_error (ret_value))
       {
         print_unhandled_exception (ret_value, source_p);
         free ((void*) source_p);
@@ -421,7 +422,7 @@ jerry_cmd_main (int argc, char *argv[])
 
   int ret_code = JERRY_STANDALONE_EXIT_CODE_OK;
 
-  if (jerry_value_has_error_flag (ret_value))
+  if (jerry_value_is_error (ret_value))
   {
     ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL;
   }
@@ -473,19 +474,16 @@ jerry_port_log (jerry_log_level_t level, /**< log level */
 } /* jerry_port_log */
 
 /**
- * Dummy function to get the time zone.
+ * Dummy function to get the time zone adjustment.
  *
- * @return true
+ * @return 0
  */
-bool
-jerry_port_get_time_zone (jerry_time_zone_t *tz_p)
+double
+jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc)
 {
   /* We live in UTC. */
-  tz_p->offset = 0;
-  tz_p->daylight_saving_time = 0;
-
-  return true;
-} /* jerry_port_get_time_zone */
+  return 0;
+} /* jerry_port_get_local_time_zone_adjustment */
 
 /**
  * Dummy function to get the current time.
index 6b47db3222836b6b0b29fb513481e49cba412061..d1dd348363c4a76ab5ffcb5ad78f55d5323b87bb 100644 (file)
@@ -166,7 +166,7 @@ ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
   LDFLAGS += -g
 endif
 
-LDFLAAGS += --gc-sections
+LDFLAGS += --gc-sections
 
 HOSTCC = gcc
 HOSTINCLUDES = -I.
index d970e9625a786159dbb4f50c5e6d04fbabca0855..30b7c7ba60b126d65153fc086fda3b6fe692cc61 100644 (file)
@@ -11,6 +11,7 @@
 # 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.
+cmake_minimum_required(VERSION 3.8)
 
 include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
 project(NONE)
@@ -27,7 +28,7 @@ set_target_properties(jerry-ext PROPERTIES IMPORTED_LOCATION
                       ${CMAKE_CURRENT_BINARY_DIR}/../obj/lib/libjerry-ext.a)
 set_target_properties(jerry-ext PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
                       ${CMAKE_CURRENT_SOURCE_DIR}/../../jerry-ext/include)
-target_link_libraries(app jerry-core jerry-ext)
+target_link_libraries(app PUBLIC jerry-core jerry-ext)
 
 zephyr_get_include_directories_for_lang_as_string(C includes)
 zephyr_get_system_include_directories_for_lang_as_string(C system_includes)
@@ -40,7 +41,7 @@ add_custom_target(
   COMMAND echo Z_CFLAGS=${system_includes} ${includes} ${definitions} ${options}
   COMMAND echo NOSTDINC_FLAGS=${system_includes}
   COMMAND echo ZEPHYRINCLUDE=${includes}
-  COMMAND echo KBUILD_CFLAGS=${definitions}${options}
+  COMMAND echo KBUILD_CFLAGS=${definitions} ${options}
   VERBATIM
   USES_TERMINAL
 )
index 5c195e407001c20fe34f2a06abe30e7788006c76..e3b7c6e2dc5418d966777bb34d9510167e272b83 100644 (file)
@@ -27,19 +27,22 @@ install-apt-get-deps:
 
 # Install Zephyr SDK.
 install-zephyr-sdk:
-       wget https://github.com/zephyrproject-rtos/meta-zephyr-sdk/releases/download/0.9.2/zephyr-sdk-0.9.2-setup.run -O ../zephyr-sdk-0.9.2-setup.run
-       sh ../zephyr-sdk-0.9.2-setup.run -- -y -d $(CURDIR)/../zephyr-sdk-0.9.2
-       wget https://cmake.org/files/v3.8/cmake-3.8.2-Linux-x86_64.sh
-       sudo sh cmake-3.8.2-Linux-x86_64.sh --prefix=/usr/local --exclude-subdir
+       wget https://github.com/zephyrproject-rtos/meta-zephyr-sdk/releases/download/0.9.3/zephyr-sdk-0.9.3-setup.run -O ../zephyr-sdk-0.9.3-setup.run
+       sh ../zephyr-sdk-0.9.3-setup.run -- -y -d $(CURDIR)/../zephyr-sdk-0.9.3
        cmake --version
 
 # Fetch Zephyr Project repository and install python dependencies.
-install-zephyr: install-apt-get-deps
-       git clone https://github.com/zephyrproject-rtos/zephyr.git ../zephyr -b v1.10.0
+install-zephyr:
+       git clone https://github.com/zephyrproject-rtos/zephyr.git ../zephyr -b v1.13.0
+       pip3 install --user -U pip
+       pip3 install --user -U setuptools
+       # FIXME: It's temporary workaround to make Travis CI happy for Zephry v1.13.0.
+       pip3 install --user pyocd==0.12.0
        pip3 install --user -r ../zephyr/scripts/requirements.txt
 
 # Perform all the necessary (JerryScript-independent) installation steps.
-install: install-zephyr-sdk install-zephyr
+install-noapt: install-zephyr-sdk install-zephyr
+install: install-apt-get-deps install-noapt
 
 
 ## Targets for building Zephyr with JerryScript.
@@ -48,6 +51,6 @@ install: install-zephyr-sdk install-zephyr
 SHELL=bash
 script:
        export ZEPHYR_GCC_VARIANT=zephyr && \
-       export ZEPHYR_SDK_INSTALL_DIR=$(CURDIR)/../zephyr-sdk-0.9.2 && \
+       export ZEPHYR_SDK_INSTALL_DIR=$(CURDIR)/../zephyr-sdk-0.9.3 && \
        source ../zephyr/zephyr-env.sh && \
        $(MAKE) -f ./targets/zephyr/Makefile.zephyr BOARD=arduino_101
index 01f5b6f8291da535448e95febcf0849c2d3b131e..69b3ab47ed0b81b741d0d8d6c3a76eef4e01035e 100644 (file)
@@ -83,7 +83,6 @@ endif
         -DCMAKE_C_COMPILER_WORKS=TRUE \
         -DENABLE_LTO=OFF \
         -DENABLE_ALL_IN_ONE=OFF \
-        -DJERRY_LIBC=OFF \
         -DJERRY_CMDLINE=OFF \
         -DFEATURE_PROFILE=$(JERRYPROFILE) \
         -DFEATURE_ERROR_MESSAGES=ON \
index 09f46d8da461d7c9e52c68c067f75dfcf16955a2..628689dd5413efd2949cf36cedf5f02c91967df3 100644 (file)
@@ -4,6 +4,3 @@ CONFIG_NEWLIB_LIBC=y
 CONFIG_FLOAT=y
 CONFIG_MAIN_STACK_SIZE=2048
 CONFIG_CONSOLE_HANDLER=y
-CONFIG_CONSOLE_HANDLER_SHELL=y
-CONFIG_ARC_INIT=n
-
index b1eb9dcb67e2f0d190405ecdbbbb9ba0e153b584..5a129d8fbe736223cc6a496355ce598e1ce27828 100644 (file)
@@ -59,19 +59,16 @@ jerry_port_get_current_time (void)
 } /* jerry_port_get_current_time */
 
 /**
- * Dummy function to get the time zone.
+ * Dummy function to get the time zone adjustment.
  *
- * @return true
+ * @return 0
  */
-bool
-jerry_port_get_time_zone (jerry_time_zone_t *tz_p)
+double
+jerry_port_get_local_time_zone_adjustment (double unix_ms, bool is_utc)
 {
   /* We live in UTC. */
-  tz_p->offset = 0;
-  tz_p->daylight_saving_time = 0;
-
-  return true;
-} /* jerry_port_get_time_zone */
+  return 0;
+} /* jerry_port_get_local_time_zone_adjustment */
 
 /**
  * Provide the implementation of jerryx_port_handler_print_char.
index 5be3782e4c4b2f4db5c6d97b7a03ef51a8f41963..b2090bf76b00f849cdac26e9d3e955063fc17dcd 100644 (file)
@@ -36,7 +36,7 @@ register_js_function (const char *name_p, /**< name of the function */
 {
   jerry_value_t result_val = jerryx_handler_register_global ((const jerry_char_t *) name_p, handler_p);
 
-  if (jerry_value_has_error_flag (result_val))
+  if (jerry_value_is_error (result_val))
   {
     jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Warning: failed to register '%s' method.", name_p);
   }
@@ -50,9 +50,9 @@ static int shell_cmd_handler (char *source_buffer)
 
   ret_val = jerry_eval ((jerry_char_t *) source_buffer,
     strlen (source_buffer),
-    false);
+    JERRY_PARSE_NO_OPTS);
 
-  if (jerry_value_has_error_flag (ret_val))
+  if (jerry_value_is_error (ret_val))
   {
     /* User-friendly error messages require at least "cp" JerryScript
        profile. Include a message prefix in case "cp_minimal" profile
@@ -60,10 +60,10 @@ static int shell_cmd_handler (char *source_buffer)
     printf ("Error executing statement: ");
     /* Clear error flag, otherwise print call below won't produce any
        output. */
-    jerry_value_clear_error_flag (&ret_val);
+    ret_val = jerry_get_value_from_error (ret_val, true);
   }
 
-  if (!jerry_value_has_error_flag (print_function))
+  if (!jerry_value_is_error (print_function))
   {
     jerry_value_t ret_val_print = jerry_call_function (print_function,
       jerry_create_undefined (),
@@ -96,7 +96,7 @@ void main (void)
   print_function = jerry_get_property (global_obj_val, print_func_name_val);
   jerry_release_value (print_func_name_val);
   jerry_release_value (global_obj_val);
-  if (jerry_value_has_error_flag (print_function))
+  if (jerry_value_is_error (print_function))
   {
     printf ("Error: could not look up print function, expression results won't be printed\n");
   }
index bb6babbaec665dc090f34796317a4681210f26d3..f81cf5f457f202a363ad8a2f064edc2d6a645f37 100644 (file)
@@ -4,9 +4,19 @@ next
 step
 next
 s
+bt 1 2 t
+bt 1 2
+bt 0 3 t
 bt
+bt 2
+bt 2 t
 n
 n
 s
 backtrace
+bt 4 4
+bt 600 919
+bt 3 500
+bt 42
+bt 4 3
 c
index 69424bd6d8b72ec03c0b2f49e01860f932ca2826..21b73f50994cd952a37b94bc4f877ef4fa14c4bf 100644 (file)
@@ -14,10 +14,27 @@ out: function test
 Stopped at tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
 (jerry-debugger) s
 Stopped at tests/debugger/do_backtrace.js:23 (in foo() at line:21, col:1)
+(jerry-debugger) bt 1 2 t
+Total number of frames: 3
+Frame 1: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
+(jerry-debugger) bt 1 2
+Frame 1: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
+(jerry-debugger) bt 0 3 t
+Total number of frames: 3
+Frame 0: tests/debugger/do_backtrace.js:23 (in foo() at line:21, col:1)
+Frame 1: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
+Frame 2: tests/debugger/do_backtrace.js:40
 (jerry-debugger) bt
 Frame 0: tests/debugger/do_backtrace.js:23 (in foo() at line:21, col:1)
 Frame 1: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
 Frame 2: tests/debugger/do_backtrace.js:40
+(jerry-debugger) bt 2
+Frame 0: tests/debugger/do_backtrace.js:23 (in foo() at line:21, col:1)
+Frame 1: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
+(jerry-debugger) bt 2 t
+Total number of frames: 3
+Frame 0: tests/debugger/do_backtrace.js:23 (in foo() at line:21, col:1)
+Frame 1: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
 (jerry-debugger) n
 out: function foo
 Stopped at tests/debugger/do_backtrace.js:24 (in foo() at line:21, col:1)
@@ -30,5 +47,16 @@ Frame 0: tests/debugger/do_backtrace.js:18 (in f4() at line:17, col:1)
 Frame 1: tests/debugger/do_backtrace.js:25 (in foo() at line:21, col:1)
 Frame 2: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
 Frame 3: tests/debugger/do_backtrace.js:40
+(jerry-debugger) bt 4 4
+(jerry-debugger) bt 600 919
+(jerry-debugger) bt 3 500
+Frame 3: tests/debugger/do_backtrace.js:40
+(jerry-debugger) bt 42
+Frame 0: tests/debugger/do_backtrace.js:18 (in f4() at line:17, col:1)
+Frame 1: tests/debugger/do_backtrace.js:25 (in foo() at line:21, col:1)
+Frame 2: tests/debugger/do_backtrace.js:33 (in test() at line:30, col:1)
+Frame 3: tests/debugger/do_backtrace.js:40
+(jerry-debugger) bt 4 3
+Error: Start depth needs to be lower than or equal to max depth
 (jerry-debugger) c
 out: function f4
index 6e5560ee358937ca549eb9299b2427706c5b1b23..07217421e94c68433f142ab8e8cb7c482a62fdee 100644 (file)
@@ -18,6 +18,7 @@ out: break test
 out: var cat
 Stopped at breakpoint:1 tests/debugger/do_break.js:51
 (jerry-debugger) delete 1
+Breakpoint 1 deleted
 (jerry-debugger) list
 === Active breakpoints  ===
  2: tests/debugger/do_break.js:36 (in test() at line:20, col:1)
index bfa158e1bae8bba0a279cd45d872cfa3d8131064..0a3b714aa8003d4b79e35c74d6e646e65dcf3843 100644 (file)
@@ -7,7 +7,7 @@ Stopped at tests/debugger/do_delete.js:17
 Breakpoint 1 at tests/debugger/do_delete.js:17
 (jerry-debugger) b do_delete.js:21
 No breakpoint found, do you want to add a pending breakpoint? (y or [n])
-Pending breakpoint at do_delete.js:21
+Pending breakpoint at do_delete.js:21
 (jerry-debugger) b do_delete.js:19
 Breakpoint 3 at tests/debugger/do_delete.js:19
 (jerry-debugger) b do_delete.js:18
@@ -20,7 +20,9 @@ Breakpoint 4 at tests/debugger/do_delete.js:18
 === Pending breakpoints ===
  2: do_delete.js:21 (pending)
 (jerry-debugger) delete 2
+Pending breakpoint 2 deleted
 (jerry-debugger) delete 3
+Breakpoint 3 deleted
 (jerry-debugger) list
 === Active breakpoints  ===
  1: tests/debugger/do_delete.js:17
index 3d80eb74f3492f399d74ec76487c208c0b67b02d..94bb8b122dee0871312efbecc72a2fff7476cc28 100644 (file)
@@ -8,10 +8,10 @@ Breakpoint 2 at tests/debugger/do_delete_all.js:18
 Breakpoint 3 at tests/debugger/do_delete_all.js:21 (in delete_test() at line:20, col:1)
 (jerry-debugger) b do_delete_all:350
 No breakpoint found, do you want to add a pending breakpoint? (y or [n])
-Pending breakpoint at do_delete_all:350
+Pending breakpoint at do_delete_all:350
 (jerry-debugger) b do_delete_all:37
 No breakpoint found, do you want to add a pending breakpoint? (y or [n])
-Pending breakpoint at do_delete_all:37
+Pending breakpoint at do_delete_all:37
 (jerry-debugger) list
 === Active breakpoints  ===
  1: tests/debugger/do_delete_all.js:17
diff --git a/deps/jerry/tests/debugger/do_eval_at.cmd b/deps/jerry/tests/debugger/do_eval_at.cmd
new file mode 100644 (file)
index 0000000..85bb5d4
--- /dev/null
@@ -0,0 +1,20 @@
+eval_at 0
+eval_at 0 b
+n
+eval_at 0 b
+b do_eval_at.js:20
+n
+scopes
+eval_at 0 b
+eval_at 1 b
+eval_at 0 b=20
+eval_at 1 b=100
+n
+eval_at 0 a
+scopes
+eval_at 0 b
+eval_at -1 b
+eval_at 65536 b
+eval_at b
+eval_at 200
+c
diff --git a/deps/jerry/tests/debugger/do_eval_at.expected b/deps/jerry/tests/debugger/do_eval_at.expected
new file mode 100644 (file)
index 0000000..b0db16f
--- /dev/null
@@ -0,0 +1,44 @@
+Connecting to: localhost:5001
+Stopped at tests/debugger/do_eval_at.js:15
+(jerry-debugger) eval_at 0
+undefined
+(jerry-debugger) eval_at 0 b
+undefined
+(jerry-debugger) n
+Stopped at tests/debugger/do_eval_at.js:23
+(jerry-debugger) eval_at 0 b
+2
+(jerry-debugger) b do_eval_at.js:20
+Breakpoint 1 at tests/debugger/do_eval_at.js:20 (in f() at line:17, col:1)
+(jerry-debugger) n
+Stopped at breakpoint:1 tests/debugger/do_eval_at.js:20 (in f() at line:17, col:1)
+(jerry-debugger) scopes
+level | type   
+0     | local  
+1     | global 
+(jerry-debugger) eval_at 0 b
+6
+(jerry-debugger) eval_at 1 b
+2
+(jerry-debugger) eval_at 0 b=20
+20
+(jerry-debugger) eval_at 1 b=100
+100
+(jerry-debugger) n
+Stopped at tests/debugger/do_eval_at.js:25
+(jerry-debugger) eval_at 0 a
+23
+(jerry-debugger) scopes
+level | type   
+0     | global 
+(jerry-debugger) eval_at 0 b
+100
+(jerry-debugger) eval_at -1 b
+Error: Invalid scope chain index: -1 (must be between 0 and 65535)
+(jerry-debugger) eval_at 65536 b
+Error: Invalid scope chain index: 65536 (must be between 0 and 65535)
+(jerry-debugger) eval_at b
+Error: invalid literal for int() with base 10: 'b'
+(jerry-debugger) eval_at 200
+Uncaught exception: Error
+(jerry-debugger) c
diff --git a/deps/jerry/tests/debugger/do_eval_at.js b/deps/jerry/tests/debugger/do_eval_at.js
new file mode 100644 (file)
index 0000000..80eb998
--- /dev/null
@@ -0,0 +1,25 @@
+// 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.
+
+var b = 2;
+
+function f(a)
+{
+  var b = 6;
+  return a + b;
+}
+
+var a = f(3);
+
+null;
index 484cad6e7920edddfd393f0bf4f616803f95943c..26cde448b65af0527fbd0c11331d6292f2b20adb 100644 (file)
@@ -4,9 +4,10 @@ Stopped at tests/debugger/do_help.js:15
 
 Documented commands (type help <topic>):
 ========================================
-abort      bt        display  exception  list      next    source
-b          c         dump     f          memstats  quit    src   
-backtrace  continue  e        finish     ms        s       step  
-break      delete    eval     help       n         scroll  throw 
+abort      c         e          finish    n        s       step     
+b          continue  eval       help      next     scopes  throw    
+backtrace  delete    eval_at    list      quit     scroll  variables
+break      display   exception  memstats  res      source
+bt         dump      f          ms        restart  src   
 
 (jerry-debugger) quit
index 33efcc2632e657cda8fd0083e76d1ab4d781cdb6..df6260fc7e88980e6290554876b89e1980bdbfc1 100644 (file)
@@ -2,10 +2,10 @@ Connecting to: localhost:5001
 Stopped at tests/debugger/do_pending_breakpoints.js:15
 (jerry-debugger) break :1
 No breakpoint found, do you want to add a pending breakpoint? (y or [n])
-Pending breakpoint at :1
+Pending breakpoint at :1
 (jerry-debugger) break f
 No breakpoint found, do you want to add a pending breakpoint? (y or [n])
-Pending breakpoint at f()
+Pending breakpoint at f()
 (jerry-debugger) list
 === Pending breakpoints ===
  1: :1 (pending)
diff --git a/deps/jerry/tests/debugger/do_print.cmd b/deps/jerry/tests/debugger/do_print.cmd
new file mode 100644 (file)
index 0000000..f2ad6c7
--- /dev/null
@@ -0,0 +1 @@
+c
diff --git a/deps/jerry/tests/debugger/do_print.expected b/deps/jerry/tests/debugger/do_print.expected
new file mode 100644 (file)
index 0000000..c551d65
--- /dev/null
@@ -0,0 +1,112 @@
+Connecting to: localhost:5001
+Stopped at tests/debugger/do_print.js:15
+(jerry-debugger) c
+out: Hello world!
+out: A [  ] 110 null true undefined
+out: 
+out: [A
+out: B C
+out: D E
+out: F
+out: G]
+out: 1: Az élet gyönyörű.
+out: 2: Az élet gyönyörű.
+out: 3: Az élet gyönyörű.
+out: 4: Az élet gyönyörű.
+out: 5: Az élet gyönyörű.
+out: 6: Az élet gyönyörű.
+out: 7: Az élet gyönyörű.
+out: 8: Az élet gyönyörű.
+out: 9: Az élet gyönyörű.
+out: 10: Az élet gyönyörű.
+out: 11: Az élet gyönyörű.
+out: 12: Az élet gyönyörű.
+out: 13: Az élet gyönyörű.
+out: 14: Az élet gyönyörű.
+out: 15: Az élet gyönyörű.
+out: 16: Az élet gyönyörű.
+out: 17: Az élet gyönyörű.
+out: 18: Az élet gyönyörű.
+out: 19: Az élet gyönyörű.
+out: 20: Az élet gyönyörű.
+out: 21: Az élet gyönyörű.
+out: 22: Az élet gyönyörű.
+out: 23: Az élet gyönyörű.
+out: 24: Az élet gyönyörű.
+out: 25: Az élet gyönyörű.
+out: 26: Az élet gyönyörű.
+out: 27: Az élet gyönyörű.
+out: 28: Az élet gyönyörű.
+out: 29: Az élet gyönyörű.
+out: 30: Az élet gyönyörű.
+out: 31: Az élet gyönyörű.
+out: 32: Az élet gyönyörű.
+out: 33: Az élet gyönyörű.
+out: 34: Az élet gyönyörű.
+out: 35: Az élet gyönyörű.
+out: 36: Az élet gyönyörű.
+out: 37: Az élet gyönyörű.
+out: 38: Az élet gyönyörű.
+out: 39: Az élet gyönyörű.
+out: 40: Az élet gyönyörű.
+out: 41: Az élet gyönyörű.
+out: 42: Az élet gyönyörű.
+out: 43: Az élet gyönyörű.
+out: 44: Az élet gyönyörű.
+out: 45: Az élet gyönyörű.
+out: 46: Az élet gyönyörű.
+out: 47: Az élet gyönyörű.
+out: 48: Az élet gyönyörű.
+out: 49: Az élet gyönyörű.
+out: 50: Az élet gyönyörű.
+out: 51: Az élet gyönyörű.
+out: 52: Az élet gyönyörű.
+out: 53: Az élet gyönyörű.
+out: 54: Az élet gyönyörű.
+out: 55: Az élet gyönyörű.
+out: 56: Az élet gyönyörű.
+out: 57: Az élet gyönyörű.
+out: 58: Az élet gyönyörű.
+out: 59: Az élet gyönyörű.
+out: 60: Az élet gyönyörű.
+out: 61: Az élet gyönyörű.
+out: 62: Az élet gyönyörű.
+out: 63: Az élet gyönyörű.
+out: 64: Az élet gyönyörű.
+out: 65: Az élet gyönyörű.
+out: 66: Az élet gyönyörű.
+out: 67: Az élet gyönyörű.
+out: 68: Az élet gyönyörű.
+out: 69: Az élet gyönyörű.
+out: 70: Az élet gyönyörű.
+out: 71: Az élet gyönyörű.
+out: 72: Az élet gyönyörű.
+out: 73: Az élet gyönyörű.
+out: 74: Az élet gyönyörű.
+out: 75: Az élet gyönyörű.
+out: 76: Az élet gyönyörű.
+out: 77: Az élet gyönyörű.
+out: 78: Az élet gyönyörű.
+out: 79: Az élet gyönyörű.
+out: 80: Az élet gyönyörű.
+out: 81: Az élet gyönyörű.
+out: 82: Az élet gyönyörű.
+out: 83: Az élet gyönyörű.
+out: 84: Az élet gyönyörű.
+out: 85: Az élet gyönyörű.
+out: 86: Az élet gyönyörű.
+out: 87: Az élet gyönyörű.
+out: 88: Az élet gyönyörű.
+out: 89: Az élet gyönyörű.
+out: 90: Az élet gyönyörű.
+out: 91: Az élet gyönyörű.
+out: 92: Az élet gyönyörű.
+out: 93: Az élet gyönyörű.
+out: 94: Az élet gyönyörű.
+out: 95: Az élet gyönyörű.
+out: 96: Az élet gyönyörű.
+out: 97: Az élet gyönyörű.
+out: 98: Az élet gyönyörű.
+out: 99: Az élet gyönyörű.
+out: 100: Az élet gyönyörű.
+out: 
diff --git a/deps/jerry/tests/debugger/do_print.js b/deps/jerry/tests/debugger/do_print.js
new file mode 100644 (file)
index 0000000..9b7496e
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright JS Foundation and other contributors, http://js.foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+print("Hello world!");
+print("A", "[", "", "]", 1.1e2, null, true, undefined);
+print();
+print("[A\nB", "C\nD", "E\nF\nG]");
+
+var s = "";
+
+for (i = 1; i <= 100; i++) {
+  /* Translated from hungarian: life is beautiful */
+  s += i + ": Az élet gyönyörű.\n";
+}
+
+/* Long string with non-ascii characters. */
+print(s);
diff --git a/deps/jerry/tests/debugger/do_restart.cmd b/deps/jerry/tests/debugger/do_restart.cmd
new file mode 100644 (file)
index 0000000..9babf70
--- /dev/null
@@ -0,0 +1,4 @@
+n
+n
+n
+restart
diff --git a/deps/jerry/tests/debugger/do_restart.expected b/deps/jerry/tests/debugger/do_restart.expected
new file mode 100644 (file)
index 0000000..b92be82
--- /dev/null
@@ -0,0 +1,18 @@
+Connecting to: localhost:5001
+Stopped at tests/debugger/do_restart.js:23
+(jerry-debugger) n
+Stopped at tests/debugger/do_restart.js:24
+(jerry-debugger) n
+out: foo
+Stopped at tests/debugger/do_restart.js:25
+(jerry-debugger) n
+out: bar
+Stopped at tests/debugger/do_restart.js:24
+(jerry-debugger) restart
+Connecting to: localhost:5001
+Stopped at tests/debugger/do_restart.js:23
+(jerry-debugger) continue
+out: foo
+out: bar
+out: foo
+out: bar
diff --git a/deps/jerry/tests/debugger/do_restart.js b/deps/jerry/tests/debugger/do_restart.js
new file mode 100644 (file)
index 0000000..90097fd
--- /dev/null
@@ -0,0 +1,26 @@
+// 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.
+
+function foo() {
+  print("foo");
+}
+
+function bar() {
+  print("bar");
+}
+
+for (var i = 0; i < 2; i++) {
+  foo();
+  bar();
+}
diff --git a/deps/jerry/tests/debugger/do_scopes.cmd b/deps/jerry/tests/debugger/do_scopes.cmd
new file mode 100644 (file)
index 0000000..69a869c
--- /dev/null
@@ -0,0 +1,19 @@
+scopes
+b do_scopes.js:22
+c
+scopes
+c
+scopes
+b do_scopes.js:28
+c
+scopes
+b do_scopes.js:31
+c
+scopes
+b do_scopes.js:33
+c
+scopes
+b do_scopes.js:35
+c
+scopes
+c
diff --git a/deps/jerry/tests/debugger/do_scopes.expected b/deps/jerry/tests/debugger/do_scopes.expected
new file mode 100644 (file)
index 0000000..84e761d
--- /dev/null
@@ -0,0 +1,63 @@
+Connecting to: localhost:5001
+Stopped at tests/debugger/do_scopes.js:15
+(jerry-debugger) scopes
+level | type   
+0     | global 
+(jerry-debugger) b do_scopes.js:22
+Breakpoint 1 at tests/debugger/do_scopes.js:22 (in f() at line:17, col:1)
+(jerry-debugger) c
+Exception throw detected (to disable automatic stop type exception 0)
+Exception hint: error
+Stopped at tests/debugger/do_scopes.js:19 (in f() at line:17, col:1)
+(jerry-debugger) scopes
+level | type   
+0     | local  
+1     | global 
+(jerry-debugger) c
+Stopped at breakpoint:1 tests/debugger/do_scopes.js:22 (in f() at line:17, col:1)
+(jerry-debugger) scopes
+level | type   
+0     | catch  
+1     | local  
+2     | global 
+(jerry-debugger) b do_scopes.js:28
+Breakpoint 2 at tests/debugger/do_scopes.js:28 (in function() at line:27, col:4)
+(jerry-debugger) c
+Stopped at breakpoint:2 tests/debugger/do_scopes.js:28 (in function() at line:27, col:4)
+(jerry-debugger) scopes
+level | type    
+0     | local   
+1     | closure 
+2     | global  
+(jerry-debugger) b do_scopes.js:31
+Breakpoint 3 at tests/debugger/do_scopes.js:31 (in function() at line:27, col:4)
+(jerry-debugger) c
+Stopped at breakpoint:3 tests/debugger/do_scopes.js:31 (in function() at line:27, col:4)
+(jerry-debugger) scopes
+level | type    
+0     | with    
+1     | local   
+2     | closure 
+3     | global  
+(jerry-debugger) b do_scopes.js:33
+Breakpoint 4 at tests/debugger/do_scopes.js:33 (in function() at line:27, col:4)
+(jerry-debugger) c
+Stopped at breakpoint:4 tests/debugger/do_scopes.js:33 (in function() at line:27, col:4)
+(jerry-debugger) scopes
+level | type    
+0     | with    
+1     | with    
+2     | local   
+3     | closure 
+4     | global  
+(jerry-debugger) b do_scopes.js:35
+Breakpoint 5 at tests/debugger/do_scopes.js:35 (in function() at line:27, col:4)
+(jerry-debugger) c
+Stopped at breakpoint:5 tests/debugger/do_scopes.js:35 (in function() at line:27, col:4)
+(jerry-debugger) scopes
+level | type    
+0     | with    
+1     | local   
+2     | closure 
+3     | global  
+(jerry-debugger) c
diff --git a/deps/jerry/tests/debugger/do_scopes.js b/deps/jerry/tests/debugger/do_scopes.js
new file mode 100644 (file)
index 0000000..5c14b96
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright JS Foundation and other contributors, http://js.foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+var c = 4;
+
+function f() {
+  try {
+    throw "error";
+  }
+  catch (err) {
+    var c = 10;
+  }
+
+  var z = true;
+  var g = 0;
+  (function() {
+    var a = [1,2,3]
+    a.y = "abc";
+    with (a) {
+      var h = [4,5,6]
+      with (h) {
+        h.d = "dfg"
+      }
+      a.d = g + c;
+    }
+  })();
+}
+
+f();
+
diff --git a/deps/jerry/tests/debugger/do_variables.cmd b/deps/jerry/tests/debugger/do_variables.cmd
new file mode 100644 (file)
index 0000000..a9b0208
--- /dev/null
@@ -0,0 +1,28 @@
+scopes
+variables
+variables 1
+variables 0
+b tests/debugger/do_variables.js:20
+c
+scopes
+variables 0
+variables 1
+variables 2
+b tests/debugger/do_variables.js:30
+c
+scopes
+variables 1
+variables 0
+b tests/debugger/do_variables.js:33
+c
+c
+scopes
+variables 0
+variables 1
+b tests/debugger/do_variables.js:50
+c
+scopes
+variables 0
+variables 1
+variables 2
+c
diff --git a/deps/jerry/tests/debugger/do_variables.expected b/deps/jerry/tests/debugger/do_variables.expected
new file mode 100644 (file)
index 0000000..5b47637
--- /dev/null
@@ -0,0 +1,128 @@
+Connecting to: localhost:5001
+Stopped at tests/debugger/do_variables.js:15
+(jerry-debugger) scopes
+level | type   
+0     | global 
+(jerry-debugger) variables
+name   | type      | value     
+f      | Function  |           
+addX   | Function  |           
+z      | undefined | undefined 
+c      | undefined | undefined 
+print  | Function  |           
+gc     | Function  |           
+assert | Function  |           
+(jerry-debugger) variables 1
+name | type | value 
+(jerry-debugger) variables 0
+name   | type      | value     
+f      | Function  |           
+addX   | Function  |           
+z      | undefined | undefined 
+c      | undefined | undefined 
+print  | Function  |           
+gc     | Function  |           
+assert | Function  |           
+(jerry-debugger) b tests/debugger/do_variables.js:20
+Breakpoint 1 at tests/debugger/do_variables.js:20 (in function() at line:19, col:10)
+(jerry-debugger) c
+Stopped at breakpoint:1 tests/debugger/do_variables.js:20 (in function() at line:19, col:10)
+(jerry-debugger) scopes
+level | type    
+0     | local   
+1     | closure 
+2     | global  
+(jerry-debugger) variables 0
+name | type      | value     
+n    | Number    | 9         
+b    | undefined | undefined 
+(jerry-debugger) variables 1
+name | type   | value 
+x    | Number | 3     
+(jerry-debugger) variables 2
+name     | type     | value 
+addThree | Function |       
+f        | Function |       
+addX     | Function |       
+z        | Number   | 5     
+c        | Number   | 4     
+print    | Function |       
+gc       | Function |       
+assert   | Function |       
+(jerry-debugger) b tests/debugger/do_variables.js:30
+Breakpoint 2 at tests/debugger/do_variables.js:30 (in f() at line:28, col:1)
+(jerry-debugger) c
+Stopped at breakpoint:2 tests/debugger/do_variables.js:30 (in f() at line:28, col:1)
+(jerry-debugger) scopes
+level | type   
+0     | local  
+1     | global 
+(jerry-debugger) variables 1
+name     | type     | value 
+d        | Number   | 12    
+addThree | Function |       
+f        | Function |       
+addX     | Function |       
+z        | Number   | 5     
+c        | Number   | 4     
+print    | Function |       
+gc       | Function |       
+assert   | Function |       
+(jerry-debugger) variables 0
+name | type      | value     
+b    | undefined | undefined 
+x    | undefined | undefined 
+user | undefined | undefined 
+m    | undefined | undefined 
+c    | undefined | undefined 
+(jerry-debugger) b tests/debugger/do_variables.js:33
+Breakpoint 3 at tests/debugger/do_variables.js:33 (in f() at line:28, col:1)
+(jerry-debugger) c
+Exception throw detected (to disable automatic stop type exception 0)
+Exception hint: error
+Stopped at breakpoint:2 tests/debugger/do_variables.js:30 (in f() at line:28, col:1)
+(jerry-debugger) c
+Stopped at breakpoint:3 tests/debugger/do_variables.js:33 (in f() at line:28, col:1)
+(jerry-debugger) scopes
+level | type   
+0     | catch  
+1     | local  
+2     | global 
+(jerry-debugger) variables 0
+name | type   | value 
+err  | String | error 
+(jerry-debugger) variables 1
+name | type      | value     
+b    | undefined | undefined 
+x    | undefined | undefined 
+user | undefined | undefined 
+m    | undefined | undefined 
+c    | undefined | undefined 
+(jerry-debugger) b tests/debugger/do_variables.js:50
+Breakpoint 4 at tests/debugger/do_variables.js:50 (in function() at line:46, col:4)
+(jerry-debugger) c
+Stopped at breakpoint:4 tests/debugger/do_variables.js:50 (in function() at line:46, col:4)
+(jerry-debugger) scopes
+level | type    
+0     | with    
+1     | local   
+2     | closure 
+3     | global  
+(jerry-debugger) variables 0
+name | type   | value 
+y    | String | abc   
+2    | Number | 3     
+1    | Number | 2     
+0    | Number | 1     
+(jerry-debugger) variables 1
+name | type      | value     
+h    | undefined | undefined 
+a    | Array     | [1,2,3]   
+(jerry-debugger) variables 2
+name | type    | value           
+b    | Number  | 10              
+x    | Boolean | true            
+user | Object  | [object Object] 
+m    | Null    | null            
+c    | Number  | 10              
+(jerry-debugger) c
diff --git a/deps/jerry/tests/debugger/do_variables.js b/deps/jerry/tests/debugger/do_variables.js
new file mode 100644 (file)
index 0000000..ea76974
--- /dev/null
@@ -0,0 +1,60 @@
+// 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.
+
+var c = 4;
+var z = 5;
+
+function addX(x) {
+  return function(n) {
+    var b = 2;
+    return n + x;
+  }
+}
+
+addThree = addX(3);
+d = addThree(c+z);
+
+function f() {
+  try {
+    throw "error";
+  }
+  catch (err) {
+    var c = 10;
+  }
+
+  var m = null;
+
+  var user = {
+    name: "John",
+    age: 30
+  };
+
+  var x = true;
+  var b = 10;
+
+  (function() {
+    var a = [1,2,3]
+    a.y = "abc";
+    with (a) {
+      var h = [4,5,6]
+      with (h) {
+        h.d = "dfg"
+      }
+      a.d = x;
+    }
+  })();
+}
+
+f();
+
diff --git a/deps/jerry/tests/jerry-test-suite/11/11.08/11.08.06/11.08.06-008.js b/deps/jerry/tests/jerry-test-suite/11/11.08/11.08.06/11.08.06-008.js
new file mode 100644 (file)
index 0000000..1f41e2a
--- /dev/null
@@ -0,0 +1,17 @@
+// 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.
+
+var a = null;
+var c = a instanceof Object;
+assert (!c);
diff --git a/deps/jerry/tests/jerry/N.compact-profile-error.js b/deps/jerry/tests/jerry/N.compact-profile-error.js
deleted file mode 100644 (file)
index e91b308..0000000
+++ /dev/null
@@ -1,107 +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.
-
-var catched = false;
-
-function f1()
-{
-  var arguments = 1;
-}
-
-try
-{
-  f1();
-} catch (e)
-{
-  assert (e === CompactProfileError);
-
-  catched = true;
-}
-
-assert(catched);
-
-catched = false;
-
-function f2()
-{
-  var a = arguments;
-}
-
-try
-{
-  f2();
-} catch (e)
-{
-  assert (e === CompactProfileError);
-
-  catched = true;
-}
-
-assert(catched);
-
-catched = false;
-
-try
-{
-  eval('abc');
-} catch (e)
-{
-  assert (e === CompactProfileError);
-
-  catched = true;
-}
-
-assert(catched);
-
-catched = false;
-
-try
-{
-  Function('abc');
-} catch (e)
-{
-  assert (e === CompactProfileError);
-
-  catched = true;
-}
-
-assert(catched);
-
-catched = false;
-
-try
-{
-  new Function('abc');
-} catch (e)
-{
-  assert (e === CompactProfileError);
-
-  catched = true;
-}
-
-assert(catched);
-
-catched = false;
-
-try
-{
-  var a = Date.now();
-} catch (e)
-{
-  assert (e === CompactProfileError);
-
-  catched = true;
-}
-
-assert(catched);
index 396546557ac7e51a1afaf87d82001d7f7c97ed84..c4554cccd9e9a99aadab0e4c0a028c8c7fe3870d 100644 (file)
@@ -51,3 +51,5 @@ try {
 catch (e) {
   assert (e instanceof ReferenceError);
 }
+
+assert (0.1 + 0.2 != 0.3);
index 6b46bb3d607d7e18901a81ff3d67dede6f1de803..39ee7a3d2a696eb10ca40ea5651098f1ab6d8c5f 100644 (file)
@@ -26,3 +26,5 @@ assert(big == 2147483649); // overflow on 32bit numbers
 assert ((1152921504606846976).toString() === "1152921504606847000")
 
 assert (1.797693134862315808e+308 === Infinity);
+
+assert (9999999999999999 == 10000000000000000);
index 3f06bc1253a18b493c3f6b0981a1c1d9f6f4499f..ad9cedc9e65091fb27a78915653b33a53bd8bde2 100644 (file)
@@ -24,8 +24,7 @@ assert (d.getUTCDate() == 9);
 assert (d.getDay() == 4);
 assert (d.getUTCDay() == 4);
 assert (d.getHours() == 12);
-// FIXME: Missing timezone adjustment.
-//assert (d.getUTCHours() == (12 + d.getTimezoneOffset() / 60));
+assert (d.getUTCHours() == (12 + d.getTimezoneOffset() / 60));
 assert (d.getMinutes() == 13);
 assert (d.getUTCMinutes() == 13);
 assert (d.getSeconds() == 14);
@@ -44,9 +43,8 @@ assert (d.getDate() == 9);
 assert (d.getUTCDate() == 9);
 assert (d.getDay() == 4);
 assert (d.getUTCDay() == 4);
-// FIXME: Missing timezone adjustment.
-//assert (d.getHours() == 12);
-//assert (d.getUTCHours() == (12 + d.getTimezoneOffset() / 60));
+assert (d.getHours() == Math.floor(12 - 1.5 + d.getTimezoneOffset() / 60));
+assert (d.getUTCHours() == Math.floor(12 - 1.5));
 assert (d.getMinutes() == 43);
 assert (d.getUTCMinutes() == 43);
 assert (d.getSeconds() == 14);
@@ -65,8 +63,7 @@ assert (d.getDate() == 1);
 assert (d.getUTCDate() == 1);
 assert (d.getDay() == 4);
 assert (d.getUTCDay() == 4);
-// FIXME: Missing timezone adjustment.
-// assert (d.getHours() == 0 - (d.getTimezoneOffset() / 60));
+assert (d.getHours() == 0 - (d.getTimezoneOffset() / 60));
 assert (d.getUTCHours() == 0);
 assert (d.getMinutes() == 0);
 assert (d.getUTCMinutes() == 0);
index d587e12e02f7dcea4f95ee075a1d65cdc934b56e..3547454b2cb2a68ae76097c783e984388a0ee6b2 100644 (file)
@@ -82,25 +82,24 @@ assert (d.getUTCSeconds() == 1);
 assert (d.getUTCMilliseconds() == 1);
 
 /* 15.9.5.34 Date.prototype.setHours (hour [, min [, sec [, ms ] ] ] ) */
-// FIXME: Missing timezone adjustment.
-//d.setTime(0);
-//assert (d.setHours(1) == hour + d.getTimezoneOffset() * 60000);
-//assert (d.getHours() == 1);
-//d.setTime(0);
-//assert (d.setHours(1, 1) == hour + min + d.getTimezoneOffset() * 60000);
-//assert (d.getHours() == 1);
-//assert (d.getMinutes() == 1);
-//d.setTime(0);
-//assert (d.setHours(1, 1, 1) == hour + min + sec + d.getTimezoneOffset() * 60000);
-//assert (d.getHours() == 1);
-//assert (d.getMinutes() == 1);
-//assert (d.getSeconds() == 1);
-//d.setTime(0);
-//assert (d.setHours(1, 1, 1, 1) == hour + min + sec + ms + d.getTimezoneOffset() * 60000);
-//assert (d.getHours() == 1);
-//assert (d.getMinutes() == 1);
-//assert (d.getSeconds() == 1);
-//assert (d.getMilliseconds() == 1);
+d.setTime(0);
+assert (d.setHours(1) == hour + d.getTimezoneOffset() * 60000);
+assert (d.getHours() == 1);
+d.setTime(0);
+assert (d.setHours(1, 1) == hour + min + d.getTimezoneOffset() * 60000);
+assert (d.getHours() == 1);
+assert (d.getMinutes() == 1);
+d.setTime(0);
+assert (d.setHours(1, 1, 1) == hour + min + sec + d.getTimezoneOffset() * 60000);
+assert (d.getHours() == 1);
+assert (d.getMinutes() == 1);
+assert (d.getSeconds() == 1);
+d.setTime(0);
+assert (d.setHours(1, 1, 1, 1) == hour + min + sec + ms + d.getTimezoneOffset() * 60000);
+assert (d.getHours() == 1);
+assert (d.getMinutes() == 1);
+assert (d.getSeconds() == 1);
+assert (d.getMilliseconds() == 1);
 
 /* 15.9.5.35 Date.prototype.setUTCHours (hour [, min [, sec [, ms ] ] ] ) */
 d.setTime(0);
index ea7a290dcecabe34419370f9568261d41e79acbb..20db2970a5aad54cbb31eeed986be27cf43e5e04 100644 (file)
@@ -16,17 +16,17 @@ assert((5 == 5) == true);
 assert((7 != 2) == true);
 
 var num = 0;
-//var obj = new String("0");
+var obj = new String("0");
 var str = "0";
 var b = false;
 
 assert(num === num);
-//assert(obj === obj);
+assert(obj === obj);
 assert(str === str);
 
-//assert((num === obj) == false);
+assert((num === obj) == false);
 assert((num === str) == false);
-//assert((obj === str) == false);
-//assert((null === undefined) == false);
-//assert((obj === null) == false);
-//assert((obj === undefined) == false);
+assert((obj === str) == false);
+assert((null === undefined) == false);
+assert((obj === null) == false);
+assert((obj === undefined) == false);
diff --git a/deps/jerry/tests/jerry/es2015/array-prototype-find.js b/deps/jerry/tests/jerry/es2015/array-prototype-find.js
new file mode 100644 (file)
index 0000000..c238cc4
--- /dev/null
@@ -0,0 +1,137 @@
+// 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.
+
+var arrow_is_available = false;
+
+try {
+  assert (eval ("(f => 5) ()") === 5);
+  arrow_is_available = true;
+} catch (e) {
+  assert (e instanceof SyntaxError);
+}
+
+var array1 = [5, 12, 0, 8, 130, 44];
+
+function bigger_than_10 (element) {
+  return element > 10;
+}
+
+assert (array1.find (bigger_than_10) === 12);
+
+function less_than_0 (element) {
+  if (element == 0) {
+    throw new Error ("zero");
+  }
+  return element < 0;
+}
+
+try {
+  array1.find (less_than_0);
+  assert (false);
+} catch (e) {
+  assert (e instanceof Error);
+  assert (e.message === "zero");
+}
+
+var inventory = [
+    {name: 'apples', quantity: 2},
+    {name: 'bananas', quantity: 0},
+    {name: 'cherries', quantity: 5}
+];
+
+function isCherries (fruit) {
+    return fruit.name === 'cherries';
+}
+
+assert (JSON.stringify (inventory.find (isCherries)) === '{"name":"cherries","quantity":5}');
+
+if (arrow_is_available) {
+  assert (eval ("inventory.find (fruit => fruit.name === 'bananas')") === inventory[1]);
+}
+
+/* Test the callback function arguments */
+var src_array = [4, 6, 8, 12];
+var array_index = 0;
+
+function isPrime (element, index, array) {
+  assert (array_index++ === index);
+  assert (array === src_array)
+  assert (element === array[index]);
+
+  var start = 2;
+  while (start <= Math.sqrt (element)) {
+    if (element % start++ < 1) {
+      return false;
+    }
+  }
+  return element > 1;
+}
+
+assert (src_array.find (isPrime) === undefined);
+
+src_array = [4, 5, 8, 12];
+array_index = 0;
+assert (src_array.find (isPrime) === 5);
+
+
+// Checking behavior when unable to get length
+var obj = {};
+Object.defineProperty (obj, 'length', { 'get' : function () { throw new ReferenceError ("foo"); } });
+obj.find = Array.prototype.find;
+
+try {
+  obj.find ();
+  assert (false);
+} catch (e) {
+  assert (e.message === "foo");
+  assert (e instanceof ReferenceError);
+}
+
+var data = { 0: 1, 2: -3, 3: "string" }
+assert (Array.prototype.find.call (data, function (e) { return e < 5; }) === undefined);
+
+// Checking behavior when unable to get element
+var obj = {}
+obj.length = 1;
+Object.defineProperty (obj, '0', { 'get' : function () { throw new ReferenceError ("foo"); } });
+obj.find = Array.prototype.find
+
+try {
+  obj.find (function () { return undefined; });
+  assert (false);
+} catch (e) {
+  assert (e.message === "foo");
+  assert (e instanceof ReferenceError);
+}
+
+// Checking behavior when the first argument is not a callback
+var array = [1, 2, 3];
+
+try {
+  array.find (5);
+  assert (false);
+} catch (e) {
+  assert (e instanceof TypeError);
+}
+
+// Checking behavior when the first argument does not exist
+try {
+  array.find ();
+  assert (false);
+} catch (e) {
+  assert (e instanceof TypeError);
+}
+
+// Checking behavior when the there are more than 2 arguments
+assert (array.find (function (e) { return e < 2 }, {}, 8, 4, 5, 6, 6) === 1);
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-bound.js b/deps/jerry/tests/jerry/es2015/class-inheritance-bound.js
new file mode 100644 (file)
index 0000000..0d90a93
--- /dev/null
@@ -0,0 +1,28 @@
+/* Copyright JS Foundation and other contributors, http://js.foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var g = Array.bind (0, 1, 2, 3)
+g.prototype = Array.prototype;
+
+class C extends g {}
+
+class D extends C {
+  constructor () {
+    super (4, 5);
+  }
+}
+
+var d = new D;
+assert (Object.getPrototypeOf (d) == D.prototype);
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-builtin-array.js b/deps/jerry/tests/jerry/es2015/class-inheritance-builtin-array.js
new file mode 100644 (file)
index 0000000..22aedf2
--- /dev/null
@@ -0,0 +1,118 @@
+/* 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.
+ */
+
+ function isInstanceofArray (instance) {
+   assert (instance instanceof C);
+   assert (instance instanceof B);
+   assert (instance instanceof A);
+   assert (instance instanceof Array);
+ }
+
+ class A extends Array {
+   f () {
+     return 5;
+   }
+ }
+
+ class B extends A {
+   g () {
+     return eval ("eval ('super.f ()')");
+   }
+ }
+
+ class C extends B {
+   h () {
+     return eval ('super.g ()');
+   }
+ }
+
+ var c = new C (1, 2, 3, 4, 5, 6);
+
+ isInstanceofArray (c);
+ c.push (7);
+ assert (c.length === 7);
+ assert (c.f () === 5);
+ assert (c.g () === 5);
+ assert (c.h () === 5);
+
+/* TODO: Enable these tests after Symbol has been implemented
+ // Test built-in Array prototype methods
+ var mapped = c.map ((x) => x * 2);
+ isInstanceofArray (mapped);
+
+ for (var i = 0; i < mapped.length; i++) {
+   assert (mapped[i] == c[i] * 2);
+ }
+
+ var concated = c.concat (c);
+ isInstanceofArray (concated);
+
+ for (var i = 0; i < concated.length; i++) {
+   assert (concated[i] == c[i % (concated.length / 2)]);
+ }
+
+ var sliced = c.slice (c);
+ isInstanceofArray (sliced);
+
+ for (var i = 0; i < sliced.length; i++) {
+   assert (sliced[i] == c[i]);
+ }
+
+ var filtered = c.filter ((x) => x > 100);
+ isInstanceofArray (sliced);
+ assert (filtered.length === 0);
+
+ var spliced = c.splice (c.length - 1);
+ isInstanceofArray (spliced);
+ assert (spliced.length === 1);
+ assert (spliced[0] === 7);
+
+ c.constructor = 5;
+
+ try {
+   mapped = c.map ((x) => x * 2);
+   assert (false);
+ } catch (e) {
+   assert (e instanceof TypeError);
+ }
+
+ try {
+   concated = c.concat (c);
+   assert (false);
+ } catch (e) {
+   assert (e instanceof TypeError);
+ }
+
+ try {
+   sliced = c.slice (c);
+   assert (false);
+ } catch (e) {
+   assert (e instanceof TypeError);
+ }
+
+ try {
+   filtered = c.filter ((x) => x > 100);
+   assert (false);
+ } catch (e) {
+   assert (e instanceof TypeError);
+ }
+
+ try {
+   spliced = c.splice (0);
+   assert (false);
+ } catch (e) {
+   assert (e instanceof TypeError);
+ }
+*/
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-builtin-typedarray.js b/deps/jerry/tests/jerry/es2015/class-inheritance-builtin-typedarray.js
new file mode 100644 (file)
index 0000000..38643eb
--- /dev/null
@@ -0,0 +1,76 @@
+/* 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.
+ */
+
+ function isInstanceofTypedArray (instance) {
+   assert (instance instanceof C);
+   assert (instance instanceof B);
+   assert (instance instanceof A);
+   assert (instance instanceof Uint8Array);
+ }
+
+ class A extends Uint8Array {
+   f () {
+     return 5;
+   }
+ }
+
+ class B extends A {
+   g () {
+     return super.f ();
+   }
+ }
+
+ class C extends B {
+   h () {
+     return super.g ();
+   }
+ }
+
+ var c = new C ([1, 2, 3, 4, 5, 6]);
+
+ isInstanceofTypedArray (c);
+ assert (c.length === 6);
+ assert (c.f () === 5)
+ assert (c.g () === 5)
+ assert (c.h () === 5)
+
+/* TODO: Enable these tests after Symbol has been implemented
+ var mapped = c.map ((x) => x * 2);
+ isInstanceofTypedArray (mapped);
+
+ for (var i = 0; i < mapped.length; i++) {
+   assert (mapped[i] == c[i] * 2);
+ }
+
+ var filtered = c.filter ((x) => x > 100);
+ isInstanceofTypedArray (filtered);
+ assert (filtered.length === 0);
+
+ c.constructor = 5;
+
+ try {
+   mapped = c.map ((x) => x * 2);
+   assert (false);
+ } catch (e) {
+   assert (e instanceof TypeError)
+ }
+
+ try {
+   filtered = c.filter ((x) => x > 100);
+   assert (false);
+ } catch (e) {
+   assert (e instanceof TypeError)
+ }
+*/
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-core-1.js b/deps/jerry/tests/jerry/es2015/class-inheritance-core-1.js
new file mode 100644 (file)
index 0000000..ac8d148
--- /dev/null
@@ -0,0 +1,116 @@
+/* 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.
+ */
+
+class Animal {
+  constructor (name) {
+    this.name = name;
+  }
+
+  hello () {
+    return "Hello I am " + this.name;
+  }
+
+  static speak () {
+    return "Animals roar.";
+  }
+
+  static explain () {
+    return "I can walk,";
+  }
+
+  whoAmI () {
+    return "I am an Animal.";
+  }
+
+  breath () {
+    return "I am breathing.";
+  }
+
+  get myName () {
+    return this.name;
+  }
+
+  set rename (name) {
+    this.name = name;
+  }
+}
+
+class Dog extends Animal {
+  constructor (name, barks) {
+    super (name);
+    this.barks = barks;
+  }
+
+  hello () {
+    return super.hello () + " and I can " + (this.barks ? "bark" : "not bark");
+  }
+
+  whoAmI () {
+    return "I am a Dog.";
+  }
+
+  static speak () {
+    return "Dogs bark.";
+  }
+
+  static explain () {
+    return super.explain () + " jump,";
+  }
+
+  bark () {
+    return this.barks ? "Woof" : "----";
+  }
+}
+
+class Doge extends Dog {
+  constructor (name, barks, awesomeness) {
+    super (name, barks);
+    this.awesomeness = awesomeness;
+  }
+
+  hello () {
+    return super.hello () + " and I'm " + (this.awesomeness > 9000 ? "super awesome" : "awesome") + ".";
+  }
+
+  whoAmI ( ) {
+    return "I am a Doge.";
+  }
+
+  static speak () {
+    return "Doges wow.";
+  }
+
+  static explain () {
+    return super.explain () + " dance.";
+  }
+}
+
+var doge = new Doge ("doggoe", true, 10000);
+assert (doge.name === "doggoe");
+doge.rename = "doggo";
+assert (doge.myName === "doggo");
+assert (doge.barks === true);
+assert (doge.awesomeness === 10000);
+assert (doge.hello () === "Hello I am doggo and I can bark and I'm super awesome.");
+assert (doge.whoAmI () === "I am a Doge.");
+assert (doge.breath () === "I am breathing.");
+assert (doge.bark () === "Woof");
+assert (Doge.speak () === "Doges wow.");
+assert (Doge.explain () === "I can walk, jump, dance.");
+assert (doge instanceof Animal);
+assert (doge instanceof Dog);
+assert (doge instanceof Doge);
+assert (Dog.prototype.constructor === Dog)
+assert (Doge.prototype.constructor === Doge)
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-core-10.js b/deps/jerry/tests/jerry/es2015/class-inheritance-core-10.js
new file mode 100644 (file)
index 0000000..957521e
--- /dev/null
@@ -0,0 +1,29 @@
+/* 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.
+ */
+
+ class A extends Array {
+   constructor () {
+     return null;
+   }
+ }
+
+ class B extends A { }
+
+ try {
+   new B;
+   assert (false);
+ } catch (e) {
+   assert (e instanceof TypeError);
+ }
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-core-11.js b/deps/jerry/tests/jerry/es2015/class-inheritance-core-11.js
new file mode 100644 (file)
index 0000000..31c9e9f
--- /dev/null
@@ -0,0 +1,30 @@
+/* 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.
+ */
+
+ class A extends Array {
+   constructor () {
+     assert (false);
+     return null;
+   }
+ }
+
+ class B extends A {
+   constructor () {
+     return { o : 10 };
+   }
+ }
+
+ var b = new B;
+ assert (b.o === 10);
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-core-12.js b/deps/jerry/tests/jerry/es2015/class-inheritance-core-12.js
new file mode 100644 (file)
index 0000000..e35db54
--- /dev/null
@@ -0,0 +1,50 @@
+/* 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.
+ */
+
+ class A extends Array {
+   constructor (a, b, c) {
+     eval ("eval ('super (a, b, c)')");
+     eval ("eval ('this.f = 5;')");
+     assert (this.h ()()() === 5);
+
+     return { o : 4 };
+   }
+
+   g () {
+     return function () {
+       return 5;
+     }
+   }
+ }
+
+ class B extends A {
+   constructor (a, b, c) {
+     eval ("eval ('super (a, b, c)')");
+     assert (this.f === undefined)
+     assert (this.o === 4)
+     this.k = 5;
+     return { o : 7 };
+   }
+
+   h () {
+     return super["g"];
+   }
+ }
+
+ var b = new B (1, 2, 3, 4);
+ assert (b.k === undefined);
+ assert (b.o === 7);
+ assert (b.h === undefined);
+ assert (b.g === undefined);
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-core-13.js b/deps/jerry/tests/jerry/es2015/class-inheritance-core-13.js
new file mode 100644 (file)
index 0000000..e19f286
--- /dev/null
@@ -0,0 +1,32 @@
+/* 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.
+ */
+
+ class C extends Array {
+   constructor (a, b) {
+     var a = eval ('super (arguments);');
+   }
+ }
+
+ class D extends C {
+   constructor () {
+      var a = eval ("eval ('super (1, 2);')");
+      return
+   }
+ }
+
+ var d = new D;
+ assert (JSON.stringify (d) === '[{"0":1,"1":2}]');
+ assert (d + "" === "[object Arguments]");
+ assert (d.length === 1);
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-core-14.js b/deps/jerry/tests/jerry/es2015/class-inheritance-core-14.js
new file mode 100644 (file)
index 0000000..6b8435c
--- /dev/null
@@ -0,0 +1,53 @@
+/* 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.
+ */
+
+class A {
+  constructor () {
+    this.a = 5;
+  }
+
+  f () {
+    return 10;
+  }
+
+  super () {
+    this.super = 10;
+    return 15;
+  }
+}
+
+class B extends A {
+  constructor () {
+    super ();
+    assert (super.f === A.prototype.f);
+    super.f = 8;
+    assert (this.f === 8);
+    assert (super.f === A.prototype.f);
+
+    assert (this.a === 5);
+    super.a = 10;
+    assert (this.a === 10);
+
+    assert (super.super () === 15);
+    assert (this.super === 10);
+    super.super = 20;
+    assert (this.super === 20);
+    assert (super.super () === 15);
+  }
+}
+
+var b = new B;
+assert (b.f === 8);
+assert (b.a === 10);
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-core-15.js b/deps/jerry/tests/jerry/es2015/class-inheritance-core-15.js
new file mode 100644 (file)
index 0000000..859e527
--- /dev/null
@@ -0,0 +1,27 @@
+/* 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.
+ */
+
+ class A extends Array {
+   constructor () {
+     super ();
+     return;
+   }
+ };
+
+ var a = new A;
+ assert (a.length === 0);
+ assert (a instanceof Array);
+ assert (a instanceof A);
+ assert (JSON.stringify (a) === "[]");
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-core-2.js b/deps/jerry/tests/jerry/es2015/class-inheritance-core-2.js
new file mode 100644 (file)
index 0000000..508d675
--- /dev/null
@@ -0,0 +1,38 @@
+/* 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.
+ */
+
+ class C {
+   static a () {
+     return 5;
+   }
+ }
+
+ class D extends C {
+   constructor () {
+     super ();
+   }
+ }
+
+ assert (D.a () === 5);
+
+ C.a = function () {
+   return 6;
+ }
+
+ assert (D.a () === 6);
+
+ C = 5;
+
+ assert (D.a () === 6);
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-core-3.js b/deps/jerry/tests/jerry/es2015/class-inheritance-core-3.js
new file mode 100644 (file)
index 0000000..e1748c3
--- /dev/null
@@ -0,0 +1,27 @@
+/* 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.
+ */
+
+class A extends Array {
+  constructor (a, b, c) {
+    super (a, b);
+    this.f = 5;
+  }
+}
+
+class B extends A { }
+
+var b = new B (1, 2, 3, 4);
+assert (b.f === 5);
+assert (b.length === 2);
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-core-4.js b/deps/jerry/tests/jerry/es2015/class-inheritance-core-4.js
new file mode 100644 (file)
index 0000000..4a00876
--- /dev/null
@@ -0,0 +1,34 @@
+/* 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.
+ */
+
+ class A extends Array {
+   constructor (a, b, c) {
+     super (a, b);
+     this.f = 5;
+   }
+ }
+
+ class B extends A {
+   constructor (a, b, c) {
+     super (a, b);
+     this.g = super.f;
+     this.h = this.f;
+   }
+ }
+
+ var b = new B (1, 2, 3, 4);
+ assert (b.g === undefined);
+ assert (b.h === 5);
+ assert (b.length === 2);
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-core-5.js b/deps/jerry/tests/jerry/es2015/class-inheritance-core-5.js
new file mode 100644 (file)
index 0000000..cd47b6f
--- /dev/null
@@ -0,0 +1,27 @@
+/* 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.
+ */
+
+ class A extends Array {
+   constructor (a, b, c) {
+     eval ("eval ('super (a, b, c)')");
+     eval ("eval ('this.f = 5;')");
+   }
+ }
+
+ class B extends A { }
+
+ var b = new B (1, 2, 3, 4);
+ assert (b.f === 5);
+ assert (b.length === 3);
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-core-6.js b/deps/jerry/tests/jerry/es2015/class-inheritance-core-6.js
new file mode 100644 (file)
index 0000000..30a0f25
--- /dev/null
@@ -0,0 +1,37 @@
+/* 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.
+ */
+
+ class A extends Array {
+   constructor (a, b, c, d, e) {
+     eval ("eval ('super (a, b, c)')");
+     this.a = 6;
+     return new String ("foo");
+   }
+
+   f () {
+     return 5;
+   }
+ }
+
+ class B extends A {
+   constructor (a, b, c, d) {
+    eval ("eval ('super (a, b, c, d)')");
+    assert (super.f () === 5);
+   }
+ }
+
+ var a = new B (1, 2, 3, 4, 5, 6);
+ assert (a.a === undefined);
+ assert (a[0] + a[1] + a[2] === "foo");
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-core-7.js b/deps/jerry/tests/jerry/es2015/class-inheritance-core-7.js
new file mode 100644 (file)
index 0000000..b06188b
--- /dev/null
@@ -0,0 +1,32 @@
+/* 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.
+ */
+
+ class C extends Array {
+   constructor () {
+     var a = eval ('super (1, 2); 5');
+     assert (a === 5);
+   }
+ }
+
+ class D extends C {
+   constructor () {
+      var a = eval ("eval ('super (1, 2); 3')");
+      assert (a === 3);
+   }
+ }
+
+ var d = new D;
+
+ assert (JSON.stringify (d) === "[1,2]");
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-core-8.js b/deps/jerry/tests/jerry/es2015/class-inheritance-core-8.js
new file mode 100644 (file)
index 0000000..25b54cb
--- /dev/null
@@ -0,0 +1,85 @@
+/* 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.
+ */
+
+ var A = Array;
+ var order = 0;
+
+ function f () {
+   order++;
+
+   return function () {
+     return A;
+   }
+ }
+
+ var B = class extends f ()() {
+   constructor () {
+     assert (++order === 2);
+     eval ("eval ('super (1, 2, 3, 4)')");
+     try {
+       super (1, 2, 3, 4, 5)
+       assert (false);
+     } catch (e) {
+       assert (e instanceof ReferenceError)
+     }
+
+     assert (this.g ()()()() === 10);
+     assert (eval ("eval ('this.g ()')()")()() === 10);
+     assert (eval ("eval ('this.g ()')")()()() === 10);
+     assert (eval ("eval ('this.g ()()()')")() === 10);
+     assert (eval ("eval ('this.g')")()()()() === 10);
+     this.push (5);
+     assert (this.length === 5)
+     eval ('this.push (6)');
+     assert (this.length === 6);
+     eval ("eval ('this.push (7)')");
+     this.j = 6;
+     return;
+   }
+ }
+
+ var C = class extends B {
+   g () {
+     return function () {
+       return () => {
+         return 10;
+       }
+     }
+   }
+ }
+
+ var D = class D extends C {
+    constructor () {
+      super ();
+      this.k = 5;
+      return
+    }
+
+    g () {
+      return eval ('super["g"]');
+    }
+ }
+
+ assert (order === 1);
+
+ var d = new D;
+ assert (d.length === 7);
+ assert (d.k === 5);
+ assert (d.j === 6);
+ assert (d instanceof D);
+ assert (d instanceof C);
+ assert (d instanceof B);
+ assert (d instanceof f ()());
+ assert (JSON.stringify (d) === "[1,2,3,4,5,6,7]");
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-core-9.js b/deps/jerry/tests/jerry/es2015/class-inheritance-core-9.js
new file mode 100644 (file)
index 0000000..53f97a2
--- /dev/null
@@ -0,0 +1,29 @@
+/* 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.
+ */
+
+ var order = 0;
+
+ try {
+   var A = class extends null {
+     constructor () {
+       order++;
+     }
+   }
+
+   new A;
+ } catch (e) {
+   assert (order === 1);
+   assert (e instanceof ReferenceError);
+ }
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-early-semantics.js b/deps/jerry/tests/jerry/es2015/class-inheritance-early-semantics.js
new file mode 100644 (file)
index 0000000..68b8622
--- /dev/null
@@ -0,0 +1,133 @@
+/* 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.
+ */
+
+function must_throw (str) {
+  try {
+    eval ("switch (1) { default: " + str + "}");
+    assert (false);
+  } catch (e) { }
+
+  try {
+    eval (str);
+    assert (false);
+  }
+  catch (e) { }
+
+  try {
+    eval ("'use strict'; switch (1) { default: " + str + "}");
+    assert (false);
+  } catch (e) { }
+
+  try {
+    eval ("'use strict'; " + str);
+    assert (false);
+  } catch (e) { }
+}
+
+class A {
+  constructor (a) {
+    this.a = a;
+  }
+
+  f () {
+    return 5;
+  }
+}
+
+must_throw ("class B extends 5 + 6 + 5 { constructor (a, b) { super (a) } }");
+
+must_throw ("class B extends null { constructor () { super () } }; new B");
+
+must_throw ("var o = { a : 5 }; \
+             class B extends Object.keys (o)[0] { constructor (a, b) { super (a) } } \
+             var b = new B (1, 2);");
+
+must_throw ("class B extends A { constructor (a, b) { this.b = b} } \
+             var b = new B (1, 2);");
+
+must_throw ("class B extends A { constructor (a, b) { super.f () } } \
+             var b = new B (1, 2);");
+
+must_throw ("class B extends A { constructor (a, b) { eval ('this.b = b') } } \
+             var b = new B (1, 2);");
+
+must_throw ("class B extends A { constructor (a, b) { eval ('super.f ()') } } \
+             var b = new B (1, 2);");
+
+must_throw ("class B extends A { constructor (a, b) { super (a); super (a); } } \
+             var b = new B (1, 2);");
+
+must_throw ("class B extends A { constructor (a, b) { eval ('super (a)'); eval ('super (a)'); } } \
+             var b = new B (1, 2);");
+
+must_throw ("class B extends A { constructor (a, b) { super (a) } g () { super (a) } } \
+             var b = new B (1, 2);");
+
+must_throw ("class B extends A { constructor (a, b) { super (a) } g () { eval ('super (a)') } } \
+             var b = new B (1, 2); \
+             b.g ();");
+
+must_throw ("class B extends A { constructor (a, b) { super (a) } g () { return function () { return super.f () } } } \
+             var b = new B (1, 2); \
+             b.g ()();");
+
+must_throw ("class B extends A { constructor (a, b) { super (a) } \
+                                 g () { return function () { return eval ('super.f ()') } } } \
+             var b = new B (1, 2); \
+             b.g ()();");
+
+must_throw ("class B extends A { constructor (a, b) { super (a) } \
+                                 g () { return function () { return eval (\"eval ('super.f ();')\") } } } \
+             var b = new B (1, 2); \
+             b.g ()();");
+
+must_throw ("class A extends Array { constructor () { return 5; } }; new A");
+
+must_throw ("class A extends Array { constructor () { return undefined; } }; new A");
+
+must_throw ("class B extends undefined { }; new B;");
+
+must_throw ("var A = class extends Array { . }");
+
+must_throw ("class Array extends Array { }");
+
+must_throw ("class A extends A { }");
+
+must_throw ("class A extends { constructor () { super () } }");
+
+class B extends A {
+  constructor (a, b) {
+    super (a);
+    assert (super.f () === 5);
+  }
+
+  g () {
+    return () => {
+      return super.f ();
+    }
+  }
+
+  h () {
+    return () => {
+      return () => {
+        return eval ('super.f ()');
+      }
+    }
+  }
+}
+
+var b = new B (1, 2);
+assert (b.g ()() === 5);
+assert (b.h ()()() === 5);
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-mixins-1.js b/deps/jerry/tests/jerry/es2015/class-inheritance-mixins-1.js
new file mode 100644 (file)
index 0000000..2f75bd4
--- /dev/null
@@ -0,0 +1,38 @@
+/* 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.
+ */
+
+var calculatorMixin = Base => class extends Base {
+  f () {
+    return 1;
+  }
+};
+
+var randomizerMixin = Base => class extends Base {
+  g () {
+    return 2;
+  }
+};
+
+class A {
+  constructor () { }
+}
+
+class B extends calculatorMixin (randomizerMixin (A)) {
+
+}
+
+var b = new B ();
+assert (b.f () === 1)
+assert (b.g () === 2);
diff --git a/deps/jerry/tests/jerry/es2015/class-inheritance-mixins-2.js b/deps/jerry/tests/jerry/es2015/class-inheritance-mixins-2.js
new file mode 100644 (file)
index 0000000..ae9a68f
--- /dev/null
@@ -0,0 +1,50 @@
+/* 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.
+ */
+
+ order = 0;
+
+ var Mixin1 = (superclass) => class extends superclass {
+   foo () {
+     assert (order++ == 1)
+     if (super.foo) {
+       super.foo ();
+     }
+   }
+ };
+
+ var Mixin2 = (superclass) => class extends superclass {
+   foo () {
+     assert (order++ == 2)
+     if (super.foo) {
+       assert (super.foo () === 5);
+     }
+   }
+ };
+
+ class S {
+   foo () {
+     assert (order++ == 3)
+     return 5;
+   }
+ }
+
+ class C extends Mixin1 (Mixin2 (S)) {
+   foo () {
+     assert (order++ == 0)
+     super.foo ();
+   }
+ }
+
+ new C ().foo ()
diff --git a/deps/jerry/tests/jerry/es2015/class.js b/deps/jerry/tests/jerry/es2015/class.js
new file mode 100644 (file)
index 0000000..066b2e7
--- /dev/null
@@ -0,0 +1,199 @@
+/* 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.
+ */
+
+function must_throw(str) {
+  try {
+    eval("switch (1) { default: " + str + "}");
+    assert(false);
+  } catch (e) {
+  }
+
+  try {
+    eval(str);
+    assert(false);
+  }
+  catch (e) {
+  }
+
+  must_throw_strict(str);
+}
+
+function must_throw_strict(str) {
+  try {
+    eval ("'use strict'; switch (1) { default: " + str + "}");
+    assert (false);
+  } catch (e) {
+  }
+
+  try {
+    eval("'use strict'; " + str);
+    assert(false);
+  } catch (e) {
+  }
+}
+
+must_throw("class {}");
+must_throw("class class {}");
+must_throw("class A { constructor() {} this.a = 5 }");
+must_throw("class A { constructor() {} constructor() {} }");
+must_throw("class A { static prototype() {} }");
+must_throw("class A { get constructor() {} }");
+must_throw("class A { set constructor() {} }");
+must_throw("class A {}; A()");
+must_throw("class X {}; var o = {}; Object.defineProperty(o, 'p', { get: X, set: X }); o.p;");
+must_throw("var a = new A; class A {};");
+must_throw("class A { g\\u0065t e() {} }");
+must_throw('class A { "static" e() {} }');
+
+assert(eval("class A {}") === undefined);
+assert(eval("var a = class A {}") === undefined);
+assert(eval("var a = class {}") === undefined);
+assert(eval("class A { ; ; ; ;;;;;;;;;;;; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;; }") === undefined);
+assert(eval('class A {"constructor"() {} }') === undefined);
+assert(isNaN (eval('switch(1) { default: (class A{} % 1) }')));
+
+class B {
+}
+
+var b = new B;
+assert(typeof B  === "function");
+assert(typeof b === "object");
+
+class C {
+  c1() {
+    return 5;
+  }
+
+  c2() {
+    return this._c;
+  }
+  3() {
+    return 3;
+  }
+}
+
+var c = new C;
+assert (c.c1() === 5);
+assert (c.c2() === undefined);
+assert (c["3"]() === 3);
+
+class D {
+  constructor(d) {
+    this._d = d;
+  }
+
+  d1() {
+    return this._d;
+  }
+}
+var d = new D(5);
+assert(d.d1() === 5);
+
+class E {
+  constructor(e) {
+    this._e = e;
+  }
+
+  get e() {
+    return this._e;
+  }
+
+  set e(e) {
+    this._e = e;
+  }
+}
+var e = new E (5);
+assert (e.e === 5);
+e.e = 10;
+assert (e.e === 10);
+
+var F = class ClassF {
+  constructor(f) {
+    this._f = f;
+  }
+
+  static f1() {
+    return this;
+  }
+
+  static f2() {
+    return this._f;
+  }
+
+  static f3(a, b) {
+    return a + b;
+  }
+
+  static constructor(a) {
+    return a;
+  }
+
+  static static(a) {
+    return a;
+  }
+
+  static 2 (a) {
+    return 2 * a;
+  }
+}
+
+var f = new F(5);
+
+assert (f.f1 === undefined);
+assert (f.f2 === undefined);
+assert (F.f1() === F);
+assert (F.f2() === undefined);
+assert (F.f3(1, 1) === 2);
+assert (F.constructor(5) === 5);
+assert (F.static(5) === 5);
+assert (F["2"](5) === 10);
+
+var G = class {
+  static set a(a) {
+    this._a = a;
+  }
+  static get a() {
+    return this._a;
+  }
+  static set 1(a) {
+    this._a = a;
+  }
+  static get 1() {
+    return this._a;
+  }
+
+  static set constructor(a) {
+    this._a = a;
+  }
+  static get constructor() {
+    return this._a;
+  }
+
+  static g1() {
+    return 5;
+  }
+
+  static g1() {
+    return 10;
+  }
+}
+
+G.a = 10;
+assert (G.a === 10);
+assert (G.g1() === 10);
+G["1"] = 20;
+assert (G["1"] === 20);
+G.constructor = 30;
+assert (G.constructor === 30);
diff --git a/deps/jerry/tests/jerry/es2015/function-param-init.js b/deps/jerry/tests/jerry/es2015/function-param-init.js
new file mode 100644 (file)
index 0000000..37d7886
--- /dev/null
@@ -0,0 +1,81 @@
+// 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.
+
+var local = 0;
+
+switch(0) { /* This switch forces a pre-scanner run. */
+default:
+
+  function f(a = (5, local = 6),
+             b = ((5 + function(a = 6) { return a }() * 3)),
+             c,
+             d = true ? 1 : 2)
+  {
+    return "" + a + ", " + b + ", " + c + ", " + d;
+  }
+
+  assert(f() === "6, 23, undefined, 1");
+  assert(local === 6);
+
+  var obj = {
+    f: function(a = [10,,20],
+                b,
+                c = Math.cos(0),
+                d)
+    {
+      return "" + a + ", " + b + ", " + c + ", " + d;
+    }
+  };
+
+  assert(obj.f() === "10,,20, undefined, 1, undefined");
+
+  function g(a, b = (local = 7)) { }
+
+  local = 0;
+  g();
+  assert(local === 7);
+
+  local = 0;
+  g(0);
+  assert(local === 7);
+
+  local = 0;
+  g(0, undefined);
+  assert(local === 7);
+
+  local = 0;
+  g(0, null);
+  assert(local === 0);
+
+  local = 0;
+  g(0, false);
+  assert(local === 0);
+  break;
+}
+
+function CheckSyntaxError(str)
+{
+  try {
+    eval(str);
+    assert(false);
+  } catch (e) {
+    assert(e instanceof SyntaxError);
+  }
+}
+
+CheckSyntaxError('function x(a += 5) {}');
+CheckSyntaxError('function x(a =, b) {}');
+CheckSyntaxError('function x(a = (b) {}');
+CheckSyntaxError('function x(a, a = 5) {}');
+CheckSyntaxError('function x(a = 5, a) {}');
diff --git a/deps/jerry/tests/jerry/es2015/map.js b/deps/jerry/tests/jerry/es2015/map.js
new file mode 100644 (file)
index 0000000..05ac0b8
--- /dev/null
@@ -0,0 +1,74 @@
+/* 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.
+ */
+
+var m = new Map();
+assert(m.size == 0);
+assert(m.set(1, 1) === m);
+assert(m.has(1));
+assert(m.size == 1);
+
+assert(m.set(undefined, 123) === m);
+assert(m.size == 2);
+assert(m.has(undefined));
+assert(m.get(undefined) === 123);
+
+assert(m.set(null, 456) === m);
+assert(m.size == 3);
+assert(m.has(null));
+assert(m.get(null) === 456);
+
+assert(m.set("strItem", { x:789 }) === m);
+assert(m.size == 4);
+assert(m.has("str" + "Item"));
+assert(m.get("st" + "rItem").x === 789);
+
+assert(m.set(12.25, 12.25) === m);
+assert(m.size == 5);
+assert(m.has(12 + (function() { return 0.25 })()));
+assert(m.get(13 - (function() { return 0.75 })()) === 12.25);
+
+assert(m.delete(1))
+assert(m.size == 4);
+assert(!m.has(1));
+assert(m.get(1) === undefined);
+
+assert(!m.delete(2));
+
+assert(m.delete(12 + (function() { return 0.25 })()));
+assert(m.size == 3);
+assert(!m.has(12.25));
+assert(m.get(12.25) === undefined);
+
+assert(m.delete("strI" + "tem"))
+assert(m.delete(undefined))
+assert(m.size == 1);
+
+assert(m.delete(null))
+assert(m.size == 0);
+
+m.set(1,1)
+m.set(2,2)
+m.set(3,3)
+m.set(1,7)
+m.set(1,8)
+m.set(2,7)
+m.set(2,8)
+m.set(3,7)
+m.set(3,8)
+
+assert(m.size == 3);
+assert(m.get(1) === 8);
+assert(m.get(2) === 8);
+assert(m.get(3) === 8);
diff --git a/deps/jerry/tests/jerry/es2015/object-computed-prescanner.js b/deps/jerry/tests/jerry/es2015/object-computed-prescanner.js
new file mode 100644 (file)
index 0000000..4b315d6
--- /dev/null
@@ -0,0 +1,52 @@
+// 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.
+
+function member_str() {
+  return "member";
+}
+
+switch (true) {
+default:
+  var obj = {
+    ["val" + "ue"]: 0,
+    set[member_str()](x) {
+      // Multiple statements.
+      this.value = x + 4;
+      this.value += 2;
+    },
+    get[member_str() ? member_str() : ""]() {
+      // Multiple statements.
+      this.value = this.value + 1;
+      return this.value;
+    },
+    get
+      [1 + 2]
+      ()
+    {
+      return 3;
+    },
+    [false ? member_str()
+           : ""]
+     :8
+  }
+}
+
+obj["member"] = 10;
+assert(obj.member === 17);
+assert(obj.member === 18);
+
+assert(obj[3] === 3);
+assert(obj["3"] === 3);
+
+assert(obj[""] === 8);
diff --git a/deps/jerry/tests/jerry/es2015/object-computed.js b/deps/jerry/tests/jerry/es2015/object-computed.js
new file mode 100644 (file)
index 0000000..1371a9d
--- /dev/null
@@ -0,0 +1,139 @@
+// 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.
+
+/* Test object literals. */
+
+var local = 0;
+
+function f(x)
+{
+  return x + "et";
+}
+
+var o = {
+  a: 5,
+  [
+    "pr" +
+    "op"]  : 6,
+
+  [f
+   ("g")
+   ]
+   : 7,
+
+  [f(
+   "s"
+   )  ]: 8,
+
+  get    [f
+    ("res")
+    ]
+    () { return 9 },
+
+  set
+  [f("res")](
+   value) { local = value },
+};
+
+assert(o.a === 5);
+assert(o.prop === 6);
+assert(o.get === 7);
+assert(o.set === 8);
+
+local = 0;
+o.reset = 10;
+assert(local === 10);
+assert(o.reset === 9);
+
+/* Test classes. */
+
+function fxy() {
+  return "xy";
+}
+
+class C {
+  [fxy()] () {
+    return 6;
+  }
+
+  static [fxy()]() {
+    return 7;
+  }
+
+  get ["a" + 1]() {
+    return 8;
+  }
+
+  set ["a" + 1](x) {
+    local = x;
+  }
+
+  static get ["a" + 1]() {
+    return 10;
+  }
+
+  static set ["a" + 1](x) {
+    local = x;
+  }
+};
+
+var c = new C;
+assert(c.xy() === 6);
+assert(C.xy() === 7);
+
+local = 0;
+c.a1 = 9;
+assert(local === 9);
+assert(c.a1 === 8);
+
+local = 0;
+C.a1 = 11;
+assert(local === 11);
+assert(C.a1 === 10);
+
+class D {
+  [(() => "const" + "ructor")()] (arg) {
+    this.a = arg;
+  }
+}
+
+var d = new D;
+assert(d.a === undefined);
+d.constructor(7);
+assert(d.a === 7);
+
+class E {
+  get ["_constructor_".substring(1,12)]() {
+    return this.a;
+  }
+}
+
+var e = new E;
+assert(e.constructor === undefined);
+e.a = 8;
+assert(e.constructor === 8);
+
+function throw_error(snippet)
+{
+  try {
+    eval(snippet);
+    assert(false);
+  } catch (e) {
+    assert(e instanceof TypeError);
+  }
+}
+
+throw_error("new class { static ['proto' + 'type'] () {} }");
+throw_error("new class { static get ['proto' + 'type'] () {} }");
+throw_error("new class { static set ['proto' + 'type'] (x) {} }");
diff --git a/deps/jerry/tests/jerry/es2015/object-initializer.js b/deps/jerry/tests/jerry/es2015/object-initializer.js
new file mode 100644 (file)
index 0000000..26a7c38
--- /dev/null
@@ -0,0 +1,65 @@
+// 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.
+
+switch (1) {
+default:
+  var o = {
+    value: 10,
+    func() {
+      return 234 + this.value;
+    },
+    ["a" + "b"]() {
+      return 456 - this.value;
+    }
+  }
+}
+
+assert(o.func() === 244);
+assert(o.ab() === 446);
+
+switch (1) {
+default:
+  var ab = 5;
+  var cd = 6;
+  o = {
+    ab,
+    cd: 8,
+    cd
+  }
+}
+
+assert(o.ab === 5);
+assert(o.cd === 6);
+
+function exception_expected(str) {
+  try {
+    eval(str);
+    assert(false);
+  } catch (e) {
+    assert(e instanceof SyntaxError);
+  }
+}
+
+// These forms are invalid.
+exception_expected('({ true })');
+exception_expected('({ 13 })');
+exception_expected('({ "x" })');
+
+switch (1) {
+default:
+  // These forms are valid.
+  ({ true: true });
+  ({ 13: 13 });
+  ({ "x": "x" });
+}
diff --git a/deps/jerry/tests/jerry/es2015/regression-test-issue-2414.js b/deps/jerry/tests/jerry/es2015/regression-test-issue-2414.js
new file mode 100644 (file)
index 0000000..75be3e6
--- /dev/null
@@ -0,0 +1,26 @@
+// 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.
+
+try {
+  // By default bound functions always support new operator.
+  // However, arrow functions must throw an error even in this case.
+
+  var f = (() => 1).bind();
+
+  new f;
+
+  assert(false);
+} catch (e) {
+  assert(e instanceof TypeError);
+}
diff --git a/deps/jerry/tests/jerry/es2015/regression-test-issue-2435.js b/deps/jerry/tests/jerry/es2015/regression-test-issue-2435.js
new file mode 100644 (file)
index 0000000..0f70cca
--- /dev/null
@@ -0,0 +1,15 @@
+// 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.
+
+(new Int8Array(0)).filter(parseInt)
diff --git a/deps/jerry/tests/jerry/es2015/regression-test-issue-2465.js b/deps/jerry/tests/jerry/es2015/regression-test-issue-2465.js
new file mode 100644 (file)
index 0000000..c8a4539
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+var a = eval("Object.prototype[1] = 0;\
+              Promise.all()")
+a.catch(function(err) {
+  assert(err instanceof TypeError);
+});
diff --git a/deps/jerry/tests/jerry/es2015/regression-test-issue-2468.js b/deps/jerry/tests/jerry/es2015/regression-test-issue-2468.js
new file mode 100644 (file)
index 0000000..c1db62a
--- /dev/null
@@ -0,0 +1,16 @@
+// 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.
+
+Object.prototype[1] = 0;
+Promise.race([]);
diff --git a/deps/jerry/tests/jerry/es2015/regression-test-issue-2486.js b/deps/jerry/tests/jerry/es2015/regression-test-issue-2486.js
new file mode 100644 (file)
index 0000000..295aae9
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright JS Foundation and other contributors, http://js.foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+Object.setPrototypeOf(Math, Int32Array);
+for (var i = 0; i < 200; i++) { 
+    Promise.race([, [,] % {}]).then(); 
+}
diff --git a/deps/jerry/tests/jerry/es2015/regression-test-issue-2487.js b/deps/jerry/tests/jerry/es2015/regression-test-issue-2487.js
new file mode 100644 (file)
index 0000000..54ea854
--- /dev/null
@@ -0,0 +1,16 @@
+// 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.
+
+Object.defineProperty(Array.prototype, 0, {set: function() {var $ = $()}});
+Promise.all([0]);
diff --git a/deps/jerry/tests/jerry/es2015/regression-test-issue-2488.js b/deps/jerry/tests/jerry/es2015/regression-test-issue-2488.js
new file mode 100644 (file)
index 0000000..605d5bf
--- /dev/null
@@ -0,0 +1,16 @@
+// 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.
+
+Object.defineProperty(Array.prototype, 0, {set: function() {throw "MyError"}});
+Promise.all([0]);
diff --git a/deps/jerry/tests/jerry/es2015/regression-test-issue-2489-original.js b/deps/jerry/tests/jerry/es2015/regression-test-issue-2489-original.js
new file mode 100644 (file)
index 0000000..50308bc
--- /dev/null
@@ -0,0 +1,17 @@
+// 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.
+
+// This test case should not throw an error anymore.
+Object.defineProperty(Object.prototype, 0, {'get': function() { throw $ }});
+Promise.all();
diff --git a/deps/jerry/tests/jerry/es2015/regression-test-issue-2490.js b/deps/jerry/tests/jerry/es2015/regression-test-issue-2490.js
new file mode 100644 (file)
index 0000000..6f48b70
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright JS Foundation and other contributors, http://js.foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Original issue
+Object.defineProperty(Object.prototype, 6, {});
+Promise.all([0]);
+
+// Variant 2
+Object.defineProperty(Object.prototype, 2, {});
+Promise.all([0]);
+
+// Variant 3
+Object.defineProperty(Object.prototype, 3, {});
+Promise.all([0]);
+
+// Variant 4
+Object.defineProperty(Object.prototype, 4, {});
+Promise.all([0]);
+
+// Variant 5
+Object.defineProperty(Object.prototype, 5, {});
+Promise.all([0]);
+
+// Variant 7
+Object.defineProperty(Object.prototype, 7, {});
+Promise.all([0]);
+
+// Variant 8
+Object.defineProperty(Object.prototype, 8, {});
+Promise.all([0]);
diff --git a/deps/jerry/tests/jerry/es2015/regression-test-issue-2528.js b/deps/jerry/tests/jerry/es2015/regression-test-issue-2528.js
new file mode 100644 (file)
index 0000000..4e8f6ec
--- /dev/null
@@ -0,0 +1,15 @@
+// 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.
+
+for (/a/ in a => { }, a => { }, a => { }) throw 1
diff --git a/deps/jerry/tests/jerry/es2015/regression-test-issue-2587.js b/deps/jerry/tests/jerry/es2015/regression-test-issue-2587.js
new file mode 100644 (file)
index 0000000..d1f7e4c
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+function f(a,b,c) {
+  var args = Array.prototype.slice.call(arguments, 3);
+  assert (typeof args.splice === "function");
+}
+f();
diff --git a/deps/jerry/tests/jerry/es2015/regression-test-issue-2602.js b/deps/jerry/tests/jerry/es2015/regression-test-issue-2602.js
new file mode 100644 (file)
index 0000000..ebdcd27
--- /dev/null
@@ -0,0 +1,16 @@
+// 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.
+
+Object.defineProperty ( Array.prototype , 0 , { set : function ( ) { throw "MyError" } } ) ;
+Promise.all ( [ "2015-01-01" ] ) ;
diff --git a/deps/jerry/tests/jerry/es2015/regression-test-issue-2603.js b/deps/jerry/tests/jerry/es2015/regression-test-issue-2603.js
new file mode 100644 (file)
index 0000000..0932839
--- /dev/null
@@ -0,0 +1,17 @@
+// 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.
+
+
+Object.defineProperty( Array.prototype, 0, { set : function ( ) { throw "MyError" } } );
+Promise.all( [ .86456 ] ) ;
diff --git a/deps/jerry/tests/jerry/es2015/typedArray-fill.js b/deps/jerry/tests/jerry/es2015/typedArray-fill.js
new file mode 100644 (file)
index 0000000..01288d1
--- /dev/null
@@ -0,0 +1,105 @@
+/* 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.
+ */
+
+var a = new Int32Array([1, 2, 3, 4, 5]);
+assert(a.fill(0).toString() === '0,0,0,0,0');
+assert(a.toString() === '0,0,0,0,0');
+assert(a.fill(1, 3).toString() === '0,0,0,1,1');
+assert(a.toString() === '0,0,0,1,1');
+assert(a.fill(2, 1, 3).toString() === '0,2,2,1,1');
+assert(a.toString() === '0,2,2,1,1');
+assert(a.fill(3, -3).toString() === '0,2,3,3,3');
+assert(a.toString() === '0,2,3,3,3');
+assert(a.fill(4, -3, -1).toString() === '0,2,4,4,3');
+assert(a.toString() === '0,2,4,4,3');
+assert(a.fill(5, 3, 2).toString() === '0,2,4,4,3');
+assert(a.toString() === '0,2,4,4,3');
+assert(a.fill(6, -2, -3).toString() === '0,2,4,4,3');
+assert(a.toString() === '0,2,4,4,3');
+assert(a.fill(7, 4, 1).toString() === '0,2,4,4,3');
+assert(a.toString() === '0,2,4,4,3');
+assert(a.fill(8, -1, -4).toString() === '0,2,4,4,3');
+assert(a.toString() === '0,2,4,4,3');
+assert(a.fill(9, 1).fill(10, 1).toString() === '0,10,10,10,10');
+assert(a.toString() === '0,10,10,10,10');
+assert(a.fill(11, 0, 4).fill(12, 1, 2).toString() === '11,12,11,11,10');
+assert(a.toString() === '11,12,11,11,10');
+assert(a.fill(13, 999, 1000).fill(14, -1000, -999).toString() === '11,12,11,11,10');
+assert(a.toString() === '11,12,11,11,10');
+assert(a.fill(14, 0, 0).toString() === '11,12,11,11,10');
+assert(a.toString() === '11,12,11,11,10');
+assert(a.fill(15, a.length, a.length).toString() === '11,12,11,11,10');
+assert(a.toString() === '11,12,11,11,10');
+assert(a.fill(NaN).toString() === '0,0,0,0,0'); // NaN gets coerced into an integer.
+assert(a.toString() === '0,0,0,0,0');
+assert(a.fill({ valueOf: () => 16 }).toString() === '16,16,16,16,16');
+assert(a.toString() === '16,16,16,16,16');
+
+var b = new Uint8Array();
+assert(b.fill(1).toString() === '');
+assert(b.toString() === '');
+assert(b.fill(2, 0, 0).toString() === '');
+assert(b.toString() === '');
+assert(b.fill(3, b.length, b.length).toString() === '');
+assert(b.toString() === '');
+
+var c = new Uint8Array([0]);
+assert(c.fill(256).toString() === '0');
+assert(c.toString() === '0');
+assert(c.fill(257).toString() === '1');
+assert(c.toString() === '1');
+
+try {
+  c.fill({});
+} catch (e) {
+  assert(e instanceof TypeError);
+  assert(c.toString() === '1');
+}
+
+var d = new Float32Array([0]);
+assert(d.fill(NaN).toString() === 'NaN');
+assert(d.toString() === 'NaN');
+
+var ab = new ArrayBuffer(4);
+var e = new Uint8Array(ab);
+assert(e.fill(0).toString() === '0,0,0,0');
+
+var f = new Uint32Array(ab);
+assert(f.fill(1).toString() === '1');
+assert(e.toString() === '1,0,0,0');
+
+var g = new Uint8Array(ab, 1, 2);
+assert(g.toString() === '0,0');
+assert(g.fill(2).toString() === '2,2');
+assert(e.toString() === '1,2,2,0');
+assert(g.fill(3, -1).toString() === '2,3');
+assert(e.toString() === '1,2,3,0');
+assert(g.fill(4, 0, 2).toString() === '4,4');
+assert(e.toString() === '1,4,4,0');
+assert(g.fill(5, 0, 999).toString() === '5,5');
+assert(e.toString() === '1,5,5,0');
+assert(g.fill(6, -999, 999).toString() === '6,6');
+assert(e.toString() === '1,6,6,0');
+assert(g.fill(7, -999, 0).toString() === '6,6');
+assert(e.toString() === '1,6,6,0');
+
+var ab2 = new ArrayBuffer(4);
+var h = new Uint8Array(ab2);
+var i = new Uint16Array(ab2, 0, 1);
+assert(i.fill(1).toString() === '1');
+assert(h.toString() === '1,0,0,0');
+var j = new Uint16Array(ab2, 2, 1);
+assert(j.fill(1).toString() === '1');
+assert(h.toString() === '1,0,1,0');
diff --git a/deps/jerry/tests/jerry/es2015/typedArray-find.js b/deps/jerry/tests/jerry/es2015/typedArray-find.js
new file mode 100644 (file)
index 0000000..5cf059d
--- /dev/null
@@ -0,0 +1,116 @@
+// 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.
+
+var arrow_is_available = false;
+
+try {
+  assert (eval ("(f => 5) ()") === 5);
+  arrow_is_available = true;
+} catch (e) {
+  assert (e instanceof SyntaxError);
+}
+
+var typedArrayTypes = [Int8Array,
+                       Uint8Array,
+                       Uint8ClampedArray,
+                       Int16Array,
+                       Uint16Array,
+                       Int32Array,
+                       Uint32Array,
+                       Float32Array,
+                       Float64Array];
+
+
+typedArrayTypes.forEach (function (TypedArray) {
+
+  var array1 = new TypedArray ([5, 12, 0, 8, 120, 44]);
+
+  function bigger_than_10 (element) {
+    return element > 10;
+  }
+
+  assert (array1.find (bigger_than_10) === 12);
+
+  function less_than_0 (element) {
+    if (element == 0) {
+      throw new Error ("zero");
+    }
+    return element < 0;
+  }
+
+  try {
+    array1.find (less_than_0);
+    assert (false);
+  } catch (e) {
+    assert (e instanceof Error);
+    assert (e.message === "zero");
+  }
+
+  if (arrow_is_available) {
+      assert (eval ("array1.find (e => e > 100)") === 120);
+  }
+
+  /* Test the callback function arguments */
+  var src_array = new TypedArray ([4, 6, 8, 12]);
+  var array_index = 0;
+
+  function isPrime (element, index, array) {
+    assert (array_index++ === index);
+    assert (array === src_array)
+    assert (element === array[index]);
+
+    var start = 2;
+    while (start <= Math.sqrt (element)) {
+      if (element % start++ < 1) {
+        return false;
+      }
+    }
+    return element > 1;
+  }
+
+  assert (src_array.find (isPrime) === undefined);
+
+  src_array = new TypedArray ([4, 5, 8, 12]);
+  array_index = 0;
+  assert (src_array.find (isPrime) === 5);
+
+  // Checking behavior when the given object is not %TypedArray%
+  try {
+    TypedArray.prototype.find.call (5);
+    assert (false);
+  } catch (e) {
+    assert (e instanceof TypeError);
+  }
+
+  // Checking behavior when the first argument is not a callback
+  var array = new TypedArray ([1, 2, 3]);
+
+  try {
+    array.find (5);
+    assert (false);
+  } catch (e) {
+    assert (e instanceof TypeError);
+  }
+
+  // Checking behavior when the first argument is not exists
+  try {
+    array.find ();
+    assert (false);
+  } catch (e) {
+    assert (e instanceof TypeError);
+  }
+
+  // Checking behavior when the there are more than 2 arguments
+  assert (array.find (function (e) { return e < 2 }, {}, 8, 4, 5, 6, 6) === 1);
+})
diff --git a/deps/jerry/tests/jerry/es2015/typedArray-join.js b/deps/jerry/tests/jerry/es2015/typedArray-join.js
new file mode 100644 (file)
index 0000000..ce53a35
--- /dev/null
@@ -0,0 +1,24 @@
+/* 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.
+ */
+
+var float_array = new Float32Array([1.125, 5.5, -1.25, -0.0]);
+var int_array = new Int8Array([3, 2, 1, 100, -30]);
+var uint_array = new Uint8Array([3, 2, 1, 100, -30]);
+var empty_array = new Uint32Array();
+
+assert(float_array.join() === float_array.toString());
+assert(int_array.join('-') === "3-2-1-100--30");
+assert(uint_array.join('=') === "3=2=1=100=226");
+assert(empty_array.join('_') === "");
diff --git a/deps/jerry/tests/jerry/es2015/typedArray-set-with-typedArray.js b/deps/jerry/tests/jerry/es2015/typedArray-set-with-typedArray.js
new file mode 100644 (file)
index 0000000..2697a8b
--- /dev/null
@@ -0,0 +1,94 @@
+/* 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.
+ */
+
+var a = new Int32Array([1, 2, 3, 4, 5]);
+var b = new Int32Array(5);
+
+try {
+  a.set(b, 123456);
+  assert(1 === 0); // Should not get here.
+} catch (e) {
+  assert(e instanceof RangeError);
+}
+
+b.set(a);
+assert(b.join() === '1,2,3,4,5');
+try {
+  b.set(a, 1);
+  assert(1 === 0); // Should not get here.
+} catch (e) {
+  assert(e instanceof RangeError);
+}
+
+b.set(new Int32Array([99, 98]), 2);
+assert(b.join() === '1,2,99,98,5');
+
+b.set(new Int32Array([99, 98, 97]), 2);
+assert(b.join() === '1,2,99,98,97');
+
+try {
+  b.set(new Int32Array([99, 98, 97, 96]), 2);
+  assert(1 === 0); // Should not get here.
+} catch (e) {
+  assert(e instanceof RangeError);
+}
+
+try {
+  b.set([101, 102, 103, 104], 4);
+  assert(1 === 0); // Should not get here.
+} catch (e) {
+  assert(e instanceof RangeError);
+}
+
+//  ab = [ 0, 1, 2, 3, 4, 5, 6, 7 ]
+//  a1 = [ ^, ^, ^, ^, ^, ^, ^, ^ ]
+//  a2 =             [ ^, ^, ^, ^ ]
+var ab = new ArrayBuffer(8);
+var a1 = new Uint8Array(ab);
+for (var i = 0; i < a1.length; i += 1) {
+  a1.set([i], i);
+}
+
+var a2 = new Uint8Array(ab, 4);
+a1.set(a2, 2);
+assert(a1.join() === '0,1,4,5,6,7,6,7');
+assert(a2.join() === '6,7,6,7');
+
+var a3 = new Uint32Array(ab, 4);
+a1.set(a3, 2);
+assert(a1.join() === '0,1,6,5,6,7,6,7');
+assert(a3.join() === '117835526');
+
+var a4 = new Uint8Array(ab, 0, 4);
+a1.set(a4, 2);
+assert(a1.join() === '0,1,0,1,6,5,6,7');
+assert(a4.join() === '0,1,0,1');
+
+var a5 = new Uint32Array(ab, 4, 1);
+a1.set(a5, 2);
+assert(a1.join() === '0,1,6,1,6,5,6,7');
+assert(a5.join() === '117835014');
+
+var c = new Int32Array([0xFFFFFFFF]);
+var d = new Uint8Array(4);
+d.set(c);
+assert(d.join() === '255,0,0,0');
+
+var e = new Float32Array([3.33]);
+var f = new Uint8Array(1);
+f.set(e);
+assert(f.join() === '3');
+e.set(f);
+assert(e.join() === '3');
diff --git a/deps/jerry/tests/jerry/es2015/typedArray-sort.js b/deps/jerry/tests/jerry/es2015/typedArray-sort.js
new file mode 100644 (file)
index 0000000..82ccac1
--- /dev/null
@@ -0,0 +1,74 @@
+/* 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.
+ */
+
+// Default sorting behavior.
+var a = Uint8Array.from([4, 1, 3, 5, 4, 2]);
+assert(a.sort().toString() === '1,2,3,4,4,5');
+assert(a.toString() === '1,2,3,4,4,5');
+
+// Views into typedarrays should be properly sorted.
+var b = Uint8Array.from([2, 1, 4, 3, 0]);
+assert(b.subarray(2, 4).sort().toString() === '3,4');
+assert(b.toString() === '2,1,3,4,0');
+
+// Empty typedarrays should be able to be "sorted".
+var c = Uint8Array.from([]);
+assert(c.sort().toString() === '');
+
+// Infinity should be supported.
+var d = Float32Array.from([Infinity, 3, 2, 1, -Infinity]);
+assert(d.sort().toString() === '-Infinity,1,2,3,Infinity');
+
+// +0 and -0 should be properly sorted.
+var e = Float32Array.from([1, 0, -0, -1]);
+assert(e.sort().toString() === '-1,0,0,1');
+
+// NaN should be supported and always at the end.
+var f = Float32Array.from([NaN, 0, 1, -1, -Infinity, Infinity, NaN]);
+assert(f.sort().toString() === '-Infinity,-1,0,1,Infinity,NaN,NaN');
+
+// The element size of the view should be sorted properly.
+var ab = new ArrayBuffer(4);
+var g = new Uint32Array(ab);
+var h = new Uint8Array(ab);
+h.set([0xFF, 0, 0xFF, 0]);
+assert(h.toString() === '255,0,255,0');
+assert(g.toString() === '16711935');
+assert(h.subarray(0, 2).sort().toString() === '0,255');
+assert(h.subarray(2, 4).sort().toString() === '0,255');
+assert(g.toString() === '4278255360');
+assert(g.sort().toString() === '4278255360');
+assert(h.toString() === '0,255,0,255');
+
+// Comparator argument should be callable.
+var i = Uint8Array.from([1, 2, 3]);
+try {
+  i.sort({});
+  assert(false);
+} catch (e) {
+  assert(e instanceof TypeError);
+}
+
+// Comparator function returns a Number.
+i.sort(function (lhs, rhs) {
+  return rhs - lhs;
+});
+assert(i.toString() === '3,2,1');
+
+// Comparator function returns a non-Number type that coerces to a Number.
+i.sort(function (lhs, rhs) {
+  return { valueOf: function() { return rhs - lhs; } };
+});
+assert(i.toString() === '3,2,1');
diff --git a/deps/jerry/tests/jerry/es2015/typedArray-subarray.js b/deps/jerry/tests/jerry/es2015/typedArray-subarray.js
new file mode 100644 (file)
index 0000000..57bf771
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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.
+ */
+
+var a = new Int32Array([1, 2, 3, 4, 5]);
+assert(a.subarray().toString() === '1,2,3,4,5');
+assert(a.subarray(3).toString() === '4,5');
+assert(a.subarray(1, 3).toString() === '2,3');
+assert(a.subarray(-3).toString() === '3,4,5');
+assert(a.subarray(-3, -1).toString() === '3,4');
+assert(a.subarray(3, 2).toString() === '');
+assert(a.subarray(-2, -3).toString() === '');
+assert(a.subarray(4, 1).toString() === '');
+assert(a.subarray(-1, -4).toString() === '');
+assert(a.subarray(1).subarray(1).toString() === '3,4,5');
+assert(a.subarray(1, 4).subarray(1, 2).toString() === '3');
+
+var b = new Uint8Array([]);
+assert(b.subarray(123456, -123456).toString() === '');
+assert(b.subarray().subarray().toString() === '');
+
+var ab = new ArrayBuffer(28);
+var tmp = new Int32Array(ab);
+tmp.set([0, 1, 2, 3, 4, 5, 0]);
+var c = new Int32Array(ab, 4, 5);
+assert(c.toString() === '1,2,3,4,5');
+assert(c.subarray().toString() === '1,2,3,4,5');
+assert(c.subarray(3).toString() === '4,5');
+assert(c.subarray(1, 3).toString() === '2,3');
+assert(c.subarray(-3).toString() === '3,4,5');
+assert(c.subarray(-3, -1).toString() === '3,4');
+assert(c.subarray(3, 2).toString() === '');
+assert(c.subarray(-2, -3).toString() === '');
+assert(c.subarray(4, 1).toString() === '');
+assert(c.subarray(-1, -4).toString() === '');
+assert(c.subarray(1).subarray(1).toString() === '3,4,5');
+assert(c.subarray(1, 4).subarray(1, 2).toString() === '3');
diff --git a/deps/jerry/tests/jerry/es2015/typedArray-tostring.js b/deps/jerry/tests/jerry/es2015/typedArray-tostring.js
new file mode 100644 (file)
index 0000000..27fc33a
--- /dev/null
@@ -0,0 +1,24 @@
+/* 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.
+ */
+
+var float_array = new Float32Array([1.125, 5.5, -1.25, -0.0]);
+var int_array = new Int8Array([3, 2, 1, 100, -30])
+var uint_array = new Uint8Array([3, 2, 1, 100, -30])
+var empty_array = new Uint32Array();
+
+assert(float_array.toString() === "1.125,5.5,-1.25,0");
+assert(int_array.toString() === "3,2,1,100,-30");
+assert(uint_array.toString() === "3,2,1,100,226");
+assert(empty_array.toString() === "");
diff --git a/deps/jerry/tests/jerry/es5.1/object-literal-fails.js b/deps/jerry/tests/jerry/es5.1/object-literal-fails.js
new file mode 100644 (file)
index 0000000..e381c16
--- /dev/null
@@ -0,0 +1,47 @@
+// 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.
+
+function throw_error(snippet)
+{
+  try
+  {
+    eval(snippet);
+    assert (false);
+  }
+  catch (e)
+  {
+    assert (e instanceof SyntaxError);
+  }
+}
+
+function throw_error_strict(snippet)
+{
+  'use strict'
+
+  try
+  {
+    eval(snippet);
+    assert (false);
+  }
+  catch (e)
+  {
+    assert (e instanceof SyntaxError);
+  }
+}
+
+// These should be failed in ECMA-262 v5.1
+throw_error_strict("({a:1, a:2})");
+throw_error("({a:1, get a() { return 1 }})");
+throw_error("({get a() {return undefined}, get a() {return undefined}})");
+throw_error("({ get 1() {}, 1:1 })");
diff --git a/deps/jerry/tests/jerry/fail/object-get-data.js b/deps/jerry/tests/jerry/fail/object-get-data.js
deleted file mode 100644 (file)
index 459a157..0000000
+++ /dev/null
@@ -1,15 +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.
-
-var a = {a:1, get a() {return 1}}
diff --git a/deps/jerry/tests/jerry/fail/object-get-get.js b/deps/jerry/tests/jerry/fail/object-get-get.js
deleted file mode 100644 (file)
index 4d987df..0000000
+++ /dev/null
@@ -1,15 +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.
-
-var a = {get a() {return undefined}, get a() {return undefined}}
diff --git a/deps/jerry/tests/jerry/fail/object-several-prop-names-strict.js b/deps/jerry/tests/jerry/fail/object-several-prop-names-strict.js
deleted file mode 100644 (file)
index cec4eca..0000000
+++ /dev/null
@@ -1,17 +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.
-
-"use strict"
-
-var a = {a:1, a:2};
diff --git a/deps/jerry/tests/jerry/fail/regression-test-issue-2344.js b/deps/jerry/tests/jerry/fail/regression-test-issue-2344.js
new file mode 100644 (file)
index 0000000..6d8364f
--- /dev/null
@@ -0,0 +1,16 @@
+// 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.
+
+
+new RegExp().compile("\\1\\");
diff --git a/deps/jerry/tests/jerry/fail/regression-test-issue-2489.js b/deps/jerry/tests/jerry/fail/regression-test-issue-2489.js
new file mode 100644 (file)
index 0000000..7788c32
--- /dev/null
@@ -0,0 +1,25 @@
+// 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.
+
+Object.defineProperty(Object.prototype, 0, {'get': function() { throw $ }});
+/**
+ * The below line is added becase the patch #2526 introduces internal properties for promises.
+ * The Reference Error this issue produced can still be reproduced by calling this line.
+ * The reason it was present before is that Promise's 0th property was Promise which could be modified
+ * with the above line, and the engine getting that property for internal purposes got the `throw $` instead.
+ * Thanks to internal properties, it can't be modified anymore from JS side, therefore Promise won't trigger the error.
+ * To keep this issue's output as it was before, the `Array.prototype[0];` line is added.
+ */
+Array.prototype[0];
+Promise.all();
diff --git a/deps/jerry/tests/jerry/fail/regression-test-issue-2544.js b/deps/jerry/tests/jerry/fail/regression-test-issue-2544.js
new file mode 100644 (file)
index 0000000..946751f
--- /dev/null
@@ -0,0 +1,16 @@
+// 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.
+
+Object.defineProperty(Array.prototype, 0, { get : function () { throw $; } });
+Promise.race([ , this]).then(Error);
diff --git a/deps/jerry/tests/jerry/function-expr-named.js b/deps/jerry/tests/jerry/function-expr-named.js
new file mode 100644 (file)
index 0000000..63d0b4d
--- /dev/null
@@ -0,0 +1,51 @@
+// 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.
+
+var expr = "Dummy value";
+
+var f = function expr() {
+  assert(expr === f);
+  expr = 6;
+  assert(expr === f);
+  assert(!(delete expr));
+  assert(expr === f);
+}
+
+f();
+
+f = function expr() {
+  assert(expr === undefined);
+  var expr = 6;
+  assert(expr === 6);
+}
+
+f();
+
+var f = function expr() {
+  assert(expr === f);
+  eval("var expr = 8");
+  assert(expr === 8);
+}
+
+f();
+
+var f = function expr(i) {
+  assert(expr === f);
+
+  if (i > 0) {
+    expr(i - 1);
+  }
+}
+
+f(10);
index 8bd449e753a52ea31f8695e35ca06ada9929e88f..0b80ff8d5b07bf1637111de5782b65f0e01942a5 100644 (file)
@@ -14,7 +14,7 @@
 
 assert ( isNaN (Math.pow (0.0 /* any number */, NaN)) );
 assert ( Math.pow (NaN, 0.0) === 1.0 );
-// assert ( Math.pow (NaN, -0.0) === 1.0 );
+assert ( Math.pow (NaN, -0.0) === 1.0 );
 assert ( isNaN (Math.pow (NaN, 1.0 /* any non-zero number */)) );
 assert ( Math.pow (2.0, Infinity) === Infinity );
 assert ( Math.pow (2.0, -Infinity) === 0.0 );
@@ -27,17 +27,17 @@ assert ( Math.pow (Infinity, -1.0) === 0 );
 assert ( Math.pow (-Infinity, 3.0) === -Infinity );
 assert ( Math.pow (-Infinity, 2.0) === Infinity );
 assert ( Math.pow (-Infinity, 2.5) === Infinity );
-// assert ( Math.pow (-Infinity, -3.0) === -0.0 );
+assert ( Math.pow (-Infinity, -3.0) === -0.0 );
 assert ( Math.pow (-Infinity, -2.0) === 0.0 );
 assert ( Math.pow (-Infinity, -2.5) === 0.0 );
 assert ( Math.pow (0.0, 1.2) === 0.0 );
 assert ( Math.pow (0.0, -1.2) === Infinity );
-// assert ( Math.pow (-0.0, 3.0) === -0.0 );
-// assert ( Math.pow (-0.0, 2.0) === 0.0 );
-// assert ( Math.pow (-0.0, 2.5) === 0.0 );
-// assert ( Math.pow (-0.0, -3.0) === -Infinity );
-// assert ( Math.pow (-0.0, -2.0) === Infinity );
-// assert ( Math.pow (-0.0, -2.5) === Infinity );
+assert ( Math.pow (-0.0, 3.0) === -0.0 );
+assert ( Math.pow (-0.0, 2.0) === 0.0 );
+assert ( Math.pow (-0.0, 2.5) === 0.0 );
+assert ( Math.pow (-0.0, -3.0) === -Infinity );
+assert ( Math.pow (-0.0, -2.0) === Infinity );
+assert ( Math.pow (-0.0, -2.5) === Infinity );
 assert ( isNaN (Math.pow (-3, 2.5)) );
 
 assert(Math.pow (-2, 2) === 4);
index 10ab4cbf3aad1eaa3e6e88bb2c326fd1a07facb8..f6dfb9fb49fbb5059df4f0f1015fb25d96fd0309 100644 (file)
@@ -65,7 +65,7 @@ assert (props.length === 2);
 
 // Test non-object argument
 try {
-  Object.getOwnPrototypeNames("hello");
+  Object.getOwnPropertyNames("hello");
   assert (false);
 } catch (e) {
   assert (e instanceof TypeError);
diff --git a/deps/jerry/tests/jerry/object-literal-3.js b/deps/jerry/tests/jerry/object-literal-3.js
deleted file mode 100644 (file)
index f7a5aa4..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright JS Foundation and other contributors, http://js.foundation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-try
-{
-  // This should be failed in ECMA-262 v5.1
-  eval("({ get 1() {}, 1:1 })");
-  assert (false);
-}
-catch (e)
-{
-  assert (e instanceof SyntaxError);
-}
diff --git a/deps/jerry/tests/jerry/object-literal-prescanner.js b/deps/jerry/tests/jerry/object-literal-prescanner.js
new file mode 100644 (file)
index 0000000..38333bd
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright JS Foundation and other contributors, http://js.foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+switch (true) {
+default:
+  var obj = {
+    value: 0,
+    set
+      member
+      (x)
+    {
+      // Multiple statements.
+      this.value = x + 4;
+      this.value += 2;
+    },
+    get"member"() {
+      // Multiple statements.
+      this.value = this.value + 1;
+      return this.value;
+    },
+    get 3() {
+      return 3;
+    }
+  }
+}
+
+obj["member"] = 10;
+assert(obj.member === 17);
+assert(obj.member === 18);
+
+assert(obj[3] === 3);
+assert(obj["3"] === 3);
diff --git a/deps/jerry/tests/jerry/parser-oom2.js b/deps/jerry/tests/jerry/parser-oom2.js
new file mode 100644 (file)
index 0000000..7886cb4
--- /dev/null
@@ -0,0 +1,39 @@
+// 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.
+
+/* String which is 32 bytes long. */
+var str = "'\\t' +'\\t' +'\\t'+'\\t'+'\\t'+'\\t'+";
+
+for (var i = 0; i < 10; i++) {
+  str = str + str;
+}
+
+str = "(function() { return " + str + "1 })";
+
+/* Eat memory. */
+var array = [];
+
+try
+{
+  for (var i = 0; i < 90; i++)
+  {
+    array[i] = eval(str);
+  }
+  assert (false);
+}
+catch (err)
+{
+  array = null;
+  assert (err === null);
+}
diff --git a/deps/jerry/tests/jerry/regression-test-issue-1821.js b/deps/jerry/tests/jerry/regression-test-issue-1821.js
new file mode 100644 (file)
index 0000000..7c08601
--- /dev/null
@@ -0,0 +1,16 @@
+// 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.
+
+'\
+'
diff --git a/deps/jerry/tests/jerry/regression-test-issue-1833.js b/deps/jerry/tests/jerry/regression-test-issue-1833.js
deleted file mode 100644 (file)
index 7c08601..0000000
+++ /dev/null
@@ -1,16 +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.
-
-'\
-'
diff --git a/deps/jerry/tests/jerry/regression-test-issue-2230.js b/deps/jerry/tests/jerry/regression-test-issue-2230.js
new file mode 100644 (file)
index 0000000..11945da
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright JS Foundation and other contributors, http://js.foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+try {
+  ((new RegExp("[\\u0")).exec("u"));
+  assert (false);
+} catch (e) {
+  assert (e instanceof SyntaxError);
+}
+
+try {
+  ((new RegExp("[\\x0")).exec("x"));
+  assert (false);
+} catch (e) {
+  assert (e instanceof SyntaxError);
+}
diff --git a/deps/jerry/tests/jerry/regression-test-issue-2237.js b/deps/jerry/tests/jerry/regression-test-issue-2237.js
new file mode 100644 (file)
index 0000000..69cb339
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright JS Foundation and other contributors, http://js.foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+try {
+  (new RegExp("[\\u0020")).exec("u");
+  assert (false);
+} catch (e) {
+  assert (e instanceof SyntaxError);
+}
+
+try {
+  (new RegExp("[\\x20")).exec("x");
+  assert (false);
+} catch (e) {
+  assert (e instanceof SyntaxError);
+}
diff --git a/deps/jerry/tests/jerry/regression-test-issue-2384.js b/deps/jerry/tests/jerry/regression-test-issue-2384.js
new file mode 100644 (file)
index 0000000..fc2c410
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+try {
+  "[]{83}".match("(?=){12,8}");
+  assert (false);
+} catch (e) {
+  assert (e instanceof SyntaxError);
+}
diff --git a/deps/jerry/tests/jerry/regression-test-issue-2386.js b/deps/jerry/tests/jerry/regression-test-issue-2386.js
new file mode 100644 (file)
index 0000000..929c176
--- /dev/null
@@ -0,0 +1,15 @@
+// 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.
+
+Math in Number
diff --git a/deps/jerry/tests/jerry/regression-test-issue-2398.js b/deps/jerry/tests/jerry/regression-test-issue-2398.js
new file mode 100644 (file)
index 0000000..1e67272
--- /dev/null
@@ -0,0 +1,21 @@
+// 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.
+
+// This issue was triggered when show opcodes was enabled at compile
+// time but not enabled in runtime. A memory leak was created.
+
+function f()
+{
+  var \u0042 = true;
+};
diff --git a/deps/jerry/tests/jerry/regression-test-issue-2400.js b/deps/jerry/tests/jerry/regression-test-issue-2400.js
new file mode 100644 (file)
index 0000000..f6b4005
--- /dev/null
@@ -0,0 +1,22 @@
+// 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.
+
+// Wrong byte codes were dumped for this function when show opcodes had been enabled
+
+function abc(a,b) {
+  var c = 6;
+  return arguments[0] + b + c;
+}
+
+abc(1, 2);
diff --git a/deps/jerry/tests/jerry/regression-test-issue-2409.js b/deps/jerry/tests/jerry/regression-test-issue-2409.js
new file mode 100644 (file)
index 0000000..e6b7ec4
--- /dev/null
@@ -0,0 +1,27 @@
+// 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.
+
+// Must be a success.
+eval('g\\u0065t: break get')
+
+try {
+  // Must be a fail.
+  eval('({ g\\u0065t a() {} })')
+  assert(false);
+} catch (e) {
+  assert(e instanceof SyntaxError);
+}
+
+// Must be a success.
+eval('({ g\\u0065t: 5 })')
diff --git a/deps/jerry/tests/jerry/regression-test-issue-2451.js b/deps/jerry/tests/jerry/regression-test-issue-2451.js
new file mode 100644 (file)
index 0000000..026db7a
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+var src = "var a = 0; while(a) { switch(a) {" ;
+for (var i = 0; i < 4000; i++)
+    src += "-Infinity" + i + "\u00a0\u00a01.2e3";
+src += "\udc00%f0%90%80%80\udc00";
+print(src);
diff --git a/deps/jerry/tests/jerry/regression-test-issue-2452.js b/deps/jerry/tests/jerry/regression-test-issue-2452.js
new file mode 100644 (file)
index 0000000..40927d5
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+var src = "";
+for (var i = 0; i < 4000; i++)
+  src += "\udc00%f0%90%80%80\udc00";
+src += "} }";
+print(src);
diff --git a/deps/jerry/tests/jerry/regression-test-issue-2453.js b/deps/jerry/tests/jerry/regression-test-issue-2453.js
new file mode 100644 (file)
index 0000000..994a206
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+var src = "";
+for (var i = 0; i < 4000; i++)
+  src += 4 + i + ": a += a += a; break; ";
+  src += "\𝔺\
+\
";
+print(src);
diff --git a/deps/jerry/tests/jerry/regression-test-issue-2478.js b/deps/jerry/tests/jerry/regression-test-issue-2478.js
new file mode 100644 (file)
index 0000000..4c72d56
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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.
+ */
+function fn(x) {
+  switch (x) {
+    case 1: { return }
+  }
+}
+
+new Function("switch(1) { default: { return }}")
diff --git a/deps/jerry/tests/jerry/regression-test-issue-2494.js b/deps/jerry/tests/jerry/regression-test-issue-2494.js
new file mode 100644 (file)
index 0000000..0a87b63
--- /dev/null
@@ -0,0 +1,16 @@
+// 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.
+
+Object.defineProperty(Object.prototype, "", {});
+assert(JSON.stringify() === undefined)
diff --git a/deps/jerry/tests/jerry/regression-test-issue-2614.js b/deps/jerry/tests/jerry/regression-test-issue-2614.js
new file mode 100644 (file)
index 0000000..028e6a9
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+try {
+  eval(".5.");
+  assert(false);
+} catch(e) {
+  assert(e instanceof SyntaxError);
+}
diff --git a/deps/jerry/tests/jerry/unusual.js b/deps/jerry/tests/jerry/unusual.js
new file mode 100644 (file)
index 0000000..85cfd0a
--- /dev/null
@@ -0,0 +1,27 @@
+// 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.
+
+var x = [0];
+assert (x == x);
+assert (x == !x);
+assert (Array(3) == ",,");
+
+assert ([] + [] == "");
+assert ([] + {} == "[object Object]");
+assert (eval ("{} + []") == 0);
+assert (isNaN (eval ("{} + {}")));
+assert ({} + [] == "[object Object]");
+assert ({} + {} == "[object Object][object Object]");
+
+assert ((! + [] + [] + ![]) === "truefalse");
diff --git a/deps/jerry/tests/jerry/windows-line-ending.js b/deps/jerry/tests/jerry/windows-line-ending.js
new file mode 100644 (file)
index 0000000..02a652f
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright JS Foundation and other contributors, http://js.foundation\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//     http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+\r
+// This test file should use CR-LF styled line endings to test if everything is\r
+// parsed correctly\r
+\r
+\r
+var value =\r
+  5;\r
+\r
+assert (value === 5);\r
index dbd9a2594cdf20c4e7eb15eea472c0ceacd51c00..63ddc4601e2c63da2c02b90247d5201f6d95017e 100644 (file)
@@ -34,9 +34,9 @@ foreach(SOURCE_UNIT_TEST_MAIN ${SOURCE_UNIT_TEST_MAIN_MODULES})
   set(TARGET_NAME unit-${TARGET_NAME})
 
   add_executable(${TARGET_NAME} ${SOURCE_UNIT_TEST_MAIN})
-  set_property(TARGET ${TARGET_NAME}
-               PROPERTY LINK_FLAGS "${LINKER_FLAGS_COMMON}")
-
+  target_include_directories(${TARGET_NAME} PRIVATE ${INCLUDE_CORE_PRIVATE})
+  set_property(TARGET ${TARGET_NAME} PROPERTY LINK_FLAGS "${LINKER_FLAGS_COMMON}")
+  set_property(TARGET ${TARGET_NAME} PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests")
   target_link_libraries(${TARGET_NAME} jerry-core jerry-port-default-minimal)
 
   add_dependencies(unittests-core ${TARGET_NAME})
index 88f15d1065b0e84ac2246207b20304c9a9955397..5de92834f0a559a0625e1b8194a25ad8fbe568b1 100644 (file)
@@ -30,7 +30,7 @@ callback_func (const jerry_value_t function_obj,
   JERRY_UNUSED (args_count);
 
   jerry_value_t value = jerry_create_string ((jerry_char_t *) "Abort run!");
-  jerry_value_set_abort_flag (&value);
+  value = jerry_create_abort_from_value (value, true);
   return value;
 } /* callback_func */
 
@@ -45,86 +45,90 @@ main (void)
   jerry_value_t callback_name = jerry_create_string ((jerry_char_t *) "callback");
   jerry_value_t func = jerry_create_external_function (callback_func);
   jerry_value_t res = jerry_set_property (global, callback_name, func);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
 
   jerry_release_value (res);
   jerry_release_value (func);
   jerry_release_value (callback_name);
   jerry_release_value (global);
 
-  const char *inf_loop_code_src_p = ("while(true) {\n"
-                                     "  with ({}) {\n"
-                                     "    try {\n"
-                                     "      callback();\n"
-                                     "    } catch (e) {\n"
-                                     "    } finally {\n"
-                                     "    }\n"
-                                     "  }\n"
-                                     "}");
+  const jerry_char_t inf_loop_code_src1[] = TEST_STRING_LITERAL (
+    "while(true) {\n"
+    "  with ({}) {\n"
+    "    try {\n"
+    "      callback();\n"
+    "    } catch (e) {\n"
+    "    } finally {\n"
+    "    }\n"
+    "  }\n"
+    "}"
+  );
 
   jerry_value_t parsed_code_val = jerry_parse (NULL,
                                                0,
-                                               (jerry_char_t *) inf_loop_code_src_p,
-                                               strlen (inf_loop_code_src_p),
+                                               inf_loop_code_src1,
+                                               sizeof (inf_loop_code_src1) - 1,
                                                JERRY_PARSE_NO_OPTS);
 
-  TEST_ASSERT (!jerry_value_has_error_flag (parsed_code_val));
+  TEST_ASSERT (!jerry_value_is_error (parsed_code_val));
   res = jerry_run (parsed_code_val);
 
-  TEST_ASSERT (jerry_value_has_abort_flag (res));
+  TEST_ASSERT (jerry_value_is_abort (res));
 
   jerry_release_value (res);
   jerry_release_value (parsed_code_val);
 
-  inf_loop_code_src_p = ("function f() {"
-                         "  while(true) {\n"
-                         "    with ({}) {\n"
-                         "      try {\n"
-                         "        callback();\n"
-                         "      } catch (e) {\n"
-                         "      } finally {\n"
-                         "      }\n"
-                         "    }\n"
-                         "  }"
-                         "}\n"
-                         "function g() {\n"
-                         "  for (a in { x:5 })\n"
-                         "    f();\n"
-                         "}\n"
-                          "\n"
-                         "with({})\n"
-                         " f();\n");
+  const jerry_char_t inf_loop_code_src2[] = TEST_STRING_LITERAL (
+    "function f() {"
+    "  while(true) {\n"
+    "    with ({}) {\n"
+    "      try {\n"
+    "        callback();\n"
+    "      } catch (e) {\n"
+    "      } finally {\n"
+    "      }\n"
+    "    }\n"
+    "  }"
+    "}\n"
+    "function g() {\n"
+    "  for (a in { x:5 })\n"
+    "    f();\n"
+    "}\n"
+    "\n"
+    "with({})\n"
+    " f();\n"
+  );
 
   parsed_code_val = jerry_parse (NULL,
                                  0,
-                                 (jerry_char_t *) inf_loop_code_src_p,
-                                 strlen (inf_loop_code_src_p),
+                                 inf_loop_code_src2,
+                                 sizeof (inf_loop_code_src2) - 1,
                                  JERRY_PARSE_NO_OPTS);
 
-  TEST_ASSERT (!jerry_value_has_error_flag (parsed_code_val));
+  TEST_ASSERT (!jerry_value_is_error (parsed_code_val));
   res = jerry_run (parsed_code_val);
 
-  TEST_ASSERT (jerry_value_has_abort_flag (res));
+  TEST_ASSERT (jerry_value_is_abort (res));
 
   jerry_release_value (res);
   jerry_release_value (parsed_code_val);
 
   /* Test flag overwrites. */
   jerry_value_t value = jerry_create_string ((jerry_char_t *) "Error description");
-  TEST_ASSERT (!jerry_value_has_abort_flag (value));
-  TEST_ASSERT (!jerry_value_has_error_flag (value));
+  TEST_ASSERT (!jerry_value_is_abort (value));
+  TEST_ASSERT (!jerry_value_is_error (value));
 
-  jerry_value_set_abort_flag (&value);
-  TEST_ASSERT (jerry_value_has_abort_flag (value));
-  TEST_ASSERT (jerry_value_has_error_flag (value));
+  value = jerry_create_abort_from_value (value, true);
+  TEST_ASSERT (jerry_value_is_abort (value));
+  TEST_ASSERT (jerry_value_is_error (value));
 
-  jerry_value_set_error_flag (&value);
-  TEST_ASSERT (!jerry_value_has_abort_flag (value));
-  TEST_ASSERT (jerry_value_has_error_flag (value));
+  value = jerry_create_error_from_value (value, true);
+  TEST_ASSERT (!jerry_value_is_abort (value));
+  TEST_ASSERT (jerry_value_is_error (value));
 
-  jerry_value_set_abort_flag (&value);
-  TEST_ASSERT (jerry_value_has_abort_flag (value));
-  TEST_ASSERT (jerry_value_has_error_flag (value));
+  value = jerry_create_abort_from_value (value, true);
+  TEST_ASSERT (jerry_value_is_abort (value));
+  TEST_ASSERT (jerry_value_is_error (value));
 
   jerry_release_value (value);
 
index db17ecb4d1d1e27c98d9d9f43029f59660901f9c..1c755a1d53a883aad4c601fe2219bab7dc3eb117 100644 (file)
@@ -37,10 +37,10 @@ main (void)
   for (size_t idx = 0; idx < sizeof (errors) / sizeof (errors[0]); idx++)
   {
     jerry_value_t error_obj = jerry_create_error (errors[idx], (const jerry_char_t *)"test");
-    TEST_ASSERT (jerry_value_has_error_flag (error_obj));
+    TEST_ASSERT (jerry_value_is_error (error_obj));
     TEST_ASSERT (jerry_get_error_type (error_obj) == errors[idx]);
 
-    jerry_value_clear_error_flag (&error_obj);
+    error_obj = jerry_get_value_from_error (error_obj, true);
 
     TEST_ASSERT (jerry_get_error_type (error_obj) == errors[idx]);
 
diff --git a/deps/jerry/tests/unit-core/test-api-property.c b/deps/jerry/tests/unit-core/test-api-property.c
new file mode 100644 (file)
index 0000000..c1f5de1
--- /dev/null
@@ -0,0 +1,74 @@
+/* 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 "jerryscript.h"
+
+#include "test-common.h"
+
+int
+main (void)
+{
+  TEST_INIT ();
+
+  jerry_init (JERRY_INIT_EMPTY);
+
+  /* Test: init property descriptor */
+  jerry_property_descriptor_t prop_desc;
+  jerry_init_property_descriptor_fields (&prop_desc);
+  TEST_ASSERT (prop_desc.is_value_defined == false);
+  TEST_ASSERT (jerry_value_is_undefined (prop_desc.value));
+  TEST_ASSERT (prop_desc.is_writable_defined == false);
+  TEST_ASSERT (prop_desc.is_writable == false);
+  TEST_ASSERT (prop_desc.is_enumerable_defined == false);
+  TEST_ASSERT (prop_desc.is_enumerable == false);
+  TEST_ASSERT (prop_desc.is_configurable_defined == false);
+  TEST_ASSERT (prop_desc.is_configurable == false);
+  TEST_ASSERT (prop_desc.is_get_defined == false);
+  TEST_ASSERT (jerry_value_is_undefined (prop_desc.getter));
+  TEST_ASSERT (prop_desc.is_set_defined == false);
+  TEST_ASSERT (jerry_value_is_undefined (prop_desc.setter));
+
+  /* Test: define own properties */
+  jerry_value_t global_obj_val = jerry_get_global_object ();
+  jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "my_defined_property");
+  prop_desc.is_value_defined = true;
+  prop_desc.value = jerry_acquire_value (prop_name);
+  jerry_value_t res = jerry_define_own_property (global_obj_val, prop_name, &prop_desc);
+  TEST_ASSERT (!jerry_value_is_error (res));
+  TEST_ASSERT (jerry_value_is_boolean (res));
+  TEST_ASSERT (jerry_get_boolean_value (res));
+  jerry_release_value (res);
+  jerry_free_property_descriptor_fields (&prop_desc);
+
+  /* Test: get own property descriptor */
+  bool is_ok = jerry_get_own_property_descriptor (global_obj_val, prop_name, &prop_desc);
+  TEST_ASSERT (is_ok);
+  TEST_ASSERT (prop_desc.is_value_defined == true);
+  TEST_ASSERT (jerry_value_is_string (prop_desc.value));
+  TEST_ASSERT (prop_desc.is_writable == false);
+  TEST_ASSERT (prop_desc.is_enumerable == false);
+  TEST_ASSERT (prop_desc.is_configurable == false);
+  TEST_ASSERT (prop_desc.is_get_defined == false);
+  TEST_ASSERT (jerry_value_is_undefined (prop_desc.getter));
+  TEST_ASSERT (prop_desc.is_set_defined == false);
+  TEST_ASSERT (jerry_value_is_undefined (prop_desc.setter));
+  jerry_release_value (prop_name);
+  jerry_free_property_descriptor_fields (&prop_desc);
+
+  jerry_release_value (global_obj_val);
+  jerry_cleanup ();
+
+  return 0;
+} /* main */
index 65302bbdbda3d805083eee459cd48da1f07dcda7..12dd7642d3e7dd28c69ef419ae0eb03a3764912e 100644 (file)
 #include "jerryscript.h"
 #include "test-common.h"
 
+static void
+compare_str (jerry_value_t value, const jerry_char_t *str_p, size_t str_len)
+{
+  jerry_size_t size = jerry_get_string_size (value);
+  JERRY_ASSERT (str_len == size);
+  JERRY_VLA (jerry_char_t, str_buff, size);
+  jerry_string_to_utf8_char_buffer (value, str_buff, size);
+  JERRY_ASSERT (!memcmp (str_p, str_buff, str_len));
+} /* compare_str */
+
 int
 main (void)
 {
@@ -24,13 +34,173 @@ main (void)
   jerry_init (JERRY_INIT_EMPTY);
 
   jerry_value_t obj_val = jerry_create_object ();
-  jerry_value_set_error_flag (&obj_val);
+  obj_val = jerry_create_error_from_value (obj_val, true);
   jerry_value_t err_val = jerry_acquire_value (obj_val);
 
-  jerry_value_clear_error_flag (&obj_val);
-  jerry_release_value (obj_val);
+  obj_val = jerry_get_value_from_error (err_val, true);
 
+  JERRY_ASSERT (obj_val != err_val);
   jerry_release_value (err_val);
+  jerry_release_value (obj_val);
+
+  const jerry_char_t pterodactylus[] = "Pterodactylus";
+  const size_t pterodactylus_size = sizeof (pterodactylus) - 1;
+
+  jerry_value_t str = jerry_create_string (pterodactylus);
+  jerry_value_t error = jerry_create_error_from_value (str, true);
+  str = jerry_get_value_from_error (error, true);
+
+  compare_str (str, pterodactylus, pterodactylus_size);
+  jerry_release_value (str);
+
+  str = jerry_create_string (pterodactylus);
+  error = jerry_create_error_from_value (str, false);
+  jerry_release_value (str);
+  str = jerry_get_value_from_error (error, true);
+
+  compare_str (str, pterodactylus, pterodactylus_size);
+  jerry_release_value (str);
+
+  str = jerry_create_string (pterodactylus);
+  error = jerry_create_abort_from_value (str, true);
+  str = jerry_get_value_from_error (error, true);
+
+  compare_str (str, pterodactylus, pterodactylus_size);
+  jerry_release_value (str);
+
+  str = jerry_create_string (pterodactylus);
+  error = jerry_create_abort_from_value (str, false);
+  jerry_release_value (str);
+  str = jerry_get_value_from_error (error, true);
+
+  compare_str (str, pterodactylus, pterodactylus_size);
+  jerry_release_value (str);
+
+  str = jerry_create_string (pterodactylus);
+  error = jerry_create_error_from_value (str, true);
+  error = jerry_create_abort_from_value (error, true);
+  JERRY_ASSERT (jerry_value_is_abort (error));
+  str = jerry_get_value_from_error (error, true);
+
+  compare_str (str, pterodactylus, pterodactylus_size);
+  jerry_release_value (str);
+
+  str = jerry_create_string (pterodactylus);
+  error = jerry_create_error_from_value (str, true);
+  jerry_value_t error2 = jerry_create_abort_from_value (error, false);
+  JERRY_ASSERT (jerry_value_is_abort (error2));
+  jerry_release_value (error);
+  str = jerry_get_value_from_error (error2, true);
+
+  compare_str (str, pterodactylus, pterodactylus_size);
+  jerry_release_value (str);
+
+  double test_num = 3.1415926;
+  jerry_value_t num = jerry_create_number (test_num);
+  jerry_value_t num2 = jerry_create_error_from_value (num, false);
+  JERRY_ASSERT (jerry_value_is_error (num2));
+  jerry_release_value (num);
+  num2 = jerry_get_value_from_error (num2, true);
+  JERRY_ASSERT (jerry_get_number_value (num2) == test_num);
+  jerry_release_value (num2);
+
+  num = jerry_create_number (test_num);
+  num2 = jerry_create_error_from_value (num, true);
+  JERRY_ASSERT (jerry_value_is_error (num2));
+  num2 = jerry_get_value_from_error (num2, true);
+  JERRY_ASSERT (jerry_get_number_value (num2) == test_num);
+  jerry_release_value (num2);
+
+  num = jerry_create_number (test_num);
+  num2 = jerry_create_error_from_value (num, false);
+  JERRY_ASSERT (jerry_value_is_error (num2));
+  jerry_release_value (num);
+  jerry_value_t num3 = jerry_create_error_from_value (num2, false);
+  JERRY_ASSERT (jerry_value_is_error (num3));
+  jerry_release_value (num2);
+  num2 = jerry_get_value_from_error (num3, true);
+  JERRY_ASSERT (jerry_get_number_value (num2) == test_num);
+  jerry_release_value (num2);
+
+  num = jerry_create_number (test_num);
+  num2 = jerry_create_error_from_value (num, true);
+  JERRY_ASSERT (jerry_value_is_error (num2));
+  num3 = jerry_create_error_from_value (num2, true);
+  JERRY_ASSERT (jerry_value_is_error (num3));
+  num2 = jerry_get_value_from_error (num3, true);
+  JERRY_ASSERT (jerry_get_number_value (num2) == test_num);
+  jerry_release_value (num2);
+
+  num = jerry_create_number (test_num);
+  error = jerry_create_abort_from_value (num, true);
+  JERRY_ASSERT (jerry_value_is_abort (error));
+  num2 = jerry_create_error_from_value (error, true);
+  JERRY_ASSERT (jerry_value_is_error (num2));
+  num = jerry_get_value_from_error (num2, true);
+  JERRY_ASSERT (jerry_get_number_value (num) == test_num);
+  jerry_release_value (num);
+
+  num = jerry_create_number (test_num);
+  error = jerry_create_abort_from_value (num, false);
+  jerry_release_value (num);
+  JERRY_ASSERT (jerry_value_is_abort (error));
+  num2 = jerry_create_error_from_value (error, true);
+  JERRY_ASSERT (jerry_value_is_error (num2));
+  num = jerry_get_value_from_error (num2, true);
+  JERRY_ASSERT (jerry_get_number_value (num) == test_num);
+  jerry_release_value (num);
+
+  num = jerry_create_number (test_num);
+  error = jerry_create_abort_from_value (num, true);
+  JERRY_ASSERT (jerry_value_is_abort (error));
+  num2 = jerry_create_error_from_value (error, false);
+  jerry_release_value (error);
+  JERRY_ASSERT (jerry_value_is_error (num2));
+  num = jerry_get_value_from_error (num2, true);
+  JERRY_ASSERT (jerry_get_number_value (num) == test_num);
+  jerry_release_value (num);
+
+  num = jerry_create_number (test_num);
+  error = jerry_create_abort_from_value (num, false);
+  jerry_release_value (num);
+  JERRY_ASSERT (jerry_value_is_abort (error));
+  num2 = jerry_create_error_from_value (error, false);
+  jerry_release_value (error);
+  JERRY_ASSERT (jerry_value_is_error (num2));
+  num = jerry_get_value_from_error (num2, true);
+  JERRY_ASSERT (jerry_get_number_value (num) == test_num);
+  jerry_release_value (num);
+
+  jerry_value_t value = jerry_create_number (42);
+  value = jerry_get_value_from_error (value, true);
+  jerry_release_value (value);
+
+  value = jerry_create_number (42);
+  jerry_value_t value2 = jerry_get_value_from_error (value, false);
+  jerry_release_value (value);
+  jerry_release_value (value2);
+
+  value = jerry_create_number (42);
+  error = jerry_create_error_from_value (value, true);
+  error = jerry_create_error_from_value (error, true);
+  jerry_release_value (error);
+
+  value = jerry_create_number (42);
+  error = jerry_create_abort_from_value (value, true);
+  error = jerry_create_abort_from_value (error, true);
+  jerry_release_value (error);
+
+  value = jerry_create_number (42);
+  error = jerry_create_error_from_value (value, true);
+  error2 = jerry_create_error_from_value (error, false);
+  jerry_release_value (error);
+  jerry_release_value (error2);
+
+  value = jerry_create_number (42);
+  error = jerry_create_abort_from_value (value, true);
+  error2 = jerry_create_abort_from_value (error, false);
+  jerry_release_value (error);
+  jerry_release_value (error2);
 
   jerry_cleanup ();
 } /* main */
diff --git a/deps/jerry/tests/unit-core/test-api-strings.c b/deps/jerry/tests/unit-core/test-api-strings.c
new file mode 100644 (file)
index 0000000..ca3c722
--- /dev/null
@@ -0,0 +1,299 @@
+/* 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 "jerryscript.h"
+
+#include "test-common.h"
+
+static bool
+strict_equals (jerry_value_t a, /**< the first string to compare */
+               jerry_value_t b) /**< the second string to compare */
+{
+  const jerry_char_t is_equal_src[] = "var isEqual = function(a, b) { return (a === b); }; isEqual";
+  jerry_value_t is_equal_fn_val = jerry_eval (is_equal_src, sizeof (is_equal_src) - 1, JERRY_PARSE_NO_OPTS);
+  TEST_ASSERT (!jerry_value_is_error (is_equal_fn_val));
+  jerry_value_t args[2] = {a, b};
+  jerry_value_t res = jerry_call_function (is_equal_fn_val, jerry_create_undefined (), args, 2);
+  TEST_ASSERT (!jerry_value_is_error (res));
+  TEST_ASSERT (jerry_value_is_boolean (res));
+  bool is_strict_equal = jerry_get_boolean_value (res);
+  jerry_release_value (res);
+  jerry_release_value (is_equal_fn_val);
+  return is_strict_equal;
+} /* strict_equals */
+
+int
+main (void)
+{
+  jerry_size_t sz, utf8_sz, cesu8_sz;
+  jerry_length_t cesu8_length, utf8_length;
+  jerry_value_t args[2];
+
+  TEST_INIT ();
+  jerry_init (JERRY_INIT_EMPTY);
+
+  /* Test corner case for jerry_string_to_char_buffer */
+  args[0] = jerry_create_string ((jerry_char_t *) "");
+  sz = jerry_get_string_size (args[0]);
+  TEST_ASSERT (sz == 0);
+  jerry_release_value (args[0]);
+
+  /* Test create_jerry_string_from_utf8 with 4-byte long unicode sequences,
+   * test string: 'str: {DESERET CAPITAL LETTER LONG I}'
+   */
+  args[0] = jerry_create_string_from_utf8 ((jerry_char_t *) "\x73\x74\x72\x3a \xf0\x90\x90\x80");
+  args[1] = jerry_create_string ((jerry_char_t *) "\x73\x74\x72\x3a \xed\xa0\x81\xed\xb0\x80");
+
+  /* These sizes must be equal */
+  utf8_sz = jerry_get_string_size (args[0]);
+  cesu8_sz = jerry_get_string_size (args[1]);
+
+  char string_from_utf8[utf8_sz];
+  char string_from_cesu8[cesu8_sz];
+
+  jerry_string_to_char_buffer (args[0], (jerry_char_t *) string_from_utf8, utf8_sz);
+  jerry_string_to_char_buffer (args[1], (jerry_char_t *) string_from_cesu8, cesu8_sz);
+
+  TEST_ASSERT (utf8_sz == cesu8_sz);
+
+  TEST_ASSERT (!strncmp (string_from_utf8, string_from_cesu8, utf8_sz));
+  jerry_release_value (args[0]);
+  jerry_release_value (args[1]);
+
+  /* Test jerry_string_to_utf8_char_buffer, test string: 'str: {DESERET CAPITAL LETTER LONG I}' */
+  args[0] = jerry_create_string_from_utf8 ((jerry_char_t *) "\x73\x74\x72\x3a \xf0\x90\x90\x80");
+  args[1] = jerry_create_string ((jerry_char_t *) "\x73\x74\x72\x3a \xed\xa0\x81\xed\xb0\x80");
+
+  /* Test that the strings are equal / ensure hashes are equal */
+  TEST_ASSERT (strict_equals (args[0], args[1]));
+
+  /* These sizes must be equal */
+  utf8_sz = jerry_get_utf8_string_size (args[0]);
+  cesu8_sz = jerry_get_utf8_string_size (args[1]);
+
+  TEST_ASSERT (utf8_sz == cesu8_sz);
+
+  char string_from_utf8_string[utf8_sz];
+  char string_from_cesu8_string[cesu8_sz];
+
+  jerry_string_to_utf8_char_buffer (args[0], (jerry_char_t *) string_from_utf8_string, utf8_sz);
+  jerry_string_to_utf8_char_buffer (args[1], (jerry_char_t *) string_from_cesu8_string, cesu8_sz);
+
+  TEST_ASSERT (!strncmp (string_from_utf8_string, string_from_cesu8_string, utf8_sz));
+  jerry_release_value (args[0]);
+  jerry_release_value (args[1]);
+
+  /* Test string: 'str: {MATHEMATICAL FRAKTUR SMALL F}{MATHEMATICAL FRAKTUR SMALL G}' */
+  args[0] = jerry_create_string_from_utf8 ((jerry_char_t *) "\x73\x74\x72\x3a \xf0\x9d\x94\xa3 \xf0\x9d\x94\xa4");
+
+  cesu8_length = jerry_get_string_length (args[0]);
+  utf8_length = jerry_get_utf8_string_length (args[0]);
+
+  cesu8_sz = jerry_get_string_size (args[0]);
+  utf8_sz =  jerry_get_utf8_string_size (args[0]);
+
+  TEST_ASSERT (cesu8_length == 10 && utf8_length == 8);
+  TEST_ASSERT (cesu8_sz != utf8_sz);
+  TEST_ASSERT (utf8_sz == 14 && cesu8_sz == 18);
+
+  char test_string[utf8_sz];
+
+  TEST_ASSERT (jerry_string_to_utf8_char_buffer (args[0], (jerry_char_t *) test_string, utf8_sz) == 14);
+  TEST_ASSERT (!strncmp (test_string, "\x73\x74\x72\x3a \xf0\x9d\x94\xa3 \xf0\x9d\x94\xa4", utf8_sz));
+
+  sz = jerry_substring_to_utf8_char_buffer (args[0], 0, utf8_length, (jerry_char_t *) test_string, utf8_sz);
+  TEST_ASSERT (sz == 14);
+  TEST_ASSERT (!strncmp (test_string, "\x73\x74\x72\x3a \xf0\x9d\x94\xa3 \xf0\x9d\x94\xa4", sz));
+
+  sz = jerry_substring_to_utf8_char_buffer (args[0], 0, utf8_length + 1, (jerry_char_t *) test_string, utf8_sz);
+  TEST_ASSERT (sz == 14);
+  TEST_ASSERT (!strncmp (test_string, "\x73\x74\x72\x3a \xf0\x9d\x94\xa3 \xf0\x9d\x94\xa4", sz));
+
+  sz = jerry_substring_to_utf8_char_buffer (args[0], utf8_length, 0, (jerry_char_t *) test_string, utf8_sz);
+  TEST_ASSERT (sz == 0);
+
+  sz = jerry_substring_to_utf8_char_buffer (args[0], 0, utf8_length, (jerry_char_t *) test_string, utf8_sz - 1);
+  TEST_ASSERT (sz == 10);
+  TEST_ASSERT (!strncmp (test_string, "\x73\x74\x72\x3a \xf0\x9d\x94\xa3 ", sz));
+
+  sz = jerry_substring_to_utf8_char_buffer (args[0], 0, utf8_length - 1, (jerry_char_t *) test_string, utf8_sz);
+  TEST_ASSERT (sz == 10);
+  TEST_ASSERT (!strncmp (test_string, "\x73\x74\x72\x3a \xf0\x9d\x94\xa3 ", sz));
+
+  sz = jerry_substring_to_utf8_char_buffer (args[0],
+                                            utf8_length - 2,
+                                            utf8_length - 1,
+                                            (jerry_char_t *) test_string,
+                                            utf8_sz);
+  TEST_ASSERT (sz == 1);
+  TEST_ASSERT (!strncmp (test_string, " ", sz));
+
+  sz = jerry_substring_to_utf8_char_buffer (args[0],
+                                            utf8_length - 3,
+                                            utf8_length - 2,
+                                            (jerry_char_t *) test_string,
+                                            utf8_sz);
+  TEST_ASSERT (sz == 4);
+  TEST_ASSERT (!strncmp (test_string, "\xf0\x9d\x94\xa3", sz));
+
+  jerry_release_value (args[0]);
+
+  /* Test string: 'str: {DESERET CAPITAL LETTER LONG I}' */
+  args[0] = jerry_create_string ((jerry_char_t *) "\x73\x74\x72\x3a \xed\xa0\x81\xed\xb0\x80");
+
+  cesu8_length = jerry_get_string_length (args[0]);
+  utf8_length = jerry_get_utf8_string_length (args[0]);
+
+  cesu8_sz = jerry_get_string_size (args[0]);
+  utf8_sz =  jerry_get_utf8_string_size (args[0]);
+
+  TEST_ASSERT (cesu8_length == 7 && utf8_length == 6);
+  TEST_ASSERT (cesu8_sz != utf8_sz);
+  TEST_ASSERT (utf8_sz == 9 && cesu8_sz == 11);
+
+  jerry_release_value (args[0]);
+
+  /* Test string: 'price: 10{EURO SIGN}' */
+  args[0] = jerry_create_string_from_utf8 ((jerry_char_t *) "\x70\x72\x69\x63\x65\x3a \x31\x30\xe2\x82\xac");
+
+  cesu8_length = jerry_get_string_length (args[0]);
+  utf8_length = jerry_get_utf8_string_length (args[0]);
+
+  cesu8_sz = jerry_get_string_size (args[0]);
+  utf8_sz =  jerry_get_utf8_string_size (args[0]);
+
+  TEST_ASSERT (cesu8_length == utf8_length);
+  TEST_ASSERT (cesu8_length == 10);
+  TEST_ASSERT (cesu8_sz == utf8_sz);
+  TEST_ASSERT (utf8_sz == 12);
+  jerry_release_value (args[0]);
+
+  /* Test string: '3' */
+  {
+    jerry_value_t test_str = jerry_create_string ((const jerry_char_t *) "3");
+    char result_string[1] = { 'E' };
+    jerry_size_t copied_utf8 = jerry_substring_to_utf8_char_buffer (test_str,
+                                                                    0,
+                                                                    1,
+                                                                    (jerry_char_t *) result_string,
+                                                                    sizeof (result_string));
+    TEST_ASSERT (copied_utf8 == 1);
+    TEST_ASSERT (result_string[0] == '3');
+
+    result_string[0] = 'E';
+    jerry_size_t copied = jerry_substring_to_char_buffer (test_str,
+                                                          0,
+                                                          1,
+                                                          (jerry_char_t *) result_string,
+                                                          sizeof (result_string));
+    TEST_ASSERT (copied == 1);
+    TEST_ASSERT (result_string[0] == '3');
+
+    jerry_release_value (test_str);
+  }
+
+  /* Test jerry_substring_to_char_buffer */
+  args[0] = jerry_create_string ((jerry_char_t *) "an ascii string");
+
+  /* Buffer size */
+  cesu8_sz = 5;
+
+  char substring[cesu8_sz];
+  sz = jerry_substring_to_char_buffer (args[0], 3, 8, (jerry_char_t *) substring, cesu8_sz);
+  TEST_ASSERT (sz == 5);
+  TEST_ASSERT (!strncmp (substring, "ascii", sz));
+
+  /* Buffer size is 5, substring length is 11 => copied only the first 5 char */
+  sz = jerry_substring_to_char_buffer (args[0], 0, 11, (jerry_char_t *) substring, cesu8_sz);
+
+  TEST_ASSERT (sz == 5);
+  TEST_ASSERT (!strncmp (substring, "an as", sz));
+
+  /* Position of the first character is greater than the string length */
+  sz = jerry_substring_to_char_buffer (args[0], 16, 21, (jerry_char_t *) substring, cesu8_sz);
+  TEST_ASSERT (sz == 0);
+
+  sz = jerry_substring_to_char_buffer (args[0], 14, 15, (jerry_char_t *) substring, cesu8_sz);
+  TEST_ASSERT (sz == 1);
+  TEST_ASSERT (!strncmp (substring, "g", sz));
+
+  sz = jerry_substring_to_char_buffer (args[0], 0, 1, (jerry_char_t *) substring, cesu8_sz);
+  TEST_ASSERT (sz == 1);
+  TEST_ASSERT (!strncmp (substring, "a", sz));
+
+  cesu8_length = jerry_get_string_length (args[0]);
+  cesu8_sz = jerry_get_string_size (args[0]);
+  TEST_ASSERT (cesu8_length == 15);
+  TEST_ASSERT (cesu8_length == cesu8_sz);
+
+  sz = jerry_substring_to_char_buffer (args[0], 0, cesu8_length, (jerry_char_t *) substring, cesu8_sz);
+  TEST_ASSERT (sz = 15);
+  TEST_ASSERT (!strncmp (substring, "an ascii string", sz));
+
+  jerry_release_value (args[0]);
+
+  /* Test jerry_substring_to_char_buffer: '0101' */
+  args[0] = jerry_create_string ((jerry_char_t *) "0101");
+  cesu8_sz = jerry_get_string_size (args[0]);
+
+  char number_substring[cesu8_sz];
+
+  sz = jerry_substring_to_char_buffer (args[0], 1, 3, (jerry_char_t *) number_substring, cesu8_sz);
+  TEST_ASSERT (sz == 2);
+  TEST_ASSERT (!strncmp (number_substring, "10", sz));
+
+  jerry_release_value (args[0]);
+
+  /* Test jerry_substring_to_char_buffer: 'str: {greek zero sign}' */
+  args[0] = jerry_create_string ((jerry_char_t *) "\x73\x74\x72\x3a \xed\xa0\x80\xed\xb6\x8a");
+  cesu8_sz = jerry_get_string_size (args[0]);
+  cesu8_length = jerry_get_string_length (args[0]);
+  TEST_ASSERT (cesu8_sz == 11);
+  TEST_ASSERT (cesu8_length = 7);
+
+  char supl_substring[cesu8_sz];
+
+  sz = jerry_substring_to_char_buffer (args[0], 0, cesu8_length, (jerry_char_t *) supl_substring, cesu8_sz);
+  TEST_ASSERT (sz == 11);
+  TEST_ASSERT (!strncmp (supl_substring, "\x73\x74\x72\x3a \xed\xa0\x80\xed\xb6\x8a", sz));
+
+  /* Decrease the buffer size => the low surrogate char will not fit into the buffer */
+  cesu8_sz -= 1;
+  sz = jerry_substring_to_char_buffer (args[0], 0, cesu8_length, (jerry_char_t *) supl_substring, cesu8_sz);
+  TEST_ASSERT (sz == 8);
+  TEST_ASSERT (!strncmp (supl_substring, "\x73\x74\x72\x3a \xed\xa0\x80", sz));
+
+  sz = jerry_substring_to_char_buffer (args[0],
+                                       cesu8_length - 1,
+                                       cesu8_length,
+                                       (jerry_char_t *) supl_substring,
+                                       cesu8_sz);
+  TEST_ASSERT (sz == 3);
+  TEST_ASSERT (!strncmp (supl_substring, "\xed\xb6\x8a", sz));
+
+  sz = jerry_substring_to_char_buffer (args[0],
+                                       cesu8_length - 2,
+                                       cesu8_length - 1,
+                                       (jerry_char_t *) supl_substring,
+                                       cesu8_sz);
+  TEST_ASSERT (sz == 3);
+  TEST_ASSERT (!strncmp (supl_substring, "\xed\xa0\x80", sz));
+
+  jerry_release_value (args[0]);
+
+  jerry_cleanup ();
+
+  return 0;
+} /* main */
index 01d5b93ef11bbef6b84b4be05f696cad756625d3..8a85be97ebd2d1712c9fe7a8b812779dd438ac87 100644 (file)
@@ -46,7 +46,7 @@ main (void)
 
   jerry_init (JERRY_INIT_EMPTY);
 
-  jerry_char_t test_eval_function[] = "function demo(a) { return a + 1; }; demo";
+  const jerry_char_t test_eval_function[] = "function demo(a) { return a + 1; }; demo";
 
   test_entry_t entries[] =
   {
@@ -63,11 +63,13 @@ main (void)
 
     ENTRY (JERRY_TYPE_OBJECT, jerry_create_object ()),
     ENTRY (JERRY_TYPE_OBJECT, jerry_create_array (10)),
-    ENTRY (JERRY_TYPE_OBJECT, jerry_create_error (JERRY_ERROR_TYPE, (const jerry_char_t *) "error")),
+    ENTRY (JERRY_TYPE_ERROR, jerry_create_error (JERRY_ERROR_TYPE, (const jerry_char_t *) "error")),
 
     ENTRY (JERRY_TYPE_NULL, jerry_create_null ()),
 
-    ENTRY (JERRY_TYPE_FUNCTION, jerry_eval (test_eval_function, strlen ((char *) test_eval_function), false)),
+    ENTRY (JERRY_TYPE_FUNCTION, jerry_eval (test_eval_function,
+                                            sizeof (test_eval_function) - 1,
+                                            JERRY_PARSE_NO_OPTS)),
     ENTRY (JERRY_TYPE_FUNCTION, jerry_create_external_function (test_ext_function)),
 
     ENTRY (JERRY_TYPE_STRING, jerry_create_string (test_eval_function)),
index d6a30ed40d5c7af837bc47bfa8754edc8f09047c..d1ff408bd1786ea7d97f7f37e9fe0c23ed4f46b6 100644 (file)
 
 #include "test-common.h"
 
-const char *test_source = (
-                           "function assert (arg) { "
-                           "  if (!arg) { "
-                           "    throw Error('Assert failed');"
-                           "  } "
-                           "} "
-                           "this.t = 1; "
-                           "function f () { "
-                           "return this.t; "
-                           "} "
-                           "this.foo = f; "
-                           "this.bar = function (a) { "
-                           "return a + t; "
-                           "}; "
-                           "function A () { "
-                           "this.t = 12; "
-                           "} "
-                           "this.A = A; "
-                           "this.a = new A (); "
-                           "function call_external () { "
-                           "  return this.external ('1', true); "
-                           "} "
-                           "function call_throw_test() { "
-                           "  var catched = false; "
-                           "  try { "
-                           "    this.throw_test(); "
-                           "  } catch (e) { "
-                           "    catched = true; "
-                           "    assert(e.name == 'TypeError'); "
-                           "    assert(e.message == 'error'); "
-                           "  } "
-                           "  assert(catched); "
-                           "} "
-                           "function throw_reference_error() { "
-                           " throw new ReferenceError ();"
-                           "} "
-                           "p = {'alpha':32, 'bravo':false, 'charlie':{}, 'delta':123.45, 'echo':'foobar'};"
-                           "np = {}; Object.defineProperty (np, 'foxtrot', { "
-                           "get: function() { throw 'error'; }, enumerable: true }) "
-                           );
+const jerry_char_t test_source[] = TEST_STRING_LITERAL (
+  "function assert (arg) { "
+  "  if (!arg) { "
+  "    throw Error('Assert failed');"
+  "  } "
+  "} "
+  "this.t = 1; "
+  "function f () { "
+  "return this.t; "
+  "} "
+  "this.foo = f; "
+  "this.bar = function (a) { "
+  "return a + t; "
+  "}; "
+  "function A () { "
+  "this.t = 12; "
+  "} "
+  "this.A = A; "
+  "this.a = new A (); "
+  "function call_external () { "
+  "  return this.external ('1', true); "
+  "} "
+  "function call_throw_test() { "
+  "  var catched = false; "
+  "  try { "
+  "    this.throw_test(); "
+  "  } catch (e) { "
+  "    catched = true; "
+  "    assert(e.name == 'TypeError'); "
+  "    assert(e.message == 'error'); "
+  "  } "
+  "  assert(catched); "
+  "} "
+  "function throw_reference_error() { "
+  " throw new ReferenceError ();"
+  "} "
+  "p = {'alpha':32, 'bravo':false, 'charlie':{}, 'delta':123.45, 'echo':'foobar'};"
+  "np = {}; Object.defineProperty (np, 'foxtrot', { "
+  "get: function() { throw 'error'; }, enumerable: true }) "
+);
 
 bool test_api_is_free_callback_was_called = false;
 
@@ -191,10 +191,10 @@ const jerry_length_t magic_string_lengths[] =
 #undef JERRY_MAGIC_STRING_DEF
 };
 
-const jerry_char_ptr_t magic_string_items[] =
+const jerry_char_t *magic_string_items[] =
 {
 #define JERRY_MAGIC_STRING_DEF(NAME, STRING) \
-    (const jerry_char_ptr_t) jerry_magic_string_ex_ ## NAME,
+    (const jerry_char_t *) jerry_magic_string_ex_ ## NAME,
 
   JERRY_MAGIC_STRING_ITEMS
 
@@ -318,38 +318,14 @@ test_run_simple (const char *script_p) /**< source code to run */
   return jerry_run_simple ((const jerry_char_t *) script_p, script_size, JERRY_INIT_EMPTY);
 } /* test_run_simple */
 
-static bool
-strict_equals (jerry_value_t a,
-               jerry_value_t b)
-{
-  bool is_strict_equal;
-  const char *is_equal_src;
-  jerry_value_t args[2];
-  jerry_value_t is_equal_fn_val;
-  jerry_value_t res;
-
-  is_equal_src = "var isEqual = function(a, b) { return (a === b); }; isEqual";
-  is_equal_fn_val = jerry_eval ((jerry_char_t *) is_equal_src, strlen (is_equal_src), false);
-  TEST_ASSERT (!jerry_value_has_error_flag (is_equal_fn_val));
-  args[0] = a;
-  args[1] = b;
-  res = jerry_call_function (is_equal_fn_val, jerry_create_undefined (), args, 2);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
-  TEST_ASSERT (jerry_value_is_boolean (res));
-  is_strict_equal = jerry_get_boolean_value (res);
-  jerry_release_value (res);
-  jerry_release_value (is_equal_fn_val);
-  return is_strict_equal;
-} /* strict_equals */
-
 int
 main (void)
 {
   TEST_INIT ();
 
   bool is_ok;
-  jerry_size_t sz, utf8_sz, cesu8_sz;
-  jerry_length_t cesu8_length, utf8_length;
+  jerry_size_t sz, cesu8_sz;
+  jerry_length_t cesu8_length;
   jerry_value_t val_t, val_foo, val_bar, val_A, val_A_prototype, val_a, val_a_foo, val_value_field, val_p, val_np;
   jerry_value_t val_call_external;
   jerry_value_t global_obj_val, obj_val;
@@ -367,276 +343,52 @@ main (void)
 
   parsed_code_val = jerry_parse (NULL,
                                  0,
-                                 (jerry_char_t *) test_source,
-                                 strlen (test_source),
+                                 test_source,
+                                 sizeof (test_source) - 1,
                                  JERRY_PARSE_NO_OPTS);
-  TEST_ASSERT (!jerry_value_has_error_flag (parsed_code_val));
+  TEST_ASSERT (!jerry_value_is_error (parsed_code_val));
 
   res = jerry_run (parsed_code_val);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   jerry_release_value (res);
   jerry_release_value (parsed_code_val);
 
   global_obj_val = jerry_get_global_object ();
 
-  /* Test corner case for jerry_string_to_char_buffer */
-  args[0] = jerry_create_string ((jerry_char_t *) "");
-  sz = jerry_get_string_size (args[0]);
-  TEST_ASSERT (sz == 0);
-  jerry_release_value (args[0]);
-
-  /* Test create_jerry_string_from_utf8 with 4-byte long unicode sequences,
-   * test string: 'str: {DESERET CAPITAL LETTER LONG I}'
-   */
-  args[0] = jerry_create_string_from_utf8 ((jerry_char_t *) "\x73\x74\x72\x3a \xf0\x90\x90\x80");
-  args[1] = jerry_create_string ((jerry_char_t *) "\x73\x74\x72\x3a \xed\xa0\x81\xed\xb0\x80");
-
-  /* These sizes must be equal */
-  utf8_sz = jerry_get_string_size (args[0]);
-  cesu8_sz = jerry_get_string_size (args[1]);
-
-  char string_from_utf8[utf8_sz];
-  char string_from_cesu8[cesu8_sz];
-
-  jerry_string_to_char_buffer (args[0], (jerry_char_t *) string_from_utf8, utf8_sz);
-  jerry_string_to_char_buffer (args[1], (jerry_char_t *) string_from_cesu8, cesu8_sz);
-
-  TEST_ASSERT (utf8_sz == cesu8_sz);
-  TEST_ASSERT (!strncmp (string_from_utf8, string_from_cesu8, utf8_sz));
-  jerry_release_value (args[0]);
-  jerry_release_value (args[1]);
-
-  /* Test jerry_string_to_utf8_char_buffer, test string: 'str: {DESERET CAPITAL LETTER LONG I}' */
-  args[0] = jerry_create_string_from_utf8 ((jerry_char_t *) "\x73\x74\x72\x3a \xf0\x90\x90\x80");
-  args[1] = jerry_create_string ((jerry_char_t *) "\x73\x74\x72\x3a \xed\xa0\x81\xed\xb0\x80");
-
-  /* Test that the strings are equal / ensure hashes are equal */
-  TEST_ASSERT (strict_equals (args[0], args[1]));
-
-  /* These sizes must be equal */
-  utf8_sz = jerry_get_utf8_string_size (args[0]);
-  cesu8_sz = jerry_get_utf8_string_size (args[1]);
-
-  TEST_ASSERT (utf8_sz == cesu8_sz);
-
-  char string_from_utf8_string[utf8_sz];
-  char string_from_cesu8_string[cesu8_sz];
-
-  jerry_string_to_utf8_char_buffer (args[0], (jerry_char_t *) string_from_utf8_string, utf8_sz);
-  jerry_string_to_utf8_char_buffer (args[1], (jerry_char_t *) string_from_cesu8_string, cesu8_sz);
-
-  TEST_ASSERT (!strncmp (string_from_utf8_string, string_from_cesu8_string, utf8_sz));
-  jerry_release_value (args[0]);
-  jerry_release_value (args[1]);
-
-  /* Test string: 'str: {MATHEMATICAL FRAKTUR SMALL F}{MATHEMATICAL FRAKTUR SMALL G}' */
-  args[0] = jerry_create_string_from_utf8 ((jerry_char_t *) "\x73\x74\x72\x3a \xf0\x9d\x94\xa3 \xf0\x9d\x94\xa4");
-
-  cesu8_length = jerry_get_string_length (args[0]);
-  utf8_length = jerry_get_utf8_string_length (args[0]);
-
-  cesu8_sz = jerry_get_string_size (args[0]);
-  utf8_sz =  jerry_get_utf8_string_size (args[0]);
-
-  TEST_ASSERT (cesu8_length == 10 && utf8_length == 8);
-  TEST_ASSERT (cesu8_sz != utf8_sz);
-  TEST_ASSERT (utf8_sz == 14 && cesu8_sz == 18);
-
-  char test_string[utf8_sz];
-
-  TEST_ASSERT (jerry_string_to_utf8_char_buffer (args[0], (jerry_char_t *) test_string, utf8_sz) == 14);
-  TEST_ASSERT (!strncmp (test_string, "\x73\x74\x72\x3a \xf0\x9d\x94\xa3 \xf0\x9d\x94\xa4", utf8_sz));
-
-  sz = jerry_substring_to_utf8_char_buffer (args[0], 0, utf8_length, (jerry_char_t *) test_string, utf8_sz);
-  TEST_ASSERT (sz == 14);
-  TEST_ASSERT (!strncmp (test_string, "\x73\x74\x72\x3a \xf0\x9d\x94\xa3 \xf0\x9d\x94\xa4", sz));
-
-  sz = jerry_substring_to_utf8_char_buffer (args[0], 0, utf8_length + 1, (jerry_char_t *) test_string, utf8_sz);
-  TEST_ASSERT (sz == 14);
-  TEST_ASSERT (!strncmp (test_string, "\x73\x74\x72\x3a \xf0\x9d\x94\xa3 \xf0\x9d\x94\xa4", sz));
-
-  sz = jerry_substring_to_utf8_char_buffer (args[0], utf8_length, 0, (jerry_char_t *) test_string, utf8_sz);
-  TEST_ASSERT (sz == 0);
-
-  sz = jerry_substring_to_utf8_char_buffer (args[0], 0, utf8_length, (jerry_char_t *) test_string, utf8_sz - 1);
-  TEST_ASSERT (sz == 10);
-  TEST_ASSERT (!strncmp (test_string, "\x73\x74\x72\x3a \xf0\x9d\x94\xa3 ", sz));
-
-  sz = jerry_substring_to_utf8_char_buffer (args[0], 0, utf8_length - 1, (jerry_char_t *) test_string, utf8_sz);
-  TEST_ASSERT (sz == 10);
-  TEST_ASSERT (!strncmp (test_string, "\x73\x74\x72\x3a \xf0\x9d\x94\xa3 ", sz));
-
-  sz = jerry_substring_to_utf8_char_buffer (args[0],
-                                            utf8_length - 2,
-                                            utf8_length - 1,
-                                            (jerry_char_t *) test_string,
-                                            utf8_sz);
-  TEST_ASSERT (sz == 1);
-  TEST_ASSERT (!strncmp (test_string, " ", sz));
-
-  sz = jerry_substring_to_utf8_char_buffer (args[0],
-                                            utf8_length - 3,
-                                            utf8_length - 2,
-                                            (jerry_char_t *) test_string,
-                                            utf8_sz);
-  TEST_ASSERT (sz == 4);
-  TEST_ASSERT (!strncmp (test_string, "\xf0\x9d\x94\xa3", sz));
-
-  jerry_release_value (args[0]);
-
-  /* Test string: 'str: {DESERET CAPITAL LETTER LONG I}' */
-  args[0] = jerry_create_string ((jerry_char_t *) "\x73\x74\x72\x3a \xed\xa0\x81\xed\xb0\x80");
-
-  cesu8_length = jerry_get_string_length (args[0]);
-  utf8_length = jerry_get_utf8_string_length (args[0]);
-
-  cesu8_sz = jerry_get_string_size (args[0]);
-  utf8_sz =  jerry_get_utf8_string_size (args[0]);
-
-  TEST_ASSERT (cesu8_length == 7 && utf8_length == 6);
-  TEST_ASSERT (cesu8_sz != utf8_sz);
-  TEST_ASSERT (utf8_sz == 9 && cesu8_sz == 11);
-
-  jerry_release_value (args[0]);
-
-  /* Test string: 'price: 10{EURO SIGN}' */
-  args[0] = jerry_create_string_from_utf8 ((jerry_char_t *) "\x70\x72\x69\x63\x65\x3a \x31\x30\xe2\x82\xac");
-
-  cesu8_length = jerry_get_string_length (args[0]);
-  utf8_length = jerry_get_utf8_string_length (args[0]);
-
-  cesu8_sz = jerry_get_string_size (args[0]);
-  utf8_sz =  jerry_get_utf8_string_size (args[0]);
-
-  TEST_ASSERT (cesu8_length == utf8_length);
-  TEST_ASSERT (cesu8_length == 10);
-  TEST_ASSERT (cesu8_sz == utf8_sz);
-  TEST_ASSERT (utf8_sz == 12);
-  jerry_release_value (args[0]);
-
-  /* Test jerry_substring_to_char_buffer */
-  args[0] = jerry_create_string ((jerry_char_t *) "an ascii string");
-
-  /* Buffer size */
-  cesu8_sz = 5;
-
-  char substring[cesu8_sz];
-  sz = jerry_substring_to_char_buffer (args[0], 3, 8, (jerry_char_t *) substring, cesu8_sz);
-  TEST_ASSERT (sz == 5);
-  TEST_ASSERT (!strncmp (substring, "ascii", sz));
-
-  /* Buffer size is 5, substring length is 11 => copied only the first 5 char */
-  sz = jerry_substring_to_char_buffer (args[0], 0, 11, (jerry_char_t *) substring, cesu8_sz);
-
-  TEST_ASSERT (sz == 5);
-  TEST_ASSERT (!strncmp (substring, "an as", sz));
-
-  /* Position of the first character is greater than the string length */
-  sz = jerry_substring_to_char_buffer (args[0], 16, 21, (jerry_char_t *) substring, cesu8_sz);
-  TEST_ASSERT (sz == 0);
-
-  sz = jerry_substring_to_char_buffer (args[0], 14, 15, (jerry_char_t *) substring, cesu8_sz);
-  TEST_ASSERT (sz == 1);
-  TEST_ASSERT (!strncmp (substring, "g", sz));
-
-  sz = jerry_substring_to_char_buffer (args[0], 0, 1, (jerry_char_t *) substring, cesu8_sz);
-  TEST_ASSERT (sz == 1);
-  TEST_ASSERT (!strncmp (substring, "a", sz));
-
-  cesu8_length = jerry_get_string_length (args[0]);
-  cesu8_sz = jerry_get_string_size (args[0]);
-  TEST_ASSERT (cesu8_length == 15);
-  TEST_ASSERT (cesu8_length == cesu8_sz);
-
-  sz = jerry_substring_to_char_buffer (args[0], 0, cesu8_length, (jerry_char_t *) substring, cesu8_sz);
-  TEST_ASSERT (sz = 15);
-  TEST_ASSERT (!strncmp (substring, "an ascii string", sz));
-
-  jerry_release_value (args[0]);
-
-  /* Test jerry_substring_to_char_buffer: '0101' */
-  args[0] = jerry_create_string ((jerry_char_t *) "0101");
-  cesu8_sz = jerry_get_string_size (args[0]);
-
-  char number_substring[cesu8_sz];
-
-  sz = jerry_substring_to_char_buffer (args[0], 1, 3, (jerry_char_t *) number_substring, cesu8_sz);
-  TEST_ASSERT (sz == 2);
-  TEST_ASSERT (!strncmp (number_substring, "10", sz));
-
-  jerry_release_value (args[0]);
-
-  /* Test jerry_substring_to_char_buffer: 'str: {greek zero sign}' */
-  args[0] = jerry_create_string ((jerry_char_t *) "\x73\x74\x72\x3a \xed\xa0\x80\xed\xb6\x8a");
-  cesu8_sz = jerry_get_string_size (args[0]);
-  cesu8_length = jerry_get_string_length (args[0]);
-  TEST_ASSERT (cesu8_sz == 11);
-  TEST_ASSERT (cesu8_length = 7);
-
-  char supl_substring[cesu8_sz];
-
-  sz = jerry_substring_to_char_buffer (args[0], 0, cesu8_length, (jerry_char_t *) supl_substring, cesu8_sz);
-  TEST_ASSERT (sz == 11);
-  TEST_ASSERT (!strncmp (supl_substring, "\x73\x74\x72\x3a \xed\xa0\x80\xed\xb6\x8a", sz));
-
-  /* Decrease the buffer size => the low surrogate char will not fit into the buffer */
-  cesu8_sz -= 1;
-  sz = jerry_substring_to_char_buffer (args[0], 0, cesu8_length, (jerry_char_t *) supl_substring, cesu8_sz);
-  TEST_ASSERT (sz == 8);
-  TEST_ASSERT (!strncmp (supl_substring, "\x73\x74\x72\x3a \xed\xa0\x80", sz));
-
-  sz = jerry_substring_to_char_buffer (args[0],
-                                       cesu8_length - 1,
-                                       cesu8_length,
-                                       (jerry_char_t *) supl_substring,
-                                       cesu8_sz);
-  TEST_ASSERT (sz == 3);
-  TEST_ASSERT (!strncmp (supl_substring, "\xed\xb6\x8a", sz));
-
-  sz = jerry_substring_to_char_buffer (args[0],
-                                       cesu8_length - 2,
-                                       cesu8_length - 1,
-                                       (jerry_char_t *) supl_substring,
-                                       cesu8_sz);
-  TEST_ASSERT (sz == 3);
-  TEST_ASSERT (!strncmp (supl_substring, "\xed\xa0\x80", sz));
-
-  jerry_release_value (args[0]);
-
   /* Get global.boo (non-existing field) */
   val_t = get_property (global_obj_val, "boo");
-  TEST_ASSERT (!jerry_value_has_error_flag (val_t));
+  TEST_ASSERT (!jerry_value_is_error (val_t));
   TEST_ASSERT (jerry_value_is_undefined (val_t));
 
   /* Get global.t */
   val_t = get_property (global_obj_val, "t");
-  TEST_ASSERT (!jerry_value_has_error_flag (val_t));
+  TEST_ASSERT (!jerry_value_is_error (val_t));
   TEST_ASSERT (jerry_value_is_number (val_t)
                && jerry_get_number_value (val_t) == 1.0);
   jerry_release_value (val_t);
 
   /* Get global.foo */
   val_foo = get_property (global_obj_val, "foo");
-  TEST_ASSERT (!jerry_value_has_error_flag (val_foo));
+  TEST_ASSERT (!jerry_value_is_error (val_foo));
   TEST_ASSERT (jerry_value_is_object (val_foo));
 
   /* Call foo (4, 2) */
   args[0] = jerry_create_number (4);
   args[1] = jerry_create_number (2);
   res = jerry_call_function (val_foo, jerry_create_undefined (), args, 2);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_value_is_number (res)
                && jerry_get_number_value (res) == 1.0);
   jerry_release_value (res);
 
   /* Get global.bar */
   val_bar = get_property (global_obj_val, "bar");
-  TEST_ASSERT (!jerry_value_has_error_flag (val_bar));
+  TEST_ASSERT (!jerry_value_is_error (val_bar));
   TEST_ASSERT (jerry_value_is_object (val_bar));
 
   /* Call bar (4, 2) */
   res = jerry_call_function (val_bar, jerry_create_undefined (), args, 2);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_value_is_number (res)
                && jerry_get_number_value (res) == 5.0);
   jerry_release_value (res);
@@ -646,13 +398,13 @@ main (void)
   jerry_release_value (args[0]);
   args[0] = jerry_create_string ((jerry_char_t *) "abcd");
   res = set_property (global_obj_val, "t", args[0]);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_get_boolean_value (res));
   jerry_release_value (res);
 
   /* Call foo (4, 2) */
   res = jerry_call_function (val_foo, jerry_create_undefined (), args, 2);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_value_is_string (res));
   sz = jerry_get_string_size (res);
   TEST_ASSERT (sz == 4);
@@ -665,20 +417,20 @@ main (void)
 
   /* Get global.A */
   val_A = get_property (global_obj_val, "A");
-  TEST_ASSERT (!jerry_value_has_error_flag (val_A));
+  TEST_ASSERT (!jerry_value_is_error (val_A));
   TEST_ASSERT (jerry_value_is_object (val_A));
 
   /* Get A.prototype */
   is_ok = jerry_value_is_constructor (val_A);
   TEST_ASSERT (is_ok);
   val_A_prototype = get_property (val_A, "prototype");
-  TEST_ASSERT (!jerry_value_has_error_flag (val_A_prototype));
+  TEST_ASSERT (!jerry_value_is_error (val_A_prototype));
   TEST_ASSERT (jerry_value_is_object (val_A_prototype));
   jerry_release_value (val_A);
 
   /* Set A.prototype.foo = global.foo */
   res = set_property (val_A_prototype, "foo", val_foo);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_get_boolean_value (res));
   jerry_release_value (res);
   jerry_release_value (val_A_prototype);
@@ -686,12 +438,12 @@ main (void)
 
   /* Get global.a */
   val_a = get_property (global_obj_val, "a");
-  TEST_ASSERT (!jerry_value_has_error_flag (val_a));
+  TEST_ASSERT (!jerry_value_is_error (val_a));
   TEST_ASSERT (jerry_value_is_object (val_a));
 
   /* Get a.t */
   res = get_property (val_a, "t");
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_value_is_number (res)
                && jerry_get_number_value (res) == 12.0);
   jerry_release_value (res);
@@ -716,12 +468,12 @@ main (void)
 
   /* Get a.foo */
   val_a_foo = get_property (val_a, "foo");
-  TEST_ASSERT (!jerry_value_has_error_flag (val_a_foo));
+  TEST_ASSERT (!jerry_value_is_error (val_a_foo));
   TEST_ASSERT (jerry_value_is_object (val_a_foo));
 
   /* Call a.foo () */
   res = jerry_call_function (val_a_foo, val_a, NULL, 0);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_value_is_number (res)
                && jerry_get_number_value (res) == 12.0);
   jerry_release_value (res);
@@ -735,17 +487,17 @@ main (void)
                && jerry_value_is_constructor (external_func_val));
 
   res = set_property (global_obj_val, "external", external_func_val);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_get_boolean_value (res));
   jerry_release_value (external_func_val);
 
   /* Call 'call_external' function that should call external function created above */
   val_call_external = get_property (global_obj_val, "call_external");
-  TEST_ASSERT (!jerry_value_has_error_flag (val_call_external));
+  TEST_ASSERT (!jerry_value_is_error (val_call_external));
   TEST_ASSERT (jerry_value_is_object (val_call_external));
   res = jerry_call_function (val_call_external, global_obj_val, NULL, 0);
   jerry_release_value (val_call_external);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_value_is_string (res));
   sz = jerry_get_string_size (res);
   TEST_ASSERT (sz == 19);
@@ -760,19 +512,19 @@ main (void)
                && jerry_value_is_constructor (external_construct_val));
 
   res = set_property (global_obj_val, "external_construct", external_construct_val);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_get_boolean_value (res));
   jerry_release_value (res);
 
   /* Call external function created above, as constructor */
   args[0] = jerry_create_boolean (true);
   res = jerry_construct_object (external_construct_val, args, 1);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_value_is_object (res));
   val_value_field = get_property (res, "value_field");
 
   /* Get 'value_field' of constructed object */
-  TEST_ASSERT (!jerry_value_has_error_flag (val_value_field));
+  TEST_ASSERT (!jerry_value_is_error (val_value_field));
   TEST_ASSERT (jerry_value_is_boolean (val_value_field)
                && jerry_get_boolean_value (val_value_field));
   jerry_release_value (val_value_field);
@@ -805,40 +557,42 @@ main (void)
   TEST_ASSERT (jerry_value_is_function (throw_test_handler_val));
 
   res = set_property (global_obj_val, "throw_test", throw_test_handler_val);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_get_boolean_value (res));
   jerry_release_value (res);
   jerry_release_value (throw_test_handler_val);
 
   val_t = get_property (global_obj_val, "call_throw_test");
-  TEST_ASSERT (!jerry_value_has_error_flag (val_t));
+  TEST_ASSERT (!jerry_value_is_error (val_t));
   TEST_ASSERT (jerry_value_is_object (val_t));
 
   res = jerry_call_function (val_t, global_obj_val, NULL, 0);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   jerry_release_value (val_t);
   jerry_release_value (res);
 
   /* Test: Unhandled exception in called function */
   val_t = get_property (global_obj_val, "throw_reference_error");
-  TEST_ASSERT (!jerry_value_has_error_flag (val_t));
+  TEST_ASSERT (!jerry_value_is_error (val_t));
   TEST_ASSERT (jerry_value_is_object (val_t));
 
   res = jerry_call_function (val_t, global_obj_val, NULL, 0);
 
-  TEST_ASSERT (jerry_value_has_error_flag (res));
+  TEST_ASSERT (jerry_value_is_error (res));
   jerry_release_value (val_t);
 
   /* 'res' should contain exception object */
+  res = jerry_get_value_from_error (res, true);
   TEST_ASSERT (jerry_value_is_object (res));
   jerry_release_value (res);
 
   /* Test: Call of non-function */
   obj_val = jerry_create_object ();
   res = jerry_call_function (obj_val, global_obj_val, NULL, 0);
-  TEST_ASSERT (jerry_value_has_error_flag (res));
+  TEST_ASSERT (jerry_value_is_error (res));
 
   /* 'res' should contain exception object */
+  res = jerry_get_value_from_error (res, true);
   TEST_ASSERT (jerry_value_is_object (res));
   jerry_release_value (res);
 
@@ -846,23 +600,25 @@ main (void)
 
   /* Test: Unhandled exception in function called, as constructor */
   val_t = get_property (global_obj_val, "throw_reference_error");
-  TEST_ASSERT (!jerry_value_has_error_flag (val_t));
+  TEST_ASSERT (!jerry_value_is_error (val_t));
   TEST_ASSERT (jerry_value_is_object (val_t));
 
   res = jerry_construct_object (val_t, NULL, 0);
-  TEST_ASSERT (jerry_value_has_error_flag (res));
+  TEST_ASSERT (jerry_value_is_error (res));
   jerry_release_value (val_t);
 
   /* 'res' should contain exception object */
+  res = jerry_get_value_from_error (res, true);
   TEST_ASSERT (jerry_value_is_object (res));
   jerry_release_value (res);
 
   /* Test: Call of non-function as constructor */
   obj_val = jerry_create_object ();
   res = jerry_construct_object (obj_val, NULL, 0);
-  TEST_ASSERT (jerry_value_has_error_flag (res));
+  TEST_ASSERT (jerry_value_is_error (res));
 
   /* 'res' should contain exception object */
+  res = jerry_get_value_from_error (res, true);
   TEST_ASSERT (jerry_value_is_object (res));
   jerry_release_value (res);
 
@@ -890,96 +646,54 @@ main (void)
   jerry_release_value (v_und);
   jerry_release_value (array_obj_val);
 
-  /* Test: init property descriptor */
-  jerry_property_descriptor_t prop_desc;
-  jerry_init_property_descriptor_fields (&prop_desc);
-  TEST_ASSERT (prop_desc.is_value_defined == false);
-  TEST_ASSERT (jerry_value_is_undefined (prop_desc.value));
-  TEST_ASSERT (prop_desc.is_writable_defined == false);
-  TEST_ASSERT (prop_desc.is_writable == false);
-  TEST_ASSERT (prop_desc.is_enumerable_defined == false);
-  TEST_ASSERT (prop_desc.is_enumerable == false);
-  TEST_ASSERT (prop_desc.is_configurable_defined == false);
-  TEST_ASSERT (prop_desc.is_configurable == false);
-  TEST_ASSERT (prop_desc.is_get_defined == false);
-  TEST_ASSERT (jerry_value_is_undefined (prop_desc.getter));
-  TEST_ASSERT (prop_desc.is_set_defined == false);
-  TEST_ASSERT (jerry_value_is_undefined (prop_desc.setter));
-
-  /* Test: define own properties */
-  jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "my_defined_property");
-  prop_desc.is_value_defined = true;
-  prop_desc.value = jerry_acquire_value (prop_name);
-  res = jerry_define_own_property (global_obj_val, prop_name, &prop_desc);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
-  TEST_ASSERT (jerry_value_is_boolean (res));
-  TEST_ASSERT (jerry_get_boolean_value (res));
-  jerry_release_value (res);
-  jerry_free_property_descriptor_fields (&prop_desc);
-
-  /* Test: get own property descriptor */
-  is_ok = jerry_get_own_property_descriptor (global_obj_val, prop_name, &prop_desc);
-  TEST_ASSERT (is_ok);
-  TEST_ASSERT (prop_desc.is_value_defined == true);
-  TEST_ASSERT (jerry_value_is_string (prop_desc.value));
-  TEST_ASSERT (prop_desc.is_writable == false);
-  TEST_ASSERT (prop_desc.is_enumerable == false);
-  TEST_ASSERT (prop_desc.is_configurable == false);
-  TEST_ASSERT (prop_desc.is_get_defined == false);
-  TEST_ASSERT (jerry_value_is_undefined (prop_desc.getter));
-  TEST_ASSERT (prop_desc.is_set_defined == false);
-  TEST_ASSERT (jerry_value_is_undefined (prop_desc.setter));
-  jerry_release_value (prop_name);
-  jerry_free_property_descriptor_fields (&prop_desc);
-
   /* Test: object keys */
   res = jerry_get_object_keys (global_obj_val);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_value_is_array (res));
   jerry_release_value (res);
 
   /* Test: jerry_value_to_primitive */
-  obj_val = jerry_eval ((jerry_char_t *) "new String ('hello')", 20, false);
-  TEST_ASSERT (!jerry_value_has_error_flag (obj_val));
+  obj_val = jerry_eval ((jerry_char_t *) "new String ('hello')", 20, JERRY_PARSE_NO_OPTS);
+  TEST_ASSERT (!jerry_value_is_error (obj_val));
   TEST_ASSERT (jerry_value_is_object (obj_val));
   TEST_ASSERT (!jerry_value_is_string (obj_val));
   prim_val = jerry_value_to_primitive (obj_val);
-  TEST_ASSERT (!jerry_value_has_error_flag (prim_val));
+  TEST_ASSERT (!jerry_value_is_error (prim_val));
   TEST_ASSERT (jerry_value_is_string (prim_val));
   jerry_release_value (prim_val);
 
   /* Test: jerry_get_prototype */
   proto_val = jerry_get_prototype (obj_val);
-  TEST_ASSERT (!jerry_value_has_error_flag (proto_val));
+  TEST_ASSERT (!jerry_value_is_error (proto_val));
   TEST_ASSERT (jerry_value_is_object (proto_val));
   jerry_release_value (obj_val);
 
   /* Test: jerry_set_prototype */
   obj_val = jerry_create_object ();
   res = jerry_set_prototype (obj_val, jerry_create_null ());
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_value_is_boolean (res));
   TEST_ASSERT (jerry_get_boolean_value (res));
 
   res = jerry_set_prototype (obj_val, jerry_create_object ());
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_value_is_boolean (res));
   TEST_ASSERT (jerry_get_boolean_value (res));
   proto_val = jerry_get_prototype (obj_val);
-  TEST_ASSERT (!jerry_value_has_error_flag (proto_val));
+  TEST_ASSERT (!jerry_value_is_error (proto_val));
   TEST_ASSERT (jerry_value_is_object (proto_val));
   jerry_release_value (proto_val);
   jerry_release_value (obj_val);
 
   /* Test: eval */
-  const char *eval_code_src_p = "(function () { return 123; })";
-  val_t = jerry_eval ((jerry_char_t *) eval_code_src_p, strlen (eval_code_src_p), true);
-  TEST_ASSERT (!jerry_value_has_error_flag (val_t));
+  const jerry_char_t eval_code_src1[] = "(function () { return 123; })";
+  val_t = jerry_eval (eval_code_src1, sizeof (eval_code_src1) - 1, JERRY_PARSE_STRICT_MODE);
+  TEST_ASSERT (!jerry_value_is_error (val_t));
   TEST_ASSERT (jerry_value_is_object (val_t));
   TEST_ASSERT (jerry_value_is_function (val_t));
 
   res = jerry_call_function (val_t, jerry_create_undefined (), NULL, 0);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_value_is_number (res)
                && jerry_get_number_value (res) == 123.0);
   jerry_release_value (res);
@@ -990,12 +704,12 @@ main (void)
   jerry_release_value (global_obj_val);
 
   /* Test: run gc. */
-  jerry_gc ();
+  jerry_gc (JERRY_GC_SEVERITY_LOW);
 
   /* Test: spaces */
-  eval_code_src_p = "\x0a \x0b \x0c \xc2\xa0 \xe2\x80\xa8 \xe2\x80\xa9 \xef\xbb\xbf 4321";
-  val_t = jerry_eval ((jerry_char_t *) eval_code_src_p, strlen (eval_code_src_p), true);
-  TEST_ASSERT (!jerry_value_has_error_flag (val_t));
+  const jerry_char_t eval_code_src2[] = "\x0a \x0b \x0c \xc2\xa0 \xe2\x80\xa8 \xe2\x80\xa9 \xef\xbb\xbf 4321";
+  val_t = jerry_eval (eval_code_src2, sizeof (eval_code_src2) - 1, JERRY_PARSE_STRICT_MODE);
+  TEST_ASSERT (!jerry_value_is_error (val_t));
   TEST_ASSERT (jerry_value_is_number (val_t)
                && jerry_get_number_value (val_t) == 4321.0);
   jerry_release_value (val_t);
@@ -1017,19 +731,19 @@ main (void)
   jerry_release_value (val_t);
 
   /* Test: create function */
-  const char *func_resource = "unknown";
-  const char *func_arg_list = "a , b,c";
-  const char *func_src = "  return 5 +  a+\nb+c";
-
-  jerry_value_t func_val = jerry_parse_function ((const jerry_char_t *) func_resource,
-                                                 strlen (func_resource),
-                                                 (const jerry_char_t *) func_arg_list,
-                                                 strlen (func_arg_list),
-                                                 (const jerry_char_t *) func_src,
-                                                 strlen (func_src),
+  const jerry_char_t func_resource[] = "unknown";
+  const jerry_char_t func_arg_list[] = "a , b,c";
+  const jerry_char_t func_src[] = "  return 5 +  a+\nb+c";
+
+  jerry_value_t func_val = jerry_parse_function (func_resource,
+                                                 sizeof (func_resource) - 1,
+                                                 func_arg_list,
+                                                 sizeof (func_arg_list) - 1,
+                                                 func_src,
+                                                 sizeof (func_src) - 1,
                                                  JERRY_PARSE_NO_OPTS);
 
-  TEST_ASSERT (!jerry_value_has_error_flag (func_val));
+  TEST_ASSERT (!jerry_value_is_error (func_val));
 
   jerry_value_t func_args[3] =
   {
@@ -1049,17 +763,21 @@ main (void)
 
   TEST_ASSERT (test_api_is_free_callback_was_called);
 
-  /* Test: jerry_get_value_without_error_flag */
+  /* Test: jerry_get_value_from_error */
   {
     jerry_init (JERRY_INIT_EMPTY);
     jerry_value_t num_val = jerry_create_number (123);
-    jerry_value_set_error_flag (&num_val);
-    TEST_ASSERT (jerry_value_has_error_flag (num_val));
-    jerry_value_t num2_val = jerry_get_value_without_error_flag (num_val);
-    TEST_ASSERT (!jerry_value_has_error_flag (num2_val));
+    num_val = jerry_create_error_from_value (num_val, true);
+    TEST_ASSERT (jerry_value_is_error (num_val));
+    jerry_value_t num2_val = jerry_get_value_from_error (num_val, false);
+    TEST_ASSERT (jerry_value_is_error (num_val));
+    TEST_ASSERT (!jerry_value_is_error (num2_val));
     double num = jerry_get_number_value (num2_val);
     TEST_ASSERT (num == 123);
-    jerry_release_value (num_val);
+    num2_val = jerry_get_value_from_error (num_val, true);
+    TEST_ASSERT (!jerry_value_is_error (num2_val));
+    num = jerry_get_number_value (num2_val);
+    TEST_ASSERT (num == 123);
     jerry_release_value (num2_val);
     jerry_cleanup ();
   }
@@ -1069,14 +787,14 @@ main (void)
   {
     jerry_init (JERRY_INIT_SHOW_OPCODES);
 
-    const char *parser_err_src_p = "b = 'hello';\nvar a = (;";
+    const jerry_char_t parser_err_src[] = "b = 'hello';\nvar a = (;";
     parsed_code_val = jerry_parse (NULL,
                                    0,
-                                   (jerry_char_t *) parser_err_src_p,
-                                   strlen (parser_err_src_p),
+                                   parser_err_src,
+                                   sizeof (parser_err_src) - 1,
                                    JERRY_PARSE_NO_OPTS);
-    TEST_ASSERT (jerry_value_has_error_flag (parsed_code_val));
-    jerry_value_clear_error_flag (&parsed_code_val);
+    TEST_ASSERT (jerry_value_is_error (parsed_code_val));
+    parsed_code_val = jerry_get_value_from_error (parsed_code_val, true);
     jerry_value_t err_str_val = jerry_value_to_string (parsed_code_val);
     jerry_size_t err_str_size = jerry_get_string_size (err_str_val);
     jerry_char_t err_str_buf[256];
@@ -1094,21 +812,21 @@ main (void)
   /* External Magic String */
   jerry_init (JERRY_INIT_SHOW_OPCODES);
 
-  uint32_t num_magic_string_items = (uint32_t) (sizeof (magic_string_items) / sizeof (jerry_char_ptr_t));
+  uint32_t num_magic_string_items = (uint32_t) (sizeof (magic_string_items) / sizeof (jerry_char_t *));
   jerry_register_magic_strings (magic_string_items,
                                 num_magic_string_items,
                                 magic_string_lengths);
 
-  const char *ms_code_src_p = "var global = {}; var console = [1]; var process = 1;";
+  const jerry_char_t ms_code_src[] = "var global = {}; var console = [1]; var process = 1;";
   parsed_code_val = jerry_parse (NULL,
                                  0,
-                                 (jerry_char_t *) ms_code_src_p,
-                                 strlen (ms_code_src_p),
+                                 ms_code_src,
+                                 sizeof (ms_code_src) - 1,
                                  JERRY_PARSE_NO_OPTS);
-  TEST_ASSERT (!jerry_value_has_error_flag (parsed_code_val));
+  TEST_ASSERT (!jerry_value_is_error (parsed_code_val));
 
   res = jerry_run (parsed_code_val);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   jerry_release_value (res);
   jerry_release_value (parsed_code_val);
 
@@ -1128,10 +846,10 @@ main (void)
 
   jerry_release_value (args[0]);
 
-  const char *test_magic_str_access_src_p = "'console'.charAt(6) == 'e'";
-  res = jerry_eval ((const jerry_char_t *) test_magic_str_access_src_p,
-                    strlen (test_magic_str_access_src_p),
-                    false);
+  const jerry_char_t test_magic_str_access_src[] = "'console'.charAt(6) == 'e'";
+  res = jerry_eval (test_magic_str_access_src,
+                    sizeof (test_magic_str_access_src) - 1,
+                    JERRY_PARSE_NO_OPTS);
   TEST_ASSERT (jerry_value_is_boolean (res));
   TEST_ASSERT (jerry_get_boolean_value (res) == true);
 
@@ -1151,22 +869,20 @@ main (void)
 
   {
     /*json parser check*/
-    char data_check[]="John";
+    const char data_check[]="John";
     jerry_value_t key = jerry_create_string ((const jerry_char_t *) "name");
-    const char *data = "{\"name\": \"John\", \"age\": 5}";
-    jerry_size_t str_length = (jerry_size_t) strlen (data);
-    jerry_value_t parsed_json = jerry_json_parse ((jerry_char_t *) data, str_length);
+    const jerry_char_t data[] = "{\"name\": \"John\", \"age\": 5}";
+    jerry_value_t parsed_json = jerry_json_parse (data, sizeof (data) - 1);
     jerry_value_t has_prop_js = jerry_has_property (parsed_json, key);
     TEST_ASSERT (jerry_get_boolean_value (has_prop_js));
     jerry_release_value (has_prop_js);
     jerry_value_t parsed_data = jerry_get_property (parsed_json, key);
     TEST_ASSERT (jerry_value_is_string (parsed_data)== true);
-    jerry_size_t buff_size = (jerry_size_t) jerry_get_string_length (parsed_data);
     char buff[jerry_get_string_length (parsed_data)];
-    jerry_char_t *buff_p = (jerry_char_t *) buff;
-    jerry_string_to_char_buffer (parsed_data, buff_p, buff_size);
+    jerry_size_t buff_size = (jerry_size_t) jerry_get_string_length (parsed_data);
+    jerry_string_to_char_buffer (parsed_data, (jerry_char_t *) buff, buff_size);
     buff[buff_size] = '\0';
-    TEST_ASSERT (strcmp ((const char *) data_check, (const char *) buff) == false);
+    TEST_ASSERT (strcmp (data_check, buff) == false);
     jerry_release_value (parsed_json);
     jerry_release_value (key);
     jerry_release_value (parsed_data);
@@ -1179,7 +895,7 @@ main (void)
     jerry_value_t key = jerry_create_string ((const jerry_char_t *) "name");
     jerry_value_t value = jerry_create_string ((const jerry_char_t *) "John");
     jerry_set_property (obj, key, value);
-    jerry_value_t stringified = jerry_json_stringfy (obj);
+    jerry_value_t stringified = jerry_json_stringify (obj);
     TEST_ASSERT (jerry_value_is_string (stringified));
     char buff[jerry_get_string_length (stringified)];
     jerry_string_to_char_buffer (stringified, (jerry_char_t *) buff,
index eead34cf3d0b5122721e26c87413daa28b9c8c77..86cee9da86f5afcf610f7dd3470ca52a552dbf49 100644 (file)
@@ -68,39 +68,22 @@ assert_handler (const jerry_value_t func_obj_val, /**< function object */
   TEST_ASSERT (false);
 } /* assert_handler */
 
-/**
- * Checks whether global object has arraybuffer.
- */
-static bool
-arraybuffer_is_available (void)
-{
-  jerry_value_t global_obj_val = jerry_get_global_object ();
-  jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "ArrayBuffer");
-
-  jerry_value_t prop_value = jerry_has_property (global_obj_val, prop_name);
-  bool has_prop = jerry_get_boolean_value (prop_value);
-
-  jerry_release_value (global_obj_val);
-  jerry_release_value (prop_name);
-  jerry_release_value (prop_value);
-
-  return has_prop;
-} /* arraybuffer_is_available */
-
 /**
  * Test ArrayBuffer 'read' api call with various offset values.
  */
 static void
 test_read_with_offset (uint8_t offset) /**< offset for buffer read. */
 {
-  const char *eval_arraybuffer_src_p = ("var array = new Uint8Array (15);"
-                                        "for (var i = 0; i < array.length; i++) { array[i] = i * 2; };"
-                                        "array.buffer");
-  jerry_value_t arraybuffer = jerry_eval ((jerry_char_t *) eval_arraybuffer_src_p,
-                                          strlen (eval_arraybuffer_src_p),
-                                          true);
-
-  TEST_ASSERT (!jerry_value_has_error_flag (arraybuffer));
+  const jerry_char_t eval_arraybuffer_src[] = TEST_STRING_LITERAL (
+    "var array = new Uint8Array (15);"
+    "for (var i = 0; i < array.length; i++) { array[i] = i * 2; };"
+    "array.buffer"
+  );
+  jerry_value_t arraybuffer = jerry_eval (eval_arraybuffer_src,
+                                          sizeof (eval_arraybuffer_src) - 1,
+                                          JERRY_PARSE_STRICT_MODE);
+
+  TEST_ASSERT (!jerry_value_is_error (arraybuffer));
   TEST_ASSERT (jerry_value_is_arraybuffer (arraybuffer));
   TEST_ASSERT (jerry_get_arraybuffer_byte_length (arraybuffer) == 15);
 
@@ -131,12 +114,12 @@ static void test_write_with_offset (uint8_t offset) /**< offset for buffer write
     jerry_release_value (offset_val);
   }
 
-  const char *eval_arraybuffer_src_p = "var array = new Uint8Array (15); array.buffer";
-  jerry_value_t arraybuffer = jerry_eval ((jerry_char_t *) eval_arraybuffer_src_p,
-                                          strlen (eval_arraybuffer_src_p),
-                                          true);
+  const jerry_char_t eval_arraybuffer_src[] = "var array = new Uint8Array (15); array.buffer";
+  jerry_value_t arraybuffer = jerry_eval (eval_arraybuffer_src,
+                                          sizeof (eval_arraybuffer_src) - 1,
+                                          JERRY_PARSE_STRICT_MODE);
 
-  TEST_ASSERT (!jerry_value_has_error_flag (arraybuffer));
+  TEST_ASSERT (!jerry_value_is_error (arraybuffer));
   TEST_ASSERT (jerry_value_is_arraybuffer (arraybuffer));
   TEST_ASSERT (jerry_get_arraybuffer_byte_length (arraybuffer) == 15);
 
@@ -151,20 +134,21 @@ static void test_write_with_offset (uint8_t offset) /**< offset for buffer write
   jerry_length_t copied = jerry_arraybuffer_write (arraybuffer, offset, buffer, 20);
   TEST_ASSERT (copied == (jerry_length_t)(15 - offset));
 
-  const char *eval_test_arraybuffer_p = (
-      "for (var i = 0; i < offset; i++)"
-      "{"
-      "  assert (array[i] == 0, 'offset check for: ' + i + ' was: ' + array[i] + ' should be: 0');"
-      "};"
-      "for (var i = offset; i < array.length; i++)"
-      "{"
-      "  var expected = (i - offset) * 3;"
-      "  assert (array[i] == expected, 'calc check for: ' + i + ' was: ' + array[i] + ' should be: ' + expected);"
-      "};"
-      "assert (array[15] === undefined, 'ArrayBuffer out of bounds index should return undefined value');");
-  jerry_value_t res = jerry_eval ((jerry_char_t *) eval_test_arraybuffer_p,
-                                  strlen (eval_test_arraybuffer_p),
-                                  true);
+  const jerry_char_t eval_test_arraybuffer[] = TEST_STRING_LITERAL (
+    "for (var i = 0; i < offset; i++)"
+    "{"
+    "  assert (array[i] == 0, 'offset check for: ' + i + ' was: ' + array[i] + ' should be: 0');"
+    "};"
+    "for (var i = offset; i < array.length; i++)"
+    "{"
+    "  var expected = (i - offset) * 3;"
+    "  assert (array[i] == expected, 'calc check for: ' + i + ' was: ' + array[i] + ' should be: ' + expected);"
+    "};"
+    "assert (array[15] === undefined, 'ArrayBuffer out of bounds index should return undefined value');"
+  );
+  jerry_value_t res = jerry_eval (eval_test_arraybuffer,
+                                  sizeof (eval_test_arraybuffer) - 1,
+                                  JERRY_PARSE_STRICT_MODE);
   jerry_release_value (res);
   jerry_release_value (arraybuffer);
 } /* test_write_with_offset */
@@ -182,7 +166,7 @@ main (void)
 {
   jerry_init (JERRY_INIT_EMPTY);
 
-  if (!arraybuffer_is_available ())
+  if (!jerry_is_feature_enabled (JERRY_FEATURE_TYPEDARRAY))
   {
     jerry_port_log (JERRY_LOG_LEVEL_ERROR, "ArrayBuffer is disabled!\n");
     jerry_cleanup ();
@@ -195,11 +179,11 @@ main (void)
 
   /* Test array buffer queries */
   {
-    const char *eval_arraybuffer_src_p = "new ArrayBuffer (10)";
-    jerry_value_t eval_arraybuffer = jerry_eval ((jerry_char_t *) eval_arraybuffer_src_p,
-                                                 strlen (eval_arraybuffer_src_p),
-                                                 true);
-    TEST_ASSERT (!jerry_value_has_error_flag (eval_arraybuffer));
+    const jerry_char_t eval_arraybuffer_src[] = "new ArrayBuffer (10)";
+    jerry_value_t eval_arraybuffer = jerry_eval (eval_arraybuffer_src,
+                                                 sizeof (eval_arraybuffer_src) - 1,
+                                                 JERRY_PARSE_STRICT_MODE);
+    TEST_ASSERT (!jerry_value_is_error (eval_arraybuffer));
     TEST_ASSERT (jerry_value_is_arraybuffer (eval_arraybuffer));
     TEST_ASSERT (jerry_get_arraybuffer_byte_length (eval_arraybuffer) == 10);
     jerry_release_value (eval_arraybuffer);
@@ -209,7 +193,7 @@ main (void)
   {
     const uint32_t length = 15;
     jerry_value_t arraybuffer = jerry_create_arraybuffer (length);
-    TEST_ASSERT (!jerry_value_has_error_flag (arraybuffer));
+    TEST_ASSERT (!jerry_value_is_error (arraybuffer));
     TEST_ASSERT (jerry_value_is_arraybuffer (arraybuffer));
     TEST_ASSERT (jerry_get_arraybuffer_byte_length (arraybuffer) == length);
     jerry_release_value (arraybuffer);
@@ -225,7 +209,7 @@ main (void)
   {
     const uint32_t length = 0;
     jerry_value_t arraybuffer = jerry_create_arraybuffer (length);
-    TEST_ASSERT (!jerry_value_has_error_flag (arraybuffer));
+    TEST_ASSERT (!jerry_value_is_error (arraybuffer));
     TEST_ASSERT (jerry_value_is_arraybuffer (arraybuffer));
     TEST_ASSERT (jerry_get_arraybuffer_byte_length (arraybuffer) == length);
 
@@ -253,7 +237,7 @@ main (void)
   {
     const uint32_t length = 0;
     jerry_value_t arraybuffer = jerry_create_arraybuffer (length);
-    TEST_ASSERT (!jerry_value_has_error_flag (arraybuffer));
+    TEST_ASSERT (!jerry_value_is_error (arraybuffer));
     TEST_ASSERT (jerry_value_is_arraybuffer (arraybuffer));
     TEST_ASSERT (jerry_get_arraybuffer_byte_length (arraybuffer) == length);
 
@@ -310,18 +294,19 @@ main (void)
       jerry_release_value (input_buffer);
     }
 
-    const char *eval_arraybuffer_src_p = (
+    const jerry_char_t eval_arraybuffer_src[] = TEST_STRING_LITERAL (
       "var array = new Uint8Array(input_buffer);"
       "for (var i = 0; i < array.length; i++)"
       "{"
       "  array[i] = i * 2;"
       "};"
-      "array.buffer");
-    jerry_value_t buffer = jerry_eval ((jerry_char_t *) eval_arraybuffer_src_p,
-                                        strlen (eval_arraybuffer_src_p),
-                                        true);
+      "array.buffer"
+    );
+    jerry_value_t buffer = jerry_eval (eval_arraybuffer_src,
+                                       sizeof (eval_arraybuffer_src) - 1,
+                                       JERRY_PARSE_STRICT_MODE);
 
-    TEST_ASSERT (!jerry_value_has_error_flag (buffer));
+    TEST_ASSERT (!jerry_value_is_error (buffer));
     TEST_ASSERT (jerry_value_is_arraybuffer (buffer));
     TEST_ASSERT (jerry_get_arraybuffer_byte_length (buffer) == 20);
 
@@ -343,7 +328,7 @@ main (void)
 
     jerry_release_value (buffer);
 
-    const char *eval_test_arraybuffer_p = (
+    const jerry_char_t eval_test_arraybuffer[] = TEST_STRING_LITERAL (
       "var sum = 0;"
       "for (var i = 0; i < array.length; i++)"
       "{"
@@ -351,10 +336,11 @@ main (void)
       "  assert(array[i] == expected, 'Array at index ' + i + ' was: ' + array[i] + ' should be: ' + expected);"
       "  sum += array[i]"
       "};"
-      "sum");
-    jerry_value_t res = jerry_eval ((jerry_char_t *) eval_test_arraybuffer_p,
-                                    strlen (eval_test_arraybuffer_p),
-                                    true);
+      "sum"
+    );
+    jerry_value_t res = jerry_eval (eval_test_arraybuffer,
+                                    sizeof (eval_test_arraybuffer) - 1,
+                                    JERRY_PARSE_STRICT_MODE);
     TEST_ASSERT (jerry_value_is_number (res));
     TEST_ASSERT (jerry_get_number_value (res) == sum);
     jerry_release_value (res);
@@ -365,7 +351,7 @@ main (void)
   /* Test ArrayBuffer external with invalid arguments */
   {
     jerry_value_t input_buffer = jerry_create_arraybuffer_external (0, NULL, NULL);
-    TEST_ASSERT (jerry_value_has_error_flag (input_buffer));
+    TEST_ASSERT (jerry_value_is_error (input_buffer));
     TEST_ASSERT (jerry_get_error_type (input_buffer) == JERRY_ERROR_RANGE);
     jerry_release_value (input_buffer);
   }
@@ -373,4 +359,6 @@ main (void)
   jerry_cleanup ();
 
   TEST_ASSERT (callback_called == true);
+
+  return 0;
 } /* main */
index 02fdf5fd779a64a0748516d8c0dd097885742457..663d1be71386c22f4af6361e24d2c3caaa8a7830 100644 (file)
@@ -45,7 +45,7 @@ run (const char *resource_name_p, /**< resource name */
                                     (const jerry_char_t *) source_p,
                                     strlen (source_p),
                                     JERRY_PARSE_NO_OPTS);
-  TEST_ASSERT (!jerry_value_has_error_flag (code));
+  TEST_ASSERT (!jerry_value_is_error (code));
 
   jerry_value_t result = jerry_run (code);
   jerry_release_value (code);
@@ -66,7 +66,7 @@ compare (jerry_value_t array, /**< array */
 
   jerry_value_t value = jerry_get_property_by_index (array, index);
 
-  TEST_ASSERT (!jerry_value_has_error_flag (value)
+  TEST_ASSERT (!jerry_value_is_error (value)
                && jerry_value_is_string (value));
 
   TEST_ASSERT (jerry_get_string_size (value) == len);
@@ -79,13 +79,9 @@ compare (jerry_value_t array, /**< array */
   TEST_ASSERT (memcmp (buf, str, len) == 0);
 } /* compare */
 
-int
-main (void)
+static void
+test_get_backtrace_api_call (void)
 {
-  TEST_INIT ();
-
-  TEST_ASSERT (jerry_is_feature_enabled (JERRY_FEATURE_LINE_INFO));
-
   jerry_init (JERRY_INIT_EMPTY);
 
   jerry_value_t global = jerry_get_global_object ();
@@ -93,7 +89,7 @@ main (void)
   jerry_value_t func = jerry_create_external_function (backtrace_handler);
   jerry_value_t name = jerry_create_string ((const jerry_char_t *) "backtrace");
   jerry_value_t result = jerry_set_property (global, name, func);
-  TEST_ASSERT (!jerry_value_has_error_flag (result));
+  TEST_ASSERT (!jerry_value_is_error (result));
 
   jerry_release_value (result);
   jerry_release_value (name);
@@ -117,7 +113,7 @@ main (void)
 
   jerry_value_t backtrace = run ("something.js", source);
 
-  TEST_ASSERT (!jerry_value_has_error_flag (backtrace)
+  TEST_ASSERT (!jerry_value_is_error (backtrace)
                && jerry_value_is_array (backtrace));
 
   TEST_ASSERT (jerry_get_array_length (backtrace) == 4);
@@ -147,7 +143,7 @@ main (void)
 
   backtrace = run ("something_else.js", source);
 
-  TEST_ASSERT (!jerry_value_has_error_flag (backtrace)
+  TEST_ASSERT (!jerry_value_is_error (backtrace)
                && jerry_value_is_array (backtrace));
 
   TEST_ASSERT (jerry_get_array_length (backtrace) == 2);
@@ -158,34 +154,38 @@ main (void)
   jerry_release_value (backtrace);
 
   jerry_cleanup ();
+} /* test_get_backtrace_api_call */
 
+static void
+test_exception_backtrace (void)
+{
   jerry_init (JERRY_INIT_EMPTY);
 
-  source = ("function f() {\n"
-            "  undef_reference;\n"
-            "}\n"
-            "\n"
-            "function g() {\n"
-            "  return f();\n"
-            "}\n"
-            "\n"
-            "g();\n");
+  const char *source = ("function f() {\n"
+                        "  undef_reference;\n"
+                        "}\n"
+                        "\n"
+                        "function g() {\n"
+                        "  return f();\n"
+                        "}\n"
+                        "\n"
+                        "g();\n");
 
   jerry_value_t error = run ("bad.js", source);
 
-  TEST_ASSERT (jerry_value_has_error_flag (error));
+  TEST_ASSERT (jerry_value_is_error (error));
 
-  jerry_value_clear_error_flag (&error);
+  error = jerry_get_value_from_error (error, true);
 
   TEST_ASSERT (jerry_value_is_object (error));
 
-  name = jerry_create_string ((const jerry_char_t *) "stack");
-  backtrace = jerry_get_property (error, name);
+  jerry_value_t name = jerry_create_string ((const jerry_char_t *) "stack");
+  jerry_value_t backtrace = jerry_get_property (error, name);
 
   jerry_release_value (name);
   jerry_release_value (error);
 
-  TEST_ASSERT (!jerry_value_has_error_flag (backtrace)
+  TEST_ASSERT (!jerry_value_is_error (backtrace)
                && jerry_value_is_array (backtrace));
 
   TEST_ASSERT (jerry_get_array_length (backtrace) == 3);
@@ -197,6 +197,63 @@ main (void)
   jerry_release_value (backtrace);
 
   jerry_cleanup ();
+} /* test_exception_backtrace */
+
+static void
+test_large_line_count (void)
+{
+  jerry_init (JERRY_INIT_EMPTY);
+
+  const char *source = ("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+                        "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+                        "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+                        "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+                        "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+                        "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+                        "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+                        "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+                        "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+                        "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+                        "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+                        "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+                        "g();\n");
+
+  jerry_value_t error = run ("bad.js", source);
+
+  TEST_ASSERT (jerry_value_is_error (error));
+
+  error = jerry_get_value_from_error (error, true);
+
+  TEST_ASSERT (jerry_value_is_object (error));
+
+  jerry_value_t name = jerry_create_string ((const jerry_char_t *) "stack");
+  jerry_value_t backtrace = jerry_get_property (error, name);
+
+  jerry_release_value (name);
+  jerry_release_value (error);
+
+  TEST_ASSERT (!jerry_value_is_error (backtrace)
+               && jerry_value_is_array (backtrace));
+
+  TEST_ASSERT (jerry_get_array_length (backtrace) == 1);
+
+  compare (backtrace, 0, "bad.js:385");
+
+  jerry_release_value (backtrace);
+
+  jerry_cleanup ();
+} /* test_large_line_count */
+
+int
+main (void)
+{
+  TEST_INIT ();
+
+  TEST_ASSERT (jerry_is_feature_enabled (JERRY_FEATURE_LINE_INFO));
+
+  test_get_backtrace_api_call ();
+  test_exception_backtrace ();
+  test_large_line_count ();
 
   return 0;
 } /* main */
index 3a647d56451ef2b89fef0c9c8a0b52cc76b7343b..65b00049a510b4ceba6bf16cda928ab6d55838a3 100644 (file)
@@ -28,7 +28,7 @@
 #define TEST_ASSERT(x) \
   do \
   { \
-    if (unlikely (!(x))) \
+    if (JERRY_UNLIKELY (!(x))) \
     { \
       jerry_port_log (JERRY_LOG_LEVEL_ERROR, \
                       "TEST: Assertion '%s' failed at %s(%s):%lu.\n", \
@@ -50,4 +50,12 @@ do \
   srand ((unsigned) jerry_port_get_current_time ()); \
 } while (0)
 
+/**
+ * Dummy macro to enable the breaking of long string literals into multiple
+ * substrings on separate lines. (Style checker doesn't allow it without putting
+ * the whole literal into parentheses but the compiler warns about parenthesized
+ * string constants.)
+ */
+#define TEST_STRING_LITERAL(x) x
+
 #endif /* !TEST_COMMON_H */
index 94b1d7ea2826393ee6eb2620b2e647ab757b4599..36b0ae18332c5c5e131f6b3c4d38ae1ca30fb8be 100644 (file)
@@ -49,18 +49,18 @@ main (void)
   int countdown = 6;
   jerry_set_vm_exec_stop_callback (vm_exec_stop_callback, &countdown, 16);
 
-  const char *inf_loop_code_src_p = "while(true) {}";
+  const jerry_char_t inf_loop_code_src1[] = "while(true) {}";
   jerry_value_t parsed_code_val = jerry_parse (NULL,
                                                0,
-                                               (jerry_char_t *) inf_loop_code_src_p,
-                                               strlen (inf_loop_code_src_p),
+                                               inf_loop_code_src1,
+                                               sizeof (inf_loop_code_src1) - 1,
                                                JERRY_PARSE_NO_OPTS);
 
-  TEST_ASSERT (!jerry_value_has_error_flag (parsed_code_val));
+  TEST_ASSERT (!jerry_value_is_error (parsed_code_val));
   jerry_value_t res = jerry_run (parsed_code_val);
   TEST_ASSERT (countdown == 0);
 
-  TEST_ASSERT (jerry_value_has_error_flag (res));
+  TEST_ASSERT (jerry_value_is_error (res));
 
   jerry_release_value (res);
   jerry_release_value (parsed_code_val);
@@ -71,22 +71,24 @@ main (void)
   /* We keep the callback function, only the countdown is reset. */
   countdown = 6;
 
-  inf_loop_code_src_p = ("function f() { while (true) ; }\n"
-                         "try { f(); } catch(e) {}");
+  const jerry_char_t inf_loop_code_src2[] = TEST_STRING_LITERAL (
+    "function f() { while (true) ; }\n"
+    "try { f(); } catch(e) {}"
+  );
 
   parsed_code_val = jerry_parse (NULL,
                                  0,
-                                 (jerry_char_t *) inf_loop_code_src_p,
-                                 strlen (inf_loop_code_src_p),
+                                 inf_loop_code_src2,
+                                 sizeof (inf_loop_code_src2) - 1,
                                  JERRY_PARSE_NO_OPTS);
 
-  TEST_ASSERT (!jerry_value_has_error_flag (parsed_code_val));
+  TEST_ASSERT (!jerry_value_is_error (parsed_code_val));
   res = jerry_run (parsed_code_val);
   TEST_ASSERT (countdown == 0);
 
   /* The result must have an error flag which proves that
    * the error is thrown again inside the catch block. */
-  TEST_ASSERT (jerry_value_has_error_flag (res));
+  TEST_ASSERT (jerry_value_is_error (res));
 
   jerry_release_value (res);
   jerry_release_value (parsed_code_val);
index 0bb0772c18757ffb78f6829ddeb299ab89e566cb..322eb27cdd95c7a308e107f90f7c25a79c674ac8 100644 (file)
@@ -23,22 +23,22 @@ int main (void)
   {
     return 0;
   }
-  const char *test_source = (
-                         "var a = 'hello';"
-                         "var b = 'world';"
-                         "var c = a + ' ' + b;"
-                         );
+  const jerry_char_t test_source[] = TEST_STRING_LITERAL (
+    "var a = 'hello';"
+    "var b = 'world';"
+    "var c = a + ' ' + b;"
+  );
 
   jerry_init (JERRY_INIT_EMPTY);
   jerry_value_t parsed_code_val = jerry_parse (NULL,
                                                0,
-                                               (jerry_char_t *) test_source,
-                                               strlen (test_source),
+                                               test_source,
+                                               sizeof (test_source) - 1,
                                                JERRY_PARSE_NO_OPTS);
-  TEST_ASSERT (!jerry_value_has_error_flag (parsed_code_val));
+  TEST_ASSERT (!jerry_value_is_error (parsed_code_val));
 
   jerry_value_t res = jerry_run (parsed_code_val);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
 
   jerry_heap_stats_t stats;
   memset (&stats, 0, sizeof (stats));
index b4c7250fa627ac9bbab0803b6e5f541a874c52d9..d4a7207f1e83a2576469e9e2fba6df723548c999 100644 (file)
@@ -28,7 +28,7 @@ static const jerry_object_native_info_t test_info =
   .free_cb = free_test_data
 };
 
-static const char *strict_equal_source = "var x = function(a, b) {return a === b;}; x";
+static const jerry_char_t strict_equal_source[] = "var x = function(a, b) {return a === b;}; x";
 
 static bool
 find_test_object_by_data (const jerry_value_t candidate,
@@ -50,7 +50,7 @@ find_test_object_by_property (const jerry_value_t candidate,
   jerry_value_t *args_p = (jerry_value_t *) context_p;
   jerry_value_t result = jerry_has_property (candidate, args_p[0]);
 
-  bool has_property = (!jerry_value_has_error_flag (result) && jerry_get_boolean_value (result));
+  bool has_property = (!jerry_value_is_error (result) && jerry_get_boolean_value (result));
 
   /* If the object has the desired property, store a new reference to it in args_p[1]. */
   if (has_property)
@@ -72,12 +72,12 @@ main (void)
   /* Render strict-equal as a function. */
   jerry_value_t parse_result = jerry_parse (NULL,
                                             0,
-                                            (jerry_char_t *) strict_equal_source,
-                                            strlen (strict_equal_source),
+                                            strict_equal_source,
+                                            sizeof (strict_equal_source) - 1,
                                             JERRY_PARSE_STRICT_MODE);
-  TEST_ASSERT (!jerry_value_has_error_flag (parse_result));
+  TEST_ASSERT (!jerry_value_is_error (parse_result));
   jerry_value_t strict_equal = jerry_run (parse_result);
-  TEST_ASSERT (!jerry_value_has_error_flag (strict_equal));
+  TEST_ASSERT (!jerry_value_is_error (strict_equal));
   jerry_release_value (parse_result);
 
   /* Create an object and associate some native data with it. */
@@ -99,7 +99,7 @@ main (void)
   jerry_release_value (object);
 
   /* Collect garbage. */
-  jerry_gc ();
+  jerry_gc (JERRY_GC_SEVERITY_LOW);
 
   /* Attempt to retrieve the object by its native pointer again. */
   TEST_ASSERT (!jerry_objects_foreach_by_native_info (&test_info, find_test_object_by_data, &found_object));
@@ -124,7 +124,7 @@ main (void)
   jerry_release_value (args[1]);
 
   /* Collect garbage. */
-  jerry_gc ();
+  jerry_gc (JERRY_GC_SEVERITY_LOW);
 
   /* Attempt to retrieve the object by the presence of its property again. */
   args[0] = property_name;
index 621ebe434b305690cd46be24fcc3dc265b4d0767..bd37fc4039be762fa142ae40609ec6c6fcf15de4 100644 (file)
 #include "test-common.h"
 
 
-const char *test_source = (
-                           "var p1 = create_promise1();"
-                           "var p2 = create_promise2();"
-                           "p1.then(function(x) { "
-                           "  assert(x==='resolved'); "
-                           "}); "
-                           "p2.catch(function(x) { "
-                           "  assert(x==='rejected'); "
-                           "}); "
-                           );
+static const jerry_char_t test_source[] = TEST_STRING_LITERAL (
+  "var p1 = create_promise1();"
+  "var p2 = create_promise2();"
+  "p1.then(function(x) { "
+  "  assert(x==='resolved'); "
+  "}); "
+  "p2.catch(function(x) { "
+  "  assert(x==='rejected'); "
+  "}); "
+);
 
 static int count_in_assert = 0;
 static jerry_value_t my_promise1;
 static jerry_value_t my_promise2;
-const jerry_char_t s1[] = "resolved";
-const jerry_char_t s2[] = "rejected";
+static const jerry_char_t s1[] = "resolved";
+static const jerry_char_t s2[] = "rejected";
 
 static jerry_value_t
 create_promise1_handler (const jerry_value_t func_obj_val, /**< function object */
@@ -113,31 +113,12 @@ register_js_function (const char *name_p, /**< name of the function */
   jerry_release_value (result_val);
 } /* register_js_function */
 
-/**
- * Checks whether global object has promise.
- */
-static bool
-promise_is_available (void)
-{
-  jerry_value_t global_obj_val = jerry_get_global_object ();
-  jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "Promise");
-
-  jerry_value_t prop_value = jerry_has_property (global_obj_val, prop_name);
-  bool has_prop = jerry_get_boolean_value (prop_value);
-
-  jerry_release_value (global_obj_val);
-  jerry_release_value (prop_name);
-  jerry_release_value (prop_value);
-
-  return has_prop;
-} /* promise_is_available */
-
 int
 main (void)
 {
   jerry_init (JERRY_INIT_EMPTY);
 
-  if (!promise_is_available ())
+  if (!jerry_is_feature_enabled (JERRY_FEATURE_PROMISE))
   {
     jerry_port_log (JERRY_LOG_LEVEL_ERROR, "Promise is disabled!\n");
     jerry_cleanup ();
@@ -150,13 +131,13 @@ main (void)
 
   jerry_value_t parsed_code_val = jerry_parse (NULL,
                                                0,
-                                               (jerry_char_t *) test_source,
-                                               strlen (test_source),
+                                               test_source,
+                                               sizeof (test_source) - 1,
                                                JERRY_PARSE_NO_OPTS);
-  TEST_ASSERT (!jerry_value_has_error_flag (parsed_code_val));
+  TEST_ASSERT (!jerry_value_is_error (parsed_code_val));
 
   jerry_value_t res = jerry_run (parsed_code_val);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
 
   jerry_release_value (res);
   jerry_release_value (parsed_code_val);
@@ -181,7 +162,7 @@ main (void)
   /* Run the jobqueue. */
   res = jerry_run_all_enqueued_jobs ();
 
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (count_in_assert == 2);
 
   jerry_release_value (my_promise1);
@@ -190,4 +171,6 @@ main (void)
   jerry_release_value (str_reject);
 
   jerry_cleanup ();
+
+  return 0;
 } /* main */
diff --git a/deps/jerry/tests/unit-core/test-regexp.c b/deps/jerry/tests/unit-core/test-regexp.c
new file mode 100644 (file)
index 0000000..b33b7e2
--- /dev/null
@@ -0,0 +1,71 @@
+/* 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 "jerryscript.h"
+
+#include "test-common.h"
+
+int
+main (void)
+{
+  TEST_INIT ();
+  jerry_init (JERRY_INIT_EMPTY);
+
+  jerry_value_t global_obj_val = jerry_get_global_object ();
+
+  jerry_char_t pattern[] = "[^.]+";
+  jerry_regexp_flags_t flags = JERRY_REGEXP_FLAG_GLOBAL | JERRY_REGEXP_FLAG_MULTILINE;
+  jerry_value_t regex_obj = jerry_create_regexp (pattern, flags);
+  TEST_ASSERT (jerry_value_is_object (regex_obj));
+
+  const jerry_char_t func_resource[] = "unknown";
+  const jerry_char_t func_arg_list[] = "regex";
+  const jerry_char_t func_src[] = "return [regex.exec('something.domain.com'), regex.multiline, regex.global];";
+  jerry_value_t func_val = jerry_parse_function (func_resource,
+                                                 sizeof (func_resource) - 1,
+                                                 func_arg_list,
+                                                 sizeof (func_arg_list) - 1,
+                                                 func_src,
+                                                 sizeof (func_src) - 1,
+                                                 JERRY_PARSE_NO_OPTS);
+
+  jerry_value_t res = jerry_call_function (func_val, global_obj_val, &regex_obj, 1);
+  jerry_value_t regex_res = jerry_get_property_by_index (res, 0);
+  jerry_value_t regex_res_str = jerry_get_property_by_index (regex_res, 0);
+  jerry_value_t is_multiline = jerry_get_property_by_index (res, 1);
+  jerry_value_t is_global = jerry_get_property_by_index (res, 2);
+
+  jerry_size_t str_size = jerry_get_string_size (regex_res_str);
+  jerry_char_t res_buff[str_size];
+  jerry_size_t res_size = jerry_string_to_char_buffer (regex_res_str, res_buff, str_size);
+
+  const char expected_result[] = "something";
+  TEST_ASSERT (res_size == (sizeof (expected_result) - 1));
+  TEST_ASSERT (strncmp (expected_result, (const char *) res_buff, res_size) == 0);
+  TEST_ASSERT (jerry_get_boolean_value (is_multiline));
+  TEST_ASSERT (jerry_get_boolean_value (is_global));
+
+  jerry_release_value (regex_obj);
+  jerry_release_value (res);
+  jerry_release_value (func_val);
+  jerry_release_value (regex_res);
+  jerry_release_value (regex_res_str);
+  jerry_release_value (is_multiline);
+  jerry_release_value (is_global);
+  jerry_release_value (global_obj_val);
+
+  jerry_cleanup ();
+  return 0;
+} /* main */
index cd44f336606160eb68b4e8dd7954bd3a9d491bb0..219d8181f4ab58b77aa2a26d9541820ba5e7f680 100644 (file)
  */
 #define SNAPSHOT_BUFFER_SIZE (256)
 
+/**
+ * Maximum size of literal buffer
+ */
+#define LITERAL_BUFFER_SIZE (256)
+
 /**
  * Magic strings
  */
-static const jerry_char_ptr_t magic_strings[] =
+static const jerry_char_t *magic_strings[] =
 {
-  (const jerry_char_ptr_t) " ",
-  (const jerry_char_ptr_t) "a",
-  (const jerry_char_ptr_t) "b",
-  (const jerry_char_ptr_t) "c",
-  (const jerry_char_ptr_t) "from",
-  (const jerry_char_ptr_t) "func",
-  (const jerry_char_ptr_t) "string",
-  (const jerry_char_ptr_t) "snapshot"
+  (const jerry_char_t *) " ",
+  (const jerry_char_t *) "a",
+  (const jerry_char_t *) "b",
+  (const jerry_char_t *) "c",
+  (const jerry_char_t *) "from",
+  (const jerry_char_t *) "func",
+  (const jerry_char_t *) "string",
+  (const jerry_char_t *) "snapshot"
 };
 
 /**
@@ -58,21 +63,21 @@ static void test_function_snapshot (void)
   const jerry_init_flag_t flags = JERRY_INIT_EMPTY;
   static uint32_t function_snapshot_buffer[SNAPSHOT_BUFFER_SIZE];
 
-  const char *args_p = "a, b";
-  const char *code_to_snapshot_p = "return a + b";
+  const jerry_char_t func_args[] = "a, b";
+  const jerry_char_t code_to_snapshot[] = "return a + b";
 
   jerry_init (flags);
   jerry_value_t generate_result;
   generate_result = jerry_generate_function_snapshot (NULL,
                                                       0,
-                                                      (const jerry_char_t *) code_to_snapshot_p,
-                                                      strlen (code_to_snapshot_p),
-                                                      (jerry_char_t *) args_p,
-                                                      strlen (args_p),
+                                                      code_to_snapshot,
+                                                      sizeof (code_to_snapshot) - 1,
+                                                      func_args,
+                                                      sizeof (func_args) - 1,
                                                       0,
                                                       function_snapshot_buffer,
                                                       SNAPSHOT_BUFFER_SIZE);
-  TEST_ASSERT (!jerry_value_has_error_flag (generate_result)
+  TEST_ASSERT (!jerry_value_is_error (generate_result)
                && jerry_value_is_number (generate_result));
 
   size_t function_snapshot_size = (size_t) jerry_get_number_value (generate_result);
@@ -87,7 +92,7 @@ static void test_function_snapshot (void)
                                                              0,
                                                              0);
 
-  TEST_ASSERT (!jerry_value_has_error_flag (function_obj));
+  TEST_ASSERT (!jerry_value_is_error (function_obj));
   TEST_ASSERT (jerry_value_is_function (function_obj));
 
   jerry_value_t this_val = jerry_create_undefined ();
@@ -97,7 +102,7 @@ static void test_function_snapshot (void)
 
   jerry_value_t res = jerry_call_function (function_obj, this_val, args, 2);
 
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_value_is_number (res));
   double num = jerry_get_number_value (res);
   TEST_ASSERT (num == 3);
@@ -114,7 +119,7 @@ static void arguments_test_exec_snapshot (uint32_t *snapshot_p, size_t snapshot_
 {
   jerry_init (JERRY_INIT_EMPTY);
   jerry_value_t res = jerry_exec_snapshot (snapshot_p, snapshot_size, 0, exec_snapshot_flags);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_value_is_number (res));
   double raw_value = jerry_get_number_value (res);
   TEST_ASSERT (raw_value == 15);
@@ -130,25 +135,27 @@ static void test_function_arguments_snapshot (void)
   {
     static uint32_t arguments_snapshot_buffer[SNAPSHOT_BUFFER_SIZE];
 
-    const char *code_to_snapshot_p = ("function f(a,b,c) {"
-                                      "  arguments[0]++;"
-                                      "  arguments[1]++;"
-                                      "  arguments[2]++;"
-                                      "  return a + b + c;"
-                                      "}"
-                                      "f(3,4,5);");
+    const jerry_char_t code_to_snapshot[] = TEST_STRING_LITERAL (
+      "function f(a,b,c) {"
+      "  arguments[0]++;"
+      "  arguments[1]++;"
+      "  arguments[2]++;"
+      "  return a + b + c;"
+      "}"
+      "f(3,4,5);"
+    );
     jerry_init (JERRY_INIT_EMPTY);
 
     jerry_value_t generate_result;
     generate_result = jerry_generate_snapshot (NULL,
                                                0,
-                                               (jerry_char_t *) code_to_snapshot_p,
-                                               strlen (code_to_snapshot_p),
+                                               code_to_snapshot,
+                                               sizeof (code_to_snapshot) - 1,
                                                0,
                                                arguments_snapshot_buffer,
                                                SNAPSHOT_BUFFER_SIZE);
 
-    TEST_ASSERT (!jerry_value_has_error_flag (generate_result)
+    TEST_ASSERT (!jerry_value_is_error (generate_result)
                  && jerry_value_is_number (generate_result));
 
     size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
@@ -173,7 +180,7 @@ static void test_exec_snapshot (uint32_t *snapshot_p, size_t snapshot_size, uint
 
   jerry_value_t res = jerry_exec_snapshot (snapshot_p, snapshot_size, 0, exec_snapshot_flags);
 
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (jerry_value_is_string (res));
   jerry_size_t sz = jerry_get_string_size (res);
   TEST_ASSERT (sz == 20);
@@ -196,18 +203,18 @@ main (void)
   if (jerry_is_feature_enabled (JERRY_FEATURE_SNAPSHOT_SAVE)
       && jerry_is_feature_enabled (JERRY_FEATURE_SNAPSHOT_EXEC))
   {
-    const char *code_to_snapshot_p = "(function () { return 'string from snapshot'; }) ();";
+    const jerry_char_t code_to_snapshot[] = "(function () { return 'string from snapshot'; }) ();";
 
     jerry_init (JERRY_INIT_EMPTY);
     jerry_value_t generate_result;
     generate_result = jerry_generate_snapshot (NULL,
                                                0,
-                                               (const jerry_char_t *) code_to_snapshot_p,
-                                               strlen (code_to_snapshot_p),
+                                               code_to_snapshot,
+                                               sizeof (code_to_snapshot) - 1,
                                                0,
                                                snapshot_buffer,
                                                SNAPSHOT_BUFFER_SIZE);
-    TEST_ASSERT (!jerry_value_has_error_flag (generate_result)
+    TEST_ASSERT (!jerry_value_is_error (generate_result)
                  && jerry_value_is_number (generate_result));
 
     size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
@@ -216,13 +223,13 @@ main (void)
     /* Check the snapshot data. Unused bytes should be filled with zeroes */
     const uint8_t expected_data[] =
     {
-      0x4A, 0x52, 0x52, 0x59, 0x0C, 0x00, 0x00, 0x00,
+      0x4A, 0x52, 0x52, 0x59, 0x14, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
       0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
       0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
       0x00, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x00,
-      0x28, 0x00, 0xB7, 0x46, 0x00, 0x00, 0x00, 0x00,
-      0x03, 0x00, 0x01, 0x00, 0x41, 0x00, 0x00, 0x00,
+      0x28, 0x00, 0xB8, 0x46, 0x00, 0x00, 0x00, 0x00,
+      0x03, 0x00, 0x01, 0x00, 0x21, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x01, 0x01, 0x07, 0x00, 0x00, 0x00,
       0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x14, 0x00, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67,
@@ -242,11 +249,13 @@ main (void)
   if (jerry_is_feature_enabled (JERRY_FEATURE_SNAPSHOT_SAVE)
       && jerry_is_feature_enabled (JERRY_FEATURE_SNAPSHOT_EXEC))
   {
-    const char *code_to_snapshot_p = ("function func(a, b, c) {"
-                                      "  c = 'snapshot';"
-                                      "  return arguments[0] + ' ' + b + ' ' + arguments[2];"
-                                      "};"
-                                      "func('string', 'from');");
+    const jerry_char_t code_to_snapshot[] = TEST_STRING_LITERAL (
+      "function func(a, b, c) {"
+      "  c = 'snapshot';"
+      "  return arguments[0] + ' ' + b + ' ' + arguments[2];"
+      "};"
+      "func('string', 'from');"
+    );
 
     jerry_init (JERRY_INIT_EMPTY);
     jerry_register_magic_strings (magic_strings,
@@ -256,12 +265,12 @@ main (void)
     jerry_value_t generate_result;
     generate_result = jerry_generate_snapshot (NULL,
                                                0,
-                                               (jerry_char_t *) code_to_snapshot_p,
-                                               strlen (code_to_snapshot_p),
+                                               code_to_snapshot,
+                                               sizeof (code_to_snapshot) - 1,
                                                JERRY_SNAPSHOT_SAVE_STATIC,
                                                snapshot_buffer,
                                                SNAPSHOT_BUFFER_SIZE);
-    TEST_ASSERT (!jerry_value_has_error_flag (generate_result)
+    TEST_ASSERT (!jerry_value_is_error (generate_result)
                  && jerry_value_is_number (generate_result));
 
     size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
@@ -269,7 +278,7 @@ main (void)
 
     /* Static snapshots are not supported by default. */
     jerry_value_t exec_result = jerry_exec_snapshot (snapshot_buffer, snapshot_size, 0, 0);
-    TEST_ASSERT (jerry_value_has_error_flag (exec_result));
+    TEST_ASSERT (jerry_value_is_error (exec_result));
     jerry_release_value (exec_result);
 
     jerry_cleanup ();
@@ -286,18 +295,18 @@ main (void)
     size_t snapshot_sizes[2];
     static uint32_t merged_snapshot_buffer[SNAPSHOT_BUFFER_SIZE];
 
-    const char *code_to_snapshot_p = "123";
+    const jerry_char_t code_to_snapshot1[] = "var a = 'hello'; 123";
 
     jerry_init (JERRY_INIT_EMPTY);
     jerry_value_t generate_result;
     generate_result = jerry_generate_snapshot (NULL,
                                                0,
-                                               (const jerry_char_t *) code_to_snapshot_p,
-                                               strlen (code_to_snapshot_p),
+                                               code_to_snapshot1,
+                                               sizeof (code_to_snapshot1) - 1,
                                                0,
                                                snapshot_buffer_0,
                                                SNAPSHOT_BUFFER_SIZE);
-    TEST_ASSERT (!jerry_value_has_error_flag (generate_result)
+    TEST_ASSERT (!jerry_value_is_error (generate_result)
                  && jerry_value_is_number (generate_result));
 
     snapshot_sizes[0] = (size_t) jerry_get_number_value (generate_result);
@@ -305,17 +314,17 @@ main (void)
 
     jerry_cleanup ();
 
-    code_to_snapshot_p = "456";
+    const jerry_char_t code_to_snapshot2[] = "var b = 'hello'; 456";
 
     jerry_init (JERRY_INIT_EMPTY);
     generate_result = jerry_generate_snapshot (NULL,
                                                0,
-                                               (const jerry_char_t *) code_to_snapshot_p,
-                                               strlen (code_to_snapshot_p),
+                                               code_to_snapshot2,
+                                               sizeof (code_to_snapshot2) - 1,
                                                0,
                                                snapshot_buffer_1,
                                                SNAPSHOT_BUFFER_SIZE);
-    TEST_ASSERT (!jerry_value_has_error_flag (generate_result)
+    TEST_ASSERT (!jerry_value_is_error (generate_result)
                  && jerry_value_is_number (generate_result));
 
     snapshot_sizes[1] = (size_t) jerry_get_number_value (generate_result);
@@ -331,6 +340,12 @@ main (void)
     snapshot_buffers[0] = snapshot_buffer_0;
     snapshot_buffers[1] = snapshot_buffer_1;
 
+    static uint32_t snapshot_buffer_0_bck[SNAPSHOT_BUFFER_SIZE];
+    static uint32_t snapshot_buffer_1_bck[SNAPSHOT_BUFFER_SIZE];
+
+    memcpy (snapshot_buffer_0_bck, snapshot_buffer_0, SNAPSHOT_BUFFER_SIZE);
+    memcpy (snapshot_buffer_1_bck, snapshot_buffer_1, SNAPSHOT_BUFFER_SIZE);
+
     size_t merged_size = jerry_merge_snapshots (snapshot_buffers,
                                                 snapshot_sizes,
                                                 2,
@@ -340,16 +355,18 @@ main (void)
 
     jerry_cleanup ();
 
+    TEST_ASSERT (0 == memcmp (snapshot_buffer_0_bck, snapshot_buffer_0, SNAPSHOT_BUFFER_SIZE));
+    TEST_ASSERT (0 == memcmp (snapshot_buffer_1_bck, snapshot_buffer_1, SNAPSHOT_BUFFER_SIZE));
 
     jerry_init (JERRY_INIT_EMPTY);
 
     jerry_value_t res = jerry_exec_snapshot (merged_snapshot_buffer, merged_size, 0, 0);
-    TEST_ASSERT (!jerry_value_has_error_flag (res));
+    TEST_ASSERT (!jerry_value_is_error (res));
     TEST_ASSERT (jerry_get_number_value (res) == 123);
     jerry_release_value (res);
 
     res = jerry_exec_snapshot (merged_snapshot_buffer, merged_size, 1, 0);
-    TEST_ASSERT (!jerry_value_has_error_flag (res));
+    TEST_ASSERT (!jerry_value_is_error (res));
     TEST_ASSERT (jerry_get_number_value (res) == 456);
     jerry_release_value (res);
 
@@ -362,20 +379,36 @@ main (void)
     /* C format generation */
     jerry_init (JERRY_INIT_EMPTY);
 
-    static uint32_t literal_buffer_c[SNAPSHOT_BUFFER_SIZE];
-    static const char *code_for_c_format_p = "var object = { aa:'fo o', Bb:'max', aaa:'xzy0' };";
+    static jerry_char_t literal_buffer_c[LITERAL_BUFFER_SIZE];
+    static uint32_t literal_snapshot_buffer[SNAPSHOT_BUFFER_SIZE];
+    static const jerry_char_t code_for_c_format[] = "var object = { aa:'fo o', Bb:'max', aaa:'xzy0' };";
 
-    size_t literal_sizes_c_format = jerry_parse_and_save_literals ((jerry_char_t *) code_for_c_format_p,
-                                                                   strlen (code_for_c_format_p),
-                                                                   false,
-                                                                   literal_buffer_c,
-                                                                   SNAPSHOT_BUFFER_SIZE,
-                                                                   true);
-    TEST_ASSERT (literal_sizes_c_format == 203);
+    jerry_value_t generate_result;
+    generate_result = jerry_generate_snapshot (NULL,
+                                               0,
+                                               code_for_c_format,
+                                               sizeof (code_for_c_format) - 1,
+                                               0,
+                                               literal_snapshot_buffer,
+                                               SNAPSHOT_BUFFER_SIZE);
+
+    TEST_ASSERT (!jerry_value_is_error (generate_result)
+                 && jerry_value_is_number (generate_result));
+
+    size_t snapshot_size = (size_t) jerry_get_number_value (generate_result);
+    jerry_release_value (generate_result);
+    TEST_ASSERT (snapshot_size == 120);
+
+    const size_t lit_c_buf_sz = jerry_get_literals_from_snapshot (literal_snapshot_buffer,
+                                                                  snapshot_size,
+                                                                  literal_buffer_c,
+                                                                  LITERAL_BUFFER_SIZE,
+                                                                  true);
+    TEST_ASSERT (lit_c_buf_sz == 200);
 
     static const char *expected_c_format = (
                                             "jerry_length_t literal_count = 4;\n\n"
-                                            "jerry_char_ptr_t literals[4] =\n"
+                                            "jerry_char_t *literals[4] =\n"
                                             "{\n"
                                             "  \"Bb\",\n"
                                             "  \"aa\",\n"
@@ -391,24 +424,18 @@ main (void)
                                             "};\n"
                                             );
 
-    TEST_ASSERT (!strncmp ((char *) literal_buffer_c, expected_c_format, literal_sizes_c_format));
-    jerry_cleanup ();
+    TEST_ASSERT (!strncmp ((char *) literal_buffer_c, expected_c_format, lit_c_buf_sz));
 
     /* List format generation */
-    jerry_init (JERRY_INIT_EMPTY);
-
-    static uint32_t literal_buffer_list[SNAPSHOT_BUFFER_SIZE];
-    static const char *code_for_list_format_p = "var obj = { a:'aa', bb:'Bb' };";
-
-    size_t literal_sizes_list_format = jerry_parse_and_save_literals ((jerry_char_t *) code_for_list_format_p,
-                                                                      strlen (code_for_list_format_p),
-                                                                      false,
-                                                                      literal_buffer_list,
-                                                                      SNAPSHOT_BUFFER_SIZE,
-                                                                      false);
-
-    TEST_ASSERT (literal_sizes_list_format == 25);
-    TEST_ASSERT (!strncmp ((char *) literal_buffer_list, "1 a\n2 Bb\n2 aa\n2 bb\n3 obj\n", literal_sizes_list_format));
+    static jerry_char_t literal_buffer_list[LITERAL_BUFFER_SIZE];
+    const size_t lit_list_buf_sz = jerry_get_literals_from_snapshot (literal_snapshot_buffer,
+                                                                     snapshot_size,
+                                                                     literal_buffer_list,
+                                                                     LITERAL_BUFFER_SIZE,
+                                                                     false);
+
+    TEST_ASSERT (lit_list_buf_sz == 30);
+    TEST_ASSERT (!strncmp ((char *) literal_buffer_list, "2 Bb\n2 aa\n3 aaa\n4 fo o\n4 xzy0\n", lit_list_buf_sz));
 
     jerry_cleanup ();
   }
index 2337b0bbd96d78610a532da9e3daed69e7016897..3e6b20d6bc8582f96d71ed377f492a9a47ef6204 100644 (file)
@@ -80,25 +80,6 @@ assert_handler (const jerry_value_t func_obj_val, /**< function object */
   }
 } /* assert_handler */
 
-/**
- * Checks whether global object has typedarray.
- */
-static bool
-typedarray_is_available (void)
-{
-  jerry_value_t global_obj_val = jerry_get_global_object ();
-  jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "Int8Array");
-
-  jerry_value_t prop_value = jerry_has_property (global_obj_val, prop_name);
-  bool has_prop = jerry_get_boolean_value (prop_value);
-
-  jerry_release_value (global_obj_val);
-  jerry_release_value (prop_name);
-  jerry_release_value (prop_value);
-
-  return has_prop;
-} /* typedarray_is_available */
-
 /**
  * Do simple TypedArray property validation.
  */
@@ -108,7 +89,7 @@ test_typedarray_info (jerry_value_t typedarray, /**< target TypedArray to query
                       jerry_length_t element_count, /**< expected element count */
                       jerry_length_t bytes_per_element) /**< bytes per element for the given type */
 {
-  TEST_ASSERT (!jerry_value_has_error_flag (typedarray));
+  TEST_ASSERT (!jerry_value_is_error (typedarray));
   TEST_ASSERT (jerry_value_is_typedarray (typedarray));
   TEST_ASSERT (jerry_get_typedarray_type (typedarray) == typedarray_type);
   TEST_ASSERT (jerry_get_typedarray_length (typedarray) == element_count);
@@ -138,7 +119,7 @@ test_typedarray_queries (test_entry_t test_entries[]) /**< test cases */
     {
       jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) test_entries[i].constructor_name);
       jerry_value_t prop_value = jerry_get_property (global_obj_val, prop_name);
-      TEST_ASSERT (!jerry_value_has_error_flag (prop_value));
+      TEST_ASSERT (!jerry_value_is_error (prop_value));
       jerry_value_t length_arg = jerry_create_number (test_entries[i].element_count);
 
       jerry_value_t typedarray = jerry_construct_object (prop_value, &length_arg, 1);
@@ -256,7 +237,7 @@ test_typedarray_complex_creation (test_entry_t test_entries[], /**< test cases *
                                                                arraybuffer,
                                                                offset,
                                                                element_count);
-      TEST_ASSERT (!jerry_value_has_error_flag (typedarray));
+      TEST_ASSERT (!jerry_value_is_error (typedarray));
 
       jerry_release_value (js_offset);
       jerry_release_value (js_element_count);
@@ -265,15 +246,16 @@ test_typedarray_complex_creation (test_entry_t test_entries[], /**< test cases *
 
     register_js_value ("array", typedarray);
 
-    const char *eval_src_p = (
+    const jerry_char_t eval_src[] = TEST_STRING_LITERAL (
       "assert (array.length == expected_length,"
       "        'expected length: ' + expected_length + ' got: ' + array.length);"
       "assert (array.byteOffset == expected_offset);"
-      "array[0] = 0x11223344;");
-    jerry_value_t result = jerry_eval ((jerry_char_t *) eval_src_p,
-                                       strlen (eval_src_p),
-                                       true);
-    TEST_ASSERT (!jerry_value_has_error_flag (result));
+      "array[0] = 0x11223344;"
+    );
+    jerry_value_t result = jerry_eval (eval_src,
+                                       sizeof (eval_src) - 1,
+                                       JERRY_PARSE_STRICT_MODE);
+    TEST_ASSERT (!jerry_value_is_error (result));
     jerry_release_value (result);
 
     {
@@ -303,12 +285,127 @@ test_typedarray_complex_creation (test_entry_t test_entries[], /**< test cases *
   }
 } /* test_typedarray_complex_creation */
 
+/**
+ * Test get/set/delete property by index.
+ */
+static void test_property_by_index (test_entry_t test_entries[])
+{
+  int test_int_numbers[5] = {-5, -70, 13, 0, 56};
+  double test_double_numbers[5] = {-83.153, -35.15, 0, 13.1, 89.8975};
+  uint8_t test_uint_numbers[5] = {83, 15, 36, 0, 43};
+
+  for (uint32_t i = 0; test_entries[i].constructor_name != NULL; i++)
+  {
+    jerry_value_t test_number;
+    uint32_t test_numbers_length = sizeof (test_int_numbers) / sizeof (int);
+    jerry_value_t typedarray = jerry_create_typedarray (test_entries[i].typedarray_type, test_numbers_length);
+    jerry_typedarray_type_t type = jerry_get_typedarray_type (typedarray);
+
+    jerry_value_t set_result;
+    jerry_value_t get_result;
+
+    switch (type)
+    {
+      case JERRY_TYPEDARRAY_INT8:
+      case JERRY_TYPEDARRAY_INT16:
+      case JERRY_TYPEDARRAY_INT32:
+      {
+        for (uint8_t j = 0; j < test_numbers_length; j++)
+        {
+          test_number = jerry_create_number (test_int_numbers[j]);
+          TEST_ASSERT (!jerry_delete_property_by_index (typedarray, j));
+          set_result = jerry_set_property_by_index (typedarray, j, test_number);
+          get_result = jerry_get_property_by_index (typedarray, j);
+
+          TEST_ASSERT (jerry_value_is_boolean (set_result));
+          TEST_ASSERT (jerry_get_boolean_value (set_result));
+          TEST_ASSERT (!jerry_delete_property_by_index (typedarray, j));
+          TEST_ASSERT (jerry_get_number_value (get_result) == test_int_numbers[j]);
+
+          jerry_release_value (test_number);
+          jerry_release_value (set_result);
+          jerry_release_value (get_result);
+        }
+        break;
+      }
+      case JERRY_TYPEDARRAY_FLOAT32:
+      case JERRY_TYPEDARRAY_FLOAT64:
+      {
+        for (uint8_t j = 0; j < test_numbers_length; j++)
+        {
+          test_number = jerry_create_number (test_double_numbers[j]);
+          TEST_ASSERT (!jerry_delete_property_by_index (typedarray, j));
+          set_result = jerry_set_property_by_index (typedarray, j, test_number);
+          get_result = jerry_get_property_by_index (typedarray, j);
+
+          TEST_ASSERT (jerry_value_is_boolean (set_result));
+          TEST_ASSERT (jerry_get_boolean_value (set_result));
+          TEST_ASSERT (!jerry_delete_property_by_index (typedarray, j));
+
+          double epsilon = pow (10, -5);
+          double get_abs = fabs (jerry_get_number_value (get_result) - test_double_numbers[j]);
+          TEST_ASSERT (get_abs < epsilon);
+
+          jerry_release_value (test_number);
+          jerry_release_value (set_result);
+          jerry_release_value (get_result);
+
+          /* Testing positive and negative infinity */
+          for (uint8_t k = 0; k < 2; k++)
+          {
+            jerry_value_t inf = jerry_create_number_infinity (k);
+            jerry_value_t set_inf = jerry_set_property_by_index (typedarray, 0, inf);
+            TEST_ASSERT (jerry_value_is_boolean (set_inf));
+            TEST_ASSERT (jerry_get_boolean_value (set_inf));
+            jerry_value_t get_inf = jerry_get_property_by_index (typedarray, 0);
+            TEST_ASSERT (isinf (jerry_get_number_value (get_inf)));
+
+            jerry_release_value (inf);
+            jerry_release_value (set_inf);
+            jerry_release_value (get_inf);
+          }
+        }
+        break;
+      }
+      default:
+      {
+        for (uint8_t j = 0; j < test_numbers_length; j++)
+        {
+          test_number = jerry_create_number (test_uint_numbers[j]);
+          TEST_ASSERT (!jerry_delete_property_by_index (typedarray, j));
+          set_result = jerry_set_property_by_index (typedarray, j, test_number);
+          get_result = jerry_get_property_by_index (typedarray, j);
+
+          TEST_ASSERT (jerry_value_is_boolean (set_result));
+          TEST_ASSERT (jerry_get_boolean_value (set_result));
+          TEST_ASSERT (!jerry_delete_property_by_index (typedarray, j));
+          TEST_ASSERT (jerry_get_number_value (get_result) == test_uint_numbers[j]);
+
+          jerry_release_value (test_number);
+          jerry_release_value (set_result);
+          jerry_release_value (get_result);
+        }
+        break;
+      }
+    }
+
+    jerry_value_t set_undefined = jerry_set_property_by_index (typedarray, 100, jerry_create_number (50));
+    TEST_ASSERT (jerry_value_is_error (set_undefined));
+    jerry_value_t get_undefined = jerry_get_property_by_index (typedarray, 100);
+    TEST_ASSERT (jerry_value_is_undefined (get_undefined));
+
+    jerry_release_value (set_undefined);
+    jerry_release_value (get_undefined);
+    jerry_release_value (typedarray);
+  }
+} /* test_property_by_index */
+
 int
 main (void)
 {
   jerry_init (JERRY_INIT_EMPTY);
 
-  if (!typedarray_is_available ())
+  if (!jerry_is_feature_enabled (JERRY_FEATURE_TYPEDARRAY))
   {
     jerry_port_log (JERRY_LOG_LEVEL_ERROR, "TypedArray is disabled!\n");
     jerry_cleanup ();
@@ -374,18 +471,19 @@ main (void)
     }
 
     /* Check read and to write */
-    const char *eval_src_p = (
+    const jerry_char_t eval_src[] = TEST_STRING_LITERAL (
       "assert (array.length == expected_length, 'expected length: ' + expected_length + ' got: ' + array.length);"
       "for (var i = 0; i < array.length; i++)"
       "{"
       "  assert (array[i] == expected_value);"
       "  array[i] = i;"
-      "};");
-    jerry_value_t result = jerry_eval ((jerry_char_t *) eval_src_p,
-                                       strlen (eval_src_p),
-                                       true);
+      "};"
+    );
+    jerry_value_t result = jerry_eval (eval_src,
+                                       sizeof (eval_src) - 1,
+                                       JERRY_PARSE_STRICT_MODE);
 
-    TEST_ASSERT (!jerry_value_has_error_flag (result));
+    TEST_ASSERT (!jerry_value_is_error (result));
     jerry_release_value (result);
 
     /* Check write results */
@@ -414,6 +512,8 @@ main (void)
   test_typedarray_complex_creation (test_entries, false);
   test_typedarray_complex_creation (test_entries, true);
 
+  test_property_by_index (test_entries);
+
   /* test invalid things */
   {
     jerry_value_t values[] =
@@ -451,7 +551,7 @@ main (void)
         jerry_length_t offset = 22;
         jerry_length_t byte_count = 23;
         jerry_value_t error = jerry_get_typedarray_buffer (values[idx], &offset, &byte_count);
-        TEST_ASSERT (jerry_value_has_error_flag (error));
+        TEST_ASSERT (jerry_value_is_error (error));
         TEST_ASSERT (offset == 22);
         TEST_ASSERT (byte_count == 23);
         jerry_release_value (error);
@@ -463,7 +563,7 @@ main (void)
       if (!jerry_value_is_arraybuffer (values[idx]))
       {
         jerry_value_t error = jerry_create_typedarray_for_arraybuffer (JERRY_TYPEDARRAY_UINT8, values[idx]);
-        TEST_ASSERT (jerry_value_has_error_flag (error));
+        TEST_ASSERT (jerry_value_is_error (error));
         jerry_release_value (error);
       }
 
@@ -472,4 +572,6 @@ main (void)
   }
 
   jerry_cleanup ();
+
+  return 0;
 } /* main */
index 5380324f7fe4e722af6744e5c82e3ca563958d50..97ebbcfbb9d930c48d61e1a7f37007ab4a19f5ef 100644 (file)
@@ -24,7 +24,7 @@ set(COMPILE_FLAGS_DOCTEST "-Wno-unused-parameter -Wno-unused-function -Wno-unuse
 # file names that will be generated. This allows the definition of proper
 # dependencies between the MarkDown files and the generated sources.
 execute_process(
-  COMMAND ${GEN_DOCTEST} --dry -d ${CMAKE_CURRENT_SOURCE_DIR} ${DOC_FILES}
+  COMMAND ${GEN_DOCTEST} --dry -d ${CMAKE_CURRENT_BINARY_DIR} ${DOC_FILES}
   OUTPUT_VARIABLE DOCTEST_OUTPUT
   RESULT_VARIABLE GEN_DOCTEST_RESULT
 )
@@ -53,16 +53,21 @@ endforeach()
 # Add custom command to run doctest generator if any of the MarkDown sources
 # changes.
 add_custom_command(
-  COMMAND ${GEN_DOCTEST} -d ${CMAKE_CURRENT_SOURCE_DIR} ${DOC_FILES}
+  COMMAND ${GEN_DOCTEST} -d ${CMAKE_CURRENT_BINARY_DIR} ${DOC_FILES}
   DEPENDS ${GEN_DOCTEST} ${DOC_FILES}
   OUTPUT ${DOCTEST_COMPILE} ${DOCTEST_LINK} ${DOCTEST_RUN}
   COMMENT "Generating doctests"
 )
 
+# Add custom target to trigger the custom command above. Targets below can/must
+# depend on this one so that the custom command gets executed only once.
+add_custom_target(all-doc-files DEPENDS ${DOCTEST_COMPILE} ${DOCTEST_LINK} ${DOCTEST_RUN})
+
 # Process compile-only doctests: add them to a dummy library
 # (named libcompile-doc-tests.a) to trigger compilation.
 if(NOT ("${DOCTEST_COMPILE}" STREQUAL ""))
-  add_library(compile-doc-tests STATIC ${DOCTEST_COMPILE})
+  add_library(compile-doc-tests ${DOCTEST_COMPILE})
+  add_dependencies(compile-doc-tests all-doc-files)
   target_link_libraries(compile-doc-tests jerry-ext jerry-core jerry-port-default-minimal)
   set_property(TARGET compile-doc-tests APPEND_STRING PROPERTY COMPILE_FLAGS "${COMPILE_FLAGS_DOCTEST}")
 endif()
@@ -74,8 +79,10 @@ macro(doctest_add_executables NAME_PREFIX)
     set(TARGET_NAME ${NAME_PREFIX}-${TARGET_NAME})
 
     add_executable(${TARGET_NAME} ${DOCTEST_NAME})
+    add_dependencies(${TARGET_NAME} all-doc-files)
     set_property(TARGET ${TARGET_NAME} APPEND_STRING PROPERTY COMPILE_FLAGS "${COMPILE_FLAGS_DOCTEST}")
     set_property(TARGET ${TARGET_NAME} PROPERTY LINK_FLAGS "${LINKER_FLAGS_COMMON}")
+    set_property(TARGET ${TARGET_NAME} PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests")
     target_link_libraries(${TARGET_NAME} jerry-ext jerry-core jerry-port-default-minimal)
   endforeach()
 endmacro()
index e7e95d7ab216891f89eab9fa5292d2dfeb9e8727..bb211ac7e517ebd9a93a5304256aef39594dc21b 100644 (file)
@@ -28,8 +28,8 @@ foreach(SOURCE_UNIT_TEST_EXT ${SOURCE_UNIT_TEST_EXT_MODULES})
   set(TARGET_NAME unit-${TARGET_NAME})
 
   add_executable(${TARGET_NAME} ${SOURCE_UNIT_TEST_EXT})
-  set_property(TARGET ${TARGET_NAME}
-               PROPERTY LINK_FLAGS "${LINKER_FLAGS_COMMON}")
+  set_property(TARGET ${TARGET_NAME} PROPERTY LINK_FLAGS "${LINKER_FLAGS_COMMON}")
+  set_property(TARGET ${TARGET_NAME} PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests")
 
   target_link_libraries(${TARGET_NAME} jerry-ext jerry-core jerry-port-default-minimal)
 
index 7aa1bf3b795bbd4dd97b245d4e0800eab667a7ec..038df68f2d5e6dd59443310c9f60bd8bec0ac76d 100644 (file)
@@ -24,5 +24,6 @@ endif()
 
 add_executable(${JERRYX_MODULE_UNITTEST_NAME} ${JERRYX_MODULE_UNIT_TEST_SOURCES})
 set_property(TARGET ${JERRYX_MODULE_UNITTEST_NAME} PROPERTY LINK_FLAGS "${LINKER_FLAGS_COMMON}")
+set_property(TARGET ${JERRYX_MODULE_UNITTEST_NAME} PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests")
 target_link_libraries(${JERRYX_MODULE_UNITTEST_NAME} jerry-ext jerry-core jerry-port-default-minimal)
 target_include_directories(${JERRYX_MODULE_UNITTEST_NAME} PRIVATE ${INCLUDE_UNIT_EXT})
index b60936ee12f480cf94ba090603ea53ecee7feced..c371fd6dda76d025233b26e93ace4692089a5e3e 100644 (file)
@@ -60,6 +60,24 @@ const char eval_string5[] =
 "  return x === y ? 1 : 0;"
 "}) ();";
 
+/* Make sure the result of a module load is removed from the cache. */
+const char eval_string6[] =
+"(function() {"
+"  var x = require('cache-check');"
+"  clear_require_cache('cache-check');"
+"  var y = require('cache-check');"
+"  return x !== y ? 1 : 0;"
+"}) ();";
+
+/* Make sure the entire cache is cleared. */
+const char eval_string7[] =
+"(function() {"
+"  var x = require('cache-check');"
+"  clear_require_cache(undefined);"
+"  var y = require('cache-check');"
+"  return x !== y ? 1 : 0;"
+"}) ();";
+
 /*
  * Define a resolver for a module named "differently-handled-module" to check that custom resolvers work.
  */
@@ -119,6 +137,22 @@ static const jerryx_module_resolver_t *resolvers[3] =
   &cache_check_resolver
 };
 
+static jerry_value_t
+handle_clear_require_cache (const jerry_value_t js_function,
+                            const jerry_value_t this_val,
+                            const jerry_value_t args_p[],
+                            const jerry_length_t args_count)
+{
+  (void) js_function;
+  (void) this_val;
+  (void) args_count;
+
+  TEST_ASSERT (args_count == 1);
+  jerryx_module_clear_cache (args_p[0], resolvers, 3);
+
+  return 0;
+} /* handle_clear_require_cache */
+
 static jerry_value_t
 handle_require (const jerry_value_t js_function,
                 const jerry_value_t this_val,
@@ -140,14 +174,16 @@ handle_require (const jerry_value_t js_function,
 static void
 assert_number (jerry_value_t js_value, double expected_result)
 {
-  TEST_ASSERT (!jerry_value_has_error_flag (js_value));
+  TEST_ASSERT (!jerry_value_is_error (js_value));
   TEST_ASSERT (jerry_get_number_value (js_value) == expected_result);
 } /* assert_number */
 
 static void
 eval_one (const char *the_string, double expected_result)
 {
-  jerry_value_t js_eval_result = jerry_eval ((const jerry_char_t *) the_string, strlen (the_string), true);
+  jerry_value_t js_eval_result = jerry_eval ((const jerry_char_t *) the_string,
+                                             strlen (the_string),
+                                             JERRY_PARSE_STRICT_MODE);
   assert_number (js_eval_result, expected_result);
   jerry_release_value (js_eval_result);
 } /* eval_one */
@@ -172,19 +208,28 @@ main (int argc, char **argv)
   jerry_init (JERRY_INIT_EMPTY);
 
   js_global = jerry_get_global_object ();
+
   js_function = jerry_create_external_function (handle_require);
   js_property_name = jerry_create_string ((const jerry_char_t *) "require");
   jerry_set_property (js_global, js_property_name, js_function);
+  jerry_release_value (js_property_name);
+  jerry_release_value (js_function);
+
+  js_function = jerry_create_external_function (handle_clear_require_cache);
+  js_property_name = jerry_create_string ((const jerry_char_t *) "clear_require_cache");
+  jerry_set_property (js_global, js_property_name, js_function);
+  jerry_release_value (js_property_name);
+  jerry_release_value (js_function);
+
+  jerry_release_value (js_global);
 
   eval_one (eval_string1, 42);
   eval_one (eval_string2, 29);
   eval_one (eval_string3, 1);
   eval_one (eval_string4, 1);
   eval_one (eval_string5, 1);
-
-  jerry_release_value (js_property_name);
-  jerry_release_value (js_function);
-  jerry_release_value (js_global);
+  eval_one (eval_string6, 1);
+  eval_one (eval_string7, 1);
 
   jerry_cleanup ();
 } /* main */
index 330a1d30f1b31b157d70bc44ab4ccae586592c99..d4aa332a03ab7c2eb0fb5a06648b732bd4133e62 100644 (file)
@@ -35,4 +35,6 @@
     } \
   } while (0)
 
+#define TEST_STRING_LITERAL(x) x
+
 #endif /* !TEST_COMMON_H */
index e79c276787c5fd9a2398977e92539a58b9a031af..f4f7b8d39573798d6b870d127202b9c7af738f0e 100644 (file)
  * Unit test for jerry-ext/args.
  */
 
+#include <string.h>
 #include "jerryscript.h"
 #include "jerryscript-ext/arg.h"
 #include "test-common.h"
 
-#include <string.h>
-#include <jerryscript-ext/arg.h>
-
-const char *test_source = (
-                           "var arg1 = true;"
-                           "var arg2 = 10.5;"
-                           "var arg3 = 'abc';"
-                           "var arg4 = function foo() {};"
-                           "test_validator1(arg1, arg2, arg3, arg4);"
-                           "arg1 = new Boolean(true);"
-                           "arg3 = new String('abc');"
-                           "test_validator1(arg1, arg2, arg3);"
-                           "test_validator1(arg1, arg2, '');"
-                           "arg2 = new Number(10.5);"
-                           "test_validator1(arg1, arg2, arg3);"
-                           "test_validator1(arg1, 10.5, 'abcdef');"
-                           "var obj_a = new MyObjectA();"
-                           "var obj_b = new MyObjectB();"
-                           "test_validator2.call(obj_a, 5);"
-                           "test_validator2.call(obj_b, 5);"
-                           "test_validator2.call(obj_a, 1);"
-                           "var obj1 = {prop1:true, prop2:'1.5'};"
-                           "test_validator_prop1(obj1);"
-                           "test_validator_prop2(obj1);"
-                           "test_validator_prop2();"
-                           "var obj2 = {prop1:true};"
-                           "Object.defineProperty(obj2, 'prop2', {"
-                           "  get: function() { throw new TypeError('prop2 error') }"
-                           "});"
-                           "test_validator_prop3(obj2);"
-                           "test_validator_int1(-1000, 1000, 128, -1000, 1000, -127,"
-                           "                    -1000, 4294967297, 65536, -2200000000, 4294967297, -2147483647);"
-                           "test_validator_int2(-1.5, -1.5, -1.5, 1.5, 1.5, 1.5, Infinity, -Infinity, 300.5, 300.5);"
-                           "test_validator_int3(NaN);"
-                           "var arr = [1, 2];"
-                           "test_validator_array1(arr);"
-                           "test_validator_array1();"
-                           "test_validator_array2(arr);"
-                           );
+static const jerry_char_t test_source[] = TEST_STRING_LITERAL (
+  "var arg1 = true;"
+  "var arg2 = 10.5;"
+  "var arg3 = 'abc';"
+  "var arg4 = function foo() {};"
+  "test_validator1(arg1, arg2, arg3, arg4);"
+  "arg1 = new Boolean(true);"
+  "arg3 = new String('abc');"
+  "test_validator1(arg1, arg2, arg3);"
+  "test_validator1(arg1, arg2, '');"
+  "arg2 = new Number(10.5);"
+  "test_validator1(arg1, arg2, arg3);"
+  "test_validator1(arg1, 10.5, 'abcdef');"
+  "var obj_a = new MyObjectA();"
+  "var obj_b = new MyObjectB();"
+  "test_validator2.call(obj_a, 5);"
+  "test_validator2.call(obj_b, 5);"
+  "test_validator2.call(obj_a, 1);"
+  "var obj1 = {prop1:true, prop2:'1.5'};"
+  "test_validator_prop1(obj1);"
+  "test_validator_prop2(obj1);"
+  "test_validator_prop2();"
+  "var obj2 = {prop1:true};"
+  "Object.defineProperty(obj2, 'prop2', {"
+  "  get: function() { throw new TypeError('prop2 error') }"
+  "});"
+  "test_validator_prop3(obj2);"
+  "test_validator_int1(-1000, 1000, 128, -1000, 1000, -127,"
+  "                    -1000, 4294967297, 65536, -2200000000, 4294967297, -2147483647);"
+  "test_validator_int2(-1.5, -1.5, -1.5, 1.5, 1.5, 1.5, Infinity, -Infinity, 300.5, 300.5);"
+  "test_validator_int3(NaN);"
+  "var arr = [1, 2];"
+  "test_validator_array1(arr);"
+  "test_validator_array1();"
+  "test_validator_array2(arr);"
+);
 
 static const jerry_object_native_info_t thing_a_info =
 {
@@ -133,7 +131,7 @@ test_validator1_handler (const jerry_value_t func_obj_val __attribute__((unused)
 
   if (validator1_count == 0)
   {
-    TEST_ASSERT (!jerry_value_has_error_flag (is_ok));
+    TEST_ASSERT (!jerry_value_is_error (is_ok));
     TEST_ASSERT (arg1);
     TEST_ASSERT (arg2 == 10.5);
     TEST_ASSERT (strcmp (arg3, "abc") == 0);
@@ -141,7 +139,7 @@ test_validator1_handler (const jerry_value_t func_obj_val __attribute__((unused)
   }
   else if (validator1_count == 1)
   {
-    TEST_ASSERT (!jerry_value_has_error_flag (is_ok));
+    TEST_ASSERT (!jerry_value_is_error (is_ok));
     TEST_ASSERT (arg1);
     TEST_ASSERT (arg2 == 10.5);
     TEST_ASSERT (strcmp (arg3, "abc") == 0);
@@ -149,7 +147,7 @@ test_validator1_handler (const jerry_value_t func_obj_val __attribute__((unused)
   }
   else if (validator1_count == 2)
   {
-    TEST_ASSERT (!jerry_value_has_error_flag (is_ok));
+    TEST_ASSERT (!jerry_value_is_error (is_ok));
     TEST_ASSERT (arg1);
     TEST_ASSERT (arg2 == 10.5);
     TEST_ASSERT (strcmp (arg3, "") == 0);
@@ -157,7 +155,7 @@ test_validator1_handler (const jerry_value_t func_obj_val __attribute__((unused)
   }
   else
   {
-    TEST_ASSERT (jerry_value_has_error_flag (is_ok));
+    TEST_ASSERT (jerry_value_is_error (is_ok));
   }
 
   jerry_release_value (is_ok);
@@ -177,7 +175,7 @@ my_custom_transform (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS
   jerry_value_t js_arg = jerryx_arg_js_iterator_pop (js_arg_iter_p);
   jerry_value_t to_number = jerry_value_to_number (js_arg);
 
-  if (jerry_value_has_error_flag (to_number))
+  if (jerry_value_is_error (to_number))
   {
     jerry_release_value (to_number);
 
@@ -226,13 +224,13 @@ test_validator2_handler (const jerry_value_t func_obj_val __attribute__((unused)
 
   if (validator2_count == 0)
   {
-    TEST_ASSERT (!jerry_value_has_error_flag (is_ok));
+    TEST_ASSERT (!jerry_value_is_error (is_ok));
     TEST_ASSERT (thing_p == &my_thing_a);
     TEST_ASSERT (thing_p->x == 1);
   }
   else
   {
-    TEST_ASSERT (jerry_value_has_error_flag (is_ok));
+    TEST_ASSERT (jerry_value_is_error (is_ok));
   }
 
   jerry_release_value (is_ok);
@@ -269,7 +267,7 @@ test_validator_prop1_handler (const jerry_value_t func_obj_val __attribute__((un
                                                                 mapping,
                                                                 ARRAY_SIZE (mapping));
 
-  TEST_ASSERT (!jerry_value_has_error_flag (is_ok));
+  TEST_ASSERT (!jerry_value_is_error (is_ok));
   TEST_ASSERT (native1);
   TEST_ASSERT (native2 == 1.5);
   TEST_ASSERT (native3 == 3);
@@ -317,7 +315,7 @@ test_validator_prop2_handler (const jerry_value_t func_obj_val __attribute__((un
   jerry_value_t is_ok = jerryx_arg_transform_args (args_p, args_cnt, mapping, ARRAY_SIZE (mapping));
 
 
-  TEST_ASSERT (!jerry_value_has_error_flag (is_ok));
+  TEST_ASSERT (!jerry_value_is_error (is_ok));
 
   if (validator_prop_count == 1)
   {
@@ -354,7 +352,7 @@ test_validator_prop3_handler (const jerry_value_t func_obj_val __attribute__((un
                                                                 mapping,
                                                                 ARRAY_SIZE (mapping));
 
-  TEST_ASSERT (jerry_value_has_error_flag (is_ok));
+  TEST_ASSERT (jerry_value_is_error (is_ok));
   TEST_ASSERT (!native1);
   TEST_ASSERT (native2);
 
@@ -399,7 +397,7 @@ test_validator_int1_handler (const jerry_value_t func_obj_val __attribute__((unu
                                                    mapping,
                                                    ARRAY_SIZE (mapping));
 
-  TEST_ASSERT (!jerry_value_has_error_flag (is_ok));
+  TEST_ASSERT (!jerry_value_is_error (is_ok));
   TEST_ASSERT (num0 == 0);
   TEST_ASSERT (num1 == 255);
   TEST_ASSERT (num2 == 128);
@@ -448,7 +446,7 @@ test_validator_int2_handler (const jerry_value_t func_obj_val __attribute__((unu
                                                    mapping,
                                                    ARRAY_SIZE (mapping));
 
-  TEST_ASSERT (jerry_value_has_error_flag (is_ok));
+  TEST_ASSERT (jerry_value_is_error (is_ok));
   TEST_ASSERT (num0 == -2);
   TEST_ASSERT (num1 == -2);
   TEST_ASSERT (num2 == -1);
@@ -484,7 +482,7 @@ test_validator_int3_handler (const jerry_value_t func_obj_val __attribute__((unu
                                                    mapping,
                                                    ARRAY_SIZE (mapping));
 
-  TEST_ASSERT (jerry_value_has_error_flag (is_ok));
+  TEST_ASSERT (jerry_value_is_error (is_ok));
 
   jerry_release_value (is_ok);
   validator_int_count++;
@@ -522,7 +520,7 @@ test_validator_array1_handler (const jerry_value_t func_obj_val __attribute__((u
   jerry_value_t is_ok = jerryx_arg_transform_args (args_p, args_cnt, mapping, ARRAY_SIZE (mapping));
 
 
-  TEST_ASSERT (!jerry_value_has_error_flag (is_ok));
+  TEST_ASSERT (!jerry_value_is_error (is_ok));
 
   if (validator_array_count == 0)
   {
@@ -553,7 +551,7 @@ test_validator_array2_handler (const jerry_value_t func_obj_val __attribute__((u
 
   jerry_value_t is_ok = jerryx_arg_transform_array (args_p[0], item_mapping, ARRAY_SIZE (item_mapping));
 
-  TEST_ASSERT (jerry_value_has_error_flag (is_ok));
+  TEST_ASSERT (jerry_value_is_error (is_ok));
   TEST_ASSERT (native1 == 1);
   TEST_ASSERT (!native2);
 
@@ -569,7 +567,7 @@ test_utf8_string (void)
   /* test string: 'str: {DESERET CAPITAL LETTER LONG I}' */
   jerry_value_t str = jerry_create_string ((jerry_char_t *) "\x73\x74\x72\x3a \xed\xa0\x81\xed\xb0\x80");
   char expect_utf8_buf[] = "\x73\x74\x72\x3a \xf0\x90\x90\x80";
-  size_t buf_len = strlen (expect_utf8_buf);
+  size_t buf_len = sizeof (expect_utf8_buf) - 1;
   char buf[buf_len+1];
 
   jerryx_arg_t mapping[] =
@@ -582,7 +580,7 @@ test_utf8_string (void)
                                                    mapping,
                                                    ARRAY_SIZE (mapping));
 
-  TEST_ASSERT (!jerry_value_has_error_flag (is_ok));
+  TEST_ASSERT (!jerry_value_is_error (is_ok));
   TEST_ASSERT (!strcmp (buf, expect_utf8_buf));
 
   jerry_release_value (str);
@@ -662,13 +660,13 @@ main (void)
 
   jerry_value_t parsed_code_val = jerry_parse (NULL,
                                                0,
-                                               (jerry_char_t *) test_source,
-                                               strlen (test_source),
+                                               test_source,
+                                               sizeof (test_source) - 1,
                                                JERRY_PARSE_NO_OPTS);
-  TEST_ASSERT (!jerry_value_has_error_flag (parsed_code_val));
+  TEST_ASSERT (!jerry_value_is_error (parsed_code_val));
 
   jerry_value_t res = jerry_run (parsed_code_val);
-  TEST_ASSERT (!jerry_value_has_error_flag (res));
+  TEST_ASSERT (!jerry_value_is_error (res));
   TEST_ASSERT (validator1_count == 5);
   TEST_ASSERT (validator2_count == 3);
   TEST_ASSERT (validator_prop_count == 4);
index c639e995a18a27ff7c1ef1029eba567580154c4f..73de07f655bd1a65b0fd3afe839d32b54eb7c426 100644 (file)
@@ -57,7 +57,7 @@ main (void)
 
   native_free_cb_call_count = 0;
   test_autorelease_val ();
-  jerry_gc ();
+  jerry_gc (JERRY_GC_SEVERITY_HIGH);
   TEST_ASSERT (native_free_cb_call_count == 1);
 
   jerry_cleanup ();
index aaf6cddd8f75d96a4784cff00caff1abbe86264f..0e31658230e119493092a5e5575505736011f95b 100644 (file)
@@ -36,9 +36,10 @@ main (int argc, char **argv)
   jerry_value_t module = jerryx_module_resolve (module_name, &resolver, 1);
   jerry_release_value (module_name);
 
-  TEST_ASSERT (jerry_value_has_error_flag (module));
+  TEST_ASSERT (jerry_value_is_error (module));
 
   /* Retrieve the error message. */
+  module = jerry_get_value_from_error (module, true);
   jerry_value_t prop_name = jerry_create_string ((const jerry_char_t *) "message");
   jerry_value_t prop = jerry_get_property (module, prop_name);
 
index 83a8b256b85beeab6ad16ac4704c2fd33da66611..026a563a0b8c016c02e6e4d96c21e6770b03aecf 100644 (file)
@@ -26,13 +26,10 @@ foreach(SOURCE_UNIT_TEST_MAIN ${SOURCE_UNIT_TEST_MAIN_MODULES})
   set(TARGET_NAME unit-${TARGET_NAME})
 
   add_executable(${TARGET_NAME} ${SOURCE_UNIT_TEST_MAIN})
-  set_property(TARGET ${TARGET_NAME}
-               PROPERTY LINK_FLAGS "${LINKER_FLAGS_COMMON}")
+  set_property(TARGET ${TARGET_NAME} PROPERTY LINK_FLAGS "${LINKER_FLAGS_COMMON}")
+  set_property(TARGET ${TARGET_NAME} PROPERTY RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/tests")
 
   target_link_libraries(${TARGET_NAME} jerry-libm)
-  if(JERRY_LIBC)
-    target_link_libraries(${TARGET_NAME} jerry-libc)
-  endif()
 
   add_dependencies(unittests-libm ${TARGET_NAME})
 endforeach()
index 87bd70ebc881d36f8d1abcdb214eb1aaa5cfc43b..cc6816d1e359971e0db842d598f71440ceb69baf 100755 (executable)
@@ -24,10 +24,6 @@ import subprocess
 import sys
 import settings
 
-BUILD_DIR = os.path.join(settings.PROJECT_DIR, 'build')
-
-DEFAULT_PROFILE = 'es5.1'
-
 def default_toolchain():
     (sysname, _, _, _, machine) = os.uname()
     toolchain = os.path.join(settings.PROJECT_DIR,
@@ -39,7 +35,7 @@ def get_arguments():
     devhelp_preparser = argparse.ArgumentParser(add_help=False)
     devhelp_preparser.add_argument('--devhelp', action='store_true', default=False,
                                    help='show help with all options '
-                                   '(including those, which are useful for developers only)')
+                                        '(including those, which are useful for developers only)')
 
     devhelp_arguments, args = devhelp_preparser.parse_known_args()
     if devhelp_arguments.devhelp:
@@ -48,96 +44,106 @@ def get_arguments():
     def devhelp(helpstring):
         return helpstring if devhelp_arguments.devhelp else argparse.SUPPRESS
 
-    parser = argparse.ArgumentParser(parents=[devhelp_preparser])
-    parser.add_argument('--all-in-one', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                        help='all-in-one build (%(choices)s; default: %(default)s)')
-    parser.add_argument('--builddir', metavar='DIR', action='store', default=BUILD_DIR,
-                        help='specify output directory (default: %(default)s)')
-    parser.add_argument('--clean', action='store_true', default=False, help='clean build')
-    parser.add_argument('--cmake-param', metavar='OPT', action='append', default=[],
-                        help='add custom argument to CMake')
-    parser.add_argument('--compile-flag', metavar='OPT', action='append', default=[],
-                        help='add custom compile flag')
-    parser.add_argument('--cpointer-32bit', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                        help='enable 32 bit compressed pointers (%(choices)s; default: %(default)s)')
-    parser.add_argument('--debug', action='store_const', const='Debug', default='MinSizeRel', dest='build_type',
-                        help='debug build')
-    parser.add_argument('--doctests', action='store_const', const='ON', default='OFF',
-                        help='build doctests')
-    parser.add_argument('--error-messages', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                        help='enable error messages (%(choices)s; default: %(default)s)')
-    parser.add_argument('--external-context', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                        help='enable external context (%(choices)s; default: %(default)s)')
-    parser.add_argument('-j', '--jobs', metavar='N', action='store', type=int, default=multiprocessing.cpu_count() + 1,
-                        help='Allowed N build jobs at once (default: %(default)s)')
-    parser.add_argument('--jerry-cmdline', metavar='X', choices=['ON', 'OFF'], default='ON', type=str.upper,
-                        help='build jerry command line tool (%(choices)s; default: %(default)s)')
-    parser.add_argument('--jerry-cmdline-snapshot', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                        help='build snapshot command line tool (%(choices)s; default: %(default)s)')
-    parser.add_argument('--jerry-debugger', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                        help='enable the jerry debugger (%(choices)s; default: %(default)s)')
-    parser.add_argument('--jerry-ext', metavar='X', choices=['ON', 'OFF'], default='ON', type=str.upper,
-                        help='build jerry-ext (default: %(default)s)')
-    parser.add_argument('--jerry-libc', metavar='X', choices=['ON', 'OFF'], default='ON', type=str.upper,
-                        help='build and use jerry-libc (%(choices)s; default: %(default)s)')
-    parser.add_argument('--jerry-libm', metavar='X', choices=['ON', 'OFF'], default='ON', type=str.upper,
-                        help='build and use jerry-libm (%(choices)s; default: %(default)s)')
-    parser.add_argument('--jerry-port-default', metavar='X', choices=['ON', 'OFF'], default='ON', type=str.upper,
-                        help='build default jerry port implementation (%(choices)s; default: %(default)s)')
-    parser.add_argument('--js-parser', metavar='X', choices=['ON', 'OFF'], default='ON', type=str.upper,
-                        help='enable js-parser (%(choices)s; default: %(default)s)')
-    parser.add_argument('--line-info', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                        help='provide line info (%(choices)s; default: %(default)s)')
-    parser.add_argument('--link-lib', metavar='OPT', action='append', default=[],
-                        help='add custom library to be linked')
-    parser.add_argument('--linker-flag', metavar='OPT', action='append', default=[],
-                        help='add custom linker flag')
-    parser.add_argument('--lto', metavar='X', choices=['ON', 'OFF'], default='ON', type=str.upper,
-                        help='enable link-time optimizations (%(choices)s; default: %(default)s)')
-    parser.add_argument('--mem-heap', metavar='SIZE', action='store', type=int, default=512,
-                        help='size of memory heap, in kilobytes (default: %(default)s)')
-    parser.add_argument('--profile', metavar='FILE', action='store', default=DEFAULT_PROFILE,
-                        help='specify profile file (default: %(default)s)')
-    parser.add_argument('--snapshot-exec', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                        help='enable executing snapshot files (%(choices)s; default: %(default)s)')
-    parser.add_argument('--snapshot-save', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                        help='enable saving snapshot files (%(choices)s; default: %(default)s)')
-    parser.add_argument('--system-allocator', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                        help='enable system allocator (%(choices)s; default: %(default)s)')
-    parser.add_argument('--static-link', metavar='X', choices=['ON', 'OFF'], default='ON', type=str.upper,
-                        help='enable static linking of binaries (%(choices)s; default: %(default)s)')
-    parser.add_argument('--strip', metavar='X', choices=['ON', 'OFF'], default='ON', type=str.upper,
-                        help='strip release binaries (%(choices)s; default: %(default)s)')
-    parser.add_argument('--toolchain', metavar='FILE', action='store', default=default_toolchain(),
-                        help='add toolchain file (default: %(default)s)')
-    parser.add_argument('--unittests', action='store_const', const='ON', default='OFF',
-                        help='build unittests')
-    parser.add_argument('-v', '--verbose', action='store_const', const='ON', default='OFF',
-                        help='increase verbosity')
-    parser.add_argument('--vm-exec-stop', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                        help='enable VM execution stopping (%(choices)s; default: %(default)s)')
-
-    devgroup = parser.add_argument_group('developer options')
-    devgroup.add_argument('--jerry-cmdline-test', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                          help=devhelp('build test version of the jerry command line tool '
-                                       '(%(choices)s; default: %(default)s)'))
-    devgroup.add_argument('--link-map', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                          help=devhelp('enable the generation of a link map file for jerry command line tool '
-                                       '(%(choices)s; default: %(default)s)'))
-    devgroup.add_argument('--mem-stats', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                          help=devhelp('enable memory statistics (%(choices)s; default: %(default)s)'))
-    devgroup.add_argument('--mem-stress-test', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                          help=devhelp('enable mem-stress test (%(choices)s; default: %(default)s)'))
-    devgroup.add_argument('--regexp-strict-mode', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                          help=devhelp('enable regexp strict mode (%(choices)s; default: %(default)s)'))
-    devgroup.add_argument('--show-opcodes', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                          help=devhelp('enable parser byte-code dumps (%(choices)s; default: %(default)s)'))
-    devgroup.add_argument('--show-regexp-opcodes', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                          help=devhelp('enable regexp byte-code dumps (%(choices)s; default: %(default)s)'))
-    devgroup.add_argument('--valgrind', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                          help=devhelp('enable Valgrind support (%(choices)s; default: %(default)s)'))
-    devgroup.add_argument('--valgrind-freya', metavar='X', choices=['ON', 'OFF'], default='OFF', type=str.upper,
-                          help=devhelp('enable Valgrind-Freya support (%(choices)s; default: %(default)s)'))
+    parser = argparse.ArgumentParser(parents=[devhelp_preparser], epilog="""
+        This tool is a thin wrapper around cmake and make to help build the
+        project easily. All the real build logic is in the CMakeLists.txt files.
+        For most of the options, the defaults are also defined there.
+        """)
+
+    buildgrp = parser.add_argument_group('general build options')
+    buildgrp.add_argument('--builddir', metavar='DIR', default=os.path.join(settings.PROJECT_DIR, 'build'),
+                          help='specify build directory (default: %(default)s)')
+    buildgrp.add_argument('--clean', action='store_true', default=False,
+                          help='clean build')
+    buildgrp.add_argument('--cmake-param', metavar='OPT', action='append', default=[],
+                          help='add custom argument to CMake')
+    buildgrp.add_argument('--compile-flag', metavar='OPT', action='append', default=[],
+                          help='add custom compile flag')
+    buildgrp.add_argument('--debug', action='store_const', const='Debug', dest='build_type',
+                          help='debug build')
+    buildgrp.add_argument('--install', metavar='DIR', nargs='?', default=None, const=False,
+                          help='install after build (default: don\'t install; '
+                               'default directory if install: OS-specific)')
+    buildgrp.add_argument('-j', '--jobs', metavar='N', type=int, default=multiprocessing.cpu_count() + 1,
+                          help='number of parallel build jobs (default: %(default)s)')
+    buildgrp.add_argument('--link-lib', metavar='OPT', action='append', default=[],
+                          help='add custom library to be linked')
+    buildgrp.add_argument('--linker-flag', metavar='OPT', action='append', default=[],
+                          help='add custom linker flag')
+    buildgrp.add_argument('--lto', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                          help='enable link-time optimizations (%(choices)s)')
+    buildgrp.add_argument('--shared-libs', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                          help='enable building of shared libraries (%(choices)s)')
+    buildgrp.add_argument('--strip', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                          help='strip release binaries (%(choices)s)')
+    buildgrp.add_argument('--toolchain', metavar='FILE', default=default_toolchain(),
+                          help='specify toolchain file (default: %(default)s)')
+    buildgrp.add_argument('-v', '--verbose', action='store_const', const='ON',
+                          help='increase verbosity')
+
+    compgrp = parser.add_argument_group('optional components')
+    compgrp.add_argument('--doctests', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help=devhelp('build doctests (%(choices)s)'))
+    compgrp.add_argument('--jerry-cmdline', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='build jerry command line tool (%(choices)s)')
+    compgrp.add_argument('--jerry-cmdline-snapshot', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='build snapshot command line tool (%(choices)s)')
+    compgrp.add_argument('--jerry-cmdline-test', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help=devhelp('build test version of the jerry command line tool (%(choices)s)'))
+    compgrp.add_argument('--jerry-ext', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='build jerry-ext (%(choices)s)')
+    compgrp.add_argument('--jerry-libm', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='build and use jerry-libm (%(choices)s)')
+    compgrp.add_argument('--jerry-port-default', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='build default jerry port implementation (%(choices)s)')
+    compgrp.add_argument('--unittests', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help=devhelp('build unittests (%(choices)s)'))
+
+    coregrp = parser.add_argument_group('jerry-core options')
+    coregrp.add_argument('--all-in-one', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='all-in-one build (%(choices)s)')
+    coregrp.add_argument('--cpointer-32bit', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='enable 32 bit compressed pointers (%(choices)s)')
+    coregrp.add_argument('--error-messages', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='enable error messages (%(choices)s)')
+    coregrp.add_argument('--external-context', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='enable external context (%(choices)s)')
+    coregrp.add_argument('--jerry-debugger', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='enable the jerry debugger (%(choices)s)')
+    coregrp.add_argument('--js-parser', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='enable js-parser (%(choices)s)')
+    coregrp.add_argument('--line-info', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='provide line info (%(choices)s)')
+    coregrp.add_argument('--logging', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='enable logging (%(choices)s)')
+    coregrp.add_argument('--mem-heap', metavar='SIZE', type=int,
+                         help='size of memory heap (in kilobytes)')
+    coregrp.add_argument('--mem-stats', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help=devhelp('enable memory statistics (%(choices)s)'))
+    coregrp.add_argument('--mem-stress-test', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help=devhelp('enable mem-stress test (%(choices)s)'))
+    coregrp.add_argument('--profile', metavar='FILE',
+                         help='specify profile file')
+    coregrp.add_argument('--regexp-strict-mode', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help=devhelp('enable regexp strict mode (%(choices)s)'))
+    coregrp.add_argument('--show-opcodes', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help=devhelp('enable parser byte-code dumps (%(choices)s)'))
+    coregrp.add_argument('--show-regexp-opcodes', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help=devhelp('enable regexp byte-code dumps (%(choices)s)'))
+    coregrp.add_argument('--snapshot-exec', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='enable executing snapshot files (%(choices)s)')
+    coregrp.add_argument('--snapshot-save', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='enable saving snapshot files (%(choices)s)')
+    coregrp.add_argument('--system-allocator', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='enable system allocator (%(choices)s)')
+    coregrp.add_argument('--valgrind', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help=devhelp('enable Valgrind support (%(choices)s)'))
+    coregrp.add_argument('--vm-exec-stop', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help='enable VM execution stopping (%(choices)s)')
+
+    maingrp = parser.add_argument_group('jerry-main options')
+    maingrp.add_argument('--link-map', metavar='X', choices=['ON', 'OFF'], type=str.upper,
+                         help=devhelp('enable the generation of link map for jerry command line tool (%(choices)s)'))
 
     arguments = parser.parse_args(args)
     if arguments.devhelp:
@@ -149,53 +155,59 @@ def get_arguments():
 def generate_build_options(arguments):
     build_options = []
 
-    build_options.append('-DENABLE_ALL_IN_ONE=%s' % arguments.all_in_one)
-    build_options.append('-DCMAKE_BUILD_TYPE=%s' % arguments.build_type)
-    build_options.append('-DEXTERNAL_COMPILE_FLAGS=' + ' '.join(arguments.compile_flag))
-    build_options.append('-DFEATURE_CPOINTER_32_BIT=%s' % arguments.cpointer_32bit)
-    build_options.append('-DFEATURE_ERROR_MESSAGES=%s' % arguments.error_messages)
-    build_options.append('-DFEATURE_LINE_INFO=%s' % arguments.line_info)
-    build_options.append('-DJERRY_CMDLINE=%s' % arguments.jerry_cmdline)
-    build_options.append('-DJERRY_CMDLINE_TEST=%s' % arguments.jerry_cmdline_test)
-    build_options.append('-DJERRY_CMDLINE_SNAPSHOT=%s' % arguments.jerry_cmdline_snapshot)
-    build_options.append('-DJERRY_PORT_DEFAULT=%s' % arguments.jerry_port_default)
-    build_options.append('-DJERRY_EXT=%s' % arguments.jerry_ext)
-    build_options.append('-DJERRY_LIBC=%s' % arguments.jerry_libc)
-    build_options.append('-DJERRY_LIBM=%s' % arguments.jerry_libm)
-    build_options.append('-DFEATURE_JS_PARSER=%s' % arguments.js_parser)
-    build_options.append('-DEXTERNAL_LINK_LIBS=' + ' '.join(arguments.link_lib))
-    build_options.append('-DEXTERNAL_LINKER_FLAGS=' + ' '.join(arguments.linker_flag))
-    build_options.append('-DENABLE_LTO=%s' % arguments.lto)
-    build_options.append('-DMEM_HEAP_SIZE_KB=%d' % arguments.mem_heap)
-
-    build_options.append('-DFEATURE_PROFILE=%s' % arguments.profile)
-    build_options.append('-DFEATURE_DEBUGGER=%s' % arguments.jerry_debugger)
-    build_options.append('-DFEATURE_EXTERNAL_CONTEXT=%s' % arguments.external_context)
-    build_options.append('-DFEATURE_SNAPSHOT_EXEC=%s' % arguments.snapshot_exec)
-    build_options.append('-DFEATURE_SNAPSHOT_SAVE=%s' % arguments.snapshot_save)
-    build_options.append('-DFEATURE_SYSTEM_ALLOCATOR=%s' % arguments.system_allocator)
-    build_options.append('-DENABLE_STATIC_LINK=%s' % arguments.static_link)
-    build_options.append('-DENABLE_STRIP=%s' % arguments.strip)
-    build_options.append('-DFEATURE_VM_EXEC_STOP=%s' % arguments.vm_exec_stop)
-
-    if arguments.toolchain:
-        build_options.append('-DCMAKE_TOOLCHAIN_FILE=%s' % arguments.toolchain)
-
-    build_options.append('-DUNITTESTS=%s' % arguments.unittests)
-    build_options.append('-DDOCTESTS=%s' % arguments.doctests)
-    build_options.append('-DCMAKE_VERBOSE_MAKEFILE=%s' % arguments.verbose)
-
-    # developer options
-    build_options.append('-DENABLE_LINK_MAP=%s' % arguments.link_map)
-    build_options.append('-DFEATURE_MEM_STATS=%s' % arguments.mem_stats)
-    build_options.append('-DFEATURE_MEM_STRESS_TEST=%s' % arguments.mem_stress_test)
-    build_options.append('-DFEATURE_PARSER_DUMP=%s' % arguments.show_opcodes)
-    build_options.append('-DFEATURE_REGEXP_STRICT_MODE=%s' % arguments.regexp_strict_mode)
-    build_options.append('-DFEATURE_REGEXP_DUMP=%s' % arguments.show_regexp_opcodes)
-    build_options.append('-DFEATURE_VALGRIND=%s' % arguments.valgrind)
-    build_options.append('-DFEATURE_VALGRIND_FREYA=%s' % arguments.valgrind_freya)
-
-    build_options.extend(arguments.cmake_param)
+    def build_options_append(cmakeopt, cliarg):
+        if cliarg:
+            build_options.append('-D%s=%s' % (cmakeopt, cliarg))
+
+    # general build options
+    build_options_append('CMAKE_BUILD_TYPE', arguments.build_type)
+    build_options_append('EXTERNAL_COMPILE_FLAGS', ' '.join(arguments.compile_flag))
+    build_options_append('EXTERNAL_LINK_LIBS', ' '.join(arguments.link_lib))
+    build_options_append('EXTERNAL_LINKER_FLAGS', ' '.join(arguments.linker_flag))
+    build_options_append('ENABLE_LTO', arguments.lto)
+    build_options_append('BUILD_SHARED_LIBS', arguments.shared_libs)
+    build_options_append('ENABLE_STRIP', arguments.strip)
+    build_options_append('CMAKE_TOOLCHAIN_FILE', arguments.toolchain)
+    build_options_append('CMAKE_VERBOSE_MAKEFILE', arguments.verbose)
+
+    # optional components
+    build_options_append('DOCTESTS', arguments.doctests)
+    build_options_append('JERRY_CMDLINE', arguments.jerry_cmdline)
+    build_options_append('JERRY_CMDLINE_SNAPSHOT', arguments.jerry_cmdline_snapshot)
+    build_options_append('JERRY_CMDLINE_TEST', arguments.jerry_cmdline_test)
+    build_options_append('JERRY_EXT', arguments.jerry_ext)
+    build_options_append('JERRY_LIBM', arguments.jerry_libm)
+    build_options_append('JERRY_PORT_DEFAULT', arguments.jerry_port_default)
+    build_options_append('UNITTESTS', arguments.unittests)
+
+    # jerry-core options
+    build_options_append('ENABLE_ALL_IN_ONE', arguments.all_in_one)
+    build_options_append('FEATURE_CPOINTER_32_BIT', arguments.cpointer_32bit)
+    build_options_append('FEATURE_ERROR_MESSAGES', arguments.error_messages)
+    build_options_append('FEATURE_EXTERNAL_CONTEXT', arguments.external_context)
+    build_options_append('FEATURE_DEBUGGER', arguments.jerry_debugger)
+    build_options_append('FEATURE_JS_PARSER', arguments.js_parser)
+    build_options_append('FEATURE_LINE_INFO', arguments.line_info)
+    build_options_append('FEATURE_LOGGING', arguments.logging)
+    build_options_append('MEM_HEAP_SIZE_KB', arguments.mem_heap)
+    build_options_append('FEATURE_MEM_STATS', arguments.mem_stats)
+    build_options_append('FEATURE_MEM_STRESS_TEST', arguments.mem_stress_test)
+    build_options_append('FEATURE_PROFILE', arguments.profile)
+    build_options_append('FEATURE_REGEXP_STRICT_MODE', arguments.regexp_strict_mode)
+    build_options_append('FEATURE_PARSER_DUMP', arguments.show_opcodes)
+    build_options_append('FEATURE_REGEXP_DUMP', arguments.show_regexp_opcodes)
+    build_options_append('FEATURE_SNAPSHOT_EXEC', arguments.snapshot_exec)
+    build_options_append('FEATURE_SNAPSHOT_SAVE', arguments.snapshot_save)
+    build_options_append('FEATURE_SYSTEM_ALLOCATOR', arguments.system_allocator)
+    build_options_append('FEATURE_VALGRIND', arguments.valgrind)
+    build_options_append('FEATURE_VM_EXEC_STOP', arguments.vm_exec_stop)
+
+    # jerry-main options
+    build_options_append('ENABLE_LINK_MAP', arguments.link_map)
+
+    # general build options (final step)
+    if arguments.cmake_param:
+        build_options.extend(arguments.cmake_param)
 
     return build_options
 
@@ -209,18 +221,27 @@ def configure_output_dir(arguments):
     if not os.path.exists(arguments.builddir):
         os.makedirs(arguments.builddir)
 
-def configure_build(arguments):
+def configure_jerry(arguments):
     configure_output_dir(arguments)
 
     build_options = generate_build_options(arguments)
 
     cmake_cmd = ['cmake', '-B' + arguments.builddir, '-H' + settings.PROJECT_DIR]
+
+    if arguments.install:
+        cmake_cmd.append('-DCMAKE_INSTALL_PREFIX=%s' % arguments.install)
+
     cmake_cmd.extend(build_options)
 
     return subprocess.call(cmake_cmd)
 
-def build_jerry(arguments):
-    return subprocess.call(['make', '--no-print-directory', '-j', str(arguments.jobs), '-C', arguments.builddir])
+def make_jerry(arguments, target=None):
+    make_cmd = ['make', '--no-print-directory', '-j', str(arguments.jobs), '-C', arguments.builddir]
+
+    if target:
+        make_cmd.append(target)
+
+    return subprocess.call(make_cmd)
 
 def print_result(ret):
     print('=' * 30)
@@ -232,10 +253,14 @@ def print_result(ret):
 
 def main():
     arguments = get_arguments()
-    ret = configure_build(arguments)
+
+    ret = configure_jerry(arguments)
 
     if not ret:
-        ret = build_jerry(arguments)
+        ret = make_jerry(arguments)
+
+    if not ret and arguments.install is not None:
+        ret = make_jerry(arguments, 'install')
 
     print_result(ret)
     sys.exit(ret)
index cca8d6f1795a6dafe6e8d02c27a7334732b18c57..8da40d50194856f6196bb7625d362732faf20606 100755 (executable)
 # limitations under the License.
 
 if [[ "$OSTYPE" == "linux"* ]]; then
-    CPPCHECK_JOBS=${CPPCHECK_JOBS:=$(nproc)}
+  CPPCHECK_JOBS=${CPPCHECK_JOBS:=$(nproc)}
 elif [[ "$OSTYPE" == "darwin"* ]]; then
-    CPPCHECK_JOBS=${CPPCHECK_JOBS:=$(sysctl -n hw.ncpu)}
+  CPPCHECK_JOBS=${CPPCHECK_JOBS:=$(sysctl -n hw.ncpu)}
 else
-    CPPCHECK_JOBS=${CPPCHECK_JOBS:=1}
+  CPPCHECK_JOBS=${CPPCHECK_JOBS:=1}
 fi
 
 JERRY_CORE_DIRS=`find jerry-core -type d`
 JERRY_EXT_DIRS=`find jerry-ext -type d`
 JERRY_PORT_DIRS=`find jerry-port -type d`
-JERRY_LIBC_DIRS=`find jerry-libc -type d`
 JERRY_LIBM_DIRS=`find jerry-libm -type d`
 
 
 INCLUDE_DIRS=()
-for DIR in $JERRY_CORE_DIRS $JERRY_EXT_DIRS $JERRY_PORT_DIRS $JERRY_LIBC_DIRS $JERRY_LIBM_DIRS
+for DIR in $JERRY_CORE_DIRS $JERRY_EXT_DIRS $JERRY_PORT_DIRS $JERRY_LIBM_DIRS
 do
- INCLUDE_DIRS=("${INCLUDE_DIRS[@]}" "-I$DIR")
 INCLUDE_DIRS=("${INCLUDE_DIRS[@]}" "-I$DIR")
 done
 
 cppcheck -j$CPPCHECK_JOBS --force \
- --language=c --std=c99 \
- --enable=warning,style,performance,portability,information \
- --template="{file}:{line}: {severity}({id}): {message}" \
- --error-exitcode=1 \
- --exitcode-suppressions=tools/cppcheck/suppressions-list \
- --suppressions-list=tools/cppcheck/suppressions-list \
- "${INCLUDE_DIRS[@]}" \
- jerry-core jerry-ext jerry-port jerry-libc jerry-libm jerry-main tests/unit-*
+  --language=c --std=c99 \
+  --quiet \
+  --enable=warning,style,performance,portability,information \
+  --template="{file}:{line}: {severity}({id}): {message}" \
+  --error-exitcode=1 \
+  --exitcode-suppressions=tools/cppcheck/suppressions-list \
+  --suppressions-list=tools/cppcheck/suppressions-list \
+  "${INCLUDE_DIRS[@]}" \
+  jerry-core jerry-ext jerry-port jerry-libm jerry-main tests/unit-*
index ad1594c1c98c1c9db7df9657b2c63dc0f70ef519..dbc353ca2c80b1b70c9af979f88559732bd19b4f 100755 (executable)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-echo -n "Generating documentation with doxygen ..."
-DOXYGEN_WARNINGS=$((doxygen > /dev/null) 2>&1)
-echo " finished"
-
-if [ -n "$DOXYGEN_WARNINGS" ]
+doxygen 2>&1 >/dev/null | head -n 1000 | tee doxygen.log
+if [ -s doxygen.log ]
 then
-  echo "$DOXYGEN_WARNINGS"
-  exit 1
+  EXIT=1
+else
+  EXIT=0
 fi
+rm -f doxygen.log
+exit $EXIT
index 56d4b3c2320b90174a5091f0313f244fa63b4f22..46e9346302e81dd9ee5ca7e22b2180bcebb5d584 100755 (executable)
@@ -16,6 +16,7 @@
 
 from __future__ import print_function
 
+import io
 import os
 import re
 import sys
@@ -41,7 +42,6 @@ INCLUDE_DIRS = [
     'cmake',
     'jerry-core',
     'jerry-ext',
-    'jerry-libc',
     'jerry-libm',
     'jerry-main',
     'jerry-port',
@@ -78,7 +78,7 @@ def main():
             for fname in files:
                 if any(fname.endswith(ext) for ext in EXTENSIONS):
                     fpath = os.path.join(root, fname)
-                    with open(fpath) as curr_file:
+                    with io.open(fpath, 'r', errors='ignore') as curr_file:
                         if not LICENSE.search(curr_file.read()):
                             print('%s: incorrect license' % fpath)
                             is_ok = False
index 23b96e1db7c4b6c8600f216b8eed2708a9906aaf..3c8e54dd21869df6e4d49ebf3b1a1cdc28087ca8 100755 (executable)
@@ -20,13 +20,17 @@ MAGIC_STRINGS_TEMP=`mktemp lit-magic-strings.inc.h.XXXXXXXXXX`
 
 cp $MAGIC_STRINGS_INC_H $MAGIC_STRINGS_TEMP
 $MAGIC_STRINGS_GEN
-diff -q $MAGIC_STRINGS_INC_H $MAGIC_STRINGS_TEMP
 DIFF_RESULT=$?
-mv $MAGIC_STRINGS_TEMP $MAGIC_STRINGS_INC_H
 
-if [ $DIFF_RESULT -ne 0 ]
+if [ $DIFF_RESULT -eq 0 ]
 then
-  echo -e "\e[1;33m$MAGIC_STRINGS_INC_H must be re-generated. Run $MAGIC_STRINGS_GEN\e[0m"
+  diff -q $MAGIC_STRINGS_INC_H $MAGIC_STRINGS_TEMP
+  DIFF_RESULT=$?
+  if [ $DIFF_RESULT -ne 0 ]
+  then
+    echo -e "\e[1;33m$MAGIC_STRINGS_INC_H must be re-generated. Run $MAGIC_STRINGS_GEN\e[0m"
+  fi
 fi
+mv $MAGIC_STRINGS_TEMP $MAGIC_STRINGS_INC_H
 
 exit $DIFF_RESULT
diff --git a/deps/jerry/tools/check-sonarqube.sh b/deps/jerry/tools/check-sonarqube.sh
new file mode 100755 (executable)
index 0000000..5bba89f
--- /dev/null
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+# 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.
+
+if [[ "${TRAVIS_REPO_SLUG}" == "jerryscript-project/jerryscript"
+  && ${TRAVIS_BRANCH} == "master"
+  && ${TRAVIS_EVENT_TYPE} == "push" ]]
+then
+  git fetch --unshallow
+  build-wrapper-linux-x86-64 --out-dir bw-output \
+    ./tools/build.py --error-messages=on \
+                     --jerry-cmdline-snapshot=on \
+                     --jerry-debugger=on \
+                     --line-info=on \
+                     --mem-stats=on \
+                     --profile=es2015-subset \
+                     --snapshot-save=on \
+                     --snapshot-exec=on \
+                     --valgrind=on \
+                     --vm-exec-stop=on
+  sonar-scanner -Dsonar.projectVersion="${TRAVIS_COMMIT}"
+else
+  # SonarQube analysis works only on the master branch.
+  # Ensure the build works with the options used for the analysis.
+  ./tools/build.py --error-messages=on \
+                   --jerry-cmdline-snapshot=on \
+                   --jerry-debugger=on \
+                   --line-info=on \
+                   --mem-stats=on \
+                   --profile=es2015-subset \
+                   --snapshot-save=on \
+                   --snapshot-exec=on \
+                   --valgrind=on \
+                   --vm-exec-stop=on
+fi
index e8375458901ef72ee1d0aa87c8f971bc986b5588..0b26806deb195f93e3ccaae2a24ab97a7112be12 100755 (executable)
@@ -17,7 +17,6 @@
 JERRY_CORE_FILES=`find ./jerry-core -name "*.c" -or -name "*.h"`
 JERRY_EXT_FILES=`find ./jerry-ext -name "*.c" -or -name "*.h"`
 JERRY_PORT_FILES=`find ./jerry-port -name "*.c" -or -name "*.h"`
-JERRY_LIBC_FILES=`find ./jerry-libc -name "*.c" -or -name "*.h"`
 JERRY_LIBM_FILES=`find ./jerry-libm -name "*.c" -or -name "*.h"`
 JERRY_MAIN_FILES=`find ./jerry-main -name "*.c" -or -name "*.h"`
 UNIT_TEST_FILES=`find ./tests/unit-* -name "*.c" -or -name "*.h"`
@@ -29,4 +28,4 @@ fi
 
 vera++ -r tools/vera++ -p jerry \
  -e --no-duplicate \
- $MANUAL_CHECK_FILES $JERRY_CORE_FILES $JERRY_EXT_FILES $JERRY_PORT_FILES $JERRY_LIBC_FILES $JERRY_LIBM_FILES $JERRY_MAIN_FILES $UNIT_TEST_FILES
+ $MANUAL_CHECK_FILES $JERRY_CORE_FILES $JERRY_EXT_FILES $JERRY_PORT_FILES $JERRY_LIBM_FILES $JERRY_MAIN_FILES $UNIT_TEST_FILES
index af0a3cebf09a5aaffd00301b355c6f1af9c021f7..ea48aec21b81ea136f3c83d29389082728378951 100644 (file)
@@ -1,5 +1,4 @@
 wrongmathcall:tests/unit-libm/test-libm.inc.h
 variableScope:jerry-libm/*.c
 invalidPointerCast:jerry-libm/*.c
-arithOperationsOnVoidPointer:jerry-libc/*.c
 commaSeparatedReturn:*
index 970ab3d837d634540df9fd1da83dd540162b1f5c..9c22b5f7fe43753d8468a4da38fe90d37d306be1 100755 (executable)
@@ -119,10 +119,10 @@ def extract_magic_string_refs(debug=False):
         guard_stack = []
 
         for line in fileinput.input(fname):
-            if_match = re.match('^# *if(.*)', line)
-            elif_match = re.match('^# *elif(.*)', line)
-            else_match = re.match('^# *else', line)
-            endif_match = re.match('^# *endif', line)
+            if_match = re.match('^ *# *if(.*)', line)
+            elif_match = re.match('^ *# *elif(.*)', line)
+            else_match = re.match('^ *# *else', line)
+            endif_match = re.match('^ *# *endif', line)
             if if_match is not None:
                 guard_stack.append([process_guard(if_match.group(1))])
             elif elif_match is not None:
diff --git a/deps/jerry/tools/generator.sh b/deps/jerry/tools/generator.sh
deleted file mode 100755 (executable)
index c482121..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-echo "#define JERRY_MCU_SCRIPT \\" > $2
-# escape all " characters, wrap each line in double quotes and end the line with '\'
-sed 's/"/\\"/g' $1 | sed 's/^.*$/"\0" \\/g' >> $2
-echo >> $2
diff --git a/deps/jerry/tools/make-log-perf-compare.sh b/deps/jerry/tools/make-log-perf-compare.sh
deleted file mode 100755 (executable)
index 5731045..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-commit_first=$1
-shift
-
-commit_second=$1
-shift
-
-exceptions="-e '' $*"
-
-if [[ "$commit_first" == "" ]] || [[ "$commit_second" == "" ]]
-then
-  exit 1
-fi
-
-perf_first=`git notes --ref=arm-linux-perf show $commit_first | grep -v $exceptions`
-if [ $? -ne 0 ]
-then
-  exit 1
-fi
-
-perf_second=`git notes --ref=arm-linux-perf show $commit_second | grep -v $exceptions`
-if [ $? -ne 0 ]
-then
-  exit 1
-fi
-
-n=0
-rel_mult=1.0
-for bench in `echo "$perf_first" | cut -d ':' -f 1`
-do
-  value1=`echo "$perf_first" | grep "^$bench: " | cut -d ':' -f 2 | cut -d 's' -f 1`
-  value2=`echo "$perf_second" | grep "^$bench: " | cut -d ':' -f 2 | cut -d 's' -f 1`
-  rel=`echo $value1 $value2 | awk '{print $2 / $1; }'`
-  percent=`echo $rel | awk '{print (1.0 - $1) * 100; }'`
-
-  n=`echo $n | awk '{print $1 + 1;}'`;
-  rel_mult=`echo $rel_mult $rel | awk '{print $1 * $2;}'`
-
-  echo $bench":"$value1"s ->"$value2"s ("$percent" %)"
-done
-
-rel_gmean=`echo $rel_mult $n | awk '{print $1 ^ (1.0 / $2);}'`
-percent_gmean=`echo $rel_gmean | awk '{print (1.0 - $1) * 100;}'`
-
-echo
-echo $n $rel_mult $rel_gmean "("$percent_gmean "%)"
index e6a6d86da2499083cf7af4cf7ae19d2e14128810..e07b6b80f215e162e4bfffdc13f98d0348595948 100644 (file)
@@ -275,7 +275,7 @@ docstring-min-length=-1
 [ELIF]
 
 # Maximum number of nested blocks for function / method body
-max-nested-blocks=5
+max-nested-blocks=7
 
 
 [LOGGING]
@@ -319,7 +319,7 @@ max-returns=6
 max-branches=15
 
 # Maximum number of statements in function / method body
-max-statements=50
+max-statements=75
 
 # Maximum number of parents for a class (see R0901).
 max-parents=7
index 970dc2b29568b67f96d7c05baf2dae3932f1e189..80b28d6b553e9e79a58c3b8a10ed9f6593de4f78 100755 (executable)
@@ -18,104 +18,93 @@ from __future__ import print_function
 
 import argparse
 import collections
+import hashlib
 import os
+import platform
 import subprocess
 import sys
 import settings
 
 OUTPUT_DIR = os.path.join(settings.PROJECT_DIR, 'build', 'tests')
 
-Options = collections.namedtuple('Options', ['name', 'build_args', 'test_args'])
-Options.__new__.__defaults__ = ([], [])
+Options = collections.namedtuple('Options', ['name', 'build_args', 'test_args', 'skip'])
+Options.__new__.__defaults__ = ([], [], False)
 
-def get_binary_path(bin_dir_path):
-    return os.path.join(bin_dir_path, 'jerry')
+def skip_if(condition, desc):
+    return desc if condition else False
+
+OPTIONS_PROFILE_MIN = ['--profile=minimal']
+OPTIONS_PROFILE_ES51 = [] # NOTE: same as ['--profile=es5.1']
+OPTIONS_PROFILE_ES2015 = ['--profile=es2015-subset']
+OPTIONS_DEBUG = ['--debug']
+OPTIONS_SNAPSHOT = ['--snapshot-save=on', '--snapshot-exec=on', '--jerry-cmdline-snapshot=on']
+OPTIONS_UNITTESTS = ['--unittests=on', '--jerry-cmdline=off', '--error-messages=on',
+                     '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on',
+                     '--line-info=on', '--mem-stats=on']
+OPTIONS_DOCTESTS = ['--doctests=on', '--jerry-cmdline=off', '--error-messages=on',
+                    '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on']
 
 # Test options for unittests
 JERRY_UNITTESTS_OPTIONS = [
-    Options('unittests',
-            ['--unittests', '--profile=es2015-subset', '--jerry-cmdline=off', '--error-messages=on',
-             '--snapshot-save=on', '--snapshot-exec=on', '--line-info=on', '--vm-exec-stop=on',
-             '--mem-stats=on']),
-    Options('unittests-debug',
-            ['--unittests', '--debug', '--profile=es2015-subset', '--jerry-cmdline=off',
-             '--error-messages=on', '--snapshot-save=on', '--snapshot-exec=on', '--line-info=on',
-             '--vm-exec-stop=on', '--mem-stats=on']),
-    Options('doctests',
-            ['--doctests', '--jerry-cmdline=off', '--error-messages=on', '--snapshot-save=on',
-             '--snapshot-exec=on', '--vm-exec-stop=on', '--profile=es2015-subset']),
-    Options('doctests-debug',
-            ['--doctests', '--jerry-cmdline=off', '--debug', '--error-messages=on',
-             '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on', '--profile=es2015-subset']),
+    Options('unittests-es2015_subset',
+            OPTIONS_UNITTESTS + OPTIONS_PROFILE_ES2015),
+    Options('unittests-es2015_subset-debug',
+            OPTIONS_UNITTESTS + OPTIONS_PROFILE_ES2015 + OPTIONS_DEBUG),
+    Options('doctests-es2015_subset',
+            OPTIONS_DOCTESTS + OPTIONS_PROFILE_ES2015),
+    Options('doctests-es2015_subset-debug',
+            OPTIONS_DOCTESTS + OPTIONS_PROFILE_ES2015 + OPTIONS_DEBUG),
     Options('unittests-es5.1',
-            ['--unittests', '--profile=es5.1', '--jerry-cmdline=off', '--error-messages=on',
-             '--snapshot-save=on', '--snapshot-exec=on', '--line-info=on', '--vm-exec-stop=on',
-             '--mem-stats=on']),
+            OPTIONS_UNITTESTS + OPTIONS_PROFILE_ES51),
     Options('unittests-es5.1-debug',
-            ['--unittests', '--debug', '--profile=es5.1', '--jerry-cmdline=off',
-             '--error-messages=on', '--snapshot-save=on', '--snapshot-exec=on', '--line-info=on',
-             '--vm-exec-stop=on', '--mem-stats=on']),
+            OPTIONS_UNITTESTS + OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG),
     Options('doctests-es5.1',
-            ['--doctests', '--jerry-cmdline=off', '--error-messages=on', '--snapshot-save=on',
-             '--snapshot-exec=on', '--vm-exec-stop=on', '--profile=es5.1']),
+            OPTIONS_DOCTESTS + OPTIONS_PROFILE_ES51),
     Options('doctests-es5.1-debug',
-            ['--doctests', '--jerry-cmdline=off', '--debug', '--error-messages=on',
-             '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on', '--profile=es5.1'])
+            OPTIONS_DOCTESTS + OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG)
 ]
 
 # Test options for jerry-tests
 JERRY_TESTS_OPTIONS = [
-    Options('jerry_tests'),
-    Options('jerry_tests-debug',
-            ['--debug']),
-    Options('jerry_tests-debug-cpointer_32bit',
-            ['--debug', '--cpointer-32bit=on', '--mem-heap=1024']),
-    Options('jerry_tests-snapshot',
-            ['--snapshot-save=on', '--snapshot-exec=on', '--jerry-cmdline-snapshot=on'],
+    Options('jerry_tests-es5.1',
+            OPTIONS_PROFILE_ES51),
+    Options('jerry_tests-es5.1-snapshot',
+            OPTIONS_PROFILE_ES51 + OPTIONS_SNAPSHOT,
             ['--snapshot']),
-    Options('jerry_tests-debug-snapshot',
-            ['--debug', '--snapshot-save=on', '--snapshot-exec=on', '--jerry-cmdline-snapshot=on'],
+    Options('jerry_tests-es5.1-debug',
+            OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG),
+    Options('jerry_tests-es5.1-debug-snapshot',
+            OPTIONS_PROFILE_ES51 + OPTIONS_SNAPSHOT + OPTIONS_DEBUG,
             ['--snapshot']),
+    Options('jerry_tests-es5.1-debug-cpointer_32bit',
+            OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG + ['--cpointer-32bit=on', '--mem-heap=1024']),
+    Options('jerry_tests-es5.1-debug-external_context',
+            OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG + ['--external-context=on']),
     Options('jerry_tests-es2015_subset-debug',
-            ['--debug', '--profile=es2015-subset']),
-    Options('jerry_tests-es5.1-debug',
-            ['--debug', '--profile=es5.1']),
-    Options('jerry_tests-debug-external_context',
-            ['--debug', '--jerry-libc=off', '--external-context=on'])
+            OPTIONS_PROFILE_ES2015 + OPTIONS_DEBUG),
 ]
 
 # Test options for jerry-test-suite
 JERRY_TEST_SUITE_OPTIONS = JERRY_TESTS_OPTIONS[:]
 JERRY_TEST_SUITE_OPTIONS.extend([
     Options('jerry_test_suite-minimal',
-            ['--profile=minimal']),
+            OPTIONS_PROFILE_MIN),
     Options('jerry_test_suite-minimal-snapshot',
-            ['--profile=minimal', '--snapshot-save=on', '--snapshot-exec=on', '--jerry-cmdline-snapshot=on'],
+            OPTIONS_PROFILE_MIN + OPTIONS_SNAPSHOT,
             ['--snapshot']),
     Options('jerry_test_suite-minimal-debug',
-            ['--debug', '--profile=minimal']),
+            OPTIONS_PROFILE_MIN + OPTIONS_DEBUG),
     Options('jerry_test_suite-minimal-debug-snapshot',
-            ['--debug', '--profile=minimal', '--snapshot-save=on', '--snapshot-exec=on',
-             '--jerry-cmdline-snapshot=on'],
+            OPTIONS_PROFILE_MIN + OPTIONS_SNAPSHOT + OPTIONS_DEBUG,
             ['--snapshot']),
     Options('jerry_test_suite-es2015_subset',
-            ['--profile=es2015-subset']),
+            OPTIONS_PROFILE_ES2015),
     Options('jerry_test_suite-es2015_subset-snapshot',
-            ['--profile=es2015-subset', '--snapshot-save=on', '--snapshot-exec=on', '--jerry-cmdline-snapshot=on'],
+            OPTIONS_PROFILE_ES2015 + OPTIONS_SNAPSHOT,
             ['--snapshot']),
     Options('jerry_test_suite-es2015_subset-debug-snapshot',
-            ['--debug', '--profile=es2015-subset', '--snapshot-save=on', '--snapshot-exec=on',
-             '--jerry-cmdline-snapshot=on'],
+            OPTIONS_PROFILE_ES2015 + OPTIONS_SNAPSHOT + OPTIONS_DEBUG,
             ['--snapshot']),
-    Options('jerry_test_suite_es5.1',
-            ['--profile=es5.1']),
-    Options('jerry_test_suite-es5.1-snapshot',
-            ['--profile=es5.1', '--snapshot-save=on', '--snapshot-exec=on', '--jerry-cmdline-snapshot=on'],
-            ['--snapshot']),
-    Options('jerry_test_suite-es5.1-debug-snapshot',
-            ['--debug', '--profile=es5.1', '--snapshot-save=on', '--snapshot-exec=on',
-             '--jerry-cmdline-snapshot=on'],
-            ['--snapshot'])
 ])
 
 # Test options for test262
@@ -126,7 +115,7 @@ TEST262_TEST_SUITE_OPTIONS = [
 # Test options for jerry-debugger
 DEBUGGER_TEST_OPTIONS = [
     Options('jerry_debugger_tests',
-            ['--debug', '--jerry-debugger=on', '--jerry-libc=off'])
+            ['--debug', '--jerry-debugger=on'])
 ]
 
 # Test options for buildoption-test
@@ -135,24 +124,30 @@ JERRY_BUILDOPTIONS = [
             ['--lto=on']),
     Options('buildoption_test-error_messages',
             ['--error-messages=on']),
+    Options('buildoption_test-logging',
+            ['--logging=on']),
     Options('buildoption_test-all_in_one',
             ['--all-in-one=on']),
     Options('buildoption_test-valgrind',
             ['--valgrind=on']),
-    Options('buildoption_test-valgrind_freya',
-            ['--valgrind-freya=on']),
     Options('buildoption_test-mem_stats',
             ['--mem-stats=on']),
     Options('buildoption_test-show_opcodes',
             ['--show-opcodes=on']),
     Options('buildoption_test-show_regexp_opcodes',
             ['--show-regexp-opcodes=on']),
-    Options('buildoption_test-compiler_default_libc',
-            ['--jerry-libc=off']),
     Options('buildoption_test-cpointer_32bit',
-            ['--jerry-libc=off', '--compile-flag=-m32', '--cpointer-32bit=on', '--system-allocator=on']),
+            ['--compile-flag=-m32', '--cpointer-32bit=on', '--system-allocator=on'],
+            skip=skip_if(
+                platform.system() != 'Linux' or (platform.machine() != 'i386' and platform.machine() != 'x86_64'),
+                '-m32 is only supported on x86[-64]-linux')
+           ),
+    Options('buildoption_test-no_lcache_prophashmap',
+            ['--compile-flag=-DCONFIG_ECMA_LCACHE_DISABLE', '--compile-flag=-DCONFIG_ECMA_PROPERTY_HASHMAP_DISABLE']),
     Options('buildoption_test-external_context',
-            ['--jerry-libc=off', '--external-context=on']),
+            ['--external-context=on']),
+    Options('buildoption_test-shared_libs',
+            ['--shared-libs=on']),
     Options('buildoption_test-cmdline_test',
             ['--jerry-cmdline-test=on']),
     Options('buildoption_test-cmdline_snapshot',
@@ -211,26 +206,48 @@ def get_arguments():
 
 BINARY_CACHE = {}
 
+TERM_NORMAL = '\033[0m'
+TERM_YELLOW = '\033[1;33m'
+TERM_BLUE = '\033[1;34m'
+
+def report_command(cmd_type, cmd, env=None):
+    sys.stderr.write('%s%s%s\n' % (TERM_BLUE, cmd_type, TERM_NORMAL))
+    if env is not None:
+        sys.stderr.write(''.join('%s%s=%r \\%s\n' % (TERM_BLUE, var, val, TERM_NORMAL)
+                                 for var, val in sorted(env.items())))
+    sys.stderr.write('%s%s%s\n' % (TERM_BLUE, (' \\%s\n\t%s' % (TERM_NORMAL, TERM_BLUE)).join(cmd), TERM_NORMAL))
+
+def report_skip(job):
+    sys.stderr.write('%sSkipping: %s' % (TERM_YELLOW, job.name))
+    if job.skip:
+        sys.stderr.write(' (%s)' % job.skip)
+    sys.stderr.write('%s\n' % TERM_NORMAL)
+
 def create_binary(job, options):
-    build_cmd = [settings.BUILD_SCRIPT]
-    build_cmd.extend(job.build_args)
+    build_args = job.build_args[:]
+    if options.buildoptions:
+        for option in options.buildoptions.split(','):
+            if option not in build_args:
+                build_args.append(option)
+
+    build_cmd = [settings.BUILD_SCRIPT] + build_args
 
     build_dir_path = os.path.join(options.outdir, job.name)
     build_cmd.append('--builddir=%s' % build_dir_path)
 
+    install_dir_path = os.path.join(build_dir_path, 'local')
+    build_cmd.append('--install=%s' % install_dir_path)
+
     if options.toolchain:
         build_cmd.append('--toolchain=%s' % options.toolchain)
 
-    if options.buildoptions:
-        build_cmd.extend(options.buildoptions.split(','))
-
-    sys.stderr.write('Build command: %s\n' % ' '.join(build_cmd))
+    report_command('Build command:', build_cmd)
 
-    binary_key = tuple(job.build_args)
+    binary_key = tuple(sorted(build_args))
     if binary_key in BINARY_CACHE:
         ret, build_dir_path = BINARY_CACHE[binary_key]
         sys.stderr.write('(skipping: already built at %s with returncode %d)\n' % (build_dir_path, ret))
-        return ret, os.path.join(build_dir_path, 'bin')
+        return ret, build_dir_path
 
     try:
         subprocess.check_output(build_cmd)
@@ -239,22 +256,65 @@ def create_binary(job, options):
         ret = err.returncode
 
     BINARY_CACHE[binary_key] = (ret, build_dir_path)
-    return ret, os.path.join(build_dir_path, 'bin')
+    return ret, build_dir_path
+
+def get_binary_path(build_dir_path):
+    return os.path.join(build_dir_path, 'local', 'bin', 'jerry')
+
+def hash_binary(bin_path):
+    blocksize = 65536
+    hasher = hashlib.sha1()
+    with open(bin_path, 'rb') as bin_file:
+        buf = bin_file.read(blocksize)
+        while len(buf) > 0:
+            hasher.update(buf)
+            buf = bin_file.read(blocksize)
+    return hasher.hexdigest()
+
+def iterate_test_runner_jobs(jobs, options):
+    tested_paths = set()
+    tested_hashes = {}
+
+    for job in jobs:
+        ret_build, build_dir_path = create_binary(job, options)
+        if ret_build:
+            yield job, ret_build, None
 
-def run_check(runnable):
-    sys.stderr.write('Test command: %s\n' % ' '.join(runnable))
+        if build_dir_path in tested_paths:
+            sys.stderr.write('(skipping: already tested with %s)\n' % build_dir_path)
+            continue
+        else:
+            tested_paths.add(build_dir_path)
 
-    try:
-        ret = subprocess.check_call(runnable)
-    except subprocess.CalledProcessError as err:
-        return err.returncode
+        bin_path = get_binary_path(build_dir_path)
+        bin_hash = hash_binary(bin_path)
 
-    return ret
+        if bin_hash in tested_hashes:
+            sys.stderr.write('(skipping: already tested with equivalent %s)\n' % tested_hashes[bin_hash])
+            continue
+        else:
+            tested_hashes[bin_hash] = build_dir_path
+
+        test_cmd = [settings.TEST_RUNNER_SCRIPT, bin_path]
+
+        yield job, ret_build, test_cmd
+
+def run_check(runnable, env=None):
+    report_command('Test command:', runnable, env=env)
+
+    if env is not None:
+        full_env = dict(os.environ)
+        full_env.update(env)
+        env = full_env
+
+    proc = subprocess.Popen(runnable, env=env)
+    proc.wait()
+    return proc.returncode
 
 def run_jerry_debugger_tests(options):
     ret_build = ret_test = 0
     for job in DEBUGGER_TEST_OPTIONS:
-        ret_build, bin_dir_path = create_binary(job, options)
+        ret_build, build_dir_path = create_binary(job, options)
         if ret_build:
             break
 
@@ -264,7 +324,7 @@ def run_jerry_debugger_tests(options):
                 test_case_path = os.path.join(settings.DEBUGGER_TESTS_DIR, test_case)
                 test_cmd = [
                     settings.DEBUGGER_TEST_RUNNER_SCRIPT,
-                    get_binary_path(bin_dir_path),
+                    get_binary_path(build_dir_path),
                     settings.DEBUGGER_CLIENT_SCRIPT,
                     os.path.relpath(test_case_path, settings.PROJECT_DIR)
                 ]
@@ -278,48 +338,41 @@ def run_jerry_debugger_tests(options):
 
 def run_jerry_tests(options):
     ret_build = ret_test = 0
-    for job in JERRY_TESTS_OPTIONS:
-        ret_build, bin_dir_path = create_binary(job, options)
+    for job, ret_build, test_cmd in iterate_test_runner_jobs(JERRY_TESTS_OPTIONS, options):
         if ret_build:
             break
 
-        test_cmd = [
-            settings.TEST_RUNNER_SCRIPT,
-            get_binary_path(bin_dir_path),
-            settings.JERRY_TESTS_DIR
-        ]
+        test_cmd.append(settings.JERRY_TESTS_DIR)
+
+        if options.quiet:
+            test_cmd.append("-q")
+
         skip_list = []
 
-        if '--profile=es2015-subset' not in job.build_args:
-            skip_list.append(r"es2015\/")
-        else:
+        if '--profile=es2015-subset' in job.build_args:
             skip_list.append(r"es5.1\/")
+        else:
+            skip_list.append(r"es2015\/")
 
         if options.skip_list:
             skip_list.append(options.skip_list)
 
-        if options.quiet:
-            test_cmd.append("-q")
-
         if skip_list:
             test_cmd.append("--skip-list=" + ",".join(skip_list))
 
         if job.test_args:
             test_cmd.extend(job.test_args)
 
-        ret_test |= run_check(test_cmd)
+        ret_test |= run_check(test_cmd, env=dict(TZ='UTC'))
 
     return ret_build | ret_test
 
 def run_jerry_test_suite(options):
     ret_build = ret_test = 0
-    for job in JERRY_TEST_SUITE_OPTIONS:
-        ret_build, bin_dir_path = create_binary(job, options)
+    for job, ret_build, test_cmd in iterate_test_runner_jobs(JERRY_TEST_SUITE_OPTIONS, options):
         if ret_build:
             break
 
-        test_cmd = [settings.TEST_RUNNER_SCRIPT, get_binary_path(bin_dir_path)]
-
         if '--profile=minimal' in job.build_args:
             test_cmd.append(settings.JERRY_TEST_SUITE_MINIMAL_LIST)
         elif '--profile=es2015-subset' in job.build_args:
@@ -343,40 +396,44 @@ def run_jerry_test_suite(options):
 def run_test262_test_suite(options):
     ret_build = ret_test = 0
     for job in TEST262_TEST_SUITE_OPTIONS:
-        ret_build, bin_dir_path = create_binary(job, options)
+        ret_build, build_dir_path = create_binary(job, options)
         if ret_build:
             break
 
         test_cmd = [
             settings.TEST262_RUNNER_SCRIPT,
-            get_binary_path(bin_dir_path),
+            get_binary_path(build_dir_path),
             settings.TEST262_TEST_SUITE_DIR
         ]
 
         if job.test_args:
             test_cmd.extend(job.test_args)
 
-        ret_test |= run_check(test_cmd)
+        ret_test |= run_check(test_cmd, env=dict(TZ='America/Los_Angeles'))
 
     return ret_build | ret_test
 
 def run_unittests(options):
     ret_build = ret_test = 0
     for job in JERRY_UNITTESTS_OPTIONS:
-        ret_build, bin_dir_path = create_binary(job, options)
+        ret_build, build_dir_path = create_binary(job, options)
         if ret_build:
             break
 
-        ret_test |= run_check([
-            settings.UNITTEST_RUNNER_SCRIPT,
-            bin_dir_path,
-            "-q" if options.quiet else "",
-        ])
+        ret_test |= run_check(
+            [settings.UNITTEST_RUNNER_SCRIPT] +
+            [os.path.join(build_dir_path, 'tests')] +
+            (["-q"] if options.quiet else [])
+        )
 
     return ret_build | ret_test
 
 def run_buildoption_test(options):
     for job in JERRY_BUILDOPTIONS:
+        if job.skip:
+            report_skip(job)
+            continue
+
         ret, _ = create_binary(job, options)
         if ret:
             break
index 29c0cc827ecaaaa884afe7fb3ead555c2ce50107..2ccbe861b8429e88ffac4d46a30c7a87ff1b0cb6 100755 (executable)
@@ -19,6 +19,10 @@ DEBUGGER_CLIENT=$2
 TEST_CASE=$3
 CLIENT_ARGS=""
 
+TERM_NORMAL='\033[0m'
+TERM_RED='\033[1;31m'
+TERM_GREEN='\033[1;32m'
+
 if [[ $TEST_CASE == *"client_source"* ]]; then
   START_DEBUG_SERVER="${JERRY} --start-debug-server --debugger-wait-source &"
   if [[ $TEST_CASE == *"client_source_multiple"* ]]; then
@@ -36,7 +40,13 @@ sleep 1s
 
 RESULT_TEMP=`mktemp ${TEST_CASE}.out.XXXXXXXXXX`
 
-(cat "${TEST_CASE}.cmd" | ${DEBUGGER_CLIENT} --non-interactive ${CLIENT_ARGS}) &> ${RESULT_TEMP}
+(cat "${TEST_CASE}.cmd" | ${DEBUGGER_CLIENT} --non-interactive ${CLIENT_ARGS}) >${RESULT_TEMP} 2>&1
+
+if [[ $TEST_CASE == *"restart"* ]]; then
+  CONTINUE_CASE=$(sed "s/restart/continue/g" <<< "$TEST_CASE")
+  (cat "${CONTINUE_CASE}.cmd" | ${DEBUGGER_CLIENT} --non-interactive ${CLIENT_ARGS}) >>${RESULT_TEMP} 2>&1
+fi
+
 diff -U0 ${TEST_CASE}.expected ${RESULT_TEMP}
 STATUS_CODE=$?
 
@@ -44,9 +54,9 @@ rm -f ${RESULT_TEMP}
 
 if [ ${STATUS_CODE} -ne 0 ]
 then
-  echo "${TEST_CASE} failed"
+  echo -e "${TERM_RED}FAIL: ${TEST_CASE}${TERM_NORMAL}\n"
 else
-  echo "${TEST_CASE} passed"
+  echo -e "${TERM_GREEN}PASS: ${TEST_CASE}${TERM_NORMAL}\n"
 fi
 
 exit ${STATUS_CODE}
diff --git a/deps/jerry/tools/runners/run-stability-test.sh b/deps/jerry/tools/runners/run-stability-test.sh
deleted file mode 100755 (executable)
index 25ec1e6..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-NUM_COMMITS=$1
-BENCH=./tests/benchmarks/jerry/loop_arithmetics_1kk.js
-TARGET=release.linux
-
-trap ctrl_c INT
-
-function ctrl_c() {
-  git checkout master >&/dev/null
-  exit 1
-}
-
-commits_to_push=`git log -$NUM_COMMITS | grep "^commit [0-9a-f]*$" | awk 'BEGIN { s = ""; } { s = $2" "s; } END { print s; }'`
-
-for commit_hash in $commits_to_push
-do
-  git checkout $commit_hash >&/dev/null
-
-  echo -e -n " > Testing...\n >  "
-  echo `git log --format=%B -n 1 $commit_hash`
-  make -s $TARGET
-  ./tools/rss-measure.sh $TARGET $BENCH
-  echo
-done
-
-git checkout master >&/dev/null
index 7a990f058441d5723ccb4b676361581a7c56699e..ea9267387df0452b28d6bff13bfcbcc0cb638d64 100755 (executable)
@@ -24,6 +24,12 @@ if [ $? -ne 0 ]
 then
     TIMEOUT_CMD=`which gtimeout`
 fi
+if [ -z "${RUNTIME}" ]
+then
+  COMMAND="${TIMEOUT_CMD} ${TIMEOUT} ${ENGINE}"
+else
+  COMMAND="${TIMEOUT_CMD} ${TIMEOUT} ${RUNTIME} ${ENGINE}"
+fi
 
 if [ $# -lt 2 ]
 then
@@ -46,23 +52,33 @@ fi
 rm -rf "${PATH_TO_TEST262}/test/suite/bestPractice"
 rm -rf "${PATH_TO_TEST262}/test/suite/intl402"
 
-# TODO: Enable these tests after daylight saving calculation is fixed.
-rm -f "${PATH_TO_TEST262}/test/suite/ch15/15.9/15.9.3/S15.9.3.1_A5_T1.js"
-rm -f "${PATH_TO_TEST262}/test/suite/ch15/15.9/15.9.3/S15.9.3.1_A5_T2.js"
-rm -f "${PATH_TO_TEST262}/test/suite/ch15/15.9/15.9.3/S15.9.3.1_A5_T3.js"
-rm -f "${PATH_TO_TEST262}/test/suite/ch15/15.9/15.9.3/S15.9.3.1_A5_T4.js"
-rm -f "${PATH_TO_TEST262}/test/suite/ch15/15.9/15.9.3/S15.9.3.1_A5_T5.js"
-rm -f "${PATH_TO_TEST262}/test/suite/ch15/15.9/15.9.3/S15.9.3.1_A5_T6.js"
+echo "Starting test262 testing for ${ENGINE}. Running test262 may take several minutes."
 
-echo "Starting test262 testing for ${ENGINE}. Running test262 may take a several minutes."
 
-python2 "${PATH_TO_TEST262}"/tools/packaging/test262.py --command "${TIMEOUT_CMD} ${TIMEOUT} ${ENGINE}" \
+function progress_monitor() {
+  NUM_LINES_GOTTEN=0
+  (>&2 echo)
+  while read line
+  do
+    if [[ $((NUM_LINES_GOTTEN % 100)) == 0 ]]
+    then
+      (>&2 echo -ne "\rExecuted approx ${NUM_LINES_GOTTEN} tests...")
+    fi
+    echo "$line"
+    NUM_LINES_GOTTEN=$((NUM_LINES_GOTTEN + 1))
+  done
+  (>&2 echo)
+  (>&2 echo)
+}
+
+python2 "${PATH_TO_TEST262}"/tools/packaging/test262.py --command "${COMMAND}" \
                                                         --tests="${PATH_TO_TEST262}" --summary \
-                                                        &> "${REPORT_PATH}"
+                                                        | progress_monitor > "${REPORT_PATH}"
+
 TEST262_EXIT_CODE=$?
 if [ $TEST262_EXIT_CODE -ne 0 ]
 then
-  echo -e "\nFailed to run test2626\n"
+  echo -e "\nFailed to run test262\n"
   echo "$0: see ${REPORT_PATH} for details about failures"
   exit $TEST262_EXIT_CODE
 fi
index d10e8fc0202c35036fe01dfe5410b0557544cd0a..b5b376e36d70226ccd70b3b117e72be95b584e46 100755 (executable)
@@ -37,6 +37,12 @@ TEST_FILES=$OUTPUT_DIR/$TESTS_BASENAME.files
 TEST_FAILED=$OUTPUT_DIR/$TESTS_BASENAME.failed
 TEST_PASSED=$OUTPUT_DIR/$TESTS_BASENAME.passed
 
+TERM_NORMAL="\033[0m"
+TERM_RED="\033[1;31m"
+TERM_GREEN="\033[1;32m"
+
+trap 'exit' SIGINT
+
 VERBOSE=1
 if [[ "$1" == "-q" ]]
 then
@@ -47,7 +53,7 @@ fi
 if [[ "$1" =~ ^--skip-list=.* ]]
 then
     SKIP_LIST=${1#--skip-list=}
-    SKIP_LIST=(${SKIP_LIST//,/ })
+    SKIP_LIST=${SKIP_LIST//,/ }
     shift
 fi
 
@@ -79,7 +85,7 @@ if [ -d $TESTS ]
 then
     TESTS_DIR=$TESTS
 
-    ( cd $TESTS; find . -name "[^N]*.js" ) | sort > $TEST_FILES
+    ( cd $TESTS; find . -name "*.js" ) | sort > $TEST_FILES
 elif [ -f $TESTS ]
 then
     TESTS_DIR=`dirname $TESTS`
@@ -91,7 +97,7 @@ else
 fi
 
 # Remove the skipped tests from list
-for TEST in "${SKIP_LIST[@]}"
+for TEST in ${SKIP_LIST}
 do
     ( sed -i -r "/$TEST/d" $TEST_FILES )
 done
@@ -148,29 +154,29 @@ do
         # Testing snapshot
         SNAPSHOT_TEMP=`mktemp $(basename -s .js $test).snapshot.XXXXXXXXXX`
 
-        cmd_line="${SNAPSHOT_TOOL#$ROOT_DIR} generate -o $SNAPSHOT_TEMP ${full_test#$ROOT_DIR}"
-        $TIMEOUT_CMD $TIMEOUT $SNAPSHOT_TOOL generate -o $SNAPSHOT_TEMP $full_test &> $ENGINE_TEMP
+        $TIMEOUT_CMD $TIMEOUT $RUNTIME $SNAPSHOT_TOOL generate -o $SNAPSHOT_TEMP $full_test &> $ENGINE_TEMP
         status_code=$?
+        comment=" (generate snapshot)"
 
         if [ $status_code -eq 0 ]
         then
-            test $VERBOSE && echo "[$tested/$TOTAL] $cmd_line: PASS"
+            test $VERBOSE && printf "[%4d/%4d] %bPASS: %s%s%b\n" "$tested" "$TOTAL" "$TERM_GREEN" "${full_test#$ROOT_DIR}" "$comment" "$TERM_NORMAL"
 
-            cmd_line="${ENGINE#$ROOT_DIR} $ENGINE_ARGS --exec-snapshot $SNAPSHOT_TEMP"
-            $TIMEOUT_CMD $TIMEOUT $ENGINE $ENGINE_ARGS --exec-snapshot $SNAPSHOT_TEMP &> $ENGINE_TEMP
+            $TIMEOUT_CMD $TIMEOUT $RUNTIME $ENGINE $ENGINE_ARGS --exec-snapshot $SNAPSHOT_TEMP &> $ENGINE_TEMP
             status_code=$?
+            comment=" (execute snapshot)"
         fi
 
         rm -f $SNAPSHOT_TEMP
     else
-        cmd_line="${ENGINE#$ROOT_DIR} $ENGINE_ARGS ${full_test#$ROOT_DIR}"
-        $TIMEOUT_CMD $TIMEOUT $ENGINE $ENGINE_ARGS $full_test &> $ENGINE_TEMP
+        $TIMEOUT_CMD $TIMEOUT $RUNTIME $ENGINE $ENGINE_ARGS $full_test &> $ENGINE_TEMP
         status_code=$?
+        comment=""
     fi
 
     if [ $status_code -ne $error_code ]
     then
-        echo "[$tested/$TOTAL] $cmd_line: FAIL ($status_code)"
+        printf "[%4d/%4d] %bFAIL (%d): %s%s%b\n" "$tested" "$TOTAL" "$TERM_RED" "$status_code" "${full_test#$ROOT_DIR}" "$comment" "$TERM_NORMAL"
         cat $ENGINE_TEMP
 
         echo "$status_code: $test" >> $TEST_FAILED
@@ -182,8 +188,7 @@ do
 
         failed=$((failed+1))
     else
-        test $VERBOSE && echo "[$tested/$TOTAL] $cmd_line: $PASS"
-
+        test $VERBOSE && printf "[%4d/%4d] %b%s: %s%s%b\n" "$tested" "$TOTAL" "$TERM_GREEN" "$PASS" "${full_test#$ROOT_DIR}" "$comment" "$TERM_NORMAL"
         echo "$test" >> $TEST_PASSED
 
         passed=$((passed+1))
@@ -195,13 +200,23 @@ done
 rm -f $ENGINE_TEMP
 
 ratio=$(echo $passed*100/$TOTAL | bc)
+if [ $passed -eq $TOTAL ]
+then
+    success_color=$TERM_GREEN
+else
+    success_color=$TERM_RED
+fi
 
 if [ "$IS_SNAPSHOT" == true ]
 then
     ENGINE_ARGS="--snapshot $ENGINE_ARGS"
 fi
 
-echo "[summary] ${ENGINE#$ROOT_DIR} $ENGINE_ARGS ${TESTS#$ROOT_DIR}: $passed PASS, $failed FAIL, $TOTAL total, $ratio% success"
+echo -e "\n[summary] ${ENGINE#$ROOT_DIR} $ENGINE_ARGS ${TESTS#$ROOT_DIR}\n"
+echo -e "TOTAL: $TOTAL"
+echo -e "${TERM_GREEN}PASS: $passed${TERM_NORMAL}"
+echo -e "${TERM_RED}FAIL: $failed${TERM_NORMAL}\n"
+echo -e "${success_color}Success: $ratio%${TERM_NORMAL}\n"
 
 if [ $failed -ne 0 ]
 then
diff --git a/deps/jerry/tools/runners/run-tests-remote.sh b/deps/jerry/tools/runners/run-tests-remote.sh
deleted file mode 100755 (executable)
index d6a01eb..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-TARGET="$1" #debug.linux release.linux
-TARGET_IP="$2" # ip address of target board
-TARGET_USER="$3" # login
-TARGET_PASS="$4" # password
-
-if [ $# -lt 4 ]
-then
-  echo "This script runs ./jerry/* and ./jerry-test-suite/* tests on the remote board."
-  echo ""
-  echo "Usage:"
-  echo "  1st parameter: target to be tested: {debug.linux, release.linux}"
-  echo "  2nd parameter: ip address of target board: {110.110.110.110}"
-  echo "  3rd parameter: ssh login to target board: {login}"
-  echo "  4th parameter: ssh password to target board: {password}"
-  echo ""
-  echo "Example:"
-  echo "  ./tools/runners/run-tests-remote.sh debug.linux 110.110.110.110 login password"
-  exit 1
-fi
-
-BASE_DIR=$(dirname "$(readlink -f "$0")" )
-
-OUT_DIR="${BASE_DIR}"/../.././build/bin
-LOGS_PATH_FULL="${OUT_DIR}"/"${TARGET}"/check
-
-export SSHPASS="${TARGET_PASS}"
-
-rm -rf "${LOGS_PATH_FULL}"
-
-mkdir -p "${LOGS_PATH_FULL}"
-
-REMOTE_TMP_DIR=$(sshpass -e ssh "${TARGET_USER}"@"${TARGET_IP}" 'mktemp -d')
-REMOTE_TMP_TAR=$(sshpass -e ssh "${TARGET_USER}"@"${TARGET_IP}" 'mktemp')
-LOCAL_TMP_TAR=$(mktemp)
-
-tar -zcf "${LOCAL_TMP_TAR}" \
-  "${BASE_DIR}"/../.././build/bin/"${TARGET}" \
-  "${BASE_DIR}"/../.././tests/benchmarks \
-  "${BASE_DIR}"/../.././tests/jerry \
-  "${BASE_DIR}"/../.././tests/jerry-test-suite \
-  "${BASE_DIR}"/../.././tools/runners \
-  "${BASE_DIR}"/../.././tools/precommit-full-testing.sh > /dev/null 2>&1
-
-sshpass -e scp "${LOCAL_TMP_TAR}" "${TARGET_USER}"@"${TARGET_IP}":"${REMOTE_TMP_TAR}"
-
-sshpass -e ssh "${TARGET_USER}"@"${TARGET_IP}" \
-  "tar -zxf \"${REMOTE_TMP_TAR}\" -C \"${REMOTE_TMP_DIR}\"; rm \"${REMOTE_TMP_TAR}\";\
-  cd \"${REMOTE_TMP_DIR}\"; \
-  ./tools/precommit-full-testing.sh ./build/bin \"$TARGET\" > ./build/bin/\"${TARGET}\"/check/run.log 2>&1; \
-  echo \$? > ./build/bin/\"${TARGET}\"/check/IS_TEST_OK"
-
-sshpass -e scp -r "${TARGET_USER}"@"${TARGET_IP}":"${REMOTE_TMP_DIR}"/build/bin/"${TARGET}"/check/* "${LOGS_PATH_FULL}"
-sshpass -e ssh "${TARGET_USER}"@"${TARGET_IP}" "rm -rf \"${REMOTE_TMP_DIR}\""
-
-STATUS=$(cat "${LOGS_PATH_FULL}"/IS_TEST_OK)
-
-if [ "${STATUS}" == 0 ] ; then
-  echo "${TARGET} testing passed."
-  exit 0
-else
-  echo "${TARGET} testing failed."
-  echo "See logs in ${LOGS_PATH_FULL} directory for details."
-  exit 1
-fi
\ No newline at end of file
diff --git a/deps/jerry/tools/runners/run-unittests-remote.sh b/deps/jerry/tools/runners/run-unittests-remote.sh
deleted file mode 100755 (executable)
index 1acd4fc..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-TARGET_IP="$1"
-TARGET_USER="$2"
-TARGET_PASS="$3"
-
-if [ $# -lt 3 ]
-then
-  echo "This script runs unittests on the remote board."
-  echo ""
-  echo "Usage:"
-  echo "  1st parameter: ip address of target board: {110.110.110.110}"
-  echo "  2nd parameter: ssh login to target board: {login}"
-  echo "  3rd parameter: ssh password to target board: {password}"
-  echo ""
-  echo "Example:"
-  echo "  ./tools/runners/run-unittests-remote.sh 110.110.110.110 login password"
-  exit 1
-fi
-
-BASE_DIR=$(dirname "$(readlink -f "$0")" )
-
-OUT_DIR="${BASE_DIR}"/../.././build/bin
-
-rm -rf "${OUT_DIR}"/unittests/check
-
-mkdir -p "${OUT_DIR}"/unittests/check
-
-export SSHPASS="${TARGET_PASS}"
-REMOTE_TMP_DIR=$(sshpass -e ssh "${TARGET_USER}"@"${TARGET_IP}" 'mktemp -d')
-
-sshpass -e scp "${BASE_DIR}"/../../tools/runners/run-unittests.sh "${TARGET_USER}"@"${TARGET_IP}":"${REMOTE_TMP_DIR}"
-sshpass -e scp -r "${OUT_DIR}"/unittests/* "${TARGET_USER}"@"${TARGET_IP}":"${REMOTE_TMP_DIR}"
-
-sshpass -e ssh "${TARGET_USER}"@"${TARGET_IP}" "mkdir -p \"${REMOTE_TMP_DIR}\"/check; \
-                                                \"${REMOTE_TMP_DIR}\"/run-unittests.sh \"${REMOTE_TMP_DIR}\"; \
-                                                echo \$? > \"${REMOTE_TMP_DIR}\"/check/IS_REMOTE_TEST_OK"
-
-sshpass -e scp -r "${TARGET_USER}"@$"{TARGET_IP}":"${REMOTE_TMP_DIR}"/check "${OUT_DIR}"/unittests
-
-sshpass -e ssh "${TARGET_USER}"@"${TARGET_IP}" "rm -rf \"${REMOTE_TMP_DIR}\""
-
-STATUS=$(cat "${OUT_DIR}"/unittests/check/IS_REMOTE_TEST_OK)
-
-if [ "${STATUS}" == 0 ] ; then
-    echo "Unit tests run passed."
-    exit 0
-else
-    echo "Unit tests run failed. See ${OUT_DIR}/unittests/unit_tests_run.log for details."
-    exit 1
-fi
index 78e94372d3673ab43cd9d512acbfe3fad789674c..651b1a07d5a1a7a8588f5625362cbe80281b0edf 100755 (executable)
@@ -29,8 +29,8 @@ UNITTEST_OK=$DIR/unittests.passed
 
 rm -f $UNITTEST_ERROR $UNITTEST_OK
 
-UNITTESTS=$(ls $DIR/unit-*)
-total=$(ls $DIR/unit-* | wc -l)
+UNITTESTS=$(find $DIR -maxdepth 1 -type f -name 'unit-*')
+total=$(find $DIR -maxdepth 1 -type f -name 'unit-*' | wc -l)
 
 if [ "$total" -eq 0 ]
 then
@@ -63,15 +63,19 @@ passed=0
 
 UNITTEST_TEMP=`mktemp unittest-out.XXXXXXXXXX`
 
+TERM_NORMAL="\033[0m"
+TERM_RED="\033[1;31m"
+TERM_GREEN="\033[1;32m"
+
 for unit_test in $UNITTESTS
 do
-    cmd_line="${unit_test#$ROOT_DIR}"
-    $unit_test &>$UNITTEST_TEMP
+    cmd_line="$RUNTIME ${unit_test#$ROOT_DIR}"
+    $RUNTIME $unit_test &>$UNITTEST_TEMP
     status_code=$?
 
     if [ $status_code -ne 0 ]
     then
-        echo "[$tested/$total] $cmd_line: FAIL ($status_code)"
+        printf "[%4d/%4d] %bFAIL (%d): %s%b\n" "$tested" "$total" "$TERM_RED" "$status_code" "${unit_test#$ROOT_DIR}" "$TERM_NORMAL"
         cat $UNITTEST_TEMP
 
         echo "$status_code: $unit_test" >> $UNITTEST_ERROR
@@ -83,8 +87,7 @@ do
 
         failed=$((failed+1))
     else
-        test $VERBOSE && echo "[$tested/$total] $cmd_line: PASS"
-
+        test $VERBOSE && printf "[%4d/%4d] %bPASS: %s%b\n" "$tested" "$total" "$TERM_GREEN" "${unit_test#$ROOT_DIR}" "$TERM_NORMAL"
         echo "$unit_test" >> $UNITTEST_OK
 
         passed=$((passed+1))
@@ -96,8 +99,18 @@ done
 rm -f $UNITTEST_TEMP
 
 ratio=$(echo $passed*100/$total | bc)
+if [ $passed -eq $total ]
+then
+    success_color=$TERM_GREEN
+else
+    success_color=$TERM_RED
+fi
 
-echo "[summary] ${DIR#$ROOT_DIR}/unit-*: $passed PASS, $failed FAIL, $total total, $ratio% success"
+echo -e "\n[summary] ${DIR#$ROOT_DIR}/unit-*\n"
+echo -e "TOTAL: $total"
+echo -e "${TERM_GREEN}PASS: $passed${TERM_NORMAL}"
+echo -e "${TERM_RED}FAIL: $failed${TERM_NORMAL}\n"
+echo -e "${success_color}Success: $ratio%${TERM_NORMAL}\n"
 
 if [ $failed -ne 0 ]
 then
index d0344eec6f637aee84ae64e7def99f0a2c96b66f..aa5cf92a3801a9ae930c9f3d37bf1b4cad73b7a4 100755 (executable)
@@ -27,7 +27,7 @@ TEST262_TEST_SUITE_DIR = path.join(PROJECT_DIR, 'tests/test262')
 
 BUILD_SCRIPT = path.join(TOOLS_DIR, 'build.py')
 CPPCHECK_SCRIPT = path.join(TOOLS_DIR, 'check-cppcheck.sh')
-DEBUGGER_CLIENT_SCRIPT = path.join(PROJECT_DIR, 'jerry-debugger/jerry-client-ws.py')
+DEBUGGER_CLIENT_SCRIPT = path.join(PROJECT_DIR, 'jerry-debugger/jerry_client.py')
 DEBUGGER_TEST_RUNNER_SCRIPT = path.join(TOOLS_DIR, 'runners/run-debugger-test.sh')
 DOXYGEN_SCRIPT = path.join(TOOLS_DIR, 'check-doxygen.sh')
 LICENSE_SCRIPT = path.join(TOOLS_DIR, 'check-license.py')
diff --git a/deps/jerry/tools/sort-fails.sh b/deps/jerry/tools/sort-fails.sh
deleted file mode 100755 (executable)
index 6dfc7dd..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-#!/bin/bash
-
-# 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.
-
-INPUT_PATH="$1"
-VERSION=$(git log -n 1 --pretty=format:"%H")
-SYSTEM=$(uname -a)
-TMP_DIR="afl-testing"
-USAGE="Usage:\n\t./tools/sort-fails.sh PATH_TO_DIR_WITH_FAILS"
-
-if [ "$#" -ne 1 ]
-then
-  echo -e "${USAGE}";
-  echo "Argument number mismatch...";
-  exit 1;
-fi
-
-rm "$TMP_DIR" -r; mkdir "$TMP_DIR";
-
-make debug.linux VALGRIND=ON -j && echo "Build OK";
-
-for file in "$INPUT_PATH"/*;
-do
-  key1=$(./build/bin/debug.linux/jerry --abort-on-fail $file 2>&1);
-  key2=$(valgrind --default-suppressions=yes ./build/bin/debug.linux/jerry --abort-on-fail $file 2>&1 \
-        | sed -e 's/^==*[0-9][0-9]*==*//g' \
-        | sed -e 's/^ Command: .*//g');
-
-  hash1=$(echo -n $key1 | md5sum);
-  hash2=$(echo -n $key2 | md5sum);
-
-  dir="$TMP_DIR/$hash1";
-  head="$TMP_DIR/$hash1.err.md";
-  body="$dir/$hash2.err.md";
-
-  if [ ! -s "$dir" ]; then
-    mkdir -p "$dir"; touch "$head";
-    echo "###### Version: $VERSION"     >> "$head";
-    echo "###### System:"               >> "$head";
-    echo '```'                          >> "$head";
-    echo "$SYSTEM"                      >> "$head";
-    echo '```'                          >> "$head";
-    echo "###### Output:"               >> "$head";
-    echo '```'                          >> "$head";
-    echo "$key1"                        >> "$head";
-    echo '```'                          >> "$head";
-  fi
-
-  if [ ! -s "$body" ]; then
-    touch "$body";
-    echo '###### Unique backtrace:```'  >> "$body";
-    echo '```'                          >> "$body";
-    echo "$key2"                        >> "$body"
-    echo '```'                          >> "$body";
-  fi
-
-  echo "###### Test case($file):"       >> "$body";
-  echo '```js'                          >> "$body";
-  cat "$file"                           >> "$body";
-  echo '```'                            >> "$body";
-
-done
-
-cd "$TMP_DIR";
-for dir in */ ; do
-  for file in "$dir"/*;
-  do
-    cat "$file" >> "${dir%/*}.err.md"
-  done
-  rm $dir -r;
-done
index 9e6d30d4bc2c4913ff236ec8c663a062c19c84e5..8308160bdb5b4422e5f80f036f465c2ed3ff2cb1 100755 (executable)
@@ -34,6 +34,7 @@ EXT_REFERENCE_ARG_MD="09.EXT-REFERENCE-ARG.md"
 EXT_REFERENCE_HANDLER_MD="10.EXT-REFERENCE-HANDLER.md"
 EXT_REFERENCE_AUTORELEASE_MD="11.EXT-REFERENCE-AUTORELEASE.md"
 EXT_REFERENCE_MODULE_MD="12.EXT-REFERENCE-MODULE.md"
+DEBUGGER_TRANSPORT_MD="13.DEBUGGER-TRANSPORT.md"
 
 declare -A titles
 
@@ -49,6 +50,7 @@ titles[$EXT_REFERENCE_ARG_MD]="'Extension API: Argument Validation'"
 titles[$EXT_REFERENCE_HANDLER_MD]="'Extension API: External Function Handlers'"
 titles[$EXT_REFERENCE_AUTORELEASE_MD]="'Extension API: Autorelease Values'"
 titles[$EXT_REFERENCE_MODULE_MD]="'Extension API: Module Support'"
+titles[$DEBUGGER_TRANSPORT_MD]="'Debugger Transport'"
 
 for docfile in $docs_dir/*.md; do
   docfile_base=`basename $docfile`
index 7a3ff1eeb898e8d03f94ecb29aa4d79afb7e6c55..101fa40f3b481e2d9315017227944ab686adeaa6 100644 (file)
@@ -42,3 +42,4 @@ unset(BUILDTESTER CACHE)
 unset(BUILDAPIEMULTESTER CACHE)
 unset(BUILD_TEST_LIB CACHE)
 unset(BUILD_HOST_HELPER CACHE)
+unset(CREATE_SHARED_LIB CACHE)
index 1ab6509e251ae35cede8b173ee9c88662b3dfc2a..c3e4d1d606a1e270806cd96ef548546beaf6f3f0 100644 (file)
@@ -29,6 +29,7 @@ TUV_SYSTEMROOT  ?= default
 TUV_BUILDTESTER ?= yes
 TUV_BUILDAPIEMULTESTER ?= no
 TUV_BUILDHOSTHELPER ?= no
+TUV_CREATE_SHARED_LIB ?= no
 
 OUTPUT_ROOT     := build
 BUILD_FOLDER    := ./$(OUTPUT_ROOT)/$(TUV_PLATFORM)/$(TUV_BUILD_TYPE)
@@ -38,7 +39,9 @@ CMAKE_DEFINES   := \
        -DCMAKE_BUILD_TYPE=$(TUV_BUILD_TYPE) \
        -DTARGET_PLATFORM=$(TUV_PLATFORM) \
        -DBUILDTESTER=${TUV_BUILDTESTER} \
-       -DBUILD_HOST_HELPER=${TUV_BUILDHOSTHELPER}
+       -DBUILD_HOST_HELPER=${TUV_BUILDHOSTHELPER} \
+       -DCREATE_SHARED_LIB=${TUV_CREATE_SHARED_LIB} \
+       -DTUV_FEATURE_PROCESS=ON
 
 ifneq ($(TUV_BOARD),unknown)
        CMAKE_DEFINES += -DTARGET_BOARD=${TUV_BOARD}
diff --git a/deps/libtuv/cmake/config/config_i686-windows.cmake b/deps/libtuv/cmake/config/config_i686-windows.cmake
new file mode 100644 (file)
index 0000000..71575e3
--- /dev/null
@@ -0,0 +1,20 @@
+# Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors
+#
+# 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 Windows)
+set(CMAKE_SYSTEM_PROCESSOR i686)
+
+if(NOT DEFINED CMAKE_C_COMPILER)
+  set(CMAKE_C_COMPILER CL.exe)
+endif()
index 211cb01c4085b8027f0daba75ad2885f560645f2..e844672c04fe0eb43e1e9ce8c866cc5b3dadef44 100644 (file)
@@ -27,7 +27,7 @@ set(COMMON_SRCFILES
     ${INCLUDE_ROOT}/uv-errno.h
     ${INCLUDE_ROOT}/uv-threadpool.h
     ${INCLUDE_ROOT}/uv-version.h
-#   ${SOURCE_ROOT}/fs-poll.c
+    ${SOURCE_ROOT}/fs-poll.c
     ${SOURCE_ROOT}/heap-inl.h
     ${SOURCE_ROOT}/inet.c
     ${SOURCE_ROOT}/queue.h
@@ -58,6 +58,18 @@ set_target_properties(${TARGETLIBNAME} PROPERTIES
     LIBRARY_OUTPUT_DIRECTORY "${LIB_OUT}"
     RUNTIME_OUTPUT_DIRECTORY "${BIN_OUT}")
 
+# build tuv shared library
+if (DEFINED CREATE_SHARED_LIB AND CREATE_SHARED_LIB STREQUAL "yes")
+  set(TARGETSHAREDLIBNAME tuv_shared)
+  add_library(${TARGETSHAREDLIBNAME} SHARED ${LIB_TUV_SRCFILES})
+  target_include_directories(${TARGETSHAREDLIBNAME} SYSTEM PRIVATE ${TARGET_INC})
+  target_include_directories(${TARGETSHAREDLIBNAME} PUBLIC ${LIB_TUV_INCDIRS})
+  set_target_properties(${TARGETSHAREDLIBNAME} PROPERTIES
+      LIBRARY_OUTPUT_DIRECTORY "${LIB_OUT}"
+      COMPILE_FLAGS -fPIC
+      OUTPUT_NAME tuv)
+endif()
+
 if(DEFINED COPY_TARGET_LIB)
   add_custom_command(TARGET ${TARGETLIBNAME} POST_BUILD
       COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${TARGETLIBNAME}>
diff --git a/deps/libtuv/cmake/option/option_i686-windows.cmake b/deps/libtuv/cmake/option/option_i686-windows.cmake
new file mode 100644 (file)
index 0000000..7eb0117
--- /dev/null
@@ -0,0 +1,19 @@
+# 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.
+
+# linux common
+include("cmake/option/option_windows_common.cmake")
+
+# i686 specific
+
index 60c0514dba5ee12629f6b20679d189f78b556a71..6c295bd927a9d650f8e6dffdaad1b5bc80ad0778 100644 (file)
@@ -47,11 +47,9 @@ set(PLATFORM_SRCFILES
       ${UNIX_PATH}/internal.h
       ${UNIX_PATH}/loop.c
       ${UNIX_PATH}/loop-watcher.c
-#     ${UNIX_PATH}/pipe.c
       ${UNIX_PATH}/poll.c
       ${UNIX_PATH}/process.c
 #     ${UNIX_PATH}/proctitle.c
-#     ${UNIX_PATH}/signal.c
       ${UNIX_PATH}/spinlock.h
       ${UNIX_PATH}/stream.c
       ${UNIX_PATH}/tcp.c
@@ -79,7 +77,48 @@ set(TEST_UNITFILES
       "${TEST_ROOT}/test_active.c"
       "${TEST_ROOT}/test_walk_handles.c"
       "${TEST_ROOT}/test_async.c"
-      )
+    )
+
+# { TUV_CHANGES@20180803:
+#   Made signal build time configurable }
+if(TUV_FEATURE_PROCESS)
+      set(TUV_FEATURE_PIPE ON)
+      set(TUV_FEATURE_SIGNAL ON)
+      set(FLAGS_COMMON "${FLAGS_COMMON}" "-DTUV_FEATURE_PROCESS=1")
+      set(TEST_UNITFILES "${TEST_UNITFILES}"
+            "${TEST_ROOT}/test_ipc.c"
+            "${TEST_ROOT}/test_spawn.c")
+endif()
+
+
+# { TUV_CHANGES@20180724:
+#   Made pipe build time configurable }
+if(TUV_FEATURE_PIPE)
+      set(PLATFORM_SRCFILES "${PLATFORM_SRCFILES}"
+            ${UNIX_PATH}/pipe.c)
+      set(FLAGS_COMMON "${FLAGS_COMMON}" "-DTUV_FEATURE_PIPE=1")
+      set(TEST_UNITFILES "${TEST_UNITFILES}"
+            "${TEST_ROOT}/test_pipe_bind_error.c"
+            "${TEST_ROOT}/test_pipe_close_stdout_read_stdin.c"
+            "${TEST_ROOT}/test_pipe_connect_error.c"
+            "${TEST_ROOT}/test_pipe_connect_multiple.c"
+            "${TEST_ROOT}/test_pipe_connect_prepare.c"
+            "${TEST_ROOT}/test_pipe_getsockname.c"
+            "${TEST_ROOT}/test_pipe_pending_instances.c"
+            "${TEST_ROOT}/test_pipe_sendmsg.c"
+            "${TEST_ROOT}/test_pipe_server_close.c"
+            "${TEST_ROOT}/test_pipe_set_non_blocking.c"
+           )
+endif()
+
+# { TUV_CHANGES@20180723:
+#   Made signal build time configurable }
+if(TUV_FEATURE_SIGNAL)
+      set(PLATFORM_SRCFILES "${PLATFORM_SRCFILES}"
+            ${UNIX_PATH}/signal.c)
+      set(FLAGS_COMMON "${FLAGS_COMMON}" "-DTUV_FEATURE_SIGNAL=1")
+      set(TEST_UNITFILES "${TEST_UNITFILES}" "${TEST_ROOT}/test_signal.c")
+endif()
 
 # configuration values
 set(CONFIG_FILESYSTEM 1)
diff --git a/deps/libtuv/cmake/option/option_windows_common.cmake b/deps/libtuv/cmake/option/option_windows_common.cmake
new file mode 100644 (file)
index 0000000..d2f7060
--- /dev/null
@@ -0,0 +1,88 @@
+# Copyright 2015-2017 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.
+
+
+#set(CMAKE_C_FLAGS_DEBUG     "-O0 -g -DDEBUG")
+#set(CMAKE_C_FLAGS_RELEASE   "-O2 -DNDEBUG")
+
+# unix common source files
+set(WIN_PATH "${SOURCE_ROOT}/win")
+
+# test include
+set(TUV_TEST_INCDIRS "${TEST_ROOT}")
+
+#
+# { TUV_CHANGES@20161129:
+#   It corresponds to uv.gyp's section "Windows" }
+#
+set(PLATFORM_SRCFILES
+      ${INCLUDE_ROOT}/uv-win.h
+      ${WIN_PATH}/async.c
+      ${WIN_PATH}/atomicops-inl.h
+      ${WIN_PATH}/core.c
+      ${WIN_PATH}/detect-wakeup.c
+      ${WIN_PATH}/dl.c
+      ${WIN_PATH}/error.c
+      ${WIN_PATH}/fs.c
+      ${WIN_PATH}/fs-event.c
+      ${WIN_PATH}/getaddrinfo.c
+      ${WIN_PATH}/getnameinfo.c
+      ${WIN_PATH}/handle.c
+      ${WIN_PATH}/handle-inl.h
+      ${WIN_PATH}/internal.h
+      ${WIN_PATH}/loop-watcher.c
+      ${WIN_PATH}/pipe.c
+      ${WIN_PATH}/thread.c
+      ${WIN_PATH}/poll.c
+      ${WIN_PATH}/process.c
+      ${WIN_PATH}/process-stdio.c
+      ${WIN_PATH}/req.c
+      ${WIN_PATH}/req-inl.h
+      ${WIN_PATH}/signal.c
+      ${WIN_PATH}/snprintf.c
+      ${WIN_PATH}/stream.c
+      ${WIN_PATH}/stream-inl.h
+      ${WIN_PATH}/tcp.c
+      ${WIN_PATH}/tty.c
+      ${WIN_PATH}/timer.c
+      ${WIN_PATH}/udp.c
+      ${WIN_PATH}/util.c
+      ${WIN_PATH}/winapi.c
+      ${WIN_PATH}/winapi.h
+      ${WIN_PATH}/winsock.c
+      ${WIN_PATH}/winsock.h
+    )
+
+set(TEST_MAINFILE "${TEST_ROOT}/runner_main.c")
+
+set(TEST_UNITFILES
+      ${TEST_ROOT}/test_idle.c
+      ${TEST_ROOT}/test_timer.c
+      ${TEST_ROOT}/test_timer_again.c
+      ${TEST_ROOT}/test_fs.c
+      ${TEST_ROOT}/test_cwd.c
+      ${TEST_ROOT}/test_error.c
+      ${TEST_ROOT}/test_tcp_open.c
+      ${TEST_ROOT}/test_shutdown_eof.c
+      ${TEST_ROOT}/echo_server.c
+      ${TEST_ROOT}/test_getaddrinfo.c
+      ${TEST_ROOT}/test_threadpool.c
+      ${TEST_ROOT}/test_condvar.c
+      ${TEST_ROOT}/test_active.c
+      ${TEST_ROOT}/test_walk_handles.c
+      ${TEST_ROOT}/test_async.c
+      )
+
+# configuration values
+set(CONFIG_FILESYSTEM 1)
index d97a893a4c182944ca500b75a5cb5139ee2beb95..7dac257b85da72a0dde4cb08cc44c8762c860254 100644 (file)
 #define SIGPROF       27
 #define TCP_NODELAY   1
 
-//-----------------------------------------------------------------------------
-// TUV_CHANGES@20171130:
-// Not used. I believe we can remove those.
-#define _SC_CLK_TCK           0x0006
-#define _SC_NPROCESSORS_ONLN  0x0061
-#define CLOCK_MONOTONIC       1
+#ifndef _SC_CLK_TCK
+#define _SC_CLK_TCK 0x0006
+#endif
+
+#ifndef CLOCK_MONOTONIC
+#define CLOCK_MONOTONIC 1
+#endif
 
 //-----------------------------------------------------------------------------
 // date time extension
index 0d00d7506276b36f3e81290c79bcacf1a56e2e5a..03209bbdb3a463b4c4b03c787e2fb395ffc40302 100644 (file)
@@ -81,7 +81,10 @@ extern "C" {
 
 /* Expand this list if necessary. */
 #define UV_ERRNO_MAP(XX)                                                      \
+  XX(E2BIG, "argument list too long")                                         \
+  XX(EACCES, "permission denied")                                             \
   XX(EADDRINUSE, "address already in use")                                    \
+  XX(EADDRNOTAVAIL, "address not available")                                  \
   XX(EAFNOSUPPORT, "address family not supported")                            \
   XX(EAGAIN, "resource temporarily unavailable")                              \
   XX(EAI_ADDRFAMILY, "address family not supported")                          \
@@ -99,21 +102,44 @@ extern "C" {
   XX(EAI_SERVICE, "service not available for socket type")                    \
   XX(EAI_SOCKTYPE, "socket type not supported")                               \
   XX(EALREADY, "connection already in progress")                              \
+  XX(EBADF, "bad file descriptor")                                            \
   XX(EBUSY, "resource busy or locked")                                        \
   XX(ECANCELED, "operation canceled")                                         \
+  XX(ECHARSET, "invalid Unicode character")                                   \
+  XX(ECONNABORTED, "software caused connection abort")                        \
   XX(ECONNREFUSED, "connection refused")                                      \
+  XX(ECONNRESET, "connection reset by peer")                                  \
+  XX(EEXIST, "file already exists")                                           \
+  XX(EFAULT, "bad address in system call argument")                           \
+  XX(EHOSTUNREACH, "host is unreachable")                                     \
   XX(EINVAL, "invalid argument")                                              \
   XX(EIO, "i/o error")                                                        \
+  XX(EISCONN, "socket is already connected")                                  \
+  XX(EISDIR, "illegal operation on a directory")                              \
   XX(ELOOP, "too many symbolic links encountered")                            \
+  XX(EMFILE, "too many open files")                                           \
+  XX(EMSGSIZE, "message too long")                                            \
   XX(ENAMETOOLONG, "name too long")                                           \
+  XX(ENETUNREACH, "network is unreachable")                                   \
   XX(ENOBUFS, "no buffer space available")                                    \
   XX(ENOENT, "no such file or directory")                                     \
   XX(ENOMEM, "not enough memory")                                             \
   XX(ENOSPC, "no space left on device")                                       \
+  XX(ENOSYS, "function not implemented")                                      \
+  XX(ENOTCONN, "socket is not connected")                                     \
   XX(ENOTDIR, "not a directory")                                              \
+  XX(ENOTEMPTY, "directory not empty")                                        \
+  XX(ENOTSOCK, "socket operation on non-socket")                              \
+  XX(ENOTSUP, "operation not supported on socket")                            \
   XX(EPERM, "operation not permitted")                                        \
+  XX(EPIPE, "broken pipe")                                                    \
+  XX(ESRCH, "no such process")                                                \
+  XX(EPROTONOSUPPORT, "protocol not supported")                               \
+  XX(EROFS, "read-only file system")                                          \
   XX(ETIMEDOUT, "connection timed out")                                       \
+  XX(EXDEV, "cross-device link not permitted")                                \
   XX(EOF, "end of file")                                                      \
+  XX(UNKNOWN, "unknown error")                                                \
 
 #define UV_HANDLE_TYPE_MAP(XX)                                                \
   XX(ASYNC, async)                                                            \
index ee62b117728065ef1d14af9d0ee2d7efed9cfc29..4cceb9b1803c815abc34cd5737fbd6e74f3334ce 100644 (file)
@@ -115,6 +115,12 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
   handle->close_cb = close_cb;
 
   switch (handle->type) {
+#ifdef TUV_FEATURE_PIPE
+  case UV_NAMED_PIPE:
+    uv__pipe_close((uv_pipe_t*)handle);
+    break;
+#endif
+
   case UV_TTY:
     uv__stream_close((uv_stream_t*)handle);
     break;
@@ -139,10 +145,26 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
     uv__timer_close((uv_timer_t*)handle);
     break;
 
+// { TUV_CHANGES@20180803:
+//   Made signal build time configurable }
+#if TUV_FEATURE_PROCESS
+  case UV_PROCESS:
+    uv__process_close((uv_process_t*)handle);
+    break;
+#endif
+
   case UV_POLL:
     uv__poll_close((uv_poll_t*)handle);
     break;
 
+#ifdef TUV_FEATURE_SIGNAL
+  case UV_SIGNAL:
+    uv__signal_close((uv_signal_t*) handle);
+    /* Signal handles may not be closed immediately. The signal code will */
+    /* itself close uv__make_close_pending whenever appropriate. */
+    return;
+#endif
+
   default:
     assert(0);
   }
@@ -195,11 +217,11 @@ static void uv__finish_close(uv_handle_t* handle) {
     case UV_IDLE:
     case UV_ASYNC:
     case UV_TIMER:
-    // case UV_PROCESS:
+    case UV_PROCESS:
     // case UV_FS_EVENT:
     // case UV_FS_POLL:
     case UV_POLL:
-    // case UV_SIGNAL:
+    case UV_SIGNAL:
       break;
 
     case UV_NAMED_PIPE:
index a9b1531a3886b99bed5b0dad6e1dce884d0ccc6a..5971915b29ac2b702ede3655fdb7cc1396252ef0 100644 (file)
@@ -407,7 +407,7 @@ static ssize_t uv__fs_scandir(uv_fs_t* req) {
       cnt++;
   }
 
-  /* Allcoate memory for the directory entries. */
+  /* Allocate memory for the directory entries. */
   dents = (uv__dirent_t**) malloc(sizeof (uv__dirent_t*) * cnt);
 
   if (cnt > 0 && dents == NULL) {
index f996e2f49738c4ea478f55ab49664d75237adb9a..aa30b595793a6a87acc6ef798030e3e8998bbf07 100644 (file)
@@ -114,7 +114,7 @@ static void uv__getaddrinfo_work(struct uv__work* w) {
   int err;
 
   req = container_of(w, uv_getaddrinfo_t, work_req);
-#if defined(__NUTTX__) || defined(__TIZENRT__)
+#if defined(__NUTTX__)
   err = 0;
 #else
   /* Only IPv4 is supported now. (Not support IPv6.)*/
@@ -220,7 +220,7 @@ int uv_getaddrinfo(uv_loop_t* loop,
 
 
 void uv_freeaddrinfo(struct addrinfo* ai) {
-#if !defined(__NUTTX__) && !defined(__TIZENRT__)
+#if !defined(__NUTTX__)
   if (ai)
     freeaddrinfo(ai);
 #endif
index 4141497c965aea61c54822dcbc1ec7db9ecdfb86..a9b137bfd093b5528d6ecb62fe0ae9ac4a1b281e 100644 (file)
@@ -459,3 +459,26 @@ uint64_t uv__hrtime(uv_clocktype_t type) {
 
   return t.tv_sec * (uint64_t) 1e9 + t.tv_nsec;
 }
+
+// { TUV_CHANGES@20180803:
+//   Made signal build time configurable }
+#if TUV_FEATURE_PROCESS
+int uv_exepath(char* buffer, size_t* size) {
+  ssize_t n;
+
+  if (buffer == NULL || size == NULL || *size == 0)
+    return -EINVAL;
+
+  n = *size - 1;
+  if (n > 0)
+    n = readlink("/proc/self/exe", buffer, n);
+
+  if (n == -1)
+    return -errno;
+
+  buffer[n] = '\0';
+  *size = n;
+
+  return 0;
+}
+#endif /* TUV_FEATURE_PROCESS */
index 39bce4f5ed1a4d71605e66c16db071e08ae066e2..16b3b0f73c07c63ed1a1011c394485201d84a894 100644 (file)
@@ -46,6 +46,10 @@ int uv_loop_init(uv_loop_t* loop) {
   void* saved_data;
   int err;
 
+#ifdef TUV_FEATURE_SIGNAL
+  uv__signal_global_once_init();
+#endif
+
   saved_data = loop->data;
   memset(loop, 0, sizeof(*loop));
   loop->data = saved_data;
@@ -68,6 +72,10 @@ int uv_loop_init(uv_loop_t* loop) {
   loop->closing_handles = NULL;
   uv__update_time(loop);
   uv__async_init(&loop->async_watcher);
+#ifdef TUV_FEATURE_SIGNAL
+  loop->signal_pipefd[0] = -1;
+  loop->signal_pipefd[1] = -1;
+#endif
   loop->backend_fd = -1;
   loop->emfile_fd = -1;
 
@@ -78,6 +86,12 @@ int uv_loop_init(uv_loop_t* loop) {
   if (err)
     return err;
 
+#ifdef TUV_FEATURE_SIGNAL
+  err = uv_signal_init(loop, &loop->child_watcher);
+  if (err)
+    goto fail_signal_init;
+#endif
+
   uv__handle_unref(&loop->child_watcher);
   loop->child_watcher.flags |= UV__HANDLE_INTERNAL;
   QUEUE_INIT(&loop->process_handles);
@@ -106,6 +120,11 @@ fail_mutex_init:
   uv_rwlock_destroy(&loop->cloexec_lock);
 
 fail_rwlock_init:
+#ifdef TUV_FEATURE_SIGNAL
+  uv__signal_loop_cleanup(loop);
+#endif
+
+fail_signal_init:
   uv__platform_loop_delete(loop);
 
   return err;
@@ -113,6 +132,9 @@ fail_rwlock_init:
 
 
 void uv__loop_close(uv_loop_t* loop) {
+#ifdef TUV_FEATURE_SIGNAL
+  uv__signal_loop_cleanup(loop);
+#endif
   uv__platform_loop_delete(loop);
   uv__async_stop(loop, &loop->async_watcher);
 
index a5280544fc993f9d73d3f3856fbd23b50c662fd8..ba06d85563ed6f4595129912e1b3dd51a5526879 100644 (file)
 #include <fcntl.h>
 #include <poll.h>
 
+#if !defined(__NUTTX__) && !defined(__TIZENRT__)
+
 #if defined(__APPLE__) && !TARGET_OS_IPHONE
 # include <crt_externs.h>
+# define environ (*_NSGetEnviron())
+#else
+extern char **environ;
 #endif
 
 #if defined(__linux__) || defined(__GLIBC__)
 # include <grp.h>
 #endif
 
+// { TUV_CHANGES@20180803:
+//   Made signal build time configurable }
+#if TUV_FEATURE_PROCESS
+static void uv__chld(uv_signal_t* handle, int signum) {
+  uv_process_t* process;
+  uv_loop_t* loop;
+  int exit_status;
+  int term_signal;
+  int status;
+  pid_t pid;
+  QUEUE pending;
+  QUEUE* q;
+  QUEUE* h;
+
+  assert(signum == SIGCHLD);
+
+  QUEUE_INIT(&pending);
+  loop = handle->loop;
+
+  h = &loop->process_handles;
+  q = QUEUE_HEAD(h);
+  while (q != h) {
+    process = QUEUE_DATA(q, uv_process_t, queue);
+    q = QUEUE_NEXT(q);
+
+    do
+      pid = waitpid(process->pid, &status, WNOHANG);
+    while (pid == -1 && errno == EINTR);
+
+    if (pid == 0)
+      continue;
+
+    if (pid == -1) {
+      if (errno != ECHILD)
+        abort();
+      continue;
+    }
+
+    process->status = status;
+    QUEUE_REMOVE(&process->queue);
+    QUEUE_INSERT_TAIL(&pending, &process->queue);
+  }
+
+  h = &pending;
+  q = QUEUE_HEAD(h);
+  while (q != h) {
+    process = QUEUE_DATA(q, uv_process_t, queue);
+    q = QUEUE_NEXT(q);
+
+    QUEUE_REMOVE(&process->queue);
+    QUEUE_INIT(&process->queue);
+    uv__handle_stop(process);
+
+    if (process->exit_cb == NULL)
+      continue;
+
+    exit_status = 0;
+    if (WIFEXITED(process->status))
+      exit_status = WEXITSTATUS(process->status);
+
+    term_signal = 0;
+    if (WIFSIGNALED(process->status))
+      term_signal = WTERMSIG(process->status);
+
+    process->exit_cb(process, exit_status, term_signal);
+  }
+  assert(QUEUE_EMPTY(&pending));
+}
+
+
+int uv__make_socketpair(int fds[2], int flags) {
+#if defined(__linux__)
+  static int no_cloexec;
+
+  if (no_cloexec)
+    goto skip;
+
+  if (socketpair(AF_UNIX, SOCK_STREAM | UV__SOCK_CLOEXEC | flags, 0, fds) == 0)
+    return 0;
+
+  /* Retry on EINVAL, it means SOCK_CLOEXEC is not supported.
+   * Anything else is a genuine error.
+   */
+  if (errno != EINVAL)
+    return -errno;
+
+  no_cloexec = 1;
+
+skip:
+#endif
+
+  if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
+    return -errno;
+
+  uv__cloexec(fds[0], 1);
+  uv__cloexec(fds[1], 1);
+
+  if (flags & UV__F_NONBLOCK) {
+    uv__nonblock(fds[0], 1);
+    uv__nonblock(fds[1], 1);
+  }
+
+  return 0;
+}
+#endif /* TUV_FEATURE_PROCESS */
 
 int uv__make_pipe(int fds[2], int flags) {
 #if defined(__linux__)
@@ -88,3 +198,409 @@ skip:
 
   return 0;
 }
+
+
+// { TUV_CHANGES@20180803:
+//   Made signal build time configurable }
+#if TUV_FEATURE_PROCESS
+/*
+ * Used for initializing stdio streams like options.stdin_stream. Returns
+ * zero on success. See also the cleanup section in uv_spawn().
+ */
+static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
+  int mask;
+  int fd;
+
+  mask = UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | UV_INHERIT_STREAM;
+
+  switch (container->flags & mask) {
+  case UV_IGNORE:
+    return 0;
+
+  case UV_CREATE_PIPE:
+    assert(container->data.stream != NULL);
+    if (container->data.stream->type != UV_NAMED_PIPE)
+      return -EINVAL;
+    else
+      return uv__make_socketpair(fds, 0);
+
+  case UV_INHERIT_FD:
+  case UV_INHERIT_STREAM:
+    if (container->flags & UV_INHERIT_FD)
+      fd = container->data.fd;
+    else
+      fd = uv__stream_fd(container->data.stream);
+
+    if (fd == -1)
+      return -EINVAL;
+
+    fds[1] = fd;
+    return 0;
+
+  default:
+    assert(0 && "Unexpected flags");
+    return -EINVAL;
+  }
+}
+
+
+static int uv__process_open_stream(uv_stdio_container_t* container,
+                                   int pipefds[2],
+                                   int writable) {
+  int flags;
+  int err;
+
+  if (!(container->flags & UV_CREATE_PIPE) || pipefds[0] < 0)
+    return 0;
+
+  err = uv__close(pipefds[1]);
+  if (err != 0)
+    abort();
+
+  pipefds[1] = -1;
+  uv__nonblock(pipefds[0], 1);
+
+  if (container->data.stream->type == UV_NAMED_PIPE &&
+      ((uv_pipe_t*)container->data.stream)->ipc)
+    flags = UV_STREAM_READABLE | UV_STREAM_WRITABLE;
+  else if (writable)
+    flags = UV_STREAM_WRITABLE;
+  else
+    flags = UV_STREAM_READABLE;
+
+  return uv__stream_open(container->data.stream, pipefds[0], flags);
+}
+
+
+static void uv__process_close_stream(uv_stdio_container_t* container) {
+  if (!(container->flags & UV_CREATE_PIPE)) return;
+  uv__stream_close((uv_stream_t*)container->data.stream);
+}
+
+
+static void uv__write_int(int fd, int val) {
+  ssize_t n;
+
+  do
+    n = write(fd, &val, sizeof(val));
+  while (n == -1 && errno == EINTR);
+
+  if (n == -1 && errno == EPIPE)
+    return; /* parent process has quit */
+
+  assert(n == sizeof(val));
+}
+
+
+#if !(defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH))
+/* execvp is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED, so must be
+ * avoided. Since this isn't called on those targets, the function
+ * doesn't even need to be defined for them.
+ */
+static void uv__process_child_init(const uv_process_options_t* options,
+                                   int stdio_count,
+                                   int (*pipes)[2],
+                                   int error_fd) {
+  int close_fd;
+  int use_fd;
+  int fd;
+
+  if (options->flags & UV_PROCESS_DETACHED)
+    setsid();
+
+  /* First duplicate low numbered fds, since it's not safe to duplicate them,
+   * they could get replaced. Example: swapping stdout and stderr; without
+   * this fd 2 (stderr) would be duplicated into fd 1, thus making both
+   * stdout and stderr go to the same fd, which was not the intention. */
+  for (fd = 0; fd < stdio_count; fd++) {
+    use_fd = pipes[fd][1];
+    if (use_fd < 0 || use_fd >= fd)
+      continue;
+    pipes[fd][1] = fcntl(use_fd, F_DUPFD, stdio_count);
+    if (pipes[fd][1] == -1) {
+      uv__write_int(error_fd, -errno);
+      _exit(127);
+    }
+  }
+
+  for (fd = 0; fd < stdio_count; fd++) {
+    close_fd = pipes[fd][0];
+    use_fd = pipes[fd][1];
+
+    if (use_fd < 0) {
+      if (fd >= 3)
+        continue;
+      else {
+        /* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is
+         * set
+         */
+        use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR);
+        close_fd = use_fd;
+
+        if (use_fd == -1) {
+          uv__write_int(error_fd, -errno);
+          _exit(127);
+        }
+      }
+    }
+
+    if (fd == use_fd)
+      uv__cloexec(use_fd, 0);
+    else
+      fd = dup2(use_fd, fd);
+
+    if (fd == -1) {
+      uv__write_int(error_fd, -errno);
+      _exit(127);
+    }
+
+    if (fd <= 2)
+      uv__nonblock(fd, 0);
+
+    if (close_fd >= stdio_count)
+      uv__close(close_fd);
+  }
+
+  for (fd = 0; fd < stdio_count; fd++) {
+    use_fd = pipes[fd][1];
+
+    if (use_fd >= stdio_count)
+      uv__close(use_fd);
+  }
+
+  if (options->cwd != NULL && chdir(options->cwd)) {
+    uv__write_int(error_fd, -errno);
+    _exit(127);
+  }
+
+  if (options->flags & (UV_PROCESS_SETUID | UV_PROCESS_SETGID)) {
+    /* When dropping privileges from root, the `setgroups` call will
+     * remove any extraneous groups. If we don't call this, then
+     * even though our uid has dropped, we may still have groups
+     * that enable us to do super-user things. This will fail if we
+     * aren't root, so don't bother checking the return value, this
+     * is just done as an optimistic privilege dropping function.
+     */
+    SAVE_ERRNO(setgroups(0, NULL));
+  }
+
+  if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) {
+    uv__write_int(error_fd, -errno);
+    _exit(127);
+  }
+
+  if ((options->flags & UV_PROCESS_SETUID) && setuid(options->uid)) {
+    uv__write_int(error_fd, -errno);
+    _exit(127);
+  }
+
+  if (options->env != NULL) {
+    environ = options->env;
+  }
+
+  execvp(options->file, options->args);
+  uv__write_int(error_fd, -errno);
+  _exit(127);
+}
+#endif
+
+
+int uv_spawn(uv_loop_t* loop,
+             uv_process_t* process,
+             const uv_process_options_t* options) {
+#if defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)
+  /* fork is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED. */
+  return -ENOSYS;
+#else
+  int signal_pipe[2] = { -1, -1 };
+  int (*pipes)[2];
+  int stdio_count;
+  ssize_t r;
+  pid_t pid;
+  int err;
+  int exec_errorno;
+  int i;
+  int status;
+
+  assert(options->file != NULL);
+  assert(!(options->flags & ~(UV_PROCESS_DETACHED |
+                              UV_PROCESS_SETGID |
+                              UV_PROCESS_SETUID |
+                              UV_PROCESS_WINDOWS_HIDE |
+                              UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
+
+  uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
+  QUEUE_INIT(&process->queue);
+
+  stdio_count = options->stdio_count;
+  if (stdio_count < 3)
+    stdio_count = 3;
+
+  err = -ENOMEM;
+  pipes = uv__malloc(stdio_count * sizeof(*pipes));
+  if (pipes == NULL)
+    goto error;
+
+  for (i = 0; i < stdio_count; i++) {
+    pipes[i][0] = -1;
+    pipes[i][1] = -1;
+  }
+
+  for (i = 0; i < options->stdio_count; i++) {
+    err = uv__process_init_stdio(options->stdio + i, pipes[i]);
+    if (err)
+      goto error;
+  }
+
+  /* This pipe is used by the parent to wait until
+   * the child has called `execve()`. We need this
+   * to avoid the following race condition:
+   *
+   *    if ((pid = fork()) > 0) {
+   *      kill(pid, SIGTERM);
+   *    }
+   *    else if (pid == 0) {
+   *      execve("/bin/cat", argp, envp);
+   *    }
+   *
+   * The parent sends a signal immediately after forking.
+   * Since the child may not have called `execve()` yet,
+   * there is no telling what process receives the signal,
+   * our fork or /bin/cat.
+   *
+   * To avoid ambiguity, we create a pipe with both ends
+   * marked close-on-exec. Then, after the call to `fork()`,
+   * the parent polls the read end until it EOFs or errors with EPIPE.
+   */
+  err = uv__make_pipe(signal_pipe, 0);
+  if (err)
+    goto error;
+
+  uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD);
+
+  /* Acquire write lock to prevent opening new fds in worker threads */
+  uv_rwlock_wrlock(&loop->cloexec_lock);
+  pid = fork();
+
+  if (pid == -1) {
+    err = -errno;
+    uv_rwlock_wrunlock(&loop->cloexec_lock);
+    uv__close(signal_pipe[0]);
+    uv__close(signal_pipe[1]);
+    goto error;
+  }
+
+  if (pid == 0) {
+    uv__process_child_init(options, stdio_count, pipes, signal_pipe[1]);
+    abort();
+  }
+
+  /* Release lock in parent process */
+  uv_rwlock_wrunlock(&loop->cloexec_lock);
+  uv__close(signal_pipe[1]);
+
+  process->status = 0;
+  exec_errorno = 0;
+  do
+    r = read(signal_pipe[0], &exec_errorno, sizeof(exec_errorno));
+  while (r == -1 && errno == EINTR);
+
+  if (r == 0)
+    ; /* okay, EOF */
+  else if (r == sizeof(exec_errorno)) {
+    do
+      err = waitpid(pid, &status, 0); /* okay, read errorno */
+    while (err == -1 && errno == EINTR);
+    assert(err == pid);
+  } else if (r == -1 && errno == EPIPE) {
+    do
+      err = waitpid(pid, &status, 0); /* okay, got EPIPE */
+    while (err == -1 && errno == EINTR);
+    assert(err == pid);
+  } else
+    abort();
+
+  uv__close_nocheckstdio(signal_pipe[0]);
+
+  for (i = 0; i < options->stdio_count; i++) {
+    err = uv__process_open_stream(options->stdio + i, pipes[i], i == 0);
+    if (err == 0)
+      continue;
+
+    while (i--)
+      uv__process_close_stream(options->stdio + i);
+
+    goto error;
+  }
+
+  /* Only activate this handle if exec() happened successfully */
+  if (exec_errorno == 0) {
+    QUEUE_INSERT_TAIL(&loop->process_handles, &process->queue);
+    uv__handle_start(process);
+  }
+
+  process->pid = pid;
+  process->exit_cb = options->exit_cb;
+
+  uv__free(pipes);
+  return exec_errorno;
+
+error:
+  if (pipes != NULL) {
+    for (i = 0; i < stdio_count; i++) {
+      if (i < options->stdio_count)
+        if (options->stdio[i].flags & (UV_INHERIT_FD | UV_INHERIT_STREAM))
+          continue;
+      if (pipes[i][0] != -1)
+        uv__close_nocheckstdio(pipes[i][0]);
+      if (pipes[i][1] != -1)
+        uv__close_nocheckstdio(pipes[i][1]);
+    }
+    uv__free(pipes);
+  }
+
+  return err;
+#endif
+}
+
+
+int uv_process_kill(uv_process_t* process, int signum) {
+  return uv_kill(process->pid, signum);
+}
+
+
+int uv_kill(int pid, int signum) {
+  if (kill(pid, signum))
+    return -errno;
+  else
+    return 0;
+}
+
+
+void uv__process_close(uv_process_t* handle) {
+  QUEUE_REMOVE(&handle->queue);
+  uv__handle_stop(handle);
+  if (QUEUE_EMPTY(&handle->loop->process_handles))
+    uv_signal_stop(&handle->loop->child_watcher);
+}
+
+#endif /* TUV_FEATURE_PROCESS */
+
+#else /* defined(__NUTTX__) || defined(__TIZENRT__) */
+
+int uv__make_pipe(int fds[2], int flags) {
+  if (pipe(fds))
+    return -errno;
+
+  uv__cloexec(fds[0], 1);
+  uv__cloexec(fds[1], 1);
+
+  if (flags & UV__F_NONBLOCK) {
+    uv__nonblock(fds[0], 1);
+    uv__nonblock(fds[1], 1);
+  }
+
+  return 0;
+}
+
+#endif /* !defined(__NUTTX__) && !defined(__TIZENRT__) */
index ece51757ab3361fe8336b7bc1eba41a74e052973..f09abaed7270bc53e0b91d81c6c6077beed488da 100644 (file)
@@ -598,7 +598,9 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
     return -EAGAIN;
 
   switch (client->type) {
+#ifdef TUV_FEATURE_PIPE
     case UV_NAMED_PIPE:
+#endif
     case UV_TCP:
       err = uv__stream_open(client,
                             server->accepted_fd,
@@ -662,6 +664,12 @@ int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
     err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb);
     break;
 
+#ifdef TUV_FEATURE_PIPE
+  case UV_NAMED_PIPE:
+    err = uv_pipe_listen((uv_pipe_t*)stream, backlog, cb);
+    break;
+#endif
+
   default:
     err = -EINVAL;
   }
@@ -1673,3 +1681,12 @@ void uv__stream_close(uv_stream_t* handle) {
   assert(!uv__io_active(&handle->io_watcher, POLLIN | POLLOUT));
 }
 
+
+#ifdef TUV_FEATURE_PIPE
+int uv_stream_set_blocking(uv_stream_t* handle, int blocking) {
+  /* Don't need to check the file descriptor, uv__nonblock()
+   * will fail with EBADF if it's not valid.
+   */
+  return uv__nonblock(uv__stream_fd(handle), !blocking);
+}
+#endif
index 31c8cbbff2c858a56ecb4c2efc2eeb2d9dfcb8eb..3cc11be809bbbda8f4145312903fc82ff6010d0f 100644 (file)
@@ -592,3 +592,24 @@ int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
   abort();
   return -EINVAL;  /* Satisfy the compiler. */
 }
+
+
+#ifdef TUV_FEATURE_PIPE
+int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
+  return -pthread_barrier_init(barrier, NULL, count);
+}
+
+
+void uv_barrier_destroy(uv_barrier_t* barrier) {
+  if (pthread_barrier_destroy(barrier))
+    abort();
+}
+
+
+int uv_barrier_wait(uv_barrier_t* barrier) {
+  int r = pthread_barrier_wait(barrier);
+  if (r && r != PTHREAD_BARRIER_SERIAL_THREAD)
+    abort();
+  return r == PTHREAD_BARRIER_SERIAL_THREAD;
+}
+#endif
index 62d77eff154953f06561b199a2e44f452ea9900f..8d10afcda9502e9f854c58dff36bff10b83c1c5f 100644 (file)
@@ -437,6 +437,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
     addrlen = sizeof *addr;
     break;
   }
+#if !defined(__TIZENRT__) || defined(CONFIG_NET_IPv6)
   case AF_INET6:
   {
     struct sockaddr_in6* addr = (void*)&taddr;
@@ -446,6 +447,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
     addrlen = sizeof *addr;
     break;
   }
+#endif
   default:
     assert(0 && "unsupported address family");
     abort();
index 1bed201704b539ecff795a9258f4b05251c27fbe..5c12d82b215aab676bc8f683189dd57e52d7cb81 100644 (file)
 #include <stdio.h>
 #include <stdlib.h> /* malloc */
 #include <string.h> /* memset */
-#include <unistd.h> /* usleep */
 
 #if defined(_WIN32)
 # include <malloc.h> /* malloc */
 #else
+# include <unistd.h> /* usleep */
 # include <net/if.h> /* if_nametoindex */
 #endif
 
@@ -67,7 +67,7 @@ static uv__allocator_t uv__allocator = {
   free,
 };
 
-#if defined(__APPLE__)
+#if defined(__APPLE__) || defined(_WIN32) || defined(TUV_FEATURE_PIPE)
 char* uv__strdup(const char* s) {
   size_t len = strlen(s) + 1;
   char* m = uv__malloc(len);
@@ -330,6 +330,11 @@ void uv_unref(uv_handle_t* handle) {
 }
 
 
+void uv_stop(uv_loop_t* loop) {
+  loop->stop_flag = 1;
+}
+
+
 uint64_t uv_now(const uv_loop_t* loop) {
   return loop->time;
 }
@@ -491,5 +496,9 @@ int uv_loop_close(uv_loop_t* loop) {
 
 /* Pause the calling thread for a number of milliseconds. */
 void uv_sleep(int msec) {
+#ifdef _WIN32
+  Sleep(msec);
+#else
   usleep(msec * 1000);
+#endif
 }
index 069b5af1f29d746912659acc881b2cc8635777cf..e52b5299e8777682ec52c34726c279a68f79900c 100644 (file)
@@ -239,7 +239,7 @@ void uv__fs_scandir_cleanup(uv_fs_t* req);
 
 /* Allocator prototypes */
 void *uv__calloc(size_t count, size_t size);
-#if defined(__APPLE__)
+#if defined(__APPLE__) || defined(_WIN32) || defined(TUV_FEATURE_PIPE)
 char *uv__strdup(const char* s);
 #endif
 void* uv__malloc(size_t size);
diff --git a/deps/libtuv/src/win/async.c b/deps/libtuv/src/win/async.c
new file mode 100644 (file)
index 0000000..424f410
--- /dev/null
@@ -0,0 +1,103 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "atomicops-inl.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+
+void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle) {
+  if (handle->flags & UV__HANDLE_CLOSING &&
+      !handle->async_sent) {
+    assert(!(handle->flags & UV_HANDLE_CLOSED));
+    uv__handle_close(handle);
+  }
+}
+
+
+int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
+  uv_req_t* req;
+
+  uv__handle_init(loop, (uv_handle_t*) handle, UV_ASYNC);
+  handle->async_sent = 0;
+  handle->async_cb = async_cb;
+
+  req = &handle->async_req;
+  uv_req_init(loop, req);
+  req->type = UV_WAKEUP;
+  req->data = handle;
+
+  uv__handle_start(handle);
+
+  return 0;
+}
+
+int tuv_async_deinit(uv_loop_t* loop, uv_async_t* handle) {
+  /* No operation required */
+  return 0;
+}
+
+void uv_async_close(uv_loop_t* loop, uv_async_t* handle) {
+  if (!((uv_async_t*)handle)->async_sent) {
+    uv_want_endgame(loop, (uv_handle_t*) handle);
+  }
+
+  uv__handle_closing(handle);
+}
+
+
+int uv_async_send(uv_async_t* handle) {
+  uv_loop_t* loop = handle->loop;
+
+  if (handle->type != UV_ASYNC) {
+    /* Can't set errno because that's not thread-safe. */
+    return -1;
+  }
+
+  /* The user should make sure never to call uv_async_send to a closing */
+  /* or closed handle. */
+  assert(!(handle->flags & UV__HANDLE_CLOSING));
+
+  if (!uv__atomic_exchange_set(&handle->async_sent)) {
+    POST_COMPLETION_FOR_REQ(loop, &handle->async_req);
+  }
+
+  return 0;
+}
+
+
+void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
+    uv_req_t* req) {
+  assert(handle->type == UV_ASYNC);
+  assert(req->type == UV_WAKEUP);
+
+  handle->async_sent = 0;
+
+  if (handle->flags & UV__HANDLE_CLOSING) {
+    uv_want_endgame(loop, (uv_handle_t*)handle);
+  } else if (handle->async_cb != NULL) {
+    handle->async_cb(handle);
+  }
+}
diff --git a/deps/libtuv/src/win/atomicops-inl.h b/deps/libtuv/src/win/atomicops-inl.h
new file mode 100644 (file)
index 0000000..61e0060
--- /dev/null
@@ -0,0 +1,56 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef UV_WIN_ATOMICOPS_INL_H_
+#define UV_WIN_ATOMICOPS_INL_H_
+
+#include "uv.h"
+
+
+/* Atomic set operation on char */
+#ifdef _MSC_VER /* MSVC */
+
+/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is  slightly less */
+/* efficient than InterlockedExchange, but InterlockedExchange8 does not */
+/* exist, and interlocked operations on larger targets might require the */
+/* target to be aligned. */
+#pragma intrinsic(_InterlockedOr8)
+
+static char __declspec(inline) uv__atomic_exchange_set(char volatile* target) {
+  return _InterlockedOr8(target, 1);
+}
+
+#else /* GCC */
+
+/* Mingw-32 version, hopefully this works for 64-bit gcc as well. */
+static inline char uv__atomic_exchange_set(char volatile* target) {
+  const char one = 1;
+  char old_value;
+  __asm__ __volatile__ ("lock xchgb %0, %1\n\t"
+                        : "=r"(old_value), "=m"(*target)
+                        : "0"(one), "m"(*target)
+                        : "memory");
+  return old_value;
+}
+
+#endif
+
+#endif /* UV_WIN_ATOMICOPS_INL_H_ */
diff --git a/deps/libtuv/src/win/core.c b/deps/libtuv/src/win/core.c
new file mode 100644 (file)
index 0000000..e84186d
--- /dev/null
@@ -0,0 +1,598 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)
+#include <crtdbg.h>
+#endif
+
+#include "uv.h"
+#include "internal.h"
+#include "queue.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+/* uv_once initialization guards */
+static uv_once_t uv_init_guard_ = UV_ONCE_INIT;
+
+
+#if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR))
+/* Our crt debug report handler allows us to temporarily disable asserts
+ * just for the current thread.
+ */
+
+UV_THREAD_LOCAL int uv__crt_assert_enabled = TRUE;
+
+static int uv__crt_dbg_report_handler(int report_type, char *message, int *ret_val) {
+  if (uv__crt_assert_enabled || report_type != _CRT_ASSERT)
+    return FALSE;
+
+  if (ret_val) {
+    /* Set ret_val to 0 to continue with normal execution.
+     * Set ret_val to 1 to trigger a breakpoint.
+    */
+
+    if(IsDebuggerPresent())
+      *ret_val = 1;
+    else
+      *ret_val = 0;
+  }
+
+  /* Don't call _CrtDbgReport. */
+  return TRUE;
+}
+#else
+UV_THREAD_LOCAL int uv__crt_assert_enabled = FALSE;
+#endif
+
+
+#if !defined(__MINGW32__) || __MSVCRT_VERSION__ >= 0x800
+static void uv__crt_invalid_parameter_handler(const wchar_t* expression,
+    const wchar_t* function, const wchar_t * file, unsigned int line,
+    uintptr_t reserved) {
+  /* No-op. */
+}
+#endif
+
+static uv_loop_t** uv__loops;
+static int uv__loops_size;
+static int uv__loops_capacity;
+#define UV__LOOPS_CHUNK_SIZE 8
+static uv_mutex_t uv__loops_lock;
+
+static void uv__loops_init() {
+  uv_mutex_init(&uv__loops_lock);
+  uv__loops = uv__calloc(UV__LOOPS_CHUNK_SIZE, sizeof(uv_loop_t*));
+  if (!uv__loops)
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+  uv__loops_size = 0;
+  uv__loops_capacity = UV__LOOPS_CHUNK_SIZE;
+}
+
+static int uv__loops_add(uv_loop_t* loop) {
+  uv_loop_t** new_loops;
+  int new_capacity, i;
+
+  uv_mutex_lock(&uv__loops_lock);
+
+  if (uv__loops_size == uv__loops_capacity) {
+    new_capacity = uv__loops_capacity + UV__LOOPS_CHUNK_SIZE;
+    new_loops = uv__realloc(uv__loops, sizeof(uv_loop_t*) * new_capacity);
+    if (!new_loops)
+      goto failed_loops_realloc;
+    uv__loops = new_loops;
+    for (i = uv__loops_capacity; i < new_capacity; ++i)
+      uv__loops[i] = NULL;
+    uv__loops_capacity = new_capacity;
+  }
+  uv__loops[uv__loops_size] = loop;
+  ++uv__loops_size;
+
+  uv_mutex_unlock(&uv__loops_lock);
+  return 0;
+
+failed_loops_realloc:
+  uv_mutex_unlock(&uv__loops_lock);
+  return ERROR_OUTOFMEMORY;
+}
+
+static void uv__loops_remove(uv_loop_t* loop) {
+  int loop_index;
+  int smaller_capacity;
+  uv_loop_t** new_loops;
+
+  uv_mutex_lock(&uv__loops_lock);
+
+  for (loop_index = 0; loop_index < uv__loops_size; ++loop_index) {
+    if (uv__loops[loop_index] == loop)
+      break;
+  }
+  /* If loop was not found, ignore */
+  if (loop_index == uv__loops_size)
+    goto loop_removed;
+
+  uv__loops[loop_index] = uv__loops[uv__loops_size - 1];
+  uv__loops[uv__loops_size - 1] = NULL;
+  --uv__loops_size;
+
+  /* If we didn't grow to big skip downsizing */
+  if (uv__loops_capacity < 4 * UV__LOOPS_CHUNK_SIZE)
+    goto loop_removed;
+
+  /* Downsize only if more than half of buffer is free */
+  smaller_capacity = uv__loops_capacity / 2;
+  if (uv__loops_size >= smaller_capacity)
+    goto loop_removed;
+  new_loops = uv__realloc(uv__loops, sizeof(uv_loop_t*) * smaller_capacity);
+  if (!new_loops)
+    goto loop_removed;
+  uv__loops = new_loops;
+  uv__loops_capacity = smaller_capacity;
+
+loop_removed:
+  uv_mutex_unlock(&uv__loops_lock);
+}
+
+void uv__wake_all_loops() {
+  int i;
+  uv_loop_t* loop;
+
+  uv_mutex_lock(&uv__loops_lock);
+  for (i = 0; i < uv__loops_size; ++i) {
+    loop = uv__loops[i];
+    assert(loop);
+    if (loop->iocp != INVALID_HANDLE_VALUE)
+      PostQueuedCompletionStatus(loop->iocp, 0, 0, NULL);
+  }
+  uv_mutex_unlock(&uv__loops_lock);
+}
+
+static void uv_init(void) {
+  /* Tell Windows that we will handle critical errors. */
+  SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
+               SEM_NOOPENFILEERRORBOX);
+
+  /* Tell the CRT to not exit the application when an invalid parameter is
+   * passed. The main issue is that invalid FDs will trigger this behavior.
+   */
+#if !defined(__MINGW32__) || __MSVCRT_VERSION__ >= 0x800
+  _set_invalid_parameter_handler(uv__crt_invalid_parameter_handler);
+#endif
+
+  /* We also need to setup our debug report handler because some CRT
+   * functions (eg _get_osfhandle) raise an assert when called with invalid
+   * FDs even though they return the proper error code in the release build.
+   */
+#if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR))
+  _CrtSetReportHook(uv__crt_dbg_report_handler);
+#endif
+
+  /* Initialize tracking of all uv loops */
+  uv__loops_init();
+
+  /* Fetch winapi function pointers. This must be done first because other
+   * initialization code might need these function pointers to be loaded.
+   */
+  uv_winapi_init();
+
+  /* Initialize winsock */
+  uv_winsock_init();
+
+  /* Initialize FS */
+  uv_fs_init();
+
+  /* Initialize signal stuff */
+  uv_signals_init();
+
+  /* Initialize console */
+  uv_console_init();
+
+  /* Initialize utilities */
+  uv__util_init();
+
+  /* Initialize system wakeup detection */
+  uv__init_detect_system_wakeup();
+}
+
+
+int uv_loop_init(uv_loop_t* loop) {
+  int err;
+
+  /* Initialize libuv itself first */
+  uv__once_init();
+
+  /* Create an I/O completion port */
+  loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
+  if (loop->iocp == NULL)
+    return uv_translate_sys_error(GetLastError());
+
+  /* To prevent uninitialized memory access, loop->time must be initialized
+   * to zero before calling uv_update_time for the first time.
+   */
+  loop->time = 0;
+  uv_update_time(loop);
+
+  QUEUE_INIT(&loop->wq);
+  QUEUE_INIT(&loop->handle_queue);
+  QUEUE_INIT(&loop->active_reqs);
+  loop->active_handles = 0;
+
+  loop->pending_reqs_tail = NULL;
+
+  loop->endgame_handles = NULL;
+
+  RB_INIT(&loop->timers);
+
+  loop->check_handles = NULL;
+  loop->prepare_handles = NULL;
+  loop->idle_handles = NULL;
+
+  loop->next_prepare_handle = NULL;
+  loop->next_check_handle = NULL;
+  loop->next_idle_handle = NULL;
+
+  memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets);
+
+  loop->active_tcp_streams = 0;
+  loop->active_udp_streams = 0;
+
+  loop->timer_counter = 0;
+  loop->stop_flag = 0;
+
+  err = uv_mutex_init(&loop->wq_mutex);
+  if (err)
+    goto fail_mutex_init;
+
+  err = uv_async_init(loop, &loop->wq_async, uv__work_done);
+  if (err)
+    goto fail_async_init;
+
+  uv__handle_unref(&loop->wq_async);
+  loop->wq_async.flags |= UV__HANDLE_INTERNAL;
+
+  err = uv__loops_add(loop);
+  if (err)
+    goto fail_async_init;
+
+  return 0;
+
+fail_async_init:
+  uv_mutex_destroy(&loop->wq_mutex);
+
+fail_mutex_init:
+  CloseHandle(loop->iocp);
+  loop->iocp = INVALID_HANDLE_VALUE;
+
+  return err;
+}
+
+
+void uv__once_init(void) {
+  uv_once(&uv_init_guard_, uv_init);
+}
+
+
+void uv__loop_close(uv_loop_t* loop) {
+  size_t i;
+
+  uv__loops_remove(loop);
+
+  /* close the async handle without needing an extra loop iteration */
+  assert(!loop->wq_async.async_sent);
+  loop->wq_async.close_cb = NULL;
+  uv__handle_closing(&loop->wq_async);
+  uv__handle_close(&loop->wq_async);
+
+  for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) {
+    SOCKET sock = loop->poll_peer_sockets[i];
+    if (sock != 0 && sock != INVALID_SOCKET)
+      closesocket(sock);
+  }
+
+  uv_mutex_lock(&loop->wq_mutex);
+  assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!");
+  assert(!uv__has_active_reqs(loop));
+  uv_mutex_unlock(&loop->wq_mutex);
+  uv_mutex_destroy(&loop->wq_mutex);
+
+  CloseHandle(loop->iocp);
+}
+
+
+int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) {
+  return UV_ENOSYS;
+}
+
+
+int uv_backend_fd(const uv_loop_t* loop) {
+  return -1;
+}
+
+
+int uv_backend_timeout(const uv_loop_t* loop) {
+  if (loop->stop_flag != 0)
+    return 0;
+
+  if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop))
+    return 0;
+
+  if (loop->pending_reqs_tail)
+    return 0;
+
+  if (loop->endgame_handles)
+    return 0;
+
+  if (loop->idle_handles)
+    return 0;
+
+  return uv__next_timeout(loop);
+}
+
+
+static void uv_poll(uv_loop_t* loop, DWORD timeout) {
+  DWORD bytes;
+  ULONG_PTR key;
+  OVERLAPPED* overlapped;
+  uv_req_t* req;
+  int repeat;
+  uint64_t timeout_time;
+
+  timeout_time = loop->time + timeout;
+
+  for (repeat = 0; ; repeat++) {
+    GetQueuedCompletionStatus(loop->iocp,
+                              &bytes,
+                              &key,
+                              &overlapped,
+                              timeout);
+
+    if (overlapped) {
+      /* Package was dequeued */
+      req = uv_overlapped_to_req(overlapped);
+      uv_insert_pending_req(loop, req);
+
+      /* Some time might have passed waiting for I/O,
+       * so update the loop time here.
+       */
+      uv_update_time(loop);
+    } else if (GetLastError() != WAIT_TIMEOUT) {
+      /* Serious error */
+      uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus");
+    } else if (timeout > 0) {
+      /* GetQueuedCompletionStatus can occasionally return a little early.
+       * Make sure that the desired timeout target time is reached.
+       */
+      uv_update_time(loop);
+      if (timeout_time > loop->time) {
+        timeout = (DWORD)(timeout_time - loop->time);
+        /* The first call to GetQueuedCompletionStatus should return very
+         * close to the target time and the second should reach it, but
+         * this is not stated in the documentation. To make sure a busy
+         * loop cannot happen, the timeout is increased exponentially
+         * starting on the third round.
+         */
+        timeout += repeat ? (1 << (repeat - 1)) : 0;
+        continue;
+      }
+    }
+    break;
+  }
+}
+
+
+static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) {
+  BOOL success;
+  uv_req_t* req;
+  OVERLAPPED_ENTRY overlappeds[128];
+  ULONG count;
+  ULONG i;
+  int repeat;
+  uint64_t timeout_time;
+
+  timeout_time = loop->time + timeout;
+
+  for (repeat = 0; ; repeat++) {
+    success = pGetQueuedCompletionStatusEx(loop->iocp,
+                                           overlappeds,
+                                           ARRAY_SIZE(overlappeds),
+                                           &count,
+                                           timeout,
+                                           FALSE);
+
+    if (success) {
+      for (i = 0; i < count; i++) {
+        /* Package was dequeued, but see if it is not a empty package
+         * meant only to wake us up.
+         */
+        if (overlappeds[i].lpOverlapped) {
+          req = uv_overlapped_to_req(overlappeds[i].lpOverlapped);
+          uv_insert_pending_req(loop, req);
+        }
+      }
+
+      /* Some time might have passed waiting for I/O,
+       * so update the loop time here.
+       */
+      uv_update_time(loop);
+    } else if (GetLastError() != WAIT_TIMEOUT) {
+      /* Serious error */
+      uv_fatal_error(GetLastError(), "GetQueuedCompletionStatusEx");
+    } else if (timeout > 0) {
+      /* GetQueuedCompletionStatus can occasionally return a little early.
+       * Make sure that the desired timeout target time is reached.
+       */
+      uv_update_time(loop);
+      if (timeout_time > loop->time) {
+        timeout = (DWORD)(timeout_time - loop->time);
+        /* The first call to GetQueuedCompletionStatus should return very
+         * close to the target time and the second should reach it, but
+         * this is not stated in the documentation. To make sure a busy
+         * loop cannot happen, the timeout is increased exponentially
+         * starting on the third round.
+         */
+        timeout += repeat ? (1 << (repeat - 1)) : 0;
+        continue;
+      }
+    }
+    break;
+  }
+}
+
+
+static int uv__loop_alive(const uv_loop_t* loop) {
+  return loop->active_handles > 0 ||
+         !QUEUE_EMPTY(&loop->active_reqs) ||
+         loop->endgame_handles != NULL;
+}
+
+
+int uv_loop_alive(const uv_loop_t* loop) {
+    return uv__loop_alive(loop);
+}
+
+
+int uv_run(uv_loop_t *loop, uv_run_mode mode) {
+  DWORD timeout;
+  int r;
+  int ran_pending;
+  void (*poll)(uv_loop_t* loop, DWORD timeout);
+
+  if (pGetQueuedCompletionStatusEx)
+    poll = &uv_poll_ex;
+  else
+    poll = &uv_poll;
+
+  r = uv__loop_alive(loop);
+  if (!r)
+    uv_update_time(loop);
+
+  while (r != 0 && loop->stop_flag == 0) {
+    uv_update_time(loop);
+    uv_process_timers(loop);
+
+    ran_pending = uv_process_reqs(loop);
+    uv_idle_invoke(loop);
+    uv_prepare_invoke(loop);
+
+    timeout = 0;
+    if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
+      timeout = uv_backend_timeout(loop);
+
+    (*poll)(loop, timeout);
+
+    uv_check_invoke(loop);
+    uv_process_endgames(loop);
+
+    if (mode == UV_RUN_ONCE) {
+      /* UV_RUN_ONCE implies forward progress: at least one callback must have
+       * been invoked when it returns. uv__io_poll() can return without doing
+       * I/O (meaning: no callbacks) when its timeout expires - which means we
+       * have pending timers that satisfy the forward progress constraint.
+       *
+       * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
+       * the check.
+       */
+      uv_process_timers(loop);
+    }
+
+    r = uv__loop_alive(loop);
+    if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT)
+      break;
+  }
+
+  /* The if statement lets the compiler compile it to a conditional store.
+   * Avoids dirtying a cache line.
+   */
+  if (loop->stop_flag != 0)
+    loop->stop_flag = 0;
+
+  return r;
+}
+
+
+int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
+  uv_os_fd_t fd_out;
+
+  switch (handle->type) {
+  case UV_TCP:
+    fd_out = (uv_os_fd_t)((uv_tcp_t*) handle)->socket;
+    break;
+
+  case UV_NAMED_PIPE:
+    fd_out = ((uv_pipe_t*) handle)->handle;
+    break;
+
+  case UV_TTY:
+    fd_out = ((uv_tty_t*) handle)->handle;
+    break;
+
+  case UV_UDP:
+    fd_out = (uv_os_fd_t)((uv_udp_t*) handle)->socket;
+    break;
+
+  case UV_POLL:
+    fd_out = (uv_os_fd_t)((uv_poll_t*) handle)->socket;
+    break;
+
+  default:
+    return UV_EINVAL;
+  }
+
+  if (uv_is_closing(handle) || fd_out == INVALID_HANDLE_VALUE)
+    return UV_EBADF;
+
+  *fd = fd_out;
+  return 0;
+}
+
+
+int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
+  int r;
+  int len;
+  SOCKET socket;
+
+  if (handle == NULL || value == NULL)
+    return UV_EINVAL;
+
+  if (handle->type == UV_TCP)
+    socket = ((uv_tcp_t*) handle)->socket;
+  else if (handle->type == UV_UDP)
+    socket = ((uv_udp_t*) handle)->socket;
+  else
+    return UV_ENOTSUP;
+
+  len = sizeof(*value);
+
+  if (*value == 0)
+    r = getsockopt(socket, SOL_SOCKET, optname, (char*) value, &len);
+  else
+    r = setsockopt(socket, SOL_SOCKET, optname, (const char*) value, len);
+
+  if (r == SOCKET_ERROR)
+    return uv_translate_sys_error(WSAGetLastError());
+
+  return 0;
+}
diff --git a/deps/libtuv/src/win/detect-wakeup.c b/deps/libtuv/src/win/detect-wakeup.c
new file mode 100644 (file)
index 0000000..a12179f
--- /dev/null
@@ -0,0 +1,35 @@
+#include "uv.h"
+#include "internal.h"
+#include "winapi.h"
+
+static void uv__register_system_resume_callback();
+
+void uv__init_detect_system_wakeup() {
+  /* Try registering system power event callback. This is the cleanest
+   * method, but it will only work on Win8 and above.
+   */
+  uv__register_system_resume_callback();
+}
+
+static ULONG CALLBACK uv__system_resume_callback(PVOID Context,
+                                                 ULONG Type,
+                                                 PVOID Setting) {
+  if (Type == PBT_APMRESUMESUSPEND || Type == PBT_APMRESUMEAUTOMATIC)
+    uv__wake_all_loops();
+
+  return 0;
+}
+
+static void uv__register_system_resume_callback() {
+  _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS recipient;
+  _HPOWERNOTIFY registration_handle;
+
+  if (pPowerRegisterSuspendResumeNotification == NULL)
+    return;
+
+  recipient.Callback = uv__system_resume_callback;
+  recipient.Context = NULL;
+  (*pPowerRegisterSuspendResumeNotification)(DEVICE_NOTIFY_CALLBACK,
+                                             &recipient,
+                                             &registration_handle);
+}
diff --git a/deps/libtuv/src/win/dl.c b/deps/libtuv/src/win/dl.c
new file mode 100644 (file)
index 0000000..39e400a
--- /dev/null
@@ -0,0 +1,118 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "internal.h"
+
+static int uv__dlerror(uv_lib_t* lib, int errorno);
+
+
+int uv_dlopen(const char* filename, uv_lib_t* lib) {
+  WCHAR filename_w[32768];
+
+  lib->handle = NULL;
+  lib->errmsg = NULL;
+
+  if (!MultiByteToWideChar(CP_UTF8,
+                           0,
+                           filename,
+                           -1,
+                           filename_w,
+                           ARRAY_SIZE(filename_w))) {
+    return uv__dlerror(lib, GetLastError());
+  }
+
+  lib->handle = LoadLibraryExW(filename_w, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+  if (lib->handle == NULL) {
+    return uv__dlerror(lib, GetLastError());
+  }
+
+  return 0;
+}
+
+
+void uv_dlclose(uv_lib_t* lib) {
+  if (lib->errmsg) {
+    LocalFree((void*)lib->errmsg);
+    lib->errmsg = NULL;
+  }
+
+  if (lib->handle) {
+    /* Ignore errors. No good way to signal them without leaking memory. */
+    FreeLibrary(lib->handle);
+    lib->handle = NULL;
+  }
+}
+
+
+int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) {
+  *ptr = (void*) GetProcAddress(lib->handle, name);
+  return uv__dlerror(lib, *ptr ? 0 : GetLastError());
+}
+
+
+const char* uv_dlerror(const uv_lib_t* lib) {
+  return lib->errmsg ? lib->errmsg : "no error";
+}
+
+
+static void uv__format_fallback_error(uv_lib_t* lib, int errorno){
+  DWORD_PTR args[1] = { (DWORD_PTR) errorno };
+  LPSTR fallback_error = "error: %1!d!";
+
+  FormatMessageA(FORMAT_MESSAGE_FROM_STRING |
+                 FORMAT_MESSAGE_ARGUMENT_ARRAY |
+                 FORMAT_MESSAGE_ALLOCATE_BUFFER,
+                 fallback_error, 0, 0,
+                 (LPSTR) &lib->errmsg,
+                 0, (va_list*) args);
+}
+
+
+
+static int uv__dlerror(uv_lib_t* lib, int errorno) {
+  DWORD res;
+
+  if (lib->errmsg) {
+    LocalFree((void*)lib->errmsg);
+    lib->errmsg = NULL;
+  }
+
+  if (errorno) {
+    res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                         FORMAT_MESSAGE_FROM_SYSTEM |
+                         FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
+                         MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
+                         (LPSTR) &lib->errmsg, 0, NULL);
+    if (!res && GetLastError() == ERROR_MUI_FILE_NOT_FOUND) {
+      res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                           FORMAT_MESSAGE_FROM_SYSTEM |
+                           FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
+                           0, (LPSTR) &lib->errmsg, 0, NULL);
+    }
+
+    if (!res) {
+      uv__format_fallback_error(lib, errorno);
+    }
+  }
+
+  return errorno ? -1 : 0;
+}
diff --git a/deps/libtuv/src/win/error.c b/deps/libtuv/src/win/error.c
new file mode 100644 (file)
index 0000000..642d111
--- /dev/null
@@ -0,0 +1,171 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "internal.h"
+
+
+/*
+ * Display an error message and abort the event loop.
+ */
+void uv_fatal_error(const int errorno, const char* syscall) {
+  char* buf = NULL;
+  const char* errmsg;
+
+  FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+      FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
+      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buf, 0, NULL);
+
+  if (buf) {
+    errmsg = buf;
+  } else {
+    errmsg = "Unknown error";
+  }
+
+  /* FormatMessage messages include a newline character already, */
+  /* so don't add another. */
+  if (syscall) {
+    fprintf(stderr, "%s: (%d) %s", syscall, errorno, errmsg);
+  } else {
+    fprintf(stderr, "(%d) %s", errorno, errmsg);
+  }
+
+  if (buf) {
+    LocalFree(buf);
+  }
+
+  *((char*)NULL) = 0xff; /* Force debug break */
+  abort();
+}
+
+
+int uv_translate_sys_error(int sys_errno) {
+  if (sys_errno <= 0) {
+    return sys_errno;  /* If < 0 then it's already a libuv error. */
+  }
+
+  switch (sys_errno) {
+    case ERROR_NOACCESS:                    return UV_EACCES;
+    case WSAEACCES:                         return UV_EACCES;
+    case ERROR_ELEVATION_REQUIRED:          return UV_EACCES;
+    case ERROR_ADDRESS_ALREADY_ASSOCIATED:  return UV_EADDRINUSE;
+    case WSAEADDRINUSE:                     return UV_EADDRINUSE;
+    case WSAEADDRNOTAVAIL:                  return UV_EADDRNOTAVAIL;
+    case WSAEAFNOSUPPORT:                   return UV_EAFNOSUPPORT;
+    case WSAEWOULDBLOCK:                    return UV_EAGAIN;
+    case WSAEALREADY:                       return UV_EALREADY;
+    case ERROR_INVALID_FLAGS:               return UV_EBADF;
+    case ERROR_INVALID_HANDLE:              return UV_EBADF;
+    case ERROR_LOCK_VIOLATION:              return UV_EBUSY;
+    case ERROR_PIPE_BUSY:                   return UV_EBUSY;
+    case ERROR_SHARING_VIOLATION:           return UV_EBUSY;
+    case ERROR_OPERATION_ABORTED:           return UV_ECANCELED;
+    case WSAEINTR:                          return UV_ECANCELED;
+    case ERROR_NO_UNICODE_TRANSLATION:      return UV_ECHARSET;
+    case ERROR_CONNECTION_ABORTED:          return UV_ECONNABORTED;
+    case WSAECONNABORTED:                   return UV_ECONNABORTED;
+    case ERROR_CONNECTION_REFUSED:          return UV_ECONNREFUSED;
+    case WSAECONNREFUSED:                   return UV_ECONNREFUSED;
+    case ERROR_NETNAME_DELETED:             return UV_ECONNRESET;
+    case WSAECONNRESET:                     return UV_ECONNRESET;
+    case ERROR_ALREADY_EXISTS:              return UV_EEXIST;
+    case ERROR_FILE_EXISTS:                 return UV_EEXIST;
+    case ERROR_BUFFER_OVERFLOW:             return UV_EFAULT;
+    case WSAEFAULT:                         return UV_EFAULT;
+    case ERROR_HOST_UNREACHABLE:            return UV_EHOSTUNREACH;
+    case WSAEHOSTUNREACH:                   return UV_EHOSTUNREACH;
+    case ERROR_INSUFFICIENT_BUFFER:         return UV_EINVAL;
+    case ERROR_INVALID_DATA:                return UV_EINVAL;
+    case ERROR_INVALID_PARAMETER:           return UV_EINVAL;
+    case ERROR_SYMLINK_NOT_SUPPORTED:       return UV_EINVAL;
+    case WSAEINVAL:                         return UV_EINVAL;
+    case WSAEPFNOSUPPORT:                   return UV_EINVAL;
+    case WSAESOCKTNOSUPPORT:                return UV_EINVAL;
+    case ERROR_BEGINNING_OF_MEDIA:          return UV_EIO;
+    case ERROR_BUS_RESET:                   return UV_EIO;
+    case ERROR_CRC:                         return UV_EIO;
+    case ERROR_DEVICE_DOOR_OPEN:            return UV_EIO;
+    case ERROR_DEVICE_REQUIRES_CLEANING:    return UV_EIO;
+    case ERROR_DISK_CORRUPT:                return UV_EIO;
+    case ERROR_EOM_OVERFLOW:                return UV_EIO;
+    case ERROR_FILEMARK_DETECTED:           return UV_EIO;
+    case ERROR_GEN_FAILURE:                 return UV_EIO;
+    case ERROR_INVALID_BLOCK_LENGTH:        return UV_EIO;
+    case ERROR_IO_DEVICE:                   return UV_EIO;
+    case ERROR_NO_DATA_DETECTED:            return UV_EIO;
+    case ERROR_NO_SIGNAL_SENT:              return UV_EIO;
+    case ERROR_OPEN_FAILED:                 return UV_EIO;
+    case ERROR_SETMARK_DETECTED:            return UV_EIO;
+    case ERROR_SIGNAL_REFUSED:              return UV_EIO;
+    case WSAEISCONN:                        return UV_EISCONN;
+    case ERROR_CANT_RESOLVE_FILENAME:       return UV_ELOOP;
+    case ERROR_TOO_MANY_OPEN_FILES:         return UV_EMFILE;
+    case WSAEMFILE:                         return UV_EMFILE;
+    case WSAEMSGSIZE:                       return UV_EMSGSIZE;
+    case ERROR_FILENAME_EXCED_RANGE:        return UV_ENAMETOOLONG;
+    case ERROR_NETWORK_UNREACHABLE:         return UV_ENETUNREACH;
+    case WSAENETUNREACH:                    return UV_ENETUNREACH;
+    case WSAENOBUFS:                        return UV_ENOBUFS;
+    case ERROR_BAD_PATHNAME:                return UV_ENOENT;
+    case ERROR_DIRECTORY:                   return UV_ENOENT;
+    case ERROR_FILE_NOT_FOUND:              return UV_ENOENT;
+    case ERROR_INVALID_NAME:                return UV_ENOENT;
+    case ERROR_INVALID_DRIVE:               return UV_ENOENT;
+    case ERROR_INVALID_REPARSE_DATA:        return UV_ENOENT;
+    case ERROR_MOD_NOT_FOUND:               return UV_ENOENT;
+    case ERROR_PATH_NOT_FOUND:              return UV_ENOENT;
+    case WSAHOST_NOT_FOUND:                 return UV_ENOENT;
+    case WSANO_DATA:                        return UV_ENOENT;
+    case ERROR_NOT_ENOUGH_MEMORY:           return UV_ENOMEM;
+    case ERROR_OUTOFMEMORY:                 return UV_ENOMEM;
+    case ERROR_CANNOT_MAKE:                 return UV_ENOSPC;
+    case ERROR_DISK_FULL:                   return UV_ENOSPC;
+    case ERROR_EA_TABLE_FULL:               return UV_ENOSPC;
+    case ERROR_END_OF_MEDIA:                return UV_ENOSPC;
+    case ERROR_HANDLE_DISK_FULL:            return UV_ENOSPC;
+    case ERROR_NOT_CONNECTED:               return UV_ENOTCONN;
+    case WSAENOTCONN:                       return UV_ENOTCONN;
+    case ERROR_DIR_NOT_EMPTY:               return UV_ENOTEMPTY;
+    case WSAENOTSOCK:                       return UV_ENOTSOCK;
+    case ERROR_NOT_SUPPORTED:               return UV_ENOTSUP;
+    case ERROR_BROKEN_PIPE:                 return UV_EOF;
+    case ERROR_ACCESS_DENIED:               return UV_EPERM;
+    case ERROR_PRIVILEGE_NOT_HELD:          return UV_EPERM;
+    case ERROR_BAD_PIPE:                    return UV_EPIPE;
+    case ERROR_NO_DATA:                     return UV_EPIPE;
+    case ERROR_PIPE_NOT_CONNECTED:          return UV_EPIPE;
+    case WSAESHUTDOWN:                      return UV_EPIPE;
+    case WSAEPROTONOSUPPORT:                return UV_EPROTONOSUPPORT;
+    case ERROR_WRITE_PROTECT:               return UV_EROFS;
+    case ERROR_SEM_TIMEOUT:                 return UV_ETIMEDOUT;
+    case WSAETIMEDOUT:                      return UV_ETIMEDOUT;
+    case ERROR_NOT_SAME_DEVICE:             return UV_EXDEV;
+    case ERROR_INVALID_FUNCTION:            return UV_EISDIR;
+    case ERROR_META_EXPANSION_TOO_LONG:     return UV_E2BIG;
+    default:                                return UV_UNKNOWN;
+  }
+}
diff --git a/deps/libtuv/src/win/fs-event.c b/deps/libtuv/src/win/fs-event.c
new file mode 100644 (file)
index 0000000..03e4adc
--- /dev/null
@@ -0,0 +1,545 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+
+const unsigned int uv_directory_watcher_buffer_size = 4096;
+
+
+static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop,
+    uv_fs_event_t* handle) {
+  assert(handle->dir_handle != INVALID_HANDLE_VALUE);
+  assert(!handle->req_pending);
+
+  memset(&(handle->req.u.io.overlapped), 0,
+         sizeof(handle->req.u.io.overlapped));
+  if (!ReadDirectoryChangesW(handle->dir_handle,
+                             handle->buffer,
+                             uv_directory_watcher_buffer_size,
+                             (handle->flags & UV_FS_EVENT_RECURSIVE) ? TRUE : FALSE,
+                             FILE_NOTIFY_CHANGE_FILE_NAME      |
+                               FILE_NOTIFY_CHANGE_DIR_NAME     |
+                               FILE_NOTIFY_CHANGE_ATTRIBUTES   |
+                               FILE_NOTIFY_CHANGE_SIZE         |
+                               FILE_NOTIFY_CHANGE_LAST_WRITE   |
+                               FILE_NOTIFY_CHANGE_LAST_ACCESS  |
+                               FILE_NOTIFY_CHANGE_CREATION     |
+                               FILE_NOTIFY_CHANGE_SECURITY,
+                             NULL,
+                             &handle->req.u.io.overlapped,
+                             NULL)) {
+    /* Make this req pending reporting an error. */
+    SET_REQ_ERROR(&handle->req, GetLastError());
+    uv_insert_pending_req(loop, (uv_req_t*)&handle->req);
+  }
+
+  handle->req_pending = 1;
+}
+
+static void uv_relative_path(const WCHAR* filename,
+                             const WCHAR* dir,
+                             WCHAR** relpath) {
+  size_t relpathlen;
+  size_t filenamelen = wcslen(filename);
+  size_t dirlen = wcslen(dir);
+  if (dirlen > 0 && dir[dirlen - 1] == '\\')
+    dirlen--;
+  relpathlen = filenamelen - dirlen - 1;
+  *relpath = uv__malloc((relpathlen + 1) * sizeof(WCHAR));
+  if (!*relpath)
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+  wcsncpy(*relpath, filename + dirlen + 1, relpathlen);
+  (*relpath)[relpathlen] = L'\0';
+}
+
+static int uv_split_path(const WCHAR* filename, WCHAR** dir,
+    WCHAR** file) {
+  int len = wcslen(filename);
+  int i = len;
+  while (i > 0 && filename[--i] != '\\' && filename[i] != '/');
+
+  if (i == 0) {
+    if (dir) {
+      *dir = (WCHAR*)uv__malloc((MAX_PATH + 1) * sizeof(WCHAR));
+      if (!*dir) {
+        uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+      }
+
+      if (!GetCurrentDirectoryW(MAX_PATH, *dir)) {
+        uv__free(*dir);
+        *dir = NULL;
+        return -1;
+      }
+    }
+
+    *file = wcsdup(filename);
+  } else {
+    if (dir) {
+      *dir = (WCHAR*)uv__malloc((i + 2) * sizeof(WCHAR));
+      if (!*dir) {
+        uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+      }
+      wcsncpy(*dir, filename, i + 1);
+      (*dir)[i + 1] = L'\0';
+    }
+
+    *file = (WCHAR*)uv__malloc((len - i) * sizeof(WCHAR));
+    if (!*file) {
+      uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+    }
+    wcsncpy(*file, filename + i + 1, len - i - 1);
+    (*file)[len - i - 1] = L'\0';
+  }
+
+  return 0;
+}
+
+
+int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
+  uv__handle_init(loop, (uv_handle_t*) handle, UV_FS_EVENT);
+  handle->dir_handle = INVALID_HANDLE_VALUE;
+  handle->buffer = NULL;
+  handle->req_pending = 0;
+  handle->filew = NULL;
+  handle->short_filew = NULL;
+  handle->dirw = NULL;
+
+  uv_req_init(loop, (uv_req_t*)&handle->req);
+  handle->req.type = UV_FS_EVENT_REQ;
+  handle->req.data = handle;
+
+  return 0;
+}
+
+
+int uv_fs_event_start(uv_fs_event_t* handle,
+                      uv_fs_event_cb cb,
+                      const char* path,
+                      unsigned int flags) {
+  int name_size, is_path_dir;
+  DWORD attr, last_error;
+  WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
+  WCHAR short_path[MAX_PATH];
+
+  if (uv__is_active(handle))
+    return UV_EINVAL;
+
+  handle->cb = cb;
+  handle->path = uv__strdup(path);
+  if (!handle->path) {
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+  }
+
+  uv__handle_start(handle);
+
+  /* Convert name to UTF16. */
+
+  name_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0) *
+              sizeof(WCHAR);
+  pathw = (WCHAR*)uv__malloc(name_size);
+  if (!pathw) {
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+  }
+
+  if (!MultiByteToWideChar(CP_UTF8,
+                           0,
+                           path,
+                           -1,
+                           pathw,
+                           name_size / sizeof(WCHAR))) {
+    return uv_translate_sys_error(GetLastError());
+  }
+
+  /* Determine whether path is a file or a directory. */
+  attr = GetFileAttributesW(pathw);
+  if (attr == INVALID_FILE_ATTRIBUTES) {
+    last_error = GetLastError();
+    goto error;
+  }
+
+  is_path_dir = (attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
+
+  if (is_path_dir) {
+     /* path is a directory, so that's the directory that we will watch. */
+    handle->dirw = pathw;
+    dir_to_watch = pathw;
+  } else {
+    /*
+     * path is a file.  So we split path into dir & file parts, and
+     * watch the dir directory.
+     */
+
+    /* Convert to short path. */
+    if (!GetShortPathNameW(pathw, short_path, ARRAY_SIZE(short_path))) {
+      last_error = GetLastError();
+      goto error;
+    }
+
+    if (uv_split_path(pathw, &dir, &handle->filew) != 0) {
+      last_error = GetLastError();
+      goto error;
+    }
+
+    if (uv_split_path(short_path, NULL, &handle->short_filew) != 0) {
+      last_error = GetLastError();
+      goto error;
+    }
+
+    dir_to_watch = dir;
+    uv__free(pathw);
+    pathw = NULL;
+  }
+
+  handle->dir_handle = CreateFileW(dir_to_watch,
+                                   FILE_LIST_DIRECTORY,
+                                   FILE_SHARE_READ | FILE_SHARE_DELETE |
+                                     FILE_SHARE_WRITE,
+                                   NULL,
+                                   OPEN_EXISTING,
+                                   FILE_FLAG_BACKUP_SEMANTICS |
+                                     FILE_FLAG_OVERLAPPED,
+                                   NULL);
+
+  if (dir) {
+    uv__free(dir);
+    dir = NULL;
+  }
+
+  if (handle->dir_handle == INVALID_HANDLE_VALUE) {
+    last_error = GetLastError();
+    goto error;
+  }
+
+  if (CreateIoCompletionPort(handle->dir_handle,
+                             handle->loop->iocp,
+                             (ULONG_PTR)handle,
+                             0) == NULL) {
+    last_error = GetLastError();
+    goto error;
+  }
+
+  if (!handle->buffer) {
+    handle->buffer = (char*)uv__malloc(uv_directory_watcher_buffer_size);
+  }
+  if (!handle->buffer) {
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+  }
+
+  memset(&(handle->req.u.io.overlapped), 0,
+         sizeof(handle->req.u.io.overlapped));
+
+  if (!ReadDirectoryChangesW(handle->dir_handle,
+                             handle->buffer,
+                             uv_directory_watcher_buffer_size,
+                             (flags & UV_FS_EVENT_RECURSIVE) ? TRUE : FALSE,
+                             FILE_NOTIFY_CHANGE_FILE_NAME      |
+                               FILE_NOTIFY_CHANGE_DIR_NAME     |
+                               FILE_NOTIFY_CHANGE_ATTRIBUTES   |
+                               FILE_NOTIFY_CHANGE_SIZE         |
+                               FILE_NOTIFY_CHANGE_LAST_WRITE   |
+                               FILE_NOTIFY_CHANGE_LAST_ACCESS  |
+                               FILE_NOTIFY_CHANGE_CREATION     |
+                               FILE_NOTIFY_CHANGE_SECURITY,
+                             NULL,
+                             &handle->req.u.io.overlapped,
+                             NULL)) {
+    last_error = GetLastError();
+    goto error;
+  }
+
+  handle->req_pending = 1;
+  return 0;
+
+error:
+  if (handle->path) {
+    uv__free(handle->path);
+    handle->path = NULL;
+  }
+
+  if (handle->filew) {
+    uv__free(handle->filew);
+    handle->filew = NULL;
+  }
+
+  if (handle->short_filew) {
+    uv__free(handle->short_filew);
+    handle->short_filew = NULL;
+  }
+
+  uv__free(pathw);
+
+  if (handle->dir_handle != INVALID_HANDLE_VALUE) {
+    CloseHandle(handle->dir_handle);
+    handle->dir_handle = INVALID_HANDLE_VALUE;
+  }
+
+  if (handle->buffer) {
+    uv__free(handle->buffer);
+    handle->buffer = NULL;
+  }
+
+  return uv_translate_sys_error(last_error);
+}
+
+
+int uv_fs_event_stop(uv_fs_event_t* handle) {
+  if (!uv__is_active(handle))
+    return 0;
+
+  if (handle->dir_handle != INVALID_HANDLE_VALUE) {
+    CloseHandle(handle->dir_handle);
+    handle->dir_handle = INVALID_HANDLE_VALUE;
+  }
+
+  uv__handle_stop(handle);
+
+  if (handle->filew) {
+    uv__free(handle->filew);
+    handle->filew = NULL;
+  }
+
+  if (handle->short_filew) {
+    uv__free(handle->short_filew);
+    handle->short_filew = NULL;
+  }
+
+  if (handle->path) {
+    uv__free(handle->path);
+    handle->path = NULL;
+  }
+
+  if (handle->dirw) {
+    uv__free(handle->dirw);
+    handle->dirw = NULL;
+  }
+
+  return 0;
+}
+
+
+static int file_info_cmp(WCHAR* str, WCHAR* file_name, int file_name_len) {
+  int str_len;
+
+  str_len = wcslen(str);
+
+  /*
+    Since we only care about equality, return early if the strings
+    aren't the same length
+  */
+  if (str_len != (file_name_len / sizeof(WCHAR)))
+    return -1;
+
+  return _wcsnicmp(str, file_name, str_len);
+}
+
+
+void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
+    uv_fs_event_t* handle) {
+  FILE_NOTIFY_INFORMATION* file_info;
+  int err, sizew, size;
+  char* filename = NULL;
+  WCHAR* filenamew = NULL;
+  WCHAR* long_filenamew = NULL;
+  DWORD offset = 0;
+
+  assert(req->type == UV_FS_EVENT_REQ);
+  assert(handle->req_pending);
+  handle->req_pending = 0;
+
+  /* Don't report any callbacks if:
+   * - We're closing, just push the handle onto the endgame queue
+   * - We are not active, just ignore the callback
+   */
+  if (!uv__is_active(handle)) {
+    if (handle->flags & UV__HANDLE_CLOSING) {
+      uv_want_endgame(loop, (uv_handle_t*) handle);
+    }
+    return;
+  }
+
+  file_info = (FILE_NOTIFY_INFORMATION*)(handle->buffer + offset);
+
+  if (REQ_SUCCESS(req)) {
+    if (req->u.io.overlapped.InternalHigh > 0) {
+      do {
+        file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset);
+        assert(!filename);
+        assert(!filenamew);
+        assert(!long_filenamew);
+
+        /*
+         * Fire the event only if we were asked to watch a directory,
+         * or if the filename filter matches.
+         */
+        if (handle->dirw ||
+            file_info_cmp(handle->filew,
+                          file_info->FileName,
+                          file_info->FileNameLength) == 0 ||
+            file_info_cmp(handle->short_filew,
+                          file_info->FileName,
+                          file_info->FileNameLength) == 0) {
+
+          if (handle->dirw) {
+            /*
+             * We attempt to resolve the long form of the file name explicitly.
+             * We only do this for file names that might still exist on disk.
+             * If this fails, we use the name given by ReadDirectoryChangesW.
+             * This may be the long form or the 8.3 short name in some cases.
+             */
+            if (file_info->Action != FILE_ACTION_REMOVED &&
+              file_info->Action != FILE_ACTION_RENAMED_OLD_NAME) {
+              /* Construct a full path to the file. */
+              size = wcslen(handle->dirw) +
+                file_info->FileNameLength / sizeof(WCHAR) + 2;
+
+              filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
+              if (!filenamew) {
+                uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+              }
+
+              _snwprintf(filenamew, size, L"%s\\%.*s", handle->dirw,
+                file_info->FileNameLength / (DWORD)sizeof(WCHAR),
+                file_info->FileName);
+
+              filenamew[size - 1] = L'\0';
+
+              /* Convert to long name. */
+              size = GetLongPathNameW(filenamew, NULL, 0);
+
+              if (size) {
+                long_filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
+                if (!long_filenamew) {
+                  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+                }
+
+                size = GetLongPathNameW(filenamew, long_filenamew, size);
+                if (size) {
+                  long_filenamew[size] = '\0';
+                } else {
+                  uv__free(long_filenamew);
+                  long_filenamew = NULL;
+                }
+              }
+
+              uv__free(filenamew);
+
+              if (long_filenamew) {
+                /* Get the file name out of the long path. */
+                uv_relative_path(long_filenamew,
+                                 handle->dirw,
+                                 &filenamew);
+                uv__free(long_filenamew);
+                long_filenamew = filenamew;
+                sizew = -1;
+              } else {
+                /* We couldn't get the long filename, use the one reported. */
+                filenamew = file_info->FileName;
+                sizew = file_info->FileNameLength / sizeof(WCHAR);
+              }
+            } else {
+              /*
+               * Removed or renamed events cannot be resolved to the long form.
+               * We therefore use the name given by ReadDirectoryChangesW.
+               * This may be the long form or the 8.3 short name in some cases.
+               */
+              filenamew = file_info->FileName;
+              sizew = file_info->FileNameLength / sizeof(WCHAR);
+            }
+          } else {
+            /* We already have the long name of the file, so just use it. */
+            filenamew = handle->filew;
+            sizew = -1;
+          }
+
+          /* Convert the filename to utf8. */
+          uv__convert_utf16_to_utf8(filenamew, sizew, &filename);
+
+          switch (file_info->Action) {
+            case FILE_ACTION_ADDED:
+            case FILE_ACTION_REMOVED:
+            case FILE_ACTION_RENAMED_OLD_NAME:
+            case FILE_ACTION_RENAMED_NEW_NAME:
+              handle->cb(handle, filename, UV_RENAME, 0);
+              break;
+
+            case FILE_ACTION_MODIFIED:
+              handle->cb(handle, filename, UV_CHANGE, 0);
+              break;
+          }
+
+          uv__free(filename);
+          filename = NULL;
+          uv__free(long_filenamew);
+          long_filenamew = NULL;
+          filenamew = NULL;
+        }
+
+        offset = file_info->NextEntryOffset;
+      } while (offset && !(handle->flags & UV__HANDLE_CLOSING));
+    } else {
+      handle->cb(handle, NULL, UV_CHANGE, 0);
+    }
+  } else {
+    err = GET_REQ_ERROR(req);
+    handle->cb(handle, NULL, 0, uv_translate_sys_error(err));
+  }
+
+  if (!(handle->flags & UV__HANDLE_CLOSING)) {
+    uv_fs_event_queue_readdirchanges(loop, handle);
+  } else {
+    uv_want_endgame(loop, (uv_handle_t*)handle);
+  }
+}
+
+
+void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle) {
+  uv_fs_event_stop(handle);
+
+  uv__handle_closing(handle);
+
+  if (!handle->req_pending) {
+    uv_want_endgame(loop, (uv_handle_t*)handle);
+  }
+
+}
+
+
+void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle) {
+  if ((handle->flags & UV__HANDLE_CLOSING) && !handle->req_pending) {
+    assert(!(handle->flags & UV_HANDLE_CLOSED));
+
+    if (handle->buffer) {
+      uv__free(handle->buffer);
+      handle->buffer = NULL;
+    }
+
+    uv__handle_close(handle);
+  }
+}
diff --git a/deps/libtuv/src/win/fs.c b/deps/libtuv/src/win/fs.c
new file mode 100644 (file)
index 0000000..6902d4f
--- /dev/null
@@ -0,0 +1,2494 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <direct.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <io.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <sys/utime.h>
+#include <stdio.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "req-inl.h"
+#include "handle-inl.h"
+
+#include <wincrypt.h>
+
+
+#define UV_FS_FREE_PATHS         0x0002
+#define UV_FS_FREE_PTR           0x0008
+#define UV_FS_CLEANEDUP          0x0010
+
+
+#define QUEUE_FS_TP_JOB(loop, req)                                          \
+  do {                                                                      \
+    uv__req_register(loop, req);                                            \
+    uv__work_submit((loop), &(req)->work_req, uv__fs_work, uv__fs_done);    \
+  } while (0)
+
+#define SET_REQ_RESULT(req, result_value)                                   \
+  do {                                                                      \
+    req->result = (result_value);                                           \
+    if (req->result == -1) {                                                \
+      req->sys_errno_ = _doserrno;                                          \
+      req->result = uv_translate_sys_error(req->sys_errno_);                \
+    }                                                                       \
+  } while (0)
+
+#define SET_REQ_WIN32_ERROR(req, sys_errno)                                 \
+  do {                                                                      \
+    req->sys_errno_ = (sys_errno);                                          \
+    req->result = uv_translate_sys_error(req->sys_errno_);                  \
+  } while (0)
+
+#define SET_REQ_UV_ERROR(req, uv_errno, sys_errno)                          \
+  do {                                                                      \
+    req->result = (uv_errno);                                               \
+    req->sys_errno_ = (sys_errno);                                          \
+  } while (0)
+
+#define VERIFY_FD(fd, req)                                                  \
+  if (fd == -1) {                                                           \
+    req->result = UV_EBADF;                                                 \
+    req->sys_errno_ = ERROR_INVALID_HANDLE;                                 \
+    return;                                                                 \
+  }
+
+#define FILETIME_TO_UINT(filetime)                                          \
+   (*((uint64_t*) &(filetime)) - 116444736000000000ULL)
+
+#define FILETIME_TO_TIME_T(filetime)                                        \
+   (FILETIME_TO_UINT(filetime) / 10000000ULL)
+
+#define FILETIME_TO_TIME_NS(filetime, secs)                                 \
+   ((FILETIME_TO_UINT(filetime) - (secs * 10000000ULL)) * 100)
+
+#define FILETIME_TO_TIMESPEC(ts, filetime)                                  \
+   do {                                                                     \
+     (ts).tv_sec = (long) FILETIME_TO_TIME_T(filetime);                     \
+     (ts).tv_nsec = (long) FILETIME_TO_TIME_NS(filetime, (ts).tv_sec);      \
+   } while(0)
+
+#define TIME_T_TO_FILETIME(time, filetime_ptr)                              \
+  do {                                                                      \
+    uint64_t bigtime = ((uint64_t) ((time) * 10000000ULL)) +                \
+                                  116444736000000000ULL;                    \
+    (filetime_ptr)->dwLowDateTime = bigtime & 0xFFFFFFFF;                   \
+    (filetime_ptr)->dwHighDateTime = bigtime >> 32;                         \
+  } while(0)
+
+#define IS_SLASH(c) ((c) == L'\\' || (c) == L'/')
+#define IS_LETTER(c) (((c) >= L'a' && (c) <= L'z') || \
+  ((c) >= L'A' && (c) <= L'Z'))
+
+const WCHAR JUNCTION_PREFIX[] = L"\\??\\";
+const WCHAR JUNCTION_PREFIX_LEN = 4;
+
+const WCHAR LONG_PATH_PREFIX[] = L"\\\\?\\";
+const WCHAR LONG_PATH_PREFIX_LEN = 4;
+
+const WCHAR UNC_PATH_PREFIX[] = L"\\\\?\\UNC\\";
+const WCHAR UNC_PATH_PREFIX_LEN = 8;
+
+
+void uv_fs_init() {
+  _fmode = _O_BINARY;
+}
+
+
+INLINE static int fs__capture_path(uv_fs_t* req, const char* path,
+    const char* new_path, const int copy_path) {
+  char* buf;
+  char* pos;
+  ssize_t buf_sz = 0, path_len = 0, pathw_len = 0, new_pathw_len = 0;
+
+  /* new_path can only be set if path is also set. */
+  assert(new_path == NULL || path != NULL);
+
+  if (path != NULL) {
+    pathw_len = MultiByteToWideChar(CP_UTF8,
+                                    0,
+                                    path,
+                                    -1,
+                                    NULL,
+                                    0);
+    if (pathw_len == 0) {
+      return GetLastError();
+    }
+
+    buf_sz += pathw_len * sizeof(WCHAR);
+  }
+
+  if (path != NULL && copy_path) {
+    path_len = 1 + strlen(path);
+    buf_sz += path_len;
+  }
+
+  if (new_path != NULL) {
+    new_pathw_len = MultiByteToWideChar(CP_UTF8,
+                                        0,
+                                        new_path,
+                                        -1,
+                                        NULL,
+                                        0);
+    if (new_pathw_len == 0) {
+      return GetLastError();
+    }
+
+    buf_sz += new_pathw_len * sizeof(WCHAR);
+  }
+
+
+  if (buf_sz == 0) {
+    req->file.pathw = NULL;
+    req->fs.info.new_pathw = NULL;
+    req->path = NULL;
+    return 0;
+  }
+
+  buf = (char*) uv__malloc(buf_sz);
+  if (buf == NULL) {
+    return ERROR_OUTOFMEMORY;
+  }
+
+  pos = buf;
+
+  if (path != NULL) {
+    DWORD r = MultiByteToWideChar(CP_UTF8,
+                                  0,
+                                  path,
+                                  -1,
+                                  (WCHAR*) pos,
+                                  pathw_len);
+    assert(r == (DWORD) pathw_len);
+    req->file.pathw = (WCHAR*) pos;
+    pos += r * sizeof(WCHAR);
+  } else {
+    req->file.pathw = NULL;
+  }
+
+  if (new_path != NULL) {
+    DWORD r = MultiByteToWideChar(CP_UTF8,
+                                  0,
+                                  new_path,
+                                  -1,
+                                  (WCHAR*) pos,
+                                  new_pathw_len);
+    assert(r == (DWORD) new_pathw_len);
+    req->fs.info.new_pathw = (WCHAR*) pos;
+    pos += r * sizeof(WCHAR);
+  } else {
+    req->fs.info.new_pathw = NULL;
+  }
+
+  req->path = path;
+  if (path != NULL && copy_path) {
+    memcpy(pos, path, path_len);
+    assert(path_len == buf_sz - (pos - buf));
+    req->path = pos;
+  }
+
+  req->flags |= UV_FS_FREE_PATHS;
+
+  return 0;
+}
+
+
+
+INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req,
+    uv_fs_type fs_type, const uv_fs_cb cb) {
+  uv_req_init(loop, (uv_req_t*) req);
+
+  req->type = UV_FS;
+  req->loop = loop;
+  req->flags = 0;
+  req->fs_type = fs_type;
+  req->result = 0;
+  req->ptr = NULL;
+  req->path = NULL;
+  req->cb = cb;
+  memset(&req->fs, 0, sizeof(req->fs));
+}
+
+
+static int fs__wide_to_utf8(WCHAR* w_source_ptr,
+                               DWORD w_source_len,
+                               char** target_ptr,
+                               uint64_t* target_len_ptr) {
+  int r;
+  int target_len;
+  char* target;
+  target_len = WideCharToMultiByte(CP_UTF8,
+                                   0,
+                                   w_source_ptr,
+                                   w_source_len,
+                                   NULL,
+                                   0,
+                                   NULL,
+                                   NULL);
+
+  if (target_len == 0) {
+    return -1;
+  }
+
+  if (target_len_ptr != NULL) {
+    *target_len_ptr = target_len;
+  }
+
+  if (target_ptr == NULL) {
+    return 0;
+  }
+
+  target = uv__malloc(target_len + 1);
+  if (target == NULL) {
+    SetLastError(ERROR_OUTOFMEMORY);
+    return -1;
+  }
+
+  r = WideCharToMultiByte(CP_UTF8,
+                          0,
+                          w_source_ptr,
+                          w_source_len,
+                          target,
+                          target_len,
+                          NULL,
+                          NULL);
+  assert(r == target_len);
+  target[target_len] = '\0';
+  *target_ptr = target;
+  return 0;
+}
+
+
+INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
+    uint64_t* target_len_ptr) {
+  char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
+  REPARSE_DATA_BUFFER* reparse_data = (REPARSE_DATA_BUFFER*) buffer;
+  WCHAR* w_target;
+  DWORD w_target_len;
+  DWORD bytes;
+
+  if (!DeviceIoControl(handle,
+                       FSCTL_GET_REPARSE_POINT,
+                       NULL,
+                       0,
+                       buffer,
+                       sizeof buffer,
+                       &bytes,
+                       NULL)) {
+    return -1;
+  }
+
+  if (reparse_data->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
+    /* Real symlink */
+    w_target = reparse_data->SymbolicLinkReparseBuffer.PathBuffer +
+        (reparse_data->SymbolicLinkReparseBuffer.SubstituteNameOffset /
+        sizeof(WCHAR));
+    w_target_len =
+        reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength /
+        sizeof(WCHAR);
+
+    /* Real symlinks can contain pretty much everything, but the only thing */
+    /* we really care about is undoing the implicit conversion to an NT */
+    /* namespaced path that CreateSymbolicLink will perform on absolute */
+    /* paths. If the path is win32-namespaced then the user must have */
+    /* explicitly made it so, and we better just return the unmodified */
+    /* reparse data. */
+    if (w_target_len >= 4 &&
+        w_target[0] == L'\\' &&
+        w_target[1] == L'?' &&
+        w_target[2] == L'?' &&
+        w_target[3] == L'\\') {
+      /* Starts with \??\ */
+      if (w_target_len >= 6 &&
+          ((w_target[4] >= L'A' && w_target[4] <= L'Z') ||
+           (w_target[4] >= L'a' && w_target[4] <= L'z')) &&
+          w_target[5] == L':' &&
+          (w_target_len == 6 || w_target[6] == L'\\')) {
+        /* \??\<drive>:\ */
+        w_target += 4;
+        w_target_len -= 4;
+
+      } else if (w_target_len >= 8 &&
+                 (w_target[4] == L'U' || w_target[4] == L'u') &&
+                 (w_target[5] == L'N' || w_target[5] == L'n') &&
+                 (w_target[6] == L'C' || w_target[6] == L'c') &&
+                 w_target[7] == L'\\') {
+        /* \??\UNC\<server>\<share>\ - make sure the final path looks like */
+        /* \\<server>\<share>\ */
+        w_target += 6;
+        w_target[0] = L'\\';
+        w_target_len -= 6;
+      }
+    }
+
+  } else if (reparse_data->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
+    /* Junction. */
+    w_target = reparse_data->MountPointReparseBuffer.PathBuffer +
+        (reparse_data->MountPointReparseBuffer.SubstituteNameOffset /
+        sizeof(WCHAR));
+    w_target_len = reparse_data->MountPointReparseBuffer.SubstituteNameLength /
+        sizeof(WCHAR);
+
+    /* Only treat junctions that look like \??\<drive>:\ as symlink. */
+    /* Junctions can also be used as mount points, like \??\Volume{<guid>}, */
+    /* but that's confusing for programs since they wouldn't be able to */
+    /* actually understand such a path when returned by uv_readlink(). */
+    /* UNC paths are never valid for junctions so we don't care about them. */
+    if (!(w_target_len >= 6 &&
+          w_target[0] == L'\\' &&
+          w_target[1] == L'?' &&
+          w_target[2] == L'?' &&
+          w_target[3] == L'\\' &&
+          ((w_target[4] >= L'A' && w_target[4] <= L'Z') ||
+           (w_target[4] >= L'a' && w_target[4] <= L'z')) &&
+          w_target[5] == L':' &&
+          (w_target_len == 6 || w_target[6] == L'\\'))) {
+      SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
+      return -1;
+    }
+
+    /* Remove leading \??\ */
+    w_target += 4;
+    w_target_len -= 4;
+
+  } else {
+    /* Reparse tag does not indicate a symlink. */
+    SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
+    return -1;
+  }
+
+  return fs__wide_to_utf8(w_target, w_target_len, target_ptr, target_len_ptr);
+}
+
+
+void fs__open(uv_fs_t* req) {
+  DWORD access;
+  DWORD share;
+  DWORD disposition;
+  DWORD attributes = 0;
+  HANDLE file;
+  int fd, current_umask;
+  int flags = req->fs.info.file_flags;
+
+  /* Obtain the active umask. umask() never fails and returns the previous */
+  /* umask. */
+  current_umask = umask(0);
+  umask(current_umask);
+
+  /* convert flags and mode to CreateFile parameters */
+  switch (flags & (_O_RDONLY | _O_WRONLY | _O_RDWR)) {
+  case _O_RDONLY:
+    access = FILE_GENERIC_READ;
+    break;
+  case _O_WRONLY:
+    access = FILE_GENERIC_WRITE;
+    break;
+  case _O_RDWR:
+    access = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
+    break;
+  default:
+    goto einval;
+  }
+
+  if (flags & _O_APPEND) {
+    access &= ~FILE_WRITE_DATA;
+    access |= FILE_APPEND_DATA;
+  }
+
+  /*
+   * Here is where we deviate significantly from what CRT's _open()
+   * does. We indiscriminately use all the sharing modes, to match
+   * UNIX semantics. In particular, this ensures that the file can
+   * be deleted even whilst it's open, fixing issue #1449.
+   */
+  share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+
+  switch (flags & (_O_CREAT | _O_EXCL | _O_TRUNC)) {
+  case 0:
+  case _O_EXCL:
+    disposition = OPEN_EXISTING;
+    break;
+  case _O_CREAT:
+    disposition = OPEN_ALWAYS;
+    break;
+  case _O_CREAT | _O_EXCL:
+  case _O_CREAT | _O_TRUNC | _O_EXCL:
+    disposition = CREATE_NEW;
+    break;
+  case _O_TRUNC:
+  case _O_TRUNC | _O_EXCL:
+    disposition = TRUNCATE_EXISTING;
+    break;
+  case _O_CREAT | _O_TRUNC:
+    disposition = CREATE_ALWAYS;
+    break;
+  default:
+    goto einval;
+  }
+
+  attributes |= FILE_ATTRIBUTE_NORMAL;
+  if (flags & _O_CREAT) {
+    if (!((req->fs.info.mode & ~current_umask) & _S_IWRITE)) {
+      attributes |= FILE_ATTRIBUTE_READONLY;
+    }
+  }
+
+  if (flags & _O_TEMPORARY ) {
+    attributes |= FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY;
+    access |= DELETE;
+  }
+
+  if (flags & _O_SHORT_LIVED) {
+    attributes |= FILE_ATTRIBUTE_TEMPORARY;
+  }
+
+  switch (flags & (_O_SEQUENTIAL | _O_RANDOM)) {
+  case 0:
+    break;
+  case _O_SEQUENTIAL:
+    attributes |= FILE_FLAG_SEQUENTIAL_SCAN;
+    break;
+  case _O_RANDOM:
+    attributes |= FILE_FLAG_RANDOM_ACCESS;
+    break;
+  default:
+    goto einval;
+  }
+
+  /* Setting this flag makes it possible to open a directory. */
+  attributes |= FILE_FLAG_BACKUP_SEMANTICS;
+
+  file = CreateFileW(req->file.pathw,
+                     access,
+                     share,
+                     NULL,
+                     disposition,
+                     attributes,
+                     NULL);
+  if (file == INVALID_HANDLE_VALUE) {
+    DWORD error = GetLastError();
+    if (error == ERROR_FILE_EXISTS && (flags & _O_CREAT) &&
+        !(flags & _O_EXCL)) {
+      /* Special case: when ERROR_FILE_EXISTS happens and O_CREAT was */
+      /* specified, it means the path referred to a directory. */
+      SET_REQ_UV_ERROR(req, UV_EISDIR, error);
+    } else {
+      SET_REQ_WIN32_ERROR(req, GetLastError());
+    }
+    return;
+  }
+
+  fd = _open_osfhandle((intptr_t) file, flags);
+  if (fd < 0) {
+    /* The only known failure mode for _open_osfhandle() is EMFILE, in which
+     * case GetLastError() will return zero. However we'll try to handle other
+     * errors as well, should they ever occur.
+     */
+    if (errno == EMFILE)
+      SET_REQ_UV_ERROR(req, UV_EMFILE, ERROR_TOO_MANY_OPEN_FILES);
+    else if (GetLastError() != ERROR_SUCCESS)
+      SET_REQ_WIN32_ERROR(req, GetLastError());
+    else
+      SET_REQ_WIN32_ERROR(req, UV_UNKNOWN);
+    CloseHandle(file);
+    return;
+  }
+
+  SET_REQ_RESULT(req, fd);
+  return;
+
+ einval:
+  SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
+}
+
+void fs__close(uv_fs_t* req) {
+  int fd = req->file.fd;
+  int result;
+
+  VERIFY_FD(fd, req);
+
+  if (fd > 2)
+    result = _close(fd);
+  else
+    result = 0;
+
+  /* _close doesn't set _doserrno on failure, but it does always set errno
+   * to EBADF on failure.
+   */
+  if (result == -1) {
+    assert(errno == EBADF);
+    SET_REQ_UV_ERROR(req, UV_EBADF, ERROR_INVALID_HANDLE);
+  } else {
+    req->result = 0;
+  }
+}
+
+
+void fs__read(uv_fs_t* req) {
+  int fd = req->file.fd;
+  int64_t offset = req->fs.info.offset;
+  HANDLE handle;
+  OVERLAPPED overlapped, *overlapped_ptr;
+  LARGE_INTEGER offset_;
+  DWORD bytes;
+  DWORD error;
+  int result;
+  unsigned int index;
+
+  VERIFY_FD(fd, req);
+
+  handle = uv__get_osfhandle(fd);
+
+  if (handle == INVALID_HANDLE_VALUE) {
+    SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
+    return;
+  }
+
+  if (offset != -1) {
+    memset(&overlapped, 0, sizeof overlapped);
+    overlapped_ptr = &overlapped;
+  } else {
+    overlapped_ptr = NULL;
+  }
+
+  index = 0;
+  bytes = 0;
+  do {
+    DWORD incremental_bytes;
+
+    if (offset != -1) {
+      offset_.QuadPart = offset + bytes;
+      overlapped.Offset = offset_.LowPart;
+      overlapped.OffsetHigh = offset_.HighPart;
+    }
+
+    result = ReadFile(handle,
+                      req->fs.info.bufs[index].base,
+                      req->fs.info.bufs[index].len,
+                      &incremental_bytes,
+                      overlapped_ptr);
+    bytes += incremental_bytes;
+    ++index;
+  } while (result && index < req->fs.info.nbufs);
+
+  if (result || bytes > 0) {
+    SET_REQ_RESULT(req, bytes);
+  } else {
+    error = GetLastError();
+    if (error == ERROR_HANDLE_EOF) {
+      SET_REQ_RESULT(req, bytes);
+    } else {
+      SET_REQ_WIN32_ERROR(req, error);
+    }
+  }
+}
+
+
+void fs__write(uv_fs_t* req) {
+  int fd = req->file.fd;
+  int64_t offset = req->fs.info.offset;
+  HANDLE handle;
+  OVERLAPPED overlapped, *overlapped_ptr;
+  LARGE_INTEGER offset_;
+  DWORD bytes;
+  int result;
+  unsigned int index;
+
+  VERIFY_FD(fd, req);
+
+  handle = uv__get_osfhandle(fd);
+  if (handle == INVALID_HANDLE_VALUE) {
+    SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
+    return;
+  }
+
+  if (offset != -1) {
+    memset(&overlapped, 0, sizeof overlapped);
+    overlapped_ptr = &overlapped;
+  } else {
+    overlapped_ptr = NULL;
+  }
+
+  index = 0;
+  bytes = 0;
+  do {
+    DWORD incremental_bytes;
+
+    if (offset != -1) {
+      offset_.QuadPart = offset + bytes;
+      overlapped.Offset = offset_.LowPart;
+      overlapped.OffsetHigh = offset_.HighPart;
+    }
+
+    result = WriteFile(handle,
+                       req->fs.info.bufs[index].base,
+                       req->fs.info.bufs[index].len,
+                       &incremental_bytes,
+                       overlapped_ptr);
+    bytes += incremental_bytes;
+    ++index;
+  } while (result && index < req->fs.info.nbufs);
+
+  if (result || bytes > 0) {
+    SET_REQ_RESULT(req, bytes);
+  } else {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+  }
+}
+
+
+void fs__rmdir(uv_fs_t* req) {
+  int result = _wrmdir(req->file.pathw);
+  SET_REQ_RESULT(req, result);
+}
+
+
+void fs__unlink(uv_fs_t* req) {
+  const WCHAR* pathw = req->file.pathw;
+  HANDLE handle;
+  BY_HANDLE_FILE_INFORMATION info;
+  FILE_DISPOSITION_INFORMATION disposition;
+  IO_STATUS_BLOCK iosb;
+  NTSTATUS status;
+
+  handle = CreateFileW(pathw,
+                       FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | DELETE,
+                       FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                       NULL,
+                       OPEN_EXISTING,
+                       FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
+                       NULL);
+
+  if (handle == INVALID_HANDLE_VALUE) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    return;
+  }
+
+  if (!GetFileInformationByHandle(handle, &info)) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    CloseHandle(handle);
+    return;
+  }
+
+  if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+    /* Do not allow deletion of directories, unless it is a symlink. When */
+    /* the path refers to a non-symlink directory, report EPERM as mandated */
+    /* by POSIX.1. */
+
+    /* Check if it is a reparse point. If it's not, it's a normal directory. */
+    if (!(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
+      SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED);
+      CloseHandle(handle);
+      return;
+    }
+
+    /* Read the reparse point and check if it is a valid symlink. */
+    /* If not, don't unlink. */
+    if (fs__readlink_handle(handle, NULL, NULL) < 0) {
+      DWORD error = GetLastError();
+      if (error == ERROR_SYMLINK_NOT_SUPPORTED)
+        error = ERROR_ACCESS_DENIED;
+      SET_REQ_WIN32_ERROR(req, error);
+      CloseHandle(handle);
+      return;
+    }
+  }
+
+  if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
+    /* Remove read-only attribute */
+    FILE_BASIC_INFORMATION basic = { 0 };
+
+    basic.FileAttributes = info.dwFileAttributes & ~(FILE_ATTRIBUTE_READONLY);
+
+    status = pNtSetInformationFile(handle,
+                                   &iosb,
+                                   &basic,
+                                   sizeof basic,
+                                   FileBasicInformation);
+    if (!NT_SUCCESS(status)) {
+      SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
+      CloseHandle(handle);
+      return;
+    }
+  }
+
+  /* Try to set the delete flag. */
+  disposition.DeleteFile = TRUE;
+  status = pNtSetInformationFile(handle,
+                                 &iosb,
+                                 &disposition,
+                                 sizeof disposition,
+                                 FileDispositionInformation);
+  if (NT_SUCCESS(status)) {
+    SET_REQ_SUCCESS(req);
+  } else {
+    SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
+  }
+
+  CloseHandle(handle);
+}
+
+
+void fs__mkdir(uv_fs_t* req) {
+  /* TODO: use req->mode. */
+  int result = _wmkdir(req->file.pathw);
+  SET_REQ_RESULT(req, result);
+}
+
+
+/* OpenBSD original: lib/libc/stdio/mktemp.c */
+void fs__mkdtemp(uv_fs_t* req) {
+  static const WCHAR *tempchars =
+    L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+  static const size_t num_chars = 62;
+  static const size_t num_x = 6;
+  WCHAR *cp, *ep;
+  unsigned int tries, i;
+  size_t len;
+  HCRYPTPROV h_crypt_prov;
+  uint64_t v;
+  BOOL released;
+
+  len = wcslen(req->file.pathw);
+  ep = req->file.pathw + len;
+  if (len < num_x || wcsncmp(ep - num_x, L"XXXXXX", num_x)) {
+    SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
+    return;
+  }
+
+  if (!CryptAcquireContext(&h_crypt_prov, NULL, NULL, PROV_RSA_FULL,
+                           CRYPT_VERIFYCONTEXT)) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    return;
+  }
+
+  tries = TMP_MAX;
+  do {
+    if (!CryptGenRandom(h_crypt_prov, sizeof(v), (BYTE*) &v)) {
+      SET_REQ_WIN32_ERROR(req, GetLastError());
+      break;
+    }
+
+    cp = ep - num_x;
+    for (i = 0; i < num_x; i++) {
+      *cp++ = tempchars[v % num_chars];
+      v /= num_chars;
+    }
+
+    if (_wmkdir(req->file.pathw) == 0) {
+      len = strlen(req->path);
+      wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
+      SET_REQ_RESULT(req, 0);
+      break;
+    } else if (errno != EEXIST) {
+      SET_REQ_RESULT(req, -1);
+      break;
+    }
+  } while (--tries);
+
+  released = CryptReleaseContext(h_crypt_prov, 0);
+  assert(released);
+  if (tries == 0) {
+    SET_REQ_RESULT(req, -1);
+  }
+}
+
+
+void fs__scandir(uv_fs_t* req) {
+  static const size_t dirents_initial_size = 32;
+
+  HANDLE dir_handle = INVALID_HANDLE_VALUE;
+
+  uv__dirent_t** dirents = NULL;
+  size_t dirents_size = 0;
+  size_t dirents_used = 0;
+
+  IO_STATUS_BLOCK iosb;
+  NTSTATUS status;
+
+  /* Buffer to hold directory entries returned by NtQueryDirectoryFile.
+   * It's important that this buffer can hold at least one entry, regardless
+   * of the length of the file names present in the enumerated directory.
+   * A file name is at most 256 WCHARs long.
+   * According to MSDN, the buffer must be aligned at an 8-byte boundary.
+   */
+#if _MSC_VER
+  __declspec(align(8)) char buffer[8192];
+#else
+  __attribute__ ((aligned (8))) char buffer[8192];
+#endif
+
+  STATIC_ASSERT(sizeof buffer >=
+                sizeof(FILE_DIRECTORY_INFORMATION) + 256 * sizeof(WCHAR));
+
+  /* Open the directory. */
+  dir_handle =
+      CreateFileW(req->file.pathw,
+                  FILE_LIST_DIRECTORY | SYNCHRONIZE,
+                  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                  NULL,
+                  OPEN_EXISTING,
+                  FILE_FLAG_BACKUP_SEMANTICS,
+                  NULL);
+  if (dir_handle == INVALID_HANDLE_VALUE)
+    goto win32_error;
+
+  /* Read the first chunk. */
+  status = pNtQueryDirectoryFile(dir_handle,
+                                 NULL,
+                                 NULL,
+                                 NULL,
+                                 &iosb,
+                                 &buffer,
+                                 sizeof buffer,
+                                 FileDirectoryInformation,
+                                 FALSE,
+                                 NULL,
+                                 TRUE);
+
+  /* If the handle is not a directory, we'll get STATUS_INVALID_PARAMETER.
+   * This should be reported back as UV_ENOTDIR.
+   */
+  if (status == STATUS_INVALID_PARAMETER)
+    goto not_a_directory_error;
+
+  while (NT_SUCCESS(status)) {
+    char* position = buffer;
+    size_t next_entry_offset = 0;
+
+    do {
+      FILE_DIRECTORY_INFORMATION* info;
+      uv__dirent_t* dirent;
+
+      size_t wchar_len;
+      size_t utf8_len;
+
+      /* Obtain a pointer to the current directory entry. */
+      position += next_entry_offset;
+      info = (FILE_DIRECTORY_INFORMATION*) position;
+
+      /* Fetch the offset to the next directory entry. */
+      next_entry_offset = info->NextEntryOffset;
+
+      /* Compute the length of the filename in WCHARs. */
+      wchar_len = info->FileNameLength / sizeof info->FileName[0];
+
+      /* Skip over '.' and '..' entries.  It has been reported that
+       * the SharePoint driver includes the terminating zero byte in
+       * the filename length.  Strip those first.
+       */
+      while (wchar_len > 0 && info->FileName[wchar_len - 1] == L'\0')
+        wchar_len -= 1;
+
+      if (wchar_len == 0)
+        continue;
+      if (wchar_len == 1 && info->FileName[0] == L'.')
+        continue;
+      if (wchar_len == 2 && info->FileName[0] == L'.' &&
+          info->FileName[1] == L'.')
+        continue;
+
+      /* Compute the space required to store the filename as UTF-8. */
+      utf8_len = WideCharToMultiByte(
+          CP_UTF8, 0, &info->FileName[0], wchar_len, NULL, 0, NULL, NULL);
+      if (utf8_len == 0)
+        goto win32_error;
+
+      /* Resize the dirent array if needed. */
+      if (dirents_used >= dirents_size) {
+        size_t new_dirents_size =
+            dirents_size == 0 ? dirents_initial_size : dirents_size << 1;
+        uv__dirent_t** new_dirents =
+            uv__realloc(dirents, new_dirents_size * sizeof *dirents);
+
+        if (new_dirents == NULL)
+          goto out_of_memory_error;
+
+        dirents_size = new_dirents_size;
+        dirents = new_dirents;
+      }
+
+      /* Allocate space for the uv dirent structure. The dirent structure
+       * includes room for the first character of the filename, but `utf8_len`
+       * doesn't count the NULL terminator at this point.
+       */
+      dirent = uv__malloc(sizeof *dirent + utf8_len);
+      if (dirent == NULL)
+        goto out_of_memory_error;
+
+      dirents[dirents_used++] = dirent;
+
+      /* Convert file name to UTF-8. */
+      if (WideCharToMultiByte(CP_UTF8,
+                              0,
+                              &info->FileName[0],
+                              wchar_len,
+                              &dirent->d_name[0],
+                              utf8_len,
+                              NULL,
+                              NULL) == 0)
+        goto win32_error;
+
+      /* Add a null terminator to the filename. */
+      dirent->d_name[utf8_len] = '\0';
+
+      /* Fill out the type field. */
+      if (info->FileAttributes & FILE_ATTRIBUTE_DEVICE)
+        dirent->d_type = UV__DT_CHAR;
+      else if (info->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
+        dirent->d_type = UV__DT_LINK;
+      else if (info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+        dirent->d_type = UV__DT_DIR;
+      else
+        dirent->d_type = UV__DT_FILE;
+    } while (next_entry_offset != 0);
+
+    /* Read the next chunk. */
+    status = pNtQueryDirectoryFile(dir_handle,
+                                   NULL,
+                                   NULL,
+                                   NULL,
+                                   &iosb,
+                                   &buffer,
+                                   sizeof buffer,
+                                   FileDirectoryInformation,
+                                   FALSE,
+                                   NULL,
+                                   FALSE);
+
+    /* After the first pNtQueryDirectoryFile call, the function may return
+     * STATUS_SUCCESS even if the buffer was too small to hold at least one
+     * directory entry.
+     */
+    if (status == STATUS_SUCCESS && iosb.Information == 0)
+      status = STATUS_BUFFER_OVERFLOW;
+  }
+
+  if (status != STATUS_NO_MORE_FILES)
+    goto nt_error;
+
+  CloseHandle(dir_handle);
+
+  /* Store the result in the request object. */
+  req->ptr = dirents;
+  if (dirents != NULL)
+    req->flags |= UV_FS_FREE_PTR;
+
+  SET_REQ_RESULT(req, dirents_used);
+
+  /* `nbufs` will be used as index by uv_fs_scandir_next. */
+  req->fs.info.nbufs = 0;
+
+  return;
+
+nt_error:
+  SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
+  goto cleanup;
+
+win32_error:
+  SET_REQ_WIN32_ERROR(req, GetLastError());
+  goto cleanup;
+
+not_a_directory_error:
+  SET_REQ_UV_ERROR(req, UV_ENOTDIR, ERROR_DIRECTORY);
+  goto cleanup;
+
+out_of_memory_error:
+  SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
+  goto cleanup;
+
+cleanup:
+  if (dir_handle != INVALID_HANDLE_VALUE)
+    CloseHandle(dir_handle);
+  while (dirents_used > 0)
+    uv__free(dirents[--dirents_used]);
+  if (dirents != NULL)
+    uv__free(dirents);
+}
+
+
+INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf) {
+  FILE_ALL_INFORMATION file_info;
+  FILE_FS_VOLUME_INFORMATION volume_info;
+  NTSTATUS nt_status;
+  IO_STATUS_BLOCK io_status;
+
+  nt_status = pNtQueryInformationFile(handle,
+                                      &io_status,
+                                      &file_info,
+                                      sizeof file_info,
+                                      FileAllInformation);
+
+  /* Buffer overflow (a warning status code) is expected here. */
+  if (NT_ERROR(nt_status)) {
+    SetLastError(pRtlNtStatusToDosError(nt_status));
+    return -1;
+  }
+
+  nt_status = pNtQueryVolumeInformationFile(handle,
+                                            &io_status,
+                                            &volume_info,
+                                            sizeof volume_info,
+                                            FileFsVolumeInformation);
+
+  /* Buffer overflow (a warning status code) is expected here. */
+  if (io_status.Status == STATUS_NOT_IMPLEMENTED) {
+    statbuf->st_dev = 0;
+  } else if (NT_ERROR(nt_status)) {
+    SetLastError(pRtlNtStatusToDosError(nt_status));
+    return -1;
+  } else {
+    statbuf->st_dev = volume_info.VolumeSerialNumber;
+  }
+
+  /* Todo: st_mode should probably always be 0666 for everyone. We might also
+   * want to report 0777 if the file is a .exe or a directory.
+   *
+   * Currently it's based on whether the 'readonly' attribute is set, which
+   * makes little sense because the semantics are so different: the 'read-only'
+   * flag is just a way for a user to protect against accidental deletion, and
+   * serves no security purpose. Windows uses ACLs for that.
+   *
+   * Also people now use uv_fs_chmod() to take away the writable bit for good
+   * reasons. Windows however just makes the file read-only, which makes it
+   * impossible to delete the file afterwards, since read-only files can't be
+   * deleted.
+   *
+   * IOW it's all just a clusterfuck and we should think of something that
+   * makes slightly more sense.
+   *
+   * And uv_fs_chmod should probably just fail on windows or be a total no-op.
+   * There's nothing sensible it can do anyway.
+   */
+  statbuf->st_mode = 0;
+
+  if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+    /*
+     * It is possible for a file to have FILE_ATTRIBUTE_REPARSE_POINT but not have
+     * any link data. In that case DeviceIoControl() in fs__readlink_handle() sets
+     * the last error to ERROR_NOT_A_REPARSE_POINT. Then the stat result mode
+     * calculated below will indicate a normal directory or file, as if
+     * FILE_ATTRIBUTE_REPARSE_POINT was not present.
+     */
+    if (fs__readlink_handle(handle, NULL, &statbuf->st_size) == 0) {
+      statbuf->st_mode |= S_IFLNK;
+    } else if (GetLastError() != ERROR_NOT_A_REPARSE_POINT) {
+      return -1;
+    }
+  }
+
+  if (statbuf->st_mode == 0) {
+    if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+      statbuf->st_mode |= _S_IFDIR;
+      statbuf->st_size = 0;
+    } else {
+      statbuf->st_mode |= _S_IFREG;
+      statbuf->st_size = file_info.StandardInformation.EndOfFile.QuadPart;
+    }
+  }
+
+  if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_READONLY)
+    statbuf->st_mode |= _S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6);
+  else
+    statbuf->st_mode |= (_S_IREAD | _S_IWRITE) | ((_S_IREAD | _S_IWRITE) >> 3) |
+                        ((_S_IREAD | _S_IWRITE) >> 6);
+
+  FILETIME_TO_TIMESPEC(statbuf->st_atim, file_info.BasicInformation.LastAccessTime);
+  FILETIME_TO_TIMESPEC(statbuf->st_ctim, file_info.BasicInformation.ChangeTime);
+  FILETIME_TO_TIMESPEC(statbuf->st_mtim, file_info.BasicInformation.LastWriteTime);
+  FILETIME_TO_TIMESPEC(statbuf->st_birthtim, file_info.BasicInformation.CreationTime);
+
+  statbuf->st_ino = file_info.InternalInformation.IndexNumber.QuadPart;
+
+  /* st_blocks contains the on-disk allocation size in 512-byte units. */
+  statbuf->st_blocks =
+      file_info.StandardInformation.AllocationSize.QuadPart >> 9ULL;
+
+  statbuf->st_nlink = file_info.StandardInformation.NumberOfLinks;
+
+  /* The st_blksize is supposed to be the 'optimal' number of bytes for reading
+   * and writing to the disk. That is, for any definition of 'optimal' - it's
+   * supposed to at least avoid read-update-write behavior when writing to the
+   * disk.
+   *
+   * However nobody knows this and even fewer people actually use this value,
+   * and in order to fill it out we'd have to make another syscall to query the
+   * volume for FILE_FS_SECTOR_SIZE_INFORMATION.
+   *
+   * Therefore we'll just report a sensible value that's quite commonly okay
+   * on modern hardware.
+   */
+  statbuf->st_blksize = 2048;
+
+  /* Todo: set st_flags to something meaningful. Also provide a wrapper for
+   * chattr(2).
+   */
+  statbuf->st_flags = 0;
+
+  /* Windows has nothing sensible to say about these values, so they'll just
+   * remain empty.
+   */
+  statbuf->st_gid = 0;
+  statbuf->st_uid = 0;
+  statbuf->st_rdev = 0;
+  statbuf->st_gen = 0;
+
+  return 0;
+}
+
+
+INLINE static void fs__stat_prepare_path(WCHAR* pathw) {
+  size_t len = wcslen(pathw);
+
+  /* TODO: ignore namespaced paths. */
+  if (len > 1 && pathw[len - 2] != L':' &&
+      (pathw[len - 1] == L'\\' || pathw[len - 1] == L'/')) {
+    pathw[len - 1] = '\0';
+  }
+}
+
+
+INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
+  HANDLE handle;
+  DWORD flags;
+
+  flags = FILE_FLAG_BACKUP_SEMANTICS;
+  if (do_lstat) {
+    flags |= FILE_FLAG_OPEN_REPARSE_POINT;
+  }
+
+  handle = CreateFileW(req->file.pathw,
+                       FILE_READ_ATTRIBUTES,
+                       FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                       NULL,
+                       OPEN_EXISTING,
+                       flags,
+                       NULL);
+  if (handle == INVALID_HANDLE_VALUE) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    return;
+  }
+
+  if (fs__stat_handle(handle, &req->statbuf) != 0) {
+    DWORD error = GetLastError();
+    if (do_lstat && error == ERROR_SYMLINK_NOT_SUPPORTED) {
+      /* We opened a reparse point but it was not a symlink. Try again. */
+      fs__stat_impl(req, 0);
+
+    } else {
+      /* Stat failed. */
+      SET_REQ_WIN32_ERROR(req, GetLastError());
+    }
+
+    CloseHandle(handle);
+    return;
+  }
+
+  req->ptr = &req->statbuf;
+  req->result = 0;
+  CloseHandle(handle);
+}
+
+
+static void fs__stat(uv_fs_t* req) {
+  fs__stat_prepare_path(req->file.pathw);
+  fs__stat_impl(req, 0);
+}
+
+
+static void fs__lstat(uv_fs_t* req) {
+  fs__stat_prepare_path(req->file.pathw);
+  fs__stat_impl(req, 1);
+}
+
+
+static void fs__fstat(uv_fs_t* req) {
+  int fd = req->file.fd;
+  HANDLE handle;
+
+  VERIFY_FD(fd, req);
+
+  handle = uv__get_osfhandle(fd);
+
+  if (handle == INVALID_HANDLE_VALUE) {
+    SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
+    return;
+  }
+
+  if (fs__stat_handle(handle, &req->statbuf) != 0) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    return;
+  }
+
+  req->ptr = &req->statbuf;
+  req->result = 0;
+}
+
+
+static void fs__rename(uv_fs_t* req) {
+  if (!MoveFileExW(req->file.pathw, req->fs.info.new_pathw, MOVEFILE_REPLACE_EXISTING)) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    return;
+  }
+
+  SET_REQ_RESULT(req, 0);
+}
+
+
+INLINE static void fs__sync_impl(uv_fs_t* req) {
+  int fd = req->file.fd;
+  int result;
+
+  VERIFY_FD(fd, req);
+
+  result = FlushFileBuffers(uv__get_osfhandle(fd)) ? 0 : -1;
+  if (result == -1) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+  } else {
+    SET_REQ_RESULT(req, result);
+  }
+}
+
+
+static void fs__fsync(uv_fs_t* req) {
+  fs__sync_impl(req);
+}
+
+
+static void fs__fdatasync(uv_fs_t* req) {
+  fs__sync_impl(req);
+}
+
+
+static void fs__ftruncate(uv_fs_t* req) {
+  int fd = req->file.fd;
+  HANDLE handle;
+  NTSTATUS status;
+  IO_STATUS_BLOCK io_status;
+  FILE_END_OF_FILE_INFORMATION eof_info;
+
+  VERIFY_FD(fd, req);
+
+  handle = uv__get_osfhandle(fd);
+
+  eof_info.EndOfFile.QuadPart = req->fs.info.offset;
+
+  status = pNtSetInformationFile(handle,
+                                 &io_status,
+                                 &eof_info,
+                                 sizeof eof_info,
+                                 FileEndOfFileInformation);
+
+  if (NT_SUCCESS(status)) {
+    SET_REQ_RESULT(req, 0);
+  } else {
+    SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
+  }
+}
+
+
+static void fs__sendfile(uv_fs_t* req) {
+  int fd_in = req->file.fd, fd_out = req->fs.info.fd_out;
+  size_t length = req->fs.info.bufsml[0].len;
+  int64_t offset = req->fs.info.offset;
+  const size_t max_buf_size = 65536;
+  size_t buf_size = length < max_buf_size ? length : max_buf_size;
+  int n, result = 0;
+  int64_t result_offset = 0;
+  char* buf = (char*) uv__malloc(buf_size);
+  if (!buf) {
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+  }
+
+  if (offset != -1) {
+    result_offset = _lseeki64(fd_in, offset, SEEK_SET);
+  }
+
+  if (result_offset == -1) {
+    result = -1;
+  } else {
+    while (length > 0) {
+      n = _read(fd_in, buf, length < buf_size ? length : buf_size);
+      if (n == 0) {
+        break;
+      } else if (n == -1) {
+        result = -1;
+        break;
+      }
+
+      length -= n;
+
+      n = _write(fd_out, buf, n);
+      if (n == -1) {
+        result = -1;
+        break;
+      }
+
+      result += n;
+    }
+  }
+
+  uv__free(buf);
+
+  SET_REQ_RESULT(req, result);
+}
+
+
+static void fs__access(uv_fs_t* req) {
+  DWORD attr = GetFileAttributesW(req->file.pathw);
+
+  if (attr == INVALID_FILE_ATTRIBUTES) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    return;
+  }
+
+  /*
+   * Access is possible if
+   * - write access wasn't requested,
+   * - or the file isn't read-only,
+   * - or it's a directory.
+   * (Directories cannot be read-only on Windows.)
+   */
+  if (!(req->flags & W_OK) ||
+      !(attr & FILE_ATTRIBUTE_READONLY) ||
+      (attr & FILE_ATTRIBUTE_DIRECTORY)) {
+    SET_REQ_RESULT(req, 0);
+  } else {
+    SET_REQ_WIN32_ERROR(req, UV_EPERM);
+  }
+
+}
+
+
+static void fs__chmod(uv_fs_t* req) {
+  int result = _wchmod(req->file.pathw, req->fs.info.mode);
+  SET_REQ_RESULT(req, result);
+}
+
+
+static void fs__fchmod(uv_fs_t* req) {
+  int fd = req->file.fd;
+  HANDLE handle;
+  NTSTATUS nt_status;
+  IO_STATUS_BLOCK io_status;
+  FILE_BASIC_INFORMATION file_info;
+
+  VERIFY_FD(fd, req);
+
+  handle = uv__get_osfhandle(fd);
+
+  nt_status = pNtQueryInformationFile(handle,
+                                      &io_status,
+                                      &file_info,
+                                      sizeof file_info,
+                                      FileBasicInformation);
+
+  if (!NT_SUCCESS(nt_status)) {
+    SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status));
+    return;
+  }
+
+  if (req->fs.info.mode & _S_IWRITE) {
+    file_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
+  } else {
+    file_info.FileAttributes |= FILE_ATTRIBUTE_READONLY;
+  }
+
+  nt_status = pNtSetInformationFile(handle,
+                                    &io_status,
+                                    &file_info,
+                                    sizeof file_info,
+                                    FileBasicInformation);
+
+  if (!NT_SUCCESS(nt_status)) {
+    SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status));
+    return;
+  }
+
+  SET_REQ_SUCCESS(req);
+}
+
+
+INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) {
+  FILETIME filetime_a, filetime_m;
+
+  TIME_T_TO_FILETIME(atime, &filetime_a);
+  TIME_T_TO_FILETIME(mtime, &filetime_m);
+
+  if (!SetFileTime(handle, NULL, &filetime_a, &filetime_m)) {
+    return -1;
+  }
+
+  return 0;
+}
+
+
+static void fs__utime(uv_fs_t* req) {
+  HANDLE handle;
+
+  handle = CreateFileW(req->file.pathw,
+                       FILE_WRITE_ATTRIBUTES,
+                       FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                       NULL,
+                       OPEN_EXISTING,
+                       FILE_FLAG_BACKUP_SEMANTICS,
+                       NULL);
+
+  if (handle == INVALID_HANDLE_VALUE) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    return;
+  }
+
+  if (fs__utime_handle(handle, req->fs.time.atime, req->fs.time.mtime) != 0) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    CloseHandle(handle);
+    return;
+  }
+
+  CloseHandle(handle);
+
+  req->result = 0;
+}
+
+
+static void fs__futime(uv_fs_t* req) {
+  int fd = req->file.fd;
+  HANDLE handle;
+  VERIFY_FD(fd, req);
+
+  handle = uv__get_osfhandle(fd);
+
+  if (handle == INVALID_HANDLE_VALUE) {
+    SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
+    return;
+  }
+
+  if (fs__utime_handle(handle, req->fs.time.atime, req->fs.time.mtime) != 0) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    return;
+  }
+
+  req->result = 0;
+}
+
+
+static void fs__link(uv_fs_t* req) {
+  DWORD r = CreateHardLinkW(req->fs.info.new_pathw, req->file.pathw, NULL);
+  if (r == 0) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+  } else {
+    req->result = 0;
+  }
+}
+
+
+static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
+    const WCHAR* new_path) {
+  HANDLE handle = INVALID_HANDLE_VALUE;
+  REPARSE_DATA_BUFFER *buffer = NULL;
+  int created = 0;
+  int target_len;
+  int is_absolute, is_long_path;
+  int needed_buf_size, used_buf_size, used_data_size, path_buf_len;
+  int start, len, i;
+  int add_slash;
+  DWORD bytes;
+  WCHAR* path_buf;
+
+  target_len = wcslen(path);
+  is_long_path = wcsncmp(path, LONG_PATH_PREFIX, LONG_PATH_PREFIX_LEN) == 0;
+
+  if (is_long_path) {
+    is_absolute = 1;
+  } else {
+    is_absolute = target_len >= 3 && IS_LETTER(path[0]) &&
+      path[1] == L':' && IS_SLASH(path[2]);
+  }
+
+  if (!is_absolute) {
+    /* Not supporting relative paths */
+    SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_NOT_SUPPORTED);
+    return;
+  }
+
+  /* Do a pessimistic calculation of the required buffer size */
+  needed_buf_size =
+      FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) +
+      JUNCTION_PREFIX_LEN * sizeof(WCHAR) +
+      2 * (target_len + 2) * sizeof(WCHAR);
+
+  /* Allocate the buffer */
+  buffer = (REPARSE_DATA_BUFFER*)uv__malloc(needed_buf_size);
+  if (!buffer) {
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+  }
+
+  /* Grab a pointer to the part of the buffer where filenames go */
+  path_buf = (WCHAR*)&(buffer->MountPointReparseBuffer.PathBuffer);
+  path_buf_len = 0;
+
+  /* Copy the substitute (internal) target path */
+  start = path_buf_len;
+
+  wcsncpy((WCHAR*)&path_buf[path_buf_len], JUNCTION_PREFIX,
+    JUNCTION_PREFIX_LEN);
+  path_buf_len += JUNCTION_PREFIX_LEN;
+
+  add_slash = 0;
+  for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) {
+    if (IS_SLASH(path[i])) {
+      add_slash = 1;
+      continue;
+    }
+
+    if (add_slash) {
+      path_buf[path_buf_len++] = L'\\';
+      add_slash = 0;
+    }
+
+    path_buf[path_buf_len++] = path[i];
+  }
+  path_buf[path_buf_len++] = L'\\';
+  len = path_buf_len - start;
+
+  /* Set the info about the substitute name */
+  buffer->MountPointReparseBuffer.SubstituteNameOffset = start * sizeof(WCHAR);
+  buffer->MountPointReparseBuffer.SubstituteNameLength = len * sizeof(WCHAR);
+
+  /* Insert null terminator */
+  path_buf[path_buf_len++] = L'\0';
+
+  /* Copy the print name of the target path */
+  start = path_buf_len;
+  add_slash = 0;
+  for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) {
+    if (IS_SLASH(path[i])) {
+      add_slash = 1;
+      continue;
+    }
+
+    if (add_slash) {
+      path_buf[path_buf_len++] = L'\\';
+      add_slash = 0;
+    }
+
+    path_buf[path_buf_len++] = path[i];
+  }
+  len = path_buf_len - start;
+  if (len == 2) {
+    path_buf[path_buf_len++] = L'\\';
+    len++;
+  }
+
+  /* Set the info about the print name */
+  buffer->MountPointReparseBuffer.PrintNameOffset = start * sizeof(WCHAR);
+  buffer->MountPointReparseBuffer.PrintNameLength = len * sizeof(WCHAR);
+
+  /* Insert another null terminator */
+  path_buf[path_buf_len++] = L'\0';
+
+  /* Calculate how much buffer space was actually used */
+  used_buf_size = FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) +
+    path_buf_len * sizeof(WCHAR);
+  used_data_size = used_buf_size -
+    FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer);
+
+  /* Put general info in the data buffer */
+  buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
+  buffer->ReparseDataLength = used_data_size;
+  buffer->Reserved = 0;
+
+  /* Create a new directory */
+  if (!CreateDirectoryW(new_path, NULL)) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    goto error;
+  }
+  created = 1;
+
+  /* Open the directory */
+  handle = CreateFileW(new_path,
+                       GENERIC_WRITE,
+                       0,
+                       NULL,
+                       OPEN_EXISTING,
+                       FILE_FLAG_BACKUP_SEMANTICS |
+                         FILE_FLAG_OPEN_REPARSE_POINT,
+                       NULL);
+  if (handle == INVALID_HANDLE_VALUE) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    goto error;
+  }
+
+  /* Create the actual reparse point */
+  if (!DeviceIoControl(handle,
+                       FSCTL_SET_REPARSE_POINT,
+                       buffer,
+                       used_buf_size,
+                       NULL,
+                       0,
+                       &bytes,
+                       NULL)) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    goto error;
+  }
+
+  /* Clean up */
+  CloseHandle(handle);
+  uv__free(buffer);
+
+  SET_REQ_RESULT(req, 0);
+  return;
+
+error:
+  uv__free(buffer);
+
+  if (handle != INVALID_HANDLE_VALUE) {
+    CloseHandle(handle);
+  }
+
+  if (created) {
+    RemoveDirectoryW(new_path);
+  }
+}
+
+
+static void fs__symlink(uv_fs_t* req) {
+  WCHAR* pathw = req->file.pathw;
+  WCHAR* new_pathw = req->fs.info.new_pathw;
+  int flags = req->fs.info.file_flags;
+  int result;
+
+
+  if (flags & UV_FS_SYMLINK_JUNCTION) {
+    fs__create_junction(req, pathw, new_pathw);
+  } else if (pCreateSymbolicLinkW) {
+    result = pCreateSymbolicLinkW(new_pathw,
+                                  pathw,
+                                  flags & UV_FS_SYMLINK_DIR ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) ? 0 : -1;
+    if (result == -1) {
+      SET_REQ_WIN32_ERROR(req, GetLastError());
+    } else {
+      SET_REQ_RESULT(req, result);
+    }
+  } else {
+    SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED);
+  }
+}
+
+
+static void fs__readlink(uv_fs_t* req) {
+  HANDLE handle;
+
+  handle = CreateFileW(req->file.pathw,
+                       0,
+                       0,
+                       NULL,
+                       OPEN_EXISTING,
+                       FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
+                       NULL);
+
+  if (handle == INVALID_HANDLE_VALUE) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    return;
+  }
+
+  if (fs__readlink_handle(handle, (char**) &req->ptr, NULL) != 0) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    CloseHandle(handle);
+    return;
+  }
+
+  req->flags |= UV_FS_FREE_PTR;
+  SET_REQ_RESULT(req, 0);
+
+  CloseHandle(handle);
+}
+
+
+static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
+  int r;
+  DWORD w_realpath_len;
+  WCHAR* w_realpath_ptr = NULL;
+  WCHAR* w_realpath_buf;
+
+  w_realpath_len = pGetFinalPathNameByHandleW(handle, NULL, 0, VOLUME_NAME_DOS);
+  if (w_realpath_len == 0) {
+    return -1;
+  }
+
+  w_realpath_buf = uv__malloc((w_realpath_len + 1) * sizeof(WCHAR));
+  if (w_realpath_buf == NULL) {
+    SetLastError(ERROR_OUTOFMEMORY);
+    return -1;
+  }
+  w_realpath_ptr = w_realpath_buf;
+
+  if (pGetFinalPathNameByHandleW(handle,
+                                w_realpath_ptr,
+                                w_realpath_len,
+                                VOLUME_NAME_DOS) == 0) {
+    uv__free(w_realpath_buf);
+    SetLastError(ERROR_INVALID_HANDLE);
+    return -1;
+  }
+
+  /* convert UNC path to long path */
+  if (wcsncmp(w_realpath_ptr,
+              UNC_PATH_PREFIX,
+              UNC_PATH_PREFIX_LEN) == 0) {
+    w_realpath_ptr += 6;
+    *w_realpath_ptr = L'\\';
+    w_realpath_len -= 6;
+  } else if (wcsncmp(w_realpath_ptr,
+                      LONG_PATH_PREFIX,
+                      LONG_PATH_PREFIX_LEN) == 0) {
+    w_realpath_ptr += 4;
+    w_realpath_len -= 4;
+  } else {
+    uv__free(w_realpath_buf);
+    SetLastError(ERROR_INVALID_HANDLE);
+    return -1;
+  }
+
+  r = fs__wide_to_utf8(w_realpath_ptr, w_realpath_len, realpath_ptr, NULL);
+  uv__free(w_realpath_buf);
+  return r;
+}
+
+static void fs__realpath(uv_fs_t* req) {
+  HANDLE handle;
+
+  if (!pGetFinalPathNameByHandleW) {
+    SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED);
+    return;
+  }
+
+  handle = CreateFileW(req->file.pathw,
+                       0,
+                       0,
+                       NULL,
+                       OPEN_EXISTING,
+                       FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
+                       NULL);
+  if (handle == INVALID_HANDLE_VALUE) {
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    return;
+  }
+
+  if (fs__realpath_handle(handle, (char**) &req->ptr) == -1) {
+    CloseHandle(handle);
+    SET_REQ_WIN32_ERROR(req, GetLastError());
+    return;
+  }
+
+  CloseHandle(handle);
+  req->flags |= UV_FS_FREE_PTR;
+  SET_REQ_RESULT(req, 0);
+}
+
+
+static void fs__chown(uv_fs_t* req) {
+  req->result = 0;
+}
+
+
+static void fs__fchown(uv_fs_t* req) {
+  req->result = 0;
+}
+
+
+static void uv__fs_work(struct uv__work* w) {
+  uv_fs_t* req;
+
+  req = container_of(w, uv_fs_t, work_req);
+  assert(req->type == UV_FS);
+
+#define XX(uc, lc)  case UV_FS_##uc: fs__##lc(req); break;
+  switch (req->fs_type) {
+    XX(OPEN, open)
+    XX(CLOSE, close)
+    XX(READ, read)
+    XX(WRITE, write)
+    XX(SENDFILE, sendfile)
+    XX(STAT, stat)
+    XX(LSTAT, lstat)
+    XX(FSTAT, fstat)
+    XX(FTRUNCATE, ftruncate)
+    XX(UTIME, utime)
+    XX(FUTIME, futime)
+    XX(ACCESS, access)
+    XX(CHMOD, chmod)
+    XX(FCHMOD, fchmod)
+    XX(FSYNC, fsync)
+    XX(FDATASYNC, fdatasync)
+    XX(UNLINK, unlink)
+    XX(RMDIR, rmdir)
+    XX(MKDIR, mkdir)
+    XX(MKDTEMP, mkdtemp)
+    XX(RENAME, rename)
+    XX(SCANDIR, scandir)
+    XX(LINK, link)
+    XX(SYMLINK, symlink)
+    XX(READLINK, readlink)
+    XX(REALPATH, realpath)
+    XX(CHOWN, chown)
+    XX(FCHOWN, fchown);
+    default:
+      assert(!"bad uv_fs_type");
+  }
+}
+
+
+static void uv__fs_done(struct uv__work* w, int status) {
+  uv_fs_t* req;
+
+  req = container_of(w, uv_fs_t, work_req);
+  uv__req_unregister(req->loop, req);
+
+  if (status == UV_ECANCELED) {
+    assert(req->result == 0);
+    req->result = UV_ECANCELED;
+  }
+
+  req->cb(req);
+}
+
+
+void uv_fs_req_cleanup(uv_fs_t* req) {
+  if (req->flags & UV_FS_CLEANEDUP)
+    return;
+
+  if (req->flags & UV_FS_FREE_PATHS)
+    uv__free(req->file.pathw);
+
+  if (req->flags & UV_FS_FREE_PTR) {
+    if (req->fs_type == UV_FS_SCANDIR && req->ptr != NULL)
+      uv__fs_scandir_cleanup(req);
+    else
+      uv__free(req->ptr);
+  }
+
+  if (req->fs.info.bufs != req->fs.info.bufsml)
+    uv__free(req->fs.info.bufs);
+
+  req->path = NULL;
+  req->file.pathw = NULL;
+  req->fs.info.new_pathw = NULL;
+  req->fs.info.bufs = NULL;
+  req->ptr = NULL;
+
+  req->flags |= UV_FS_CLEANEDUP;
+}
+
+
+int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
+    int mode, uv_fs_cb cb) {
+  int err;
+
+  uv_fs_req_init(loop, req, UV_FS_OPEN, cb);
+
+  err = fs__capture_path(req, path, NULL, cb != NULL);
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  req->fs.info.file_flags = flags;
+  req->fs.info.mode = mode;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__open(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
+  uv_fs_req_init(loop, req, UV_FS_CLOSE, cb);
+  req->file.fd = fd;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__close(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_read(uv_loop_t* loop,
+               uv_fs_t* req,
+               uv_file fd,
+               const uv_buf_t bufs[],
+               unsigned int nbufs,
+               int64_t offset,
+               uv_fs_cb cb) {
+  if (bufs == NULL || nbufs == 0)
+    return UV_EINVAL;
+
+  uv_fs_req_init(loop, req, UV_FS_READ, cb);
+
+  req->file.fd = fd;
+
+  req->fs.info.nbufs = nbufs;
+  req->fs.info.bufs = req->fs.info.bufsml;
+  if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
+    req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs));
+
+  if (req->fs.info.bufs == NULL)
+    return UV_ENOMEM;
+
+  memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
+
+  req->fs.info.offset = offset;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__read(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_write(uv_loop_t* loop,
+                uv_fs_t* req,
+                uv_file fd,
+                const uv_buf_t bufs[],
+                unsigned int nbufs,
+                int64_t offset,
+                uv_fs_cb cb) {
+  if (bufs == NULL || nbufs == 0)
+    return UV_EINVAL;
+
+  uv_fs_req_init(loop, req, UV_FS_WRITE, cb);
+
+  req->file.fd = fd;
+
+  req->fs.info.nbufs = nbufs;
+  req->fs.info.bufs = req->fs.info.bufsml;
+  if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
+    req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs));
+
+  if (req->fs.info.bufs == NULL)
+    return UV_ENOMEM;
+
+  memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
+
+  req->fs.info.offset = offset;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__write(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    uv_fs_cb cb) {
+  int err;
+
+  uv_fs_req_init(loop, req, UV_FS_UNLINK, cb);
+
+  err = fs__capture_path(req, path, NULL, cb != NULL);
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__unlink(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
+    uv_fs_cb cb) {
+  int err;
+
+  uv_fs_req_init(loop, req, UV_FS_MKDIR, cb);
+
+  err = fs__capture_path(req, path, NULL, cb != NULL);
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  req->fs.info.mode = mode;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__mkdir(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl,
+    uv_fs_cb cb) {
+  int err;
+
+  uv_fs_req_init(loop, req, UV_FS_MKDTEMP, cb);
+
+  err = fs__capture_path(req, tpl, NULL, TRUE);
+  if (err)
+    return uv_translate_sys_error(err);
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__mkdtemp(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
+  int err;
+
+  uv_fs_req_init(loop, req, UV_FS_RMDIR, cb);
+
+  err = fs__capture_path(req, path, NULL, cb != NULL);
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__rmdir(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
+    uv_fs_cb cb) {
+  int err;
+
+  uv_fs_req_init(loop, req, UV_FS_SCANDIR, cb);
+
+  err = fs__capture_path(req, path, NULL, cb != NULL);
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  req->fs.info.file_flags = flags;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__scandir(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    const char* new_path, uv_fs_cb cb) {
+  int err;
+
+  uv_fs_req_init(loop, req, UV_FS_LINK, cb);
+
+  err = fs__capture_path(req, path, new_path, cb != NULL);
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__link(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    const char* new_path, int flags, uv_fs_cb cb) {
+  int err;
+
+  uv_fs_req_init(loop, req, UV_FS_SYMLINK, cb);
+
+  err = fs__capture_path(req, path, new_path, cb != NULL);
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  req->fs.info.file_flags = flags;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__symlink(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    uv_fs_cb cb) {
+  int err;
+
+  uv_fs_req_init(loop, req, UV_FS_READLINK, cb);
+
+  err = fs__capture_path(req, path, NULL, cb != NULL);
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__readlink(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_realpath(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    uv_fs_cb cb) {
+  int err;
+
+  if (!req || !path) {
+    return UV_EINVAL;
+  }
+
+  uv_fs_req_init(loop, req, UV_FS_REALPATH, cb);
+
+  err = fs__capture_path(req, path, NULL, cb != NULL);
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__realpath(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid,
+    uv_gid_t gid, uv_fs_cb cb) {
+  int err;
+
+  uv_fs_req_init(loop, req, UV_FS_CHOWN, cb);
+
+  err = fs__capture_path(req, path, NULL, cb != NULL);
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__chown(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_uid_t uid,
+    uv_gid_t gid, uv_fs_cb cb) {
+  uv_fs_req_init(loop, req, UV_FS_FCHOWN, cb);
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__fchown(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
+  int err;
+
+  uv_fs_req_init(loop, req, UV_FS_STAT, cb);
+
+  err = fs__capture_path(req, path, NULL, cb != NULL);
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__stat(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
+  int err;
+
+  uv_fs_req_init(loop, req, UV_FS_LSTAT, cb);
+
+  err = fs__capture_path(req, path, NULL, cb != NULL);
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__lstat(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
+  uv_fs_req_init(loop, req, UV_FS_FSTAT, cb);
+  req->file.fd = fd;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__fstat(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    const char* new_path, uv_fs_cb cb) {
+  int err;
+
+  uv_fs_req_init(loop, req, UV_FS_RENAME, cb);
+
+  err = fs__capture_path(req, path, new_path, cb != NULL);
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__rename(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
+  uv_fs_req_init(loop, req, UV_FS_FSYNC, cb);
+  req->file.fd = fd;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__fsync(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
+  uv_fs_req_init(loop, req, UV_FS_FDATASYNC, cb);
+  req->file.fd = fd;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__fdatasync(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file fd,
+    int64_t offset, uv_fs_cb cb) {
+  uv_fs_req_init(loop, req, UV_FS_FTRUNCATE, cb);
+
+  req->file.fd = fd;
+  req->fs.info.offset = offset;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__ftruncate(req);
+    return req->result;
+  }
+}
+
+
+
+int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file fd_out,
+    uv_file fd_in, int64_t in_offset, size_t length, uv_fs_cb cb) {
+  uv_fs_req_init(loop, req, UV_FS_SENDFILE, cb);
+
+  req->file.fd = fd_in;
+  req->fs.info.fd_out = fd_out;
+  req->fs.info.offset = in_offset;
+  req->fs.info.bufsml[0].len = length;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__sendfile(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_access(uv_loop_t* loop,
+                 uv_fs_t* req,
+                 const char* path,
+                 int flags,
+                 uv_fs_cb cb) {
+  int err;
+
+  uv_fs_req_init(loop, req, UV_FS_ACCESS, cb);
+
+  err = fs__capture_path(req, path, NULL, cb != NULL);
+  if (err)
+    return uv_translate_sys_error(err);
+
+  req->flags = flags;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  }
+
+  fs__access(req);
+  return req->result;
+}
+
+
+int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
+    uv_fs_cb cb) {
+  int err;
+
+  uv_fs_req_init(loop, req, UV_FS_CHMOD, cb);
+
+  err = fs__capture_path(req, path, NULL, cb != NULL);
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  req->fs.info.mode = mode;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__chmod(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file fd, int mode,
+    uv_fs_cb cb) {
+  uv_fs_req_init(loop, req, UV_FS_FCHMOD, cb);
+
+  req->file.fd = fd;
+  req->fs.info.mode = mode;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__fchmod(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
+    double mtime, uv_fs_cb cb) {
+  int err;
+
+  uv_fs_req_init(loop, req, UV_FS_UTIME, cb);
+
+  err = fs__capture_path(req, path, NULL, cb != NULL);
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  req->fs.time.atime = atime;
+  req->fs.time.mtime = mtime;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__utime(req);
+    return req->result;
+  }
+}
+
+
+int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file fd, double atime,
+    double mtime, uv_fs_cb cb) {
+  uv_fs_req_init(loop, req, UV_FS_FUTIME, cb);
+
+  req->file.fd = fd;
+  req->fs.time.atime = atime;
+  req->fs.time.mtime = mtime;
+
+  if (cb) {
+    QUEUE_FS_TP_JOB(loop, req);
+    return 0;
+  } else {
+    fs__futime(req);
+    return req->result;
+  }
+}
diff --git a/deps/libtuv/src/win/getaddrinfo.c b/deps/libtuv/src/win/getaddrinfo.c
new file mode 100644 (file)
index 0000000..c13bfec
--- /dev/null
@@ -0,0 +1,384 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "req-inl.h"
+
+/* EAI_* constants. */
+#include <winsock2.h>
+
+
+int uv__getaddrinfo_translate_error(int sys_err) {
+  switch (sys_err) {
+    case 0:                       return 0;
+    case WSATRY_AGAIN:            return UV_EAI_AGAIN;
+    case WSAEINVAL:               return UV_EAI_BADFLAGS;
+    case WSANO_RECOVERY:          return UV_EAI_FAIL;
+    case WSAEAFNOSUPPORT:         return UV_EAI_FAMILY;
+    case WSA_NOT_ENOUGH_MEMORY:   return UV_EAI_MEMORY;
+    case WSAHOST_NOT_FOUND:       return UV_EAI_NONAME;
+    case WSATYPE_NOT_FOUND:       return UV_EAI_SERVICE;
+    case WSAESOCKTNOSUPPORT:      return UV_EAI_SOCKTYPE;
+    default:                      return uv_translate_sys_error(sys_err);
+  }
+}
+
+
+/*
+ * MinGW is missing this
+ */
+#if !defined(_MSC_VER) && !defined(__MINGW64_VERSION_MAJOR)
+  typedef struct addrinfoW {
+    int ai_flags;
+    int ai_family;
+    int ai_socktype;
+    int ai_protocol;
+    size_t ai_addrlen;
+    WCHAR* ai_canonname;
+    struct sockaddr* ai_addr;
+    struct addrinfoW* ai_next;
+  } ADDRINFOW, *PADDRINFOW;
+
+  DECLSPEC_IMPORT int WSAAPI GetAddrInfoW(const WCHAR* node,
+                                          const WCHAR* service,
+                                          const ADDRINFOW* hints,
+                                          PADDRINFOW* result);
+
+  DECLSPEC_IMPORT void WSAAPI FreeAddrInfoW(PADDRINFOW pAddrInfo);
+#endif
+
+
+/* adjust size value to be multiple of 4. Use to keep pointer aligned */
+/* Do we need different versions of this for different architectures? */
+#define ALIGNED_SIZE(X)     ((((X) + 3) >> 2) << 2)
+
+
+static void uv__getaddrinfo_work(struct uv__work* w) {
+  uv_getaddrinfo_t* req;
+  struct addrinfoW* hints;
+  int err;
+
+  req = container_of(w, uv_getaddrinfo_t, work_req);
+  hints = req->addrinfow;
+  req->addrinfow = NULL;
+  err = GetAddrInfoW(req->node, req->service, hints, &req->addrinfow);
+  req->retcode = uv__getaddrinfo_translate_error(err);
+}
+
+
+/*
+ * Called from uv_run when complete. Call user specified callback
+ * then free returned addrinfo
+ * Returned addrinfo strings are converted from UTF-16 to UTF-8.
+ *
+ * To minimize allocation we calculate total size required,
+ * and copy all structs and referenced strings into the one block.
+ * Each size calculation is adjusted to avoid unaligned pointers.
+ */
+static void uv__getaddrinfo_done(struct uv__work* w, int status) {
+  uv_getaddrinfo_t* req;
+  int addrinfo_len = 0;
+  int name_len = 0;
+  size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo));
+  struct addrinfoW* addrinfow_ptr;
+  struct addrinfo* addrinfo_ptr;
+  char* alloc_ptr = NULL;
+  char* cur_ptr = NULL;
+
+  req = container_of(w, uv_getaddrinfo_t, work_req);
+
+  /* release input parameter memory */
+  uv__free(req->alloc);
+  req->alloc = NULL;
+
+  if (status == UV_ECANCELED) {
+    assert(req->retcode == 0);
+    req->retcode = UV_EAI_CANCELED;
+    goto complete;
+  }
+
+  if (req->retcode == 0) {
+    /* convert addrinfoW to addrinfo */
+    /* first calculate required length */
+    addrinfow_ptr = req->addrinfow;
+    while (addrinfow_ptr != NULL) {
+      addrinfo_len += addrinfo_struct_len +
+          ALIGNED_SIZE(addrinfow_ptr->ai_addrlen);
+      if (addrinfow_ptr->ai_canonname != NULL) {
+        name_len = WideCharToMultiByte(CP_UTF8,
+                                       0,
+                                       addrinfow_ptr->ai_canonname,
+                                       -1,
+                                       NULL,
+                                       0,
+                                       NULL,
+                                       NULL);
+        if (name_len == 0) {
+          req->retcode = uv_translate_sys_error(GetLastError());
+          goto complete;
+        }
+        addrinfo_len += ALIGNED_SIZE(name_len);
+      }
+      addrinfow_ptr = addrinfow_ptr->ai_next;
+    }
+
+    /* allocate memory for addrinfo results */
+    alloc_ptr = (char*)uv__malloc(addrinfo_len);
+
+    /* do conversions */
+    if (alloc_ptr != NULL) {
+      cur_ptr = alloc_ptr;
+      addrinfow_ptr = req->addrinfow;
+
+      while (addrinfow_ptr != NULL) {
+        /* copy addrinfo struct data */
+        assert(cur_ptr + addrinfo_struct_len <= alloc_ptr + addrinfo_len);
+        addrinfo_ptr = (struct addrinfo*)cur_ptr;
+        addrinfo_ptr->ai_family = addrinfow_ptr->ai_family;
+        addrinfo_ptr->ai_socktype = addrinfow_ptr->ai_socktype;
+        addrinfo_ptr->ai_protocol = addrinfow_ptr->ai_protocol;
+        addrinfo_ptr->ai_flags = addrinfow_ptr->ai_flags;
+        addrinfo_ptr->ai_addrlen = addrinfow_ptr->ai_addrlen;
+        addrinfo_ptr->ai_canonname = NULL;
+        addrinfo_ptr->ai_addr = NULL;
+        addrinfo_ptr->ai_next = NULL;
+
+        cur_ptr += addrinfo_struct_len;
+
+        /* copy sockaddr */
+        if (addrinfo_ptr->ai_addrlen > 0) {
+          assert(cur_ptr + addrinfo_ptr->ai_addrlen <=
+                 alloc_ptr + addrinfo_len);
+          memcpy(cur_ptr, addrinfow_ptr->ai_addr, addrinfo_ptr->ai_addrlen);
+          addrinfo_ptr->ai_addr = (struct sockaddr*)cur_ptr;
+          cur_ptr += ALIGNED_SIZE(addrinfo_ptr->ai_addrlen);
+        }
+
+        /* convert canonical name to UTF-8 */
+        if (addrinfow_ptr->ai_canonname != NULL) {
+          name_len = WideCharToMultiByte(CP_UTF8,
+                                         0,
+                                         addrinfow_ptr->ai_canonname,
+                                         -1,
+                                         NULL,
+                                         0,
+                                         NULL,
+                                         NULL);
+          assert(name_len > 0);
+          assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len);
+          name_len = WideCharToMultiByte(CP_UTF8,
+                                         0,
+                                         addrinfow_ptr->ai_canonname,
+                                         -1,
+                                         cur_ptr,
+                                         name_len,
+                                         NULL,
+                                         NULL);
+          assert(name_len > 0);
+          addrinfo_ptr->ai_canonname = cur_ptr;
+          cur_ptr += ALIGNED_SIZE(name_len);
+        }
+        assert(cur_ptr <= alloc_ptr + addrinfo_len);
+
+        /* set next ptr */
+        addrinfow_ptr = addrinfow_ptr->ai_next;
+        if (addrinfow_ptr != NULL) {
+          addrinfo_ptr->ai_next = (struct addrinfo*)cur_ptr;
+        }
+      }
+      req->addrinfo = (struct addrinfo*)alloc_ptr;
+    } else {
+      req->retcode = UV_EAI_MEMORY;
+    }
+  }
+
+  /* return memory to system */
+  if (req->addrinfow != NULL) {
+    FreeAddrInfoW(req->addrinfow);
+    req->addrinfow = NULL;
+  }
+
+complete:
+  uv__req_unregister(req->loop, req);
+
+  /* finally do callback with converted result */
+  if (req->getaddrinfo_cb)
+    req->getaddrinfo_cb(req, req->retcode, req->addrinfo);
+}
+
+
+void uv_freeaddrinfo(struct addrinfo* ai) {
+  char* alloc_ptr = (char*)ai;
+
+  /* release copied result memory */
+  uv__free(alloc_ptr);
+}
+
+
+/*
+ * Entry point for getaddrinfo
+ * we convert the UTF-8 strings to UNICODE
+ * and save the UNICODE string pointers in the req
+ * We also copy hints so that caller does not need to keep memory until the
+ * callback.
+ * return 0 if a callback will be made
+ * return error code if validation fails
+ *
+ * To minimize allocation we calculate total size required,
+ * and copy all structs and referenced strings into the one block.
+ * Each size calculation is adjusted to avoid unaligned pointers.
+ */
+int uv_getaddrinfo(uv_loop_t* loop,
+                   uv_getaddrinfo_t* req,
+                   uv_getaddrinfo_cb getaddrinfo_cb,
+                   const char* node,
+                   const char* service,
+                   const struct addrinfo* hints) {
+  int nodesize = 0;
+  int servicesize = 0;
+  int hintssize = 0;
+  char* alloc_ptr = NULL;
+  int err;
+
+  if (req == NULL || (node == NULL && service == NULL)) {
+    return UV_EINVAL;
+  }
+
+  uv_req_init(loop, (uv_req_t*)req);
+
+  req->getaddrinfo_cb = getaddrinfo_cb;
+  req->addrinfo = NULL;
+  req->type = UV_GETADDRINFO;
+  req->loop = loop;
+  req->retcode = 0;
+
+  /* calculate required memory size for all input values */
+  if (node != NULL) {
+    nodesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8, 0, node, -1, NULL, 0) *
+                            sizeof(WCHAR));
+    if (nodesize == 0) {
+      err = GetLastError();
+      goto error;
+    }
+  }
+
+  if (service != NULL) {
+    servicesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8,
+                                                   0,
+                                                   service,
+                                                   -1,
+                                                   NULL,
+                                                   0) *
+                               sizeof(WCHAR));
+    if (servicesize == 0) {
+      err = GetLastError();
+      goto error;
+    }
+  }
+  if (hints != NULL) {
+    hintssize = ALIGNED_SIZE(sizeof(struct addrinfoW));
+  }
+
+  /* allocate memory for inputs, and partition it as needed */
+  alloc_ptr = (char*)uv__malloc(nodesize + servicesize + hintssize);
+  if (!alloc_ptr) {
+    err = WSAENOBUFS;
+    goto error;
+  }
+
+  /* save alloc_ptr now so we can free if error */
+  req->alloc = (void*)alloc_ptr;
+
+  /* convert node string to UTF16 into allocated memory and save pointer in */
+  /* the request. */
+  if (node != NULL) {
+    req->node = (WCHAR*)alloc_ptr;
+    if (MultiByteToWideChar(CP_UTF8,
+                            0,
+                            node,
+                            -1,
+                            (WCHAR*) alloc_ptr,
+                            nodesize / sizeof(WCHAR)) == 0) {
+      err = GetLastError();
+      goto error;
+    }
+    alloc_ptr += nodesize;
+  } else {
+    req->node = NULL;
+  }
+
+  /* convert service string to UTF16 into allocated memory and save pointer */
+  /* in the req. */
+  if (service != NULL) {
+    req->service = (WCHAR*)alloc_ptr;
+    if (MultiByteToWideChar(CP_UTF8,
+                            0,
+                            service,
+                            -1,
+                            (WCHAR*) alloc_ptr,
+                            servicesize / sizeof(WCHAR)) == 0) {
+      err = GetLastError();
+      goto error;
+    }
+    alloc_ptr += servicesize;
+  } else {
+    req->service = NULL;
+  }
+
+  /* copy hints to allocated memory and save pointer in req */
+  if (hints != NULL) {
+    req->addrinfow = (struct addrinfoW*)alloc_ptr;
+    req->addrinfow->ai_family = hints->ai_family;
+    req->addrinfow->ai_socktype = hints->ai_socktype;
+    req->addrinfow->ai_protocol = hints->ai_protocol;
+    req->addrinfow->ai_flags = hints->ai_flags;
+    req->addrinfow->ai_addrlen = 0;
+    req->addrinfow->ai_canonname = NULL;
+    req->addrinfow->ai_addr = NULL;
+    req->addrinfow->ai_next = NULL;
+  } else {
+    req->addrinfow = NULL;
+  }
+
+  uv__req_register(loop, req);
+
+  if (getaddrinfo_cb) {
+    uv__work_submit(loop,
+                    &req->work_req,
+                    uv__getaddrinfo_work,
+                    uv__getaddrinfo_done);
+    return 0;
+  } else {
+    uv__getaddrinfo_work(&req->work_req);
+    uv__getaddrinfo_done(&req->work_req, 0);
+    return req->retcode;
+  }
+
+error:
+  if (req != NULL) {
+    uv__free(req->alloc);
+    req->alloc = NULL;
+  }
+  return uv_translate_sys_error(err);
+}
diff --git a/deps/libtuv/src/win/getnameinfo.c b/deps/libtuv/src/win/getnameinfo.c
new file mode 100644 (file)
index 0000000..66b64b8
--- /dev/null
@@ -0,0 +1,150 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to
+* deal in the Software without restriction, including without limitation the
+* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+* sell copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+* IN THE SOFTWARE.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "req-inl.h"
+
+#ifndef GetNameInfo
+int WSAAPI GetNameInfoW(
+  const SOCKADDR *pSockaddr,
+  socklen_t SockaddrLength,
+  PWCHAR pNodeBuffer,
+  DWORD NodeBufferSize,
+  PWCHAR pServiceBuffer,
+  DWORD ServiceBufferSize,
+  INT Flags
+);
+#endif
+
+static void uv__getnameinfo_work(struct uv__work* w) {
+  uv_getnameinfo_t* req;
+  WCHAR host[NI_MAXHOST];
+  WCHAR service[NI_MAXSERV];
+  int ret = 0;
+
+  req = container_of(w, uv_getnameinfo_t, work_req);
+  if (GetNameInfoW((struct sockaddr*)&req->storage,
+                   sizeof(req->storage),
+                   host,
+                   ARRAY_SIZE(host),
+                   service,
+                   ARRAY_SIZE(service),
+                   req->flags)) {
+    ret = WSAGetLastError();
+  }
+  req->retcode = uv__getaddrinfo_translate_error(ret);
+
+  /* convert results to UTF-8 */
+  WideCharToMultiByte(CP_UTF8,
+                      0,
+                      host,
+                      -1,
+                      req->host,
+                      sizeof(req->host),
+                      NULL,
+                      NULL);
+
+  WideCharToMultiByte(CP_UTF8,
+                      0,
+                      service,
+                      -1,
+                      req->service,
+                      sizeof(req->service),
+                      NULL,
+                      NULL);
+}
+
+
+/*
+* Called from uv_run when complete.
+*/
+static void uv__getnameinfo_done(struct uv__work* w, int status) {
+  uv_getnameinfo_t* req;
+  char* host;
+  char* service;
+
+  req = container_of(w, uv_getnameinfo_t, work_req);
+  uv__req_unregister(req->loop, req);
+  host = service = NULL;
+
+  if (status == UV_ECANCELED) {
+    assert(req->retcode == 0);
+    req->retcode = UV_EAI_CANCELED;
+  } else if (req->retcode == 0) {
+    host = req->host;
+    service = req->service;
+  }
+
+  if (req->getnameinfo_cb)
+    req->getnameinfo_cb(req, req->retcode, host, service);
+}
+
+
+/*
+* Entry point for getnameinfo
+* return 0 if a callback will be made
+* return error code if validation fails
+*/
+int uv_getnameinfo(uv_loop_t* loop,
+                   uv_getnameinfo_t* req,
+                   uv_getnameinfo_cb getnameinfo_cb,
+                   const struct sockaddr* addr,
+                   int flags) {
+  if (req == NULL || addr == NULL)
+    return UV_EINVAL;
+
+  if (addr->sa_family == AF_INET) {
+    memcpy(&req->storage,
+           addr,
+           sizeof(struct sockaddr_in));
+  } else if (addr->sa_family == AF_INET6) {
+    memcpy(&req->storage,
+           addr,
+           sizeof(struct sockaddr_in6));
+  } else {
+    return UV_EINVAL;
+  }
+
+  uv_req_init(loop, (uv_req_t*)req);
+  uv__req_register(loop, req);
+
+  req->getnameinfo_cb = getnameinfo_cb;
+  req->flags = flags;
+  req->type = UV_GETNAMEINFO;
+  req->loop = loop;
+  req->retcode = 0;
+
+  if (getnameinfo_cb) {
+    uv__work_submit(loop,
+                    &req->work_req,
+                    uv__getnameinfo_work,
+                    uv__getnameinfo_done);
+    return 0;
+  } else {
+    uv__getnameinfo_work(&req->work_req);
+    uv__getnameinfo_done(&req->work_req, 0);
+    return req->retcode;
+  }
+}
diff --git a/deps/libtuv/src/win/handle-inl.h b/deps/libtuv/src/win/handle-inl.h
new file mode 100644 (file)
index 0000000..8d0334c
--- /dev/null
@@ -0,0 +1,179 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef UV_WIN_HANDLE_INL_H_
+#define UV_WIN_HANDLE_INL_H_
+
+#include <assert.h>
+#include <io.h>
+
+#include "uv.h"
+#include "internal.h"
+
+
+#define DECREASE_ACTIVE_COUNT(loop, handle)                             \
+  do {                                                                  \
+    if (--(handle)->activecnt == 0 &&                                   \
+        !((handle)->flags & UV__HANDLE_CLOSING)) {                      \
+      uv__handle_stop((handle));                                        \
+    }                                                                   \
+    assert((handle)->activecnt >= 0);                                   \
+  } while (0)
+
+
+#define INCREASE_ACTIVE_COUNT(loop, handle)                             \
+  do {                                                                  \
+    if ((handle)->activecnt++ == 0) {                                   \
+      uv__handle_start((handle));                                       \
+    }                                                                   \
+    assert((handle)->activecnt > 0);                                    \
+  } while (0)
+
+
+#define DECREASE_PENDING_REQ_COUNT(handle)                              \
+  do {                                                                  \
+    assert(handle->reqs_pending > 0);                                   \
+    handle->reqs_pending--;                                             \
+                                                                        \
+    if (handle->flags & UV__HANDLE_CLOSING &&                           \
+        handle->reqs_pending == 0) {                                    \
+      uv_want_endgame(loop, (uv_handle_t*)handle);                      \
+    }                                                                   \
+  } while (0)
+
+
+#define uv__handle_closing(handle)                                      \
+  do {                                                                  \
+    assert(!((handle)->flags & UV__HANDLE_CLOSING));                    \
+                                                                        \
+    if (!(((handle)->flags & UV__HANDLE_ACTIVE) &&                      \
+          ((handle)->flags & UV__HANDLE_REF)))                          \
+      uv__active_handle_add((uv_handle_t*) (handle));                   \
+                                                                        \
+    (handle)->flags |= UV__HANDLE_CLOSING;                              \
+    (handle)->flags &= ~UV__HANDLE_ACTIVE;                              \
+  } while (0)
+
+
+#define uv__handle_close(handle)                                        \
+  do {                                                                  \
+    QUEUE_REMOVE(&(handle)->handle_queue);                              \
+    uv__active_handle_rm((uv_handle_t*) (handle));                      \
+                                                                        \
+    (handle)->flags |= UV_HANDLE_CLOSED;                                \
+                                                                        \
+    if ((handle)->close_cb)                                             \
+      (handle)->close_cb((uv_handle_t*) (handle));                      \
+  } while (0)
+
+
+INLINE static void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle) {
+  if (!(handle->flags & UV_HANDLE_ENDGAME_QUEUED)) {
+    handle->flags |= UV_HANDLE_ENDGAME_QUEUED;
+
+    handle->endgame_next = loop->endgame_handles;
+    loop->endgame_handles = handle;
+  }
+}
+
+
+INLINE static void uv_process_endgames(uv_loop_t* loop) {
+  uv_handle_t* handle;
+
+  while (loop->endgame_handles) {
+    handle = loop->endgame_handles;
+    loop->endgame_handles = handle->endgame_next;
+
+    handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED;
+
+    switch (handle->type) {
+      case UV_TCP:
+        uv_tcp_endgame(loop, (uv_tcp_t*) handle);
+        break;
+
+      case UV_NAMED_PIPE:
+        uv_pipe_endgame(loop, (uv_pipe_t*) handle);
+        break;
+
+      case UV_TTY:
+        uv_tty_endgame(loop, (uv_tty_t*) handle);
+        break;
+
+      case UV_UDP:
+        uv_udp_endgame(loop, (uv_udp_t*) handle);
+        break;
+
+      case UV_POLL:
+        uv_poll_endgame(loop, (uv_poll_t*) handle);
+        break;
+
+      case UV_TIMER:
+        uv_timer_endgame(loop, (uv_timer_t*) handle);
+        break;
+
+      case UV_PREPARE:
+      case UV_CHECK:
+      case UV_IDLE:
+        uv_loop_watcher_endgame(loop, handle);
+        break;
+
+      case UV_ASYNC:
+        uv_async_endgame(loop, (uv_async_t*) handle);
+        break;
+
+      case UV_SIGNAL:
+        uv_signal_endgame(loop, (uv_signal_t*) handle);
+        break;
+
+      case UV_PROCESS:
+        uv_process_endgame(loop, (uv_process_t*) handle);
+        break;
+
+      case UV_FS_EVENT:
+        uv_fs_event_endgame(loop, (uv_fs_event_t*) handle);
+        break;
+
+      case UV_FS_POLL:
+        uv__fs_poll_endgame(loop, (uv_fs_poll_t*) handle);
+        break;
+
+      default:
+        assert(0);
+        break;
+    }
+  }
+}
+
+INLINE static HANDLE uv__get_osfhandle(int fd)
+{
+  /* _get_osfhandle() raises an assert in debug builds if the FD is invalid. */
+  /* But  it also correctly checks the FD and returns INVALID_HANDLE_VALUE */
+  /* for invalid FDs in release builds (or if you let the assert continue).  */
+  /* So this wrapper function disables asserts when calling _get_osfhandle. */
+
+  HANDLE handle;
+  UV_BEGIN_DISABLE_CRT_ASSERT();
+  handle = (HANDLE) _get_osfhandle(fd);
+  UV_END_DISABLE_CRT_ASSERT();
+  return handle;
+}
+
+#endif /* UV_WIN_HANDLE_INL_H_ */
diff --git a/deps/libtuv/src/win/handle.c b/deps/libtuv/src/win/handle.c
new file mode 100644 (file)
index 0000000..72b49d9
--- /dev/null
@@ -0,0 +1,154 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <io.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+
+
+uv_handle_type uv_guess_handle(uv_file file) {
+  HANDLE handle;
+  DWORD mode;
+
+  if (file < 0) {
+    return UV_UNKNOWN_HANDLE;
+  }
+
+  handle = uv__get_osfhandle(file);
+
+  switch (GetFileType(handle)) {
+    case FILE_TYPE_CHAR:
+      if (GetConsoleMode(handle, &mode)) {
+        return UV_TTY;
+      } else {
+        return UV_FILE;
+      }
+
+    case FILE_TYPE_PIPE:
+      return UV_NAMED_PIPE;
+
+    case FILE_TYPE_DISK:
+      return UV_FILE;
+
+    default:
+      return UV_UNKNOWN_HANDLE;
+  }
+}
+
+
+int uv_is_active(const uv_handle_t* handle) {
+  return (handle->flags & UV__HANDLE_ACTIVE) &&
+        !(handle->flags & UV__HANDLE_CLOSING);
+}
+
+
+void uv_close(uv_handle_t* handle, uv_close_cb cb) {
+  uv_loop_t* loop = handle->loop;
+
+  if (handle->flags & UV__HANDLE_CLOSING) {
+    assert(0);
+    return;
+  }
+
+  handle->close_cb = cb;
+
+  /* Handle-specific close actions */
+  switch (handle->type) {
+    case UV_TCP:
+      uv_tcp_close(loop, (uv_tcp_t*)handle);
+      return;
+
+    case UV_NAMED_PIPE:
+      uv_pipe_close(loop, (uv_pipe_t*) handle);
+      return;
+
+    case UV_TTY:
+      uv_tty_close((uv_tty_t*) handle);
+      return;
+
+    case UV_UDP:
+      uv_udp_close(loop, (uv_udp_t*) handle);
+      return;
+
+    case UV_POLL:
+      uv_poll_close(loop, (uv_poll_t*) handle);
+      return;
+
+    case UV_TIMER:
+      uv_timer_stop((uv_timer_t*)handle);
+      uv__handle_closing(handle);
+      uv_want_endgame(loop, handle);
+      return;
+
+    case UV_PREPARE:
+      uv_prepare_stop((uv_prepare_t*)handle);
+      uv__handle_closing(handle);
+      uv_want_endgame(loop, handle);
+      return;
+
+    case UV_CHECK:
+      uv_check_stop((uv_check_t*)handle);
+      uv__handle_closing(handle);
+      uv_want_endgame(loop, handle);
+      return;
+
+    case UV_IDLE:
+      uv_idle_stop((uv_idle_t*)handle);
+      uv__handle_closing(handle);
+      uv_want_endgame(loop, handle);
+      return;
+
+    case UV_ASYNC:
+      uv_async_close(loop, (uv_async_t*) handle);
+      return;
+
+    case UV_SIGNAL:
+      uv_signal_close(loop, (uv_signal_t*) handle);
+      return;
+
+    case UV_PROCESS:
+      uv_process_close(loop, (uv_process_t*) handle);
+      return;
+
+    case UV_FS_EVENT:
+      uv_fs_event_close(loop, (uv_fs_event_t*) handle);
+      return;
+
+    case UV_FS_POLL:
+      uv__fs_poll_close((uv_fs_poll_t*) handle);
+      uv__handle_closing(handle);
+      uv_want_endgame(loop, handle);
+      return;
+
+    default:
+      /* Not supported */
+      abort();
+  }
+}
+
+
+int uv_is_closing(const uv_handle_t* handle) {
+  return !!(handle->flags & (UV__HANDLE_CLOSING | UV_HANDLE_CLOSED));
+}
diff --git a/deps/libtuv/src/win/internal.h b/deps/libtuv/src/win/internal.h
new file mode 100644 (file)
index 0000000..b8cfde9
--- /dev/null
@@ -0,0 +1,394 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef UV_WIN_INTERNAL_H_
+#define UV_WIN_INTERNAL_H_
+
+#include "uv.h"
+#include "../uv-common.h"
+
+#include "tree.h"
+#include "winapi.h"
+#include "winsock.h"
+
+#ifdef _MSC_VER
+# define INLINE __inline
+# define UV_THREAD_LOCAL __declspec( thread )
+#else
+# define INLINE inline
+# define UV_THREAD_LOCAL __thread
+#endif
+
+
+#ifdef _DEBUG
+
+extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
+
+#define UV_BEGIN_DISABLE_CRT_ASSERT()                           \
+  {                                                             \
+    int uv__saved_crt_assert_enabled = uv__crt_assert_enabled;  \
+    uv__crt_assert_enabled = FALSE;
+
+
+#define UV_END_DISABLE_CRT_ASSERT()                             \
+    uv__crt_assert_enabled = uv__saved_crt_assert_enabled;      \
+  }
+
+#else
+#define UV_BEGIN_DISABLE_CRT_ASSERT()
+#define UV_END_DISABLE_CRT_ASSERT()
+#endif
+
+/*
+ * Handles
+ * (also see handle-inl.h)
+ */
+
+/* Used by all handles. */
+#define UV_HANDLE_CLOSED                        0x00000002
+#define UV_HANDLE_ENDGAME_QUEUED                0x00000008
+
+/* uv-common.h: #define UV__HANDLE_CLOSING      0x00000001 */
+/* uv-common.h: #define UV__HANDLE_ACTIVE       0x00000040 */
+/* uv-common.h: #define UV__HANDLE_REF          0x00000020 */
+/* uv-common.h: #define UV_HANDLE_INTERNAL      0x00000080 */
+
+/* Used by streams and UDP handles. */
+#define UV_HANDLE_READING                       0x00000100
+#define UV_HANDLE_BOUND                         0x00000200
+#define UV_HANDLE_LISTENING                     0x00000800
+#define UV_HANDLE_CONNECTION                    0x00001000
+#define UV_HANDLE_READABLE                      0x00008000
+#define UV_HANDLE_WRITABLE                      0x00010000
+#define UV_HANDLE_READ_PENDING                  0x00020000
+#define UV_HANDLE_SYNC_BYPASS_IOCP              0x00040000
+#define UV_HANDLE_ZERO_READ                     0x00080000
+#define UV_HANDLE_EMULATE_IOCP                  0x00100000
+#define UV_HANDLE_BLOCKING_WRITES               0x00200000
+#define UV_HANDLE_CANCELLATION_PENDING          0x00400000
+
+/* Used by uv_tcp_t and uv_udp_t handles */
+#define UV_HANDLE_IPV6                          0x01000000
+
+/* Only used by uv_tcp_t handles. */
+#define UV_HANDLE_TCP_NODELAY                   0x02000000
+#define UV_HANDLE_TCP_KEEPALIVE                 0x04000000
+#define UV_HANDLE_TCP_SINGLE_ACCEPT             0x08000000
+#define UV_HANDLE_TCP_ACCEPT_STATE_CHANGING     0x10000000
+#define UV_HANDLE_TCP_SOCKET_CLOSED             0x20000000
+#define UV_HANDLE_SHARED_TCP_SOCKET             0x40000000
+
+/* Only used by uv_pipe_t handles. */
+#define UV_HANDLE_NON_OVERLAPPED_PIPE           0x01000000
+#define UV_HANDLE_PIPESERVER                    0x02000000
+#define UV_HANDLE_PIPE_READ_CANCELABLE          0x04000000
+
+/* Only used by uv_tty_t handles. */
+#define UV_HANDLE_TTY_READABLE                  0x01000000
+#define UV_HANDLE_TTY_RAW                       0x02000000
+#define UV_HANDLE_TTY_SAVED_POSITION            0x04000000
+#define UV_HANDLE_TTY_SAVED_ATTRIBUTES          0x08000000
+
+/* Only used by uv_poll_t handles. */
+#define UV_HANDLE_POLL_SLOW                     0x02000000
+
+
+/*
+ * Requests: see req-inl.h
+ */
+
+
+/*
+ * Streams: see stream-inl.h
+ */
+
+
+/*
+ * TCP
+ */
+
+typedef struct {
+  WSAPROTOCOL_INFOW socket_info;
+  int delayed_error;
+} uv__ipc_socket_info_ex;
+
+int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb);
+int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client);
+int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
+    uv_read_cb read_cb);
+int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
+    const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb);
+int uv__tcp_try_write(uv_tcp_t* handle, const uv_buf_t bufs[],
+    unsigned int nbufs);
+
+void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, uv_req_t* req);
+void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
+    uv_write_t* req);
+void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
+    uv_req_t* req);
+void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
+    uv_connect_t* req);
+
+void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp);
+void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle);
+
+int uv_tcp_import(uv_tcp_t* tcp, uv__ipc_socket_info_ex* socket_info_ex,
+    int tcp_connection);
+
+int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
+    LPWSAPROTOCOL_INFOW protocol_info);
+
+
+/*
+ * UDP
+ */
+void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, uv_req_t* req);
+void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
+    uv_udp_send_t* req);
+
+void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle);
+void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle);
+
+
+/*
+ * Pipes
+ */
+int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
+    char* name, size_t nameSize);
+
+int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
+int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client);
+int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
+    uv_read_cb read_cb);
+int uv_pipe_write(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
+    const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb);
+int uv_pipe_write2(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
+    const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle,
+    uv_write_cb cb);
+void uv__pipe_pause_read(uv_pipe_t* handle);
+void uv__pipe_unpause_read(uv_pipe_t* handle);
+void uv__pipe_stop_read(uv_pipe_t* handle);
+
+void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
+    uv_req_t* req);
+void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
+    uv_write_t* req);
+void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle,
+    uv_req_t* raw_req);
+void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle,
+    uv_connect_t* req);
+void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
+    uv_shutdown_t* req);
+
+void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle);
+void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle);
+void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle);
+
+
+/*
+ * TTY
+ */
+void uv_console_init();
+
+int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
+    uv_read_cb read_cb);
+int uv_tty_read_stop(uv_tty_t* handle);
+int uv_tty_write(uv_loop_t* loop, uv_write_t* req, uv_tty_t* handle,
+    const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb);
+int uv__tty_try_write(uv_tty_t* handle, const uv_buf_t bufs[],
+    unsigned int nbufs);
+void uv_tty_close(uv_tty_t* handle);
+
+void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle,
+    uv_req_t* req);
+void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
+    uv_write_t* req);
+/* TODO: remove me */
+void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle,
+    uv_req_t* raw_req);
+/* TODO: remove me */
+void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle,
+    uv_connect_t* req);
+
+void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle);
+
+
+/*
+ * Poll watchers
+ */
+void uv_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
+    uv_req_t* req);
+
+int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle);
+void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle);
+
+
+/*
+ * Timers
+ */
+void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle);
+
+DWORD uv__next_timeout(const uv_loop_t* loop);
+void uv_process_timers(uv_loop_t* loop);
+
+
+/*
+ * Loop watchers
+ */
+void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle);
+
+void uv_prepare_invoke(uv_loop_t* loop);
+void uv_check_invoke(uv_loop_t* loop);
+void uv_idle_invoke(uv_loop_t* loop);
+
+void uv__once_init();
+
+
+/*
+ * Async watcher
+ */
+void uv_async_close(uv_loop_t* loop, uv_async_t* handle);
+void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle);
+
+void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
+    uv_req_t* req);
+
+
+/*
+ * Signal watcher
+ */
+void uv_signals_init();
+int uv__signal_dispatch(int signum);
+
+void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle);
+void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle);
+
+void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle,
+    uv_req_t* req);
+
+
+/*
+ * Spawn
+ */
+void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle);
+void uv_process_close(uv_loop_t* loop, uv_process_t* handle);
+void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle);
+
+
+/*
+ * Error
+ */
+int uv_translate_sys_error(int sys_errno);
+
+
+/*
+ * FS
+ */
+void uv_fs_init();
+
+
+/*
+ * FS Event
+ */
+void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
+    uv_fs_event_t* handle);
+void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle);
+void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle);
+
+
+/*
+ * Stat poller.
+ */
+void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle);
+
+
+/*
+ * Utilities.
+ */
+void uv__util_init();
+
+uint64_t uv__hrtime(double scale);
+int uv_parent_pid();
+int uv_current_pid();
+__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall);
+int uv__getpwuid_r(uv_passwd_t* pwd);
+int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8);
+
+
+/*
+ * Process stdio handles.
+ */
+int uv__stdio_create(uv_loop_t* loop,
+                     const uv_process_options_t* options,
+                     BYTE** buffer_ptr);
+void uv__stdio_destroy(BYTE* buffer);
+void uv__stdio_noinherit(BYTE* buffer);
+int uv__stdio_verify(BYTE* buffer, WORD size);
+WORD uv__stdio_size(BYTE* buffer);
+HANDLE uv__stdio_handle(BYTE* buffer, int fd);
+
+
+/*
+ * Winapi and ntapi utility functions
+ */
+void uv_winapi_init();
+
+
+/*
+ * Winsock utility functions
+ */
+void uv_winsock_init();
+
+int uv_ntstatus_to_winsock_error(NTSTATUS status);
+
+BOOL uv_get_acceptex_function(SOCKET socket, LPFN_ACCEPTEX* target);
+BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target);
+
+int WSAAPI uv_wsarecv_workaround(SOCKET socket, WSABUF* buffers,
+    DWORD buffer_count, DWORD* bytes, DWORD* flags, WSAOVERLAPPED *overlapped,
+    LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine);
+int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers,
+    DWORD buffer_count, DWORD* bytes, DWORD* flags, struct sockaddr* addr,
+    int* addr_len, WSAOVERLAPPED *overlapped,
+    LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine);
+
+int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in,
+    AFD_POLL_INFO* info_out, OVERLAPPED* overlapped);
+
+/* Whether there are any non-IFS LSPs stacked on TCP */
+extern int uv_tcp_non_ifs_lsp_ipv4;
+extern int uv_tcp_non_ifs_lsp_ipv6;
+
+/* Ip address used to bind to any port at any interface */
+extern struct sockaddr_in uv_addr_ip4_any_;
+extern struct sockaddr_in6 uv_addr_ip6_any_;
+
+/*
+ * Wake all loops with fake message
+ */
+void uv__wake_all_loops();
+
+/*
+ * Init system wake-up detection
+ */
+void uv__init_detect_system_wakeup();
+
+#endif /* UV_WIN_INTERNAL_H_ */
diff --git a/deps/libtuv/src/win/loop-watcher.c b/deps/libtuv/src/win/loop-watcher.c
new file mode 100644 (file)
index 0000000..20e4509
--- /dev/null
@@ -0,0 +1,122 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+
+
+void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
+  if (handle->flags & UV__HANDLE_CLOSING) {
+    assert(!(handle->flags & UV_HANDLE_CLOSED));
+    handle->flags |= UV_HANDLE_CLOSED;
+    uv__handle_close(handle);
+  }
+}
+
+
+#define UV_LOOP_WATCHER_DEFINE(name, NAME)                                    \
+  int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) {              \
+    uv__handle_init(loop, (uv_handle_t*) handle, UV_##NAME);                  \
+                                                                              \
+    return 0;                                                                 \
+  }                                                                           \
+                                                                              \
+                                                                              \
+  int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) {           \
+    uv_loop_t* loop = handle->loop;                                           \
+    uv_##name##_t* old_head;                                                  \
+                                                                              \
+    assert(handle->type == UV_##NAME);                                        \
+                                                                              \
+    if (uv__is_active(handle))                                                \
+      return 0;                                                               \
+                                                                              \
+    if (cb == NULL)                                                           \
+      return UV_EINVAL;                                                       \
+                                                                              \
+    old_head = loop->name##_handles;                                          \
+                                                                              \
+    handle->name##_next = old_head;                                           \
+    handle->name##_prev = NULL;                                               \
+                                                                              \
+    if (old_head) {                                                           \
+      old_head->name##_prev = handle;                                         \
+    }                                                                         \
+                                                                              \
+    loop->name##_handles = handle;                                            \
+                                                                              \
+    handle->name##_cb = cb;                                                   \
+    uv__handle_start(handle);                                                 \
+                                                                              \
+    return 0;                                                                 \
+  }                                                                           \
+                                                                              \
+                                                                              \
+  int uv_##name##_stop(uv_##name##_t* handle) {                               \
+    uv_loop_t* loop = handle->loop;                                           \
+                                                                              \
+    assert(handle->type == UV_##NAME);                                        \
+                                                                              \
+    if (!uv__is_active(handle))                                               \
+      return 0;                                                               \
+                                                                              \
+    /* Update loop head if needed */                                          \
+    if (loop->name##_handles == handle) {                                     \
+      loop->name##_handles = handle->name##_next;                             \
+    }                                                                         \
+                                                                              \
+    /* Update the iterator-next pointer of needed */                          \
+    if (loop->next_##name##_handle == handle) {                               \
+      loop->next_##name##_handle = handle->name##_next;                       \
+    }                                                                         \
+                                                                              \
+    if (handle->name##_prev) {                                                \
+      handle->name##_prev->name##_next = handle->name##_next;                 \
+    }                                                                         \
+    if (handle->name##_next) {                                                \
+      handle->name##_next->name##_prev = handle->name##_prev;                 \
+    }                                                                         \
+                                                                              \
+    uv__handle_stop(handle);                                                  \
+                                                                              \
+    return 0;                                                                 \
+  }                                                                           \
+                                                                              \
+                                                                              \
+  void uv_##name##_invoke(uv_loop_t* loop) {                                  \
+    uv_##name##_t* handle;                                                    \
+                                                                              \
+    (loop)->next_##name##_handle = (loop)->name##_handles;                    \
+                                                                              \
+    while ((loop)->next_##name##_handle != NULL) {                            \
+      handle = (loop)->next_##name##_handle;                                  \
+      (loop)->next_##name##_handle = handle->name##_next;                     \
+                                                                              \
+      handle->name##_cb(handle);                                              \
+    }                                                                         \
+  }
+
+UV_LOOP_WATCHER_DEFINE(prepare, PREPARE)
+UV_LOOP_WATCHER_DEFINE(check, CHECK)
+UV_LOOP_WATCHER_DEFINE(idle, IDLE)
diff --git a/deps/libtuv/src/win/pipe.c b/deps/libtuv/src/win/pipe.c
new file mode 100644 (file)
index 0000000..2442be7
--- /dev/null
@@ -0,0 +1,2130 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <io.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "stream-inl.h"
+#include "req-inl.h"
+
+typedef struct uv__ipc_queue_item_s uv__ipc_queue_item_t;
+
+struct uv__ipc_queue_item_s {
+  /*
+   * NOTE: It is important for socket_info_ex to be the first field,
+   * because we will we assigning it to the pending_ipc_info.socket_info
+   */
+  uv__ipc_socket_info_ex socket_info_ex;
+  QUEUE member;
+  int tcp_connection;
+};
+
+/* A zero-size buffer for use by uv_pipe_read */
+static char uv_zero_[] = "";
+
+/* Null uv_buf_t */
+static const uv_buf_t uv_null_buf_ = { 0, NULL };
+
+/* The timeout that the pipe will wait for the remote end to write data */
+/* when the local ends wants to shut it down. */
+static const int64_t eof_timeout = 50; /* ms */
+
+static const int default_pending_pipe_instances = 4;
+
+/* Pipe prefix */
+static char pipe_prefix[] = "\\\\?\\pipe";
+static const int pipe_prefix_len = sizeof(pipe_prefix) - 1;
+
+/* IPC protocol flags. */
+#define UV_IPC_RAW_DATA       0x0001
+#define UV_IPC_TCP_SERVER     0x0002
+#define UV_IPC_TCP_CONNECTION 0x0004
+
+/* IPC frame header. */
+typedef struct {
+  int flags;
+  uint64_t raw_data_length;
+} uv_ipc_frame_header_t;
+
+/* IPC frame, which contains an imported TCP socket stream. */
+typedef struct {
+  uv_ipc_frame_header_t header;
+  uv__ipc_socket_info_ex socket_info_ex;
+} uv_ipc_frame_uv_stream;
+
+static void eof_timer_init(uv_pipe_t* pipe);
+static void eof_timer_start(uv_pipe_t* pipe);
+static void eof_timer_stop(uv_pipe_t* pipe);
+static void eof_timer_cb(uv_timer_t* timer);
+static void eof_timer_destroy(uv_pipe_t* pipe);
+static void eof_timer_close_cb(uv_handle_t* handle);
+
+
+static void uv_unique_pipe_name(char* ptr, char* name, size_t size) {
+  snprintf(name, size, "\\\\?\\pipe\\uv\\%p-%lu", ptr, GetCurrentProcessId());
+}
+
+
+int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
+  uv_stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE);
+
+  handle->reqs_pending = 0;
+  handle->handle = INVALID_HANDLE_VALUE;
+  handle->name = NULL;
+  handle->pipe.conn.ipc_pid = 0;
+  handle->pipe.conn.remaining_ipc_rawdata_bytes = 0;
+  QUEUE_INIT(&handle->pipe.conn.pending_ipc_info.queue);
+  handle->pipe.conn.pending_ipc_info.queue_len = 0;
+  handle->ipc = ipc;
+  handle->pipe.conn.non_overlapped_writes_tail = NULL;
+  handle->pipe.conn.readfile_thread = NULL;
+
+  uv_req_init(loop, (uv_req_t*) &handle->pipe.conn.ipc_header_write_req);
+
+  return 0;
+}
+
+
+static void uv_pipe_connection_init(uv_pipe_t* handle) {
+  uv_connection_init((uv_stream_t*) handle);
+  handle->read_req.data = handle;
+  handle->pipe.conn.eof_timer = NULL;
+  assert(!(handle->flags & UV_HANDLE_PIPESERVER));
+  if (pCancelSynchronousIo &&
+      handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
+      uv_mutex_init(&handle->pipe.conn.readfile_mutex);
+      handle->flags |= UV_HANDLE_PIPE_READ_CANCELABLE;
+  }
+}
+
+
+static HANDLE open_named_pipe(const WCHAR* name, DWORD* duplex_flags) {
+  HANDLE pipeHandle;
+
+  /*
+   * Assume that we have a duplex pipe first, so attempt to
+   * connect with GENERIC_READ | GENERIC_WRITE.
+   */
+  pipeHandle = CreateFileW(name,
+                           GENERIC_READ | GENERIC_WRITE,
+                           0,
+                           NULL,
+                           OPEN_EXISTING,
+                           FILE_FLAG_OVERLAPPED,
+                           NULL);
+  if (pipeHandle != INVALID_HANDLE_VALUE) {
+    *duplex_flags = UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
+    return pipeHandle;
+  }
+
+  /*
+   * If the pipe is not duplex CreateFileW fails with
+   * ERROR_ACCESS_DENIED.  In that case try to connect
+   * as a read-only or write-only.
+   */
+  if (GetLastError() == ERROR_ACCESS_DENIED) {
+    pipeHandle = CreateFileW(name,
+                             GENERIC_READ | FILE_WRITE_ATTRIBUTES,
+                             0,
+                             NULL,
+                             OPEN_EXISTING,
+                             FILE_FLAG_OVERLAPPED,
+                             NULL);
+
+    if (pipeHandle != INVALID_HANDLE_VALUE) {
+      *duplex_flags = UV_HANDLE_READABLE;
+      return pipeHandle;
+    }
+  }
+
+  if (GetLastError() == ERROR_ACCESS_DENIED) {
+    pipeHandle = CreateFileW(name,
+                             GENERIC_WRITE | FILE_READ_ATTRIBUTES,
+                             0,
+                             NULL,
+                             OPEN_EXISTING,
+                             FILE_FLAG_OVERLAPPED,
+                             NULL);
+
+    if (pipeHandle != INVALID_HANDLE_VALUE) {
+      *duplex_flags = UV_HANDLE_WRITABLE;
+      return pipeHandle;
+    }
+  }
+
+  return INVALID_HANDLE_VALUE;
+}
+
+
+static void close_pipe(uv_pipe_t* pipe) {
+  assert(pipe->u.fd == -1 || pipe->u.fd > 2);
+  if (pipe->u.fd == -1)
+    CloseHandle(pipe->handle);
+  else
+    close(pipe->u.fd);
+
+  pipe->u.fd = -1;
+  pipe->handle = INVALID_HANDLE_VALUE;
+}
+
+
+int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
+    char* name, size_t nameSize) {
+  HANDLE pipeHandle;
+  int err;
+  char* ptr = (char*)handle;
+
+  for (;;) {
+    uv_unique_pipe_name(ptr, name, nameSize);
+
+    pipeHandle = CreateNamedPipeA(name,
+      access | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
+      PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 65536, 65536, 0,
+      NULL);
+
+    if (pipeHandle != INVALID_HANDLE_VALUE) {
+      /* No name collisions.  We're done. */
+      break;
+    }
+
+    err = GetLastError();
+    if (err != ERROR_PIPE_BUSY && err != ERROR_ACCESS_DENIED) {
+      goto error;
+    }
+
+    /* Pipe name collision.  Increment the pointer and try again. */
+    ptr++;
+  }
+
+  if (CreateIoCompletionPort(pipeHandle,
+                             loop->iocp,
+                             (ULONG_PTR)handle,
+                             0) == NULL) {
+    err = GetLastError();
+    goto error;
+  }
+
+  uv_pipe_connection_init(handle);
+  handle->handle = pipeHandle;
+
+  return 0;
+
+ error:
+  if (pipeHandle != INVALID_HANDLE_VALUE) {
+    CloseHandle(pipeHandle);
+  }
+
+  return err;
+}
+
+
+static int uv_set_pipe_handle(uv_loop_t* loop,
+                              uv_pipe_t* handle,
+                              HANDLE pipeHandle,
+                              int fd,
+                              DWORD duplex_flags) {
+  NTSTATUS nt_status;
+  IO_STATUS_BLOCK io_status;
+  FILE_MODE_INFORMATION mode_info;
+  DWORD mode = PIPE_READMODE_BYTE | PIPE_WAIT;
+  DWORD current_mode = 0;
+  DWORD err = 0;
+
+  if (!(handle->flags & UV_HANDLE_PIPESERVER) &&
+      handle->handle != INVALID_HANDLE_VALUE)
+    return UV_EBUSY;
+
+  if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) {
+    err = GetLastError();
+    if (err == ERROR_ACCESS_DENIED) {
+      /*
+       * SetNamedPipeHandleState can fail if the handle doesn't have either
+       * GENERIC_WRITE  or FILE_WRITE_ATTRIBUTES.
+       * But if the handle already has the desired wait and blocking modes
+       * we can continue.
+       */
+      if (!GetNamedPipeHandleState(pipeHandle, &current_mode, NULL, NULL,
+                                   NULL, NULL, 0)) {
+        return -1;
+      } else if (current_mode & PIPE_NOWAIT) {
+        SetLastError(ERROR_ACCESS_DENIED);
+        return -1;
+      }
+    } else {
+      /* If this returns ERROR_INVALID_PARAMETER we probably opened
+       * something that is not a pipe. */
+      if (err == ERROR_INVALID_PARAMETER) {
+        SetLastError(WSAENOTSOCK);
+      }
+      return -1;
+    }
+  }
+
+  /* Check if the pipe was created with FILE_FLAG_OVERLAPPED. */
+  nt_status = pNtQueryInformationFile(pipeHandle,
+                                      &io_status,
+                                      &mode_info,
+                                      sizeof(mode_info),
+                                      FileModeInformation);
+  if (nt_status != STATUS_SUCCESS) {
+    return -1;
+  }
+
+  if (mode_info.Mode & FILE_SYNCHRONOUS_IO_ALERT ||
+      mode_info.Mode & FILE_SYNCHRONOUS_IO_NONALERT) {
+    /* Non-overlapped pipe. */
+    handle->flags |= UV_HANDLE_NON_OVERLAPPED_PIPE;
+  } else {
+    /* Overlapped pipe.  Try to associate with IOCP. */
+    if (CreateIoCompletionPort(pipeHandle,
+                               loop->iocp,
+                               (ULONG_PTR)handle,
+                               0) == NULL) {
+      handle->flags |= UV_HANDLE_EMULATE_IOCP;
+    }
+  }
+
+  handle->handle = pipeHandle;
+  handle->u.fd = fd;
+  handle->flags |= duplex_flags;
+
+  return 0;
+}
+
+
+static DWORD WINAPI pipe_shutdown_thread_proc(void* parameter) {
+  uv_loop_t* loop;
+  uv_pipe_t* handle;
+  uv_shutdown_t* req;
+
+  req = (uv_shutdown_t*) parameter;
+  assert(req);
+  handle = (uv_pipe_t*) req->handle;
+  assert(handle);
+  loop = handle->loop;
+  assert(loop);
+
+  FlushFileBuffers(handle->handle);
+
+  /* Post completed */
+  POST_COMPLETION_FOR_REQ(loop, req);
+
+  return 0;
+}
+
+
+void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
+  int err;
+  DWORD result;
+  uv_shutdown_t* req;
+  NTSTATUS nt_status;
+  IO_STATUS_BLOCK io_status;
+  FILE_PIPE_LOCAL_INFORMATION pipe_info;
+  uv__ipc_queue_item_t* item;
+
+  if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
+    handle->flags &= ~UV_HANDLE_PIPE_READ_CANCELABLE;
+    uv_mutex_destroy(&handle->pipe.conn.readfile_mutex);
+  }
+
+  if ((handle->flags & UV_HANDLE_CONNECTION) &&
+      handle->stream.conn.shutdown_req != NULL &&
+      handle->stream.conn.write_reqs_pending == 0) {
+    req = handle->stream.conn.shutdown_req;
+
+    /* Clear the shutdown_req field so we don't go here again. */
+    handle->stream.conn.shutdown_req = NULL;
+
+    if (handle->flags & UV__HANDLE_CLOSING) {
+      UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+      /* Already closing. Cancel the shutdown. */
+      if (req->cb) {
+        req->cb(req, UV_ECANCELED);
+      }
+
+      DECREASE_PENDING_REQ_COUNT(handle);
+      return;
+    }
+
+    /* Try to avoid flushing the pipe buffer in the thread pool. */
+    nt_status = pNtQueryInformationFile(handle->handle,
+                                        &io_status,
+                                        &pipe_info,
+                                        sizeof pipe_info,
+                                        FilePipeLocalInformation);
+
+    if (nt_status != STATUS_SUCCESS) {
+      /* Failure */
+      UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+      handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */
+      if (req->cb) {
+        err = pRtlNtStatusToDosError(nt_status);
+        req->cb(req, uv_translate_sys_error(err));
+      }
+
+      DECREASE_PENDING_REQ_COUNT(handle);
+      return;
+    }
+
+    if (pipe_info.OutboundQuota == pipe_info.WriteQuotaAvailable) {
+      /* Short-circuit, no need to call FlushFileBuffers. */
+      uv_insert_pending_req(loop, (uv_req_t*) req);
+      return;
+    }
+
+    /* Run FlushFileBuffers in the thread pool. */
+    result = QueueUserWorkItem(pipe_shutdown_thread_proc,
+                               req,
+                               WT_EXECUTELONGFUNCTION);
+    if (result) {
+      return;
+
+    } else {
+      /* Failure. */
+      UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+      handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */
+      if (req->cb) {
+        err = GetLastError();
+        req->cb(req, uv_translate_sys_error(err));
+      }
+
+      DECREASE_PENDING_REQ_COUNT(handle);
+      return;
+    }
+  }
+
+  if (handle->flags & UV__HANDLE_CLOSING &&
+      handle->reqs_pending == 0) {
+    assert(!(handle->flags & UV_HANDLE_CLOSED));
+
+    if (handle->flags & UV_HANDLE_CONNECTION) {
+      /* Free pending sockets */
+      while (!QUEUE_EMPTY(&handle->pipe.conn.pending_ipc_info.queue)) {
+        QUEUE* q;
+        SOCKET socket;
+
+        q = QUEUE_HEAD(&handle->pipe.conn.pending_ipc_info.queue);
+        QUEUE_REMOVE(q);
+        item = QUEUE_DATA(q, uv__ipc_queue_item_t, member);
+
+        /* Materialize socket and close it */
+        socket = WSASocketW(FROM_PROTOCOL_INFO,
+                            FROM_PROTOCOL_INFO,
+                            FROM_PROTOCOL_INFO,
+                            &item->socket_info_ex.socket_info,
+                            0,
+                            WSA_FLAG_OVERLAPPED);
+        uv__free(item);
+
+        if (socket != INVALID_SOCKET)
+          closesocket(socket);
+      }
+      handle->pipe.conn.pending_ipc_info.queue_len = 0;
+
+      if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+        if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) {
+          UnregisterWait(handle->read_req.wait_handle);
+          handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
+        }
+        if (handle->read_req.event_handle) {
+          CloseHandle(handle->read_req.event_handle);
+          handle->read_req.event_handle = NULL;
+        }
+      }
+    }
+
+    if (handle->flags & UV_HANDLE_PIPESERVER) {
+      assert(handle->pipe.serv.accept_reqs);
+      uv__free(handle->pipe.serv.accept_reqs);
+      handle->pipe.serv.accept_reqs = NULL;
+    }
+
+    uv__handle_close(handle);
+  }
+}
+
+
+void uv_pipe_pending_instances(uv_pipe_t* handle, int count) {
+  if (handle->flags & UV_HANDLE_BOUND)
+    return;
+  handle->pipe.serv.pending_instances = count;
+  handle->flags |= UV_HANDLE_PIPESERVER;
+}
+
+
+/* Creates a pipe server. */
+int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
+  uv_loop_t* loop = handle->loop;
+  int i, err, nameSize;
+  uv_pipe_accept_t* req;
+
+  if (handle->flags & UV_HANDLE_BOUND) {
+    return UV_EINVAL;
+  }
+
+  if (!name) {
+    return UV_EINVAL;
+  }
+
+  if (!(handle->flags & UV_HANDLE_PIPESERVER)) {
+    handle->pipe.serv.pending_instances = default_pending_pipe_instances;
+  }
+
+  handle->pipe.serv.accept_reqs = (uv_pipe_accept_t*)
+    uv__malloc(sizeof(uv_pipe_accept_t) * handle->pipe.serv.pending_instances);
+  if (!handle->pipe.serv.accept_reqs) {
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+  }
+
+  for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
+    req = &handle->pipe.serv.accept_reqs[i];
+    uv_req_init(loop, (uv_req_t*) req);
+    req->type = UV_ACCEPT;
+    req->data = handle;
+    req->pipeHandle = INVALID_HANDLE_VALUE;
+    req->next_pending = NULL;
+  }
+
+  /* Convert name to UTF16. */
+  nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR);
+  handle->name = (WCHAR*)uv__malloc(nameSize);
+  if (!handle->name) {
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+  }
+
+  if (!MultiByteToWideChar(CP_UTF8,
+                           0,
+                           name,
+                           -1,
+                           handle->name,
+                           nameSize / sizeof(WCHAR))) {
+    err = GetLastError();
+    goto error;
+  }
+
+  /*
+   * Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE.
+   * If this fails then there's already a pipe server for the given pipe name.
+   */
+  handle->pipe.serv.accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name,
+      PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
+      FILE_FLAG_FIRST_PIPE_INSTANCE,
+      PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+      PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
+
+  if (handle->pipe.serv.accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) {
+    err = GetLastError();
+    if (err == ERROR_ACCESS_DENIED) {
+      err = WSAEADDRINUSE;  /* Translates to UV_EADDRINUSE. */
+    } else if (err == ERROR_PATH_NOT_FOUND || err == ERROR_INVALID_NAME) {
+      err = WSAEACCES;  /* Translates to UV_EACCES. */
+    }
+    goto error;
+  }
+
+  if (uv_set_pipe_handle(loop,
+                         handle,
+                         handle->pipe.serv.accept_reqs[0].pipeHandle,
+                         -1,
+                         0)) {
+    err = GetLastError();
+    goto error;
+  }
+
+  handle->pipe.serv.pending_accepts = NULL;
+  handle->flags |= UV_HANDLE_PIPESERVER;
+  handle->flags |= UV_HANDLE_BOUND;
+
+  return 0;
+
+error:
+  if (handle->name) {
+    uv__free(handle->name);
+    handle->name = NULL;
+  }
+
+  if (handle->pipe.serv.accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE) {
+    CloseHandle(handle->pipe.serv.accept_reqs[0].pipeHandle);
+    handle->pipe.serv.accept_reqs[0].pipeHandle = INVALID_HANDLE_VALUE;
+  }
+
+  return uv_translate_sys_error(err);
+}
+
+
+static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
+  uv_loop_t* loop;
+  uv_pipe_t* handle;
+  uv_connect_t* req;
+  HANDLE pipeHandle = INVALID_HANDLE_VALUE;
+  DWORD duplex_flags;
+
+  req = (uv_connect_t*) parameter;
+  assert(req);
+  handle = (uv_pipe_t*) req->handle;
+  assert(handle);
+  loop = handle->loop;
+  assert(loop);
+
+  /* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. */
+  /* We wait for the pipe to become available with WaitNamedPipe. */
+  while (WaitNamedPipeW(handle->name, 30000)) {
+    /* The pipe is now available, try to connect. */
+    pipeHandle = open_named_pipe(handle->name, &duplex_flags);
+    if (pipeHandle != INVALID_HANDLE_VALUE) {
+      break;
+    }
+
+    SwitchToThread();
+  }
+
+  if (pipeHandle != INVALID_HANDLE_VALUE &&
+      !uv_set_pipe_handle(loop, handle, pipeHandle, -1, duplex_flags)) {
+    SET_REQ_SUCCESS(req);
+  } else {
+    SET_REQ_ERROR(req, GetLastError());
+  }
+
+  /* Post completed */
+  POST_COMPLETION_FOR_REQ(loop, req);
+
+  return 0;
+}
+
+
+void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
+    const char* name, uv_connect_cb cb) {
+  uv_loop_t* loop = handle->loop;
+  int err, nameSize;
+  HANDLE pipeHandle = INVALID_HANDLE_VALUE;
+  DWORD duplex_flags;
+
+  uv_req_init(loop, (uv_req_t*) req);
+  req->type = UV_CONNECT;
+  req->handle = (uv_stream_t*) handle;
+  req->cb = cb;
+
+  /* Convert name to UTF16. */
+  nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR);
+  handle->name = (WCHAR*)uv__malloc(nameSize);
+  if (!handle->name) {
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+  }
+
+  if (!MultiByteToWideChar(CP_UTF8,
+                           0,
+                           name,
+                           -1,
+                           handle->name,
+                           nameSize / sizeof(WCHAR))) {
+    err = GetLastError();
+    goto error;
+  }
+
+  pipeHandle = open_named_pipe(handle->name, &duplex_flags);
+  if (pipeHandle == INVALID_HANDLE_VALUE) {
+    if (GetLastError() == ERROR_PIPE_BUSY) {
+      /* Wait for the server to make a pipe instance available. */
+      if (!QueueUserWorkItem(&pipe_connect_thread_proc,
+                             req,
+                             WT_EXECUTELONGFUNCTION)) {
+        err = GetLastError();
+        goto error;
+      }
+
+      REGISTER_HANDLE_REQ(loop, handle, req);
+      handle->reqs_pending++;
+
+      return;
+    }
+
+    err = GetLastError();
+    goto error;
+  }
+
+  assert(pipeHandle != INVALID_HANDLE_VALUE);
+
+  if (uv_set_pipe_handle(loop,
+                         (uv_pipe_t*) req->handle,
+                         pipeHandle,
+                         -1,
+                         duplex_flags)) {
+    err = GetLastError();
+    goto error;
+  }
+
+  SET_REQ_SUCCESS(req);
+  uv_insert_pending_req(loop, (uv_req_t*) req);
+  handle->reqs_pending++;
+  REGISTER_HANDLE_REQ(loop, handle, req);
+  return;
+
+error:
+  if (handle->name) {
+    uv__free(handle->name);
+    handle->name = NULL;
+  }
+
+  if (pipeHandle != INVALID_HANDLE_VALUE) {
+    CloseHandle(pipeHandle);
+  }
+
+  /* Make this req pending reporting an error. */
+  SET_REQ_ERROR(req, err);
+  uv_insert_pending_req(loop, (uv_req_t*) req);
+  handle->reqs_pending++;
+  REGISTER_HANDLE_REQ(loop, handle, req);
+  return;
+}
+
+
+void uv__pipe_pause_read(uv_pipe_t* handle) {
+  if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
+      /* Pause the ReadFile task briefly, to work
+         around the Windows kernel bug that causes
+         any access to a NamedPipe to deadlock if
+         any process has called ReadFile */
+      HANDLE h;
+      uv_mutex_lock(&handle->pipe.conn.readfile_mutex);
+      h = handle->pipe.conn.readfile_thread;
+      while (h) {
+        /* spinlock: we expect this to finish quickly,
+           or we are probably about to deadlock anyways
+           (in the kernel), so it doesn't matter */
+        pCancelSynchronousIo(h);
+        SwitchToThread(); /* yield thread control briefly */
+        h = handle->pipe.conn.readfile_thread;
+      }
+  }
+}
+
+
+void uv__pipe_unpause_read(uv_pipe_t* handle) {
+  if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
+    uv_mutex_unlock(&handle->pipe.conn.readfile_mutex);
+  }
+}
+
+
+void uv__pipe_stop_read(uv_pipe_t* handle) {
+  handle->flags &= ~UV_HANDLE_READING;
+  uv__pipe_pause_read((uv_pipe_t*)handle);
+  uv__pipe_unpause_read((uv_pipe_t*)handle);
+}
+
+
+/* Cleans up uv_pipe_t (server or connection) and all resources associated */
+/* with it. */
+void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
+  int i;
+  HANDLE pipeHandle;
+
+  uv__pipe_stop_read(handle);
+
+  if (handle->name) {
+    uv__free(handle->name);
+    handle->name = NULL;
+  }
+
+  if (handle->flags & UV_HANDLE_PIPESERVER) {
+    for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
+      pipeHandle = handle->pipe.serv.accept_reqs[i].pipeHandle;
+      if (pipeHandle != INVALID_HANDLE_VALUE) {
+        CloseHandle(pipeHandle);
+        handle->pipe.serv.accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE;
+      }
+    }
+    handle->handle = INVALID_HANDLE_VALUE;
+  }
+
+  if (handle->flags & UV_HANDLE_CONNECTION) {
+    handle->flags &= ~UV_HANDLE_WRITABLE;
+    eof_timer_destroy(handle);
+  }
+
+  if ((handle->flags & UV_HANDLE_CONNECTION)
+      && handle->handle != INVALID_HANDLE_VALUE)
+    close_pipe(handle);
+}
+
+
+void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle) {
+  if (handle->flags & UV_HANDLE_READING) {
+    handle->flags &= ~UV_HANDLE_READING;
+    DECREASE_ACTIVE_COUNT(loop, handle);
+  }
+
+  if (handle->flags & UV_HANDLE_LISTENING) {
+    handle->flags &= ~UV_HANDLE_LISTENING;
+    DECREASE_ACTIVE_COUNT(loop, handle);
+  }
+
+  uv_pipe_cleanup(loop, handle);
+
+  if (handle->reqs_pending == 0) {
+    uv_want_endgame(loop, (uv_handle_t*) handle);
+  }
+
+  handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
+  uv__handle_closing(handle);
+}
+
+
+static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle,
+    uv_pipe_accept_t* req, BOOL firstInstance) {
+  assert(handle->flags & UV_HANDLE_LISTENING);
+
+  if (!firstInstance) {
+    assert(req->pipeHandle == INVALID_HANDLE_VALUE);
+
+    req->pipeHandle = CreateNamedPipeW(handle->name,
+        PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
+        PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+        PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
+
+    if (req->pipeHandle == INVALID_HANDLE_VALUE) {
+      SET_REQ_ERROR(req, GetLastError());
+      uv_insert_pending_req(loop, (uv_req_t*) req);
+      handle->reqs_pending++;
+      return;
+    }
+
+    if (uv_set_pipe_handle(loop, handle, req->pipeHandle, -1, 0)) {
+      CloseHandle(req->pipeHandle);
+      req->pipeHandle = INVALID_HANDLE_VALUE;
+      SET_REQ_ERROR(req, GetLastError());
+      uv_insert_pending_req(loop, (uv_req_t*) req);
+      handle->reqs_pending++;
+      return;
+    }
+  }
+
+  assert(req->pipeHandle != INVALID_HANDLE_VALUE);
+
+  /* Prepare the overlapped structure. */
+  memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
+
+  if (!ConnectNamedPipe(req->pipeHandle, &req->u.io.overlapped) &&
+      GetLastError() != ERROR_IO_PENDING) {
+    if (GetLastError() == ERROR_PIPE_CONNECTED) {
+      SET_REQ_SUCCESS(req);
+    } else {
+      CloseHandle(req->pipeHandle);
+      req->pipeHandle = INVALID_HANDLE_VALUE;
+      /* Make this req pending reporting an error. */
+      SET_REQ_ERROR(req, GetLastError());
+    }
+    uv_insert_pending_req(loop, (uv_req_t*) req);
+    handle->reqs_pending++;
+    return;
+  }
+
+  handle->reqs_pending++;
+}
+
+
+int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
+  uv_loop_t* loop = server->loop;
+  uv_pipe_t* pipe_client;
+  uv_pipe_accept_t* req;
+  QUEUE* q;
+  uv__ipc_queue_item_t* item;
+  int err;
+
+  if (server->ipc) {
+    if (QUEUE_EMPTY(&server->pipe.conn.pending_ipc_info.queue)) {
+      /* No valid pending sockets. */
+      return WSAEWOULDBLOCK;
+    }
+
+    q = QUEUE_HEAD(&server->pipe.conn.pending_ipc_info.queue);
+    QUEUE_REMOVE(q);
+    server->pipe.conn.pending_ipc_info.queue_len--;
+    item = QUEUE_DATA(q, uv__ipc_queue_item_t, member);
+
+    err = uv_tcp_import((uv_tcp_t*)client,
+                        &item->socket_info_ex,
+                        item->tcp_connection);
+    if (err != 0)
+      return err;
+
+    uv__free(item);
+
+  } else {
+    pipe_client = (uv_pipe_t*)client;
+
+    /* Find a connection instance that has been connected, but not yet */
+    /* accepted. */
+    req = server->pipe.serv.pending_accepts;
+
+    if (!req) {
+      /* No valid connections found, so we error out. */
+      return WSAEWOULDBLOCK;
+    }
+
+    /* Initialize the client handle and copy the pipeHandle to the client */
+    uv_pipe_connection_init(pipe_client);
+    pipe_client->handle = req->pipeHandle;
+    pipe_client->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
+
+    /* Prepare the req to pick up a new connection */
+    server->pipe.serv.pending_accepts = req->next_pending;
+    req->next_pending = NULL;
+    req->pipeHandle = INVALID_HANDLE_VALUE;
+
+    if (!(server->flags & UV__HANDLE_CLOSING)) {
+      uv_pipe_queue_accept(loop, server, req, FALSE);
+    }
+  }
+
+  return 0;
+}
+
+
+/* Starts listening for connections for the given pipe. */
+int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
+  uv_loop_t* loop = handle->loop;
+  int i;
+
+  if (handle->flags & UV_HANDLE_LISTENING) {
+    handle->stream.serv.connection_cb = cb;
+  }
+
+  if (!(handle->flags & UV_HANDLE_BOUND)) {
+    return WSAEINVAL;
+  }
+
+  if (handle->flags & UV_HANDLE_READING) {
+    return WSAEISCONN;
+  }
+
+  if (!(handle->flags & UV_HANDLE_PIPESERVER)) {
+    return ERROR_NOT_SUPPORTED;
+  }
+
+  handle->flags |= UV_HANDLE_LISTENING;
+  INCREASE_ACTIVE_COUNT(loop, handle);
+  handle->stream.serv.connection_cb = cb;
+
+  /* First pipe handle should have already been created in uv_pipe_bind */
+  assert(handle->pipe.serv.accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE);
+
+  for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
+    uv_pipe_queue_accept(loop, handle, &handle->pipe.serv.accept_reqs[i], i == 0);
+  }
+
+  return 0;
+}
+
+
+static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
+  int result;
+  DWORD bytes;
+  uv_read_t* req = (uv_read_t*) parameter;
+  uv_pipe_t* handle = (uv_pipe_t*) req->data;
+  uv_loop_t* loop = handle->loop;
+  HANDLE hThread = NULL;
+  DWORD err;
+  uv_mutex_t *m = &handle->pipe.conn.readfile_mutex;
+
+  assert(req != NULL);
+  assert(req->type == UV_READ);
+  assert(handle->type == UV_NAMED_PIPE);
+
+  if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
+    uv_mutex_lock(m); /* mutex controls *setting* of readfile_thread */
+    if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
+                        GetCurrentProcess(), &hThread,
+                        0, TRUE, DUPLICATE_SAME_ACCESS)) {
+      handle->pipe.conn.readfile_thread = hThread;
+    } else {
+      hThread = NULL;
+    }
+    uv_mutex_unlock(m);
+  }
+restart_readfile:
+  result = ReadFile(handle->handle,
+                    &uv_zero_,
+                    0,
+                    &bytes,
+                    NULL);
+  if (!result) {
+    err = GetLastError();
+    if (err == ERROR_OPERATION_ABORTED &&
+        handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
+      if (handle->flags & UV_HANDLE_READING) {
+        /* just a brief break to do something else */
+        handle->pipe.conn.readfile_thread = NULL;
+        /* resume after it is finished */
+        uv_mutex_lock(m);
+        handle->pipe.conn.readfile_thread = hThread;
+        uv_mutex_unlock(m);
+        goto restart_readfile;
+      } else {
+        result = 1; /* successfully stopped reading */
+      }
+    }
+  }
+  if (hThread) {
+    assert(hThread == handle->pipe.conn.readfile_thread);
+    /* mutex does not control clearing readfile_thread */
+    handle->pipe.conn.readfile_thread = NULL;
+    uv_mutex_lock(m);
+    /* only when we hold the mutex lock is it safe to
+       open or close the handle */
+    CloseHandle(hThread);
+    uv_mutex_unlock(m);
+  }
+
+  if (!result) {
+    SET_REQ_ERROR(req, err);
+  }
+
+  POST_COMPLETION_FOR_REQ(loop, req);
+  return 0;
+}
+
+
+static DWORD WINAPI uv_pipe_writefile_thread_proc(void* parameter) {
+  int result;
+  DWORD bytes;
+  uv_write_t* req = (uv_write_t*) parameter;
+  uv_pipe_t* handle = (uv_pipe_t*) req->handle;
+  uv_loop_t* loop = handle->loop;
+
+  assert(req != NULL);
+  assert(req->type == UV_WRITE);
+  assert(handle->type == UV_NAMED_PIPE);
+  assert(req->write_buffer.base);
+
+  result = WriteFile(handle->handle,
+                     req->write_buffer.base,
+                     req->write_buffer.len,
+                     &bytes,
+                     NULL);
+
+  if (!result) {
+    SET_REQ_ERROR(req, GetLastError());
+  }
+
+  POST_COMPLETION_FOR_REQ(loop, req);
+  return 0;
+}
+
+
+static void CALLBACK post_completion_read_wait(void* context, BOOLEAN timed_out) {
+  uv_read_t* req;
+  uv_tcp_t* handle;
+
+  req = (uv_read_t*) context;
+  assert(req != NULL);
+  handle = (uv_tcp_t*)req->data;
+  assert(handle != NULL);
+  assert(!timed_out);
+
+  if (!PostQueuedCompletionStatus(handle->loop->iocp,
+                                  req->u.io.overlapped.InternalHigh,
+                                  0,
+                                  &req->u.io.overlapped)) {
+    uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
+  }
+}
+
+
+static void CALLBACK post_completion_write_wait(void* context, BOOLEAN timed_out) {
+  uv_write_t* req;
+  uv_tcp_t* handle;
+
+  req = (uv_write_t*) context;
+  assert(req != NULL);
+  handle = (uv_tcp_t*)req->handle;
+  assert(handle != NULL);
+  assert(!timed_out);
+
+  if (!PostQueuedCompletionStatus(handle->loop->iocp,
+                                  req->u.io.overlapped.InternalHigh,
+                                  0,
+                                  &req->u.io.overlapped)) {
+    uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
+  }
+}
+
+
+static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) {
+  uv_read_t* req;
+  int result;
+
+  assert(handle->flags & UV_HANDLE_READING);
+  assert(!(handle->flags & UV_HANDLE_READ_PENDING));
+
+  assert(handle->handle != INVALID_HANDLE_VALUE);
+
+  req = &handle->read_req;
+
+  if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
+    if (!QueueUserWorkItem(&uv_pipe_zero_readfile_thread_proc,
+                           req,
+                           WT_EXECUTELONGFUNCTION)) {
+      /* Make this req pending reporting an error. */
+      SET_REQ_ERROR(req, GetLastError());
+      goto error;
+    }
+  } else {
+    memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
+    if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+      req->u.io.overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1);
+    }
+
+    /* Do 0-read */
+    result = ReadFile(handle->handle,
+                      &uv_zero_,
+                      0,
+                      NULL,
+                      &req->u.io.overlapped);
+
+    if (!result && GetLastError() != ERROR_IO_PENDING) {
+      /* Make this req pending reporting an error. */
+      SET_REQ_ERROR(req, GetLastError());
+      goto error;
+    }
+
+    if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+      if (!req->event_handle) {
+        req->event_handle = CreateEvent(NULL, 0, 0, NULL);
+        if (!req->event_handle) {
+          uv_fatal_error(GetLastError(), "CreateEvent");
+        }
+      }
+      if (req->wait_handle == INVALID_HANDLE_VALUE) {
+        if (!RegisterWaitForSingleObject(&req->wait_handle,
+            req->u.io.overlapped.hEvent, post_completion_read_wait, (void*) req,
+            INFINITE, WT_EXECUTEINWAITTHREAD)) {
+          SET_REQ_ERROR(req, GetLastError());
+          goto error;
+        }
+      }
+    }
+  }
+
+  /* Start the eof timer if there is one */
+  eof_timer_start(handle);
+  handle->flags |= UV_HANDLE_READ_PENDING;
+  handle->reqs_pending++;
+  return;
+
+error:
+  uv_insert_pending_req(loop, (uv_req_t*)req);
+  handle->flags |= UV_HANDLE_READ_PENDING;
+  handle->reqs_pending++;
+}
+
+
+int uv_pipe_read_start(uv_pipe_t* handle,
+                       uv_alloc_cb alloc_cb,
+                       uv_read_cb read_cb) {
+  uv_loop_t* loop = handle->loop;
+
+  handle->flags |= UV_HANDLE_READING;
+  INCREASE_ACTIVE_COUNT(loop, handle);
+  handle->read_cb = read_cb;
+  handle->alloc_cb = alloc_cb;
+
+  /* If reading was stopped and then started again, there could still be a */
+  /* read request pending. */
+  if (!(handle->flags & UV_HANDLE_READ_PENDING))
+    uv_pipe_queue_read(loop, handle);
+
+  return 0;
+}
+
+
+static void uv_insert_non_overlapped_write_req(uv_pipe_t* handle,
+    uv_write_t* req) {
+  req->next_req = NULL;
+  if (handle->pipe.conn.non_overlapped_writes_tail) {
+    req->next_req =
+      handle->pipe.conn.non_overlapped_writes_tail->next_req;
+    handle->pipe.conn.non_overlapped_writes_tail->next_req = (uv_req_t*)req;
+    handle->pipe.conn.non_overlapped_writes_tail = req;
+  } else {
+    req->next_req = (uv_req_t*)req;
+    handle->pipe.conn.non_overlapped_writes_tail = req;
+  }
+}
+
+
+static uv_write_t* uv_remove_non_overlapped_write_req(uv_pipe_t* handle) {
+  uv_write_t* req;
+
+  if (handle->pipe.conn.non_overlapped_writes_tail) {
+    req = (uv_write_t*)handle->pipe.conn.non_overlapped_writes_tail->next_req;
+
+    if (req == handle->pipe.conn.non_overlapped_writes_tail) {
+      handle->pipe.conn.non_overlapped_writes_tail = NULL;
+    } else {
+      handle->pipe.conn.non_overlapped_writes_tail->next_req =
+        req->next_req;
+    }
+
+    return req;
+  } else {
+    /* queue empty */
+    return NULL;
+  }
+}
+
+
+static void uv_queue_non_overlapped_write(uv_pipe_t* handle) {
+  uv_write_t* req = uv_remove_non_overlapped_write_req(handle);
+  if (req) {
+    if (!QueueUserWorkItem(&uv_pipe_writefile_thread_proc,
+                           req,
+                           WT_EXECUTELONGFUNCTION)) {
+      uv_fatal_error(GetLastError(), "QueueUserWorkItem");
+    }
+  }
+}
+
+
+static int uv_pipe_write_impl(uv_loop_t* loop,
+                              uv_write_t* req,
+                              uv_pipe_t* handle,
+                              const uv_buf_t bufs[],
+                              unsigned int nbufs,
+                              uv_stream_t* send_handle,
+                              uv_write_cb cb) {
+  int err;
+  int result;
+  uv_tcp_t* tcp_send_handle;
+  uv_write_t* ipc_header_req = NULL;
+  uv_ipc_frame_uv_stream ipc_frame;
+
+  if (nbufs != 1 && (nbufs != 0 || !send_handle)) {
+    return ERROR_NOT_SUPPORTED;
+  }
+
+  /* Only TCP handles are supported for sharing. */
+  if (send_handle && ((send_handle->type != UV_TCP) ||
+      (!(send_handle->flags & UV_HANDLE_BOUND) &&
+       !(send_handle->flags & UV_HANDLE_CONNECTION)))) {
+    return ERROR_NOT_SUPPORTED;
+  }
+
+  assert(handle->handle != INVALID_HANDLE_VALUE);
+
+  uv_req_init(loop, (uv_req_t*) req);
+  req->type = UV_WRITE;
+  req->handle = (uv_stream_t*) handle;
+  req->cb = cb;
+  req->ipc_header = 0;
+  req->event_handle = NULL;
+  req->wait_handle = INVALID_HANDLE_VALUE;
+  memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
+
+  if (handle->ipc) {
+    assert(!(handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
+    ipc_frame.header.flags = 0;
+
+    /* Use the IPC framing protocol. */
+    if (send_handle) {
+      tcp_send_handle = (uv_tcp_t*)send_handle;
+
+      if (handle->pipe.conn.ipc_pid == 0) {
+          handle->pipe.conn.ipc_pid = uv_current_pid();
+      }
+
+      err = uv_tcp_duplicate_socket(tcp_send_handle, handle->pipe.conn.ipc_pid,
+          &ipc_frame.socket_info_ex.socket_info);
+      if (err) {
+        return err;
+      }
+
+      ipc_frame.socket_info_ex.delayed_error = tcp_send_handle->delayed_error;
+
+      ipc_frame.header.flags |= UV_IPC_TCP_SERVER;
+
+      if (tcp_send_handle->flags & UV_HANDLE_CONNECTION) {
+        ipc_frame.header.flags |= UV_IPC_TCP_CONNECTION;
+      }
+    }
+
+    if (nbufs == 1) {
+      ipc_frame.header.flags |= UV_IPC_RAW_DATA;
+      ipc_frame.header.raw_data_length = bufs[0].len;
+    }
+
+    /*
+     * Use the provided req if we're only doing a single write.
+     * If we're doing multiple writes, use ipc_header_write_req to do
+     * the first write, and then use the provided req for the second write.
+     */
+    if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) {
+      ipc_header_req = req;
+    } else {
+      /*
+       * Try to use the preallocated write req if it's available.
+       * Otherwise allocate a new one.
+       */
+      if (handle->pipe.conn.ipc_header_write_req.type != UV_WRITE) {
+        ipc_header_req = (uv_write_t*)&handle->pipe.conn.ipc_header_write_req;
+      } else {
+        ipc_header_req = (uv_write_t*)uv__malloc(sizeof(uv_write_t));
+        if (!ipc_header_req) {
+          uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+        }
+      }
+
+      uv_req_init(loop, (uv_req_t*) ipc_header_req);
+      ipc_header_req->type = UV_WRITE;
+      ipc_header_req->handle = (uv_stream_t*) handle;
+      ipc_header_req->cb = NULL;
+      ipc_header_req->ipc_header = 1;
+    }
+
+    /* Write the header or the whole frame. */
+    memset(&ipc_header_req->u.io.overlapped, 0,
+           sizeof(ipc_header_req->u.io.overlapped));
+
+    /* Using overlapped IO, but wait for completion before returning.
+       This write is blocking because ipc_frame is on stack. */
+    ipc_header_req->u.io.overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL);
+    if (!ipc_header_req->u.io.overlapped.hEvent) {
+      uv_fatal_error(GetLastError(), "CreateEvent");
+    }
+
+    result = WriteFile(handle->handle,
+                        &ipc_frame,
+                        ipc_frame.header.flags & UV_IPC_TCP_SERVER ?
+                          sizeof(ipc_frame) : sizeof(ipc_frame.header),
+                        NULL,
+                        &ipc_header_req->u.io.overlapped);
+    if (!result && GetLastError() != ERROR_IO_PENDING) {
+      err = GetLastError();
+      CloseHandle(ipc_header_req->u.io.overlapped.hEvent);
+      return err;
+    }
+
+    if (!result) {
+      /* Request not completed immediately. Wait for it.*/
+      if (WaitForSingleObject(ipc_header_req->u.io.overlapped.hEvent, INFINITE) !=
+          WAIT_OBJECT_0) {
+        err = GetLastError();
+        CloseHandle(ipc_header_req->u.io.overlapped.hEvent);
+        return err;
+      }
+    }
+    ipc_header_req->u.io.queued_bytes = 0;
+    CloseHandle(ipc_header_req->u.io.overlapped.hEvent);
+    ipc_header_req->u.io.overlapped.hEvent = NULL;
+
+    REGISTER_HANDLE_REQ(loop, handle, ipc_header_req);
+    handle->reqs_pending++;
+    handle->stream.conn.write_reqs_pending++;
+
+    /* If we don't have any raw data to write - we're done. */
+    if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) {
+      return 0;
+    }
+  }
+
+  if ((handle->flags &
+      (UV_HANDLE_BLOCKING_WRITES | UV_HANDLE_NON_OVERLAPPED_PIPE)) ==
+      (UV_HANDLE_BLOCKING_WRITES | UV_HANDLE_NON_OVERLAPPED_PIPE)) {
+    DWORD bytes;
+    result = WriteFile(handle->handle,
+                       bufs[0].base,
+                       bufs[0].len,
+                       &bytes,
+                       NULL);
+
+    if (!result) {
+      err = GetLastError();
+      return err;
+    } else {
+      /* Request completed immediately. */
+      req->u.io.queued_bytes = 0;
+    }
+
+    REGISTER_HANDLE_REQ(loop, handle, req);
+    handle->reqs_pending++;
+    handle->stream.conn.write_reqs_pending++;
+    POST_COMPLETION_FOR_REQ(loop, req);
+    return 0;
+  } else if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
+    req->write_buffer = bufs[0];
+    uv_insert_non_overlapped_write_req(handle, req);
+    if (handle->stream.conn.write_reqs_pending == 0) {
+      uv_queue_non_overlapped_write(handle);
+    }
+
+    /* Request queued by the kernel. */
+    req->u.io.queued_bytes = bufs[0].len;
+    handle->write_queue_size += req->u.io.queued_bytes;
+  } else if (handle->flags & UV_HANDLE_BLOCKING_WRITES) {
+    /* Using overlapped IO, but wait for completion before returning */
+    req->u.io.overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL);
+    if (!req->u.io.overlapped.hEvent) {
+      uv_fatal_error(GetLastError(), "CreateEvent");
+    }
+
+    result = WriteFile(handle->handle,
+                       bufs[0].base,
+                       bufs[0].len,
+                       NULL,
+                       &req->u.io.overlapped);
+
+    if (!result && GetLastError() != ERROR_IO_PENDING) {
+      err = GetLastError();
+      CloseHandle(req->u.io.overlapped.hEvent);
+      return err;
+    }
+
+    if (result) {
+      /* Request completed immediately. */
+      req->u.io.queued_bytes = 0;
+    } else {
+      /* Request queued by the kernel. */
+      req->u.io.queued_bytes = bufs[0].len;
+      handle->write_queue_size += req->u.io.queued_bytes;
+      if (WaitForSingleObject(req->u.io.overlapped.hEvent, INFINITE) !=
+          WAIT_OBJECT_0) {
+        err = GetLastError();
+        CloseHandle(req->u.io.overlapped.hEvent);
+        return uv_translate_sys_error(err);
+      }
+    }
+    CloseHandle(req->u.io.overlapped.hEvent);
+
+    REGISTER_HANDLE_REQ(loop, handle, req);
+    handle->reqs_pending++;
+    handle->stream.conn.write_reqs_pending++;
+    return 0;
+  } else {
+    result = WriteFile(handle->handle,
+                       bufs[0].base,
+                       bufs[0].len,
+                       NULL,
+                       &req->u.io.overlapped);
+
+    if (!result && GetLastError() != ERROR_IO_PENDING) {
+      return GetLastError();
+    }
+
+    if (result) {
+      /* Request completed immediately. */
+      req->u.io.queued_bytes = 0;
+    } else {
+      /* Request queued by the kernel. */
+      req->u.io.queued_bytes = bufs[0].len;
+      handle->write_queue_size += req->u.io.queued_bytes;
+    }
+
+    if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+      req->event_handle = CreateEvent(NULL, 0, 0, NULL);
+      if (!req->event_handle) {
+        uv_fatal_error(GetLastError(), "CreateEvent");
+      }
+      if (!RegisterWaitForSingleObject(&req->wait_handle,
+          req->u.io.overlapped.hEvent, post_completion_write_wait, (void*) req,
+          INFINITE, WT_EXECUTEINWAITTHREAD)) {
+        return GetLastError();
+      }
+    }
+  }
+
+  REGISTER_HANDLE_REQ(loop, handle, req);
+  handle->reqs_pending++;
+  handle->stream.conn.write_reqs_pending++;
+
+  return 0;
+}
+
+
+int uv_pipe_write(uv_loop_t* loop,
+                  uv_write_t* req,
+                  uv_pipe_t* handle,
+                  const uv_buf_t bufs[],
+                  unsigned int nbufs,
+                  uv_write_cb cb) {
+  return uv_pipe_write_impl(loop, req, handle, bufs, nbufs, NULL, cb);
+}
+
+
+int uv_pipe_write2(uv_loop_t* loop,
+                   uv_write_t* req,
+                   uv_pipe_t* handle,
+                   const uv_buf_t bufs[],
+                   unsigned int nbufs,
+                   uv_stream_t* send_handle,
+                   uv_write_cb cb) {
+  if (!handle->ipc) {
+    return WSAEINVAL;
+  }
+
+  return uv_pipe_write_impl(loop, req, handle, bufs, nbufs, send_handle, cb);
+}
+
+
+static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle,
+    uv_buf_t buf) {
+  /* If there is an eof timer running, we don't need it any more, */
+  /* so discard it. */
+  eof_timer_destroy(handle);
+
+  handle->flags &= ~UV_HANDLE_READABLE;
+  uv_read_stop((uv_stream_t*) handle);
+
+  handle->read_cb((uv_stream_t*) handle, UV_EOF, &buf);
+}
+
+
+static void uv_pipe_read_error(uv_loop_t* loop, uv_pipe_t* handle, int error,
+    uv_buf_t buf) {
+  /* If there is an eof timer running, we don't need it any more, */
+  /* so discard it. */
+  eof_timer_destroy(handle);
+
+  uv_read_stop((uv_stream_t*) handle);
+
+  handle->read_cb((uv_stream_t*)handle, uv_translate_sys_error(error), &buf);
+}
+
+
+static void uv_pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle,
+    int error, uv_buf_t buf) {
+  if (error == ERROR_BROKEN_PIPE) {
+    uv_pipe_read_eof(loop, handle, buf);
+  } else {
+    uv_pipe_read_error(loop, handle, error, buf);
+  }
+}
+
+
+void uv__pipe_insert_pending_socket(uv_pipe_t* handle,
+                                    uv__ipc_socket_info_ex* info,
+                                    int tcp_connection) {
+  uv__ipc_queue_item_t* item;
+
+  item = (uv__ipc_queue_item_t*) uv__malloc(sizeof(*item));
+  if (item == NULL)
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+
+  memcpy(&item->socket_info_ex, info, sizeof(item->socket_info_ex));
+  item->tcp_connection = tcp_connection;
+  QUEUE_INSERT_TAIL(&handle->pipe.conn.pending_ipc_info.queue, &item->member);
+  handle->pipe.conn.pending_ipc_info.queue_len++;
+}
+
+
+void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
+    uv_req_t* req) {
+  DWORD bytes, avail;
+  uv_buf_t buf;
+  uv_ipc_frame_uv_stream ipc_frame;
+
+  assert(handle->type == UV_NAMED_PIPE);
+
+  handle->flags &= ~UV_HANDLE_READ_PENDING;
+  eof_timer_stop(handle);
+
+  if (!REQ_SUCCESS(req)) {
+    /* An error occurred doing the 0-read. */
+    if (handle->flags & UV_HANDLE_READING) {
+      uv_pipe_read_error_or_eof(loop,
+                                handle,
+                                GET_REQ_ERROR(req),
+                                uv_null_buf_);
+    }
+  } else {
+    /* Do non-blocking reads until the buffer is empty */
+    while (handle->flags & UV_HANDLE_READING) {
+      if (!PeekNamedPipe(handle->handle,
+                          NULL,
+                          0,
+                          NULL,
+                          &avail,
+                          NULL)) {
+        uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_);
+        break;
+      }
+
+      if (avail == 0) {
+        /* There is nothing to read after all. */
+        break;
+      }
+
+      if (handle->ipc) {
+        /* Use the IPC framing protocol to read the incoming data. */
+        if (handle->pipe.conn.remaining_ipc_rawdata_bytes == 0) {
+          /* We're reading a new frame.  First, read the header. */
+          assert(avail >= sizeof(ipc_frame.header));
+
+          if (!ReadFile(handle->handle,
+                        &ipc_frame.header,
+                        sizeof(ipc_frame.header),
+                        &bytes,
+                        NULL)) {
+            uv_pipe_read_error_or_eof(loop, handle, GetLastError(),
+              uv_null_buf_);
+            break;
+          }
+
+          assert(bytes == sizeof(ipc_frame.header));
+          assert(ipc_frame.header.flags <= (UV_IPC_TCP_SERVER | UV_IPC_RAW_DATA |
+            UV_IPC_TCP_CONNECTION));
+
+          if (ipc_frame.header.flags & UV_IPC_TCP_SERVER) {
+            assert(avail - sizeof(ipc_frame.header) >=
+              sizeof(ipc_frame.socket_info_ex));
+
+            /* Read the TCP socket info. */
+            if (!ReadFile(handle->handle,
+                          &ipc_frame.socket_info_ex,
+                          sizeof(ipc_frame) - sizeof(ipc_frame.header),
+                          &bytes,
+                          NULL)) {
+              uv_pipe_read_error_or_eof(loop, handle, GetLastError(),
+                uv_null_buf_);
+              break;
+            }
+
+            assert(bytes == sizeof(ipc_frame) - sizeof(ipc_frame.header));
+
+            /* Store the pending socket info. */
+            uv__pipe_insert_pending_socket(
+                handle,
+                &ipc_frame.socket_info_ex,
+                ipc_frame.header.flags & UV_IPC_TCP_CONNECTION);
+          }
+
+          if (ipc_frame.header.flags & UV_IPC_RAW_DATA) {
+            handle->pipe.conn.remaining_ipc_rawdata_bytes =
+              ipc_frame.header.raw_data_length;
+            continue;
+          }
+        } else {
+          avail = min(avail, (DWORD)handle->pipe.conn.remaining_ipc_rawdata_bytes);
+        }
+      }
+
+      buf = uv_buf_init(NULL, 0);
+      handle->alloc_cb((uv_handle_t*) handle, avail, &buf);
+      if (buf.base == NULL || buf.len == 0) {
+        handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf);
+        break;
+      }
+      assert(buf.base != NULL);
+
+      if (ReadFile(handle->handle,
+                   buf.base,
+                   min(buf.len, avail),
+                   &bytes,
+                   NULL)) {
+        /* Successful read */
+        if (handle->ipc) {
+          assert(handle->pipe.conn.remaining_ipc_rawdata_bytes >= bytes);
+          handle->pipe.conn.remaining_ipc_rawdata_bytes =
+            handle->pipe.conn.remaining_ipc_rawdata_bytes - bytes;
+        }
+        handle->read_cb((uv_stream_t*)handle, bytes, &buf);
+
+        /* Read again only if bytes == buf.len */
+        if (bytes <= buf.len) {
+          break;
+        }
+      } else {
+        uv_pipe_read_error_or_eof(loop, handle, GetLastError(), buf);
+        break;
+      }
+    }
+
+    /* Post another 0-read if still reading and not closing. */
+    if ((handle->flags & UV_HANDLE_READING) &&
+        !(handle->flags & UV_HANDLE_READ_PENDING)) {
+      uv_pipe_queue_read(loop, handle);
+    }
+  }
+
+  DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
+    uv_write_t* req) {
+  int err;
+
+  assert(handle->type == UV_NAMED_PIPE);
+
+  assert(handle->write_queue_size >= req->u.io.queued_bytes);
+  handle->write_queue_size -= req->u.io.queued_bytes;
+
+  UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+    if (req->wait_handle != INVALID_HANDLE_VALUE) {
+      UnregisterWait(req->wait_handle);
+      req->wait_handle = INVALID_HANDLE_VALUE;
+    }
+    if (req->event_handle) {
+      CloseHandle(req->event_handle);
+      req->event_handle = NULL;
+    }
+  }
+
+  if (req->ipc_header) {
+    if (req == &handle->pipe.conn.ipc_header_write_req) {
+      req->type = UV_UNKNOWN_REQ;
+    } else {
+      uv__free(req);
+    }
+  } else {
+    if (req->cb) {
+      err = GET_REQ_ERROR(req);
+      req->cb(req, uv_translate_sys_error(err));
+    }
+  }
+
+  handle->stream.conn.write_reqs_pending--;
+
+  if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE &&
+      handle->pipe.conn.non_overlapped_writes_tail) {
+    assert(handle->stream.conn.write_reqs_pending > 0);
+    uv_queue_non_overlapped_write(handle);
+  }
+
+  if (handle->stream.conn.shutdown_req != NULL &&
+      handle->stream.conn.write_reqs_pending == 0) {
+    uv_want_endgame(loop, (uv_handle_t*)handle);
+  }
+
+  DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle,
+    uv_req_t* raw_req) {
+  uv_pipe_accept_t* req = (uv_pipe_accept_t*) raw_req;
+
+  assert(handle->type == UV_NAMED_PIPE);
+
+  if (handle->flags & UV__HANDLE_CLOSING) {
+    /* The req->pipeHandle should be freed already in uv_pipe_cleanup(). */
+    assert(req->pipeHandle == INVALID_HANDLE_VALUE);
+    DECREASE_PENDING_REQ_COUNT(handle);
+    return;
+  }
+
+  if (REQ_SUCCESS(req)) {
+    assert(req->pipeHandle != INVALID_HANDLE_VALUE);
+    req->next_pending = handle->pipe.serv.pending_accepts;
+    handle->pipe.serv.pending_accepts = req;
+
+    if (handle->stream.serv.connection_cb) {
+      handle->stream.serv.connection_cb((uv_stream_t*)handle, 0);
+    }
+  } else {
+    if (req->pipeHandle != INVALID_HANDLE_VALUE) {
+      CloseHandle(req->pipeHandle);
+      req->pipeHandle = INVALID_HANDLE_VALUE;
+    }
+    if (!(handle->flags & UV__HANDLE_CLOSING)) {
+      uv_pipe_queue_accept(loop, handle, req, FALSE);
+    }
+  }
+
+  DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle,
+    uv_connect_t* req) {
+  int err;
+
+  assert(handle->type == UV_NAMED_PIPE);
+
+  UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+  if (req->cb) {
+    err = 0;
+    if (REQ_SUCCESS(req)) {
+      uv_pipe_connection_init(handle);
+    } else {
+      err = GET_REQ_ERROR(req);
+    }
+    req->cb(req, uv_translate_sys_error(err));
+  }
+
+  DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
+    uv_shutdown_t* req) {
+  assert(handle->type == UV_NAMED_PIPE);
+
+  UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+  if (handle->flags & UV_HANDLE_READABLE) {
+    /* Initialize and optionally start the eof timer. Only do this if the */
+    /* pipe is readable and we haven't seen EOF come in ourselves. */
+    eof_timer_init(handle);
+
+    /* If reading start the timer right now. */
+    /* Otherwise uv_pipe_queue_read will start it. */
+    if (handle->flags & UV_HANDLE_READ_PENDING) {
+      eof_timer_start(handle);
+    }
+
+  } else {
+    /* This pipe is not readable. We can just close it to let the other end */
+    /* know that we're done writing. */
+    close_pipe(handle);
+  }
+
+  if (req->cb) {
+    req->cb(req, 0);
+  }
+
+  DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+static void eof_timer_init(uv_pipe_t* pipe) {
+  int r;
+
+  assert(pipe->pipe.conn.eof_timer == NULL);
+  assert(pipe->flags & UV_HANDLE_CONNECTION);
+
+  pipe->pipe.conn.eof_timer = (uv_timer_t*) uv__malloc(sizeof *pipe->pipe.conn.eof_timer);
+
+  r = uv_timer_init(pipe->loop, pipe->pipe.conn.eof_timer);
+  assert(r == 0); /* timers can't fail */
+  pipe->pipe.conn.eof_timer->data = pipe;
+  uv_unref((uv_handle_t*) pipe->pipe.conn.eof_timer);
+}
+
+
+static void eof_timer_start(uv_pipe_t* pipe) {
+  assert(pipe->flags & UV_HANDLE_CONNECTION);
+
+  if (pipe->pipe.conn.eof_timer != NULL) {
+    uv_timer_start(pipe->pipe.conn.eof_timer, eof_timer_cb, eof_timeout, 0);
+  }
+}
+
+
+static void eof_timer_stop(uv_pipe_t* pipe) {
+  assert(pipe->flags & UV_HANDLE_CONNECTION);
+
+  if (pipe->pipe.conn.eof_timer != NULL) {
+    uv_timer_stop(pipe->pipe.conn.eof_timer);
+  }
+}
+
+
+static void eof_timer_cb(uv_timer_t* timer) {
+  uv_pipe_t* pipe = (uv_pipe_t*) timer->data;
+  uv_loop_t* loop = timer->loop;
+
+  assert(pipe->type == UV_NAMED_PIPE);
+
+  /* This should always be true, since we start the timer only */
+  /* in uv_pipe_queue_read after successfully calling ReadFile, */
+  /* or in uv_process_pipe_shutdown_req if a read is pending, */
+  /* and we always immediately stop the timer in */
+  /* uv_process_pipe_read_req. */
+  assert(pipe->flags & UV_HANDLE_READ_PENDING);
+
+  /* If there are many packets coming off the iocp then the timer callback */
+  /* may be called before the read request is coming off the queue. */
+  /* Therefore we check here if the read request has completed but will */
+  /* be processed later. */
+  if ((pipe->flags & UV_HANDLE_READ_PENDING) &&
+      HasOverlappedIoCompleted(&pipe->read_req.u.io.overlapped)) {
+    return;
+  }
+
+  /* Force both ends off the pipe. */
+  close_pipe(pipe);
+
+  /* Stop reading, so the pending read that is going to fail will */
+  /* not be reported to the user. */
+  uv_read_stop((uv_stream_t*) pipe);
+
+  /* Report the eof and update flags. This will get reported even if the */
+  /* user stopped reading in the meantime. TODO: is that okay? */
+  uv_pipe_read_eof(loop, pipe, uv_null_buf_);
+}
+
+
+static void eof_timer_destroy(uv_pipe_t* pipe) {
+  assert(pipe->flags & UV_HANDLE_CONNECTION);
+
+  if (pipe->pipe.conn.eof_timer) {
+    uv_close((uv_handle_t*) pipe->pipe.conn.eof_timer, eof_timer_close_cb);
+    pipe->pipe.conn.eof_timer = NULL;
+  }
+}
+
+
+static void eof_timer_close_cb(uv_handle_t* handle) {
+  assert(handle->type == UV_TIMER);
+  uv__free(handle);
+}
+
+
+int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
+  HANDLE os_handle = uv__get_osfhandle(file);
+  NTSTATUS nt_status;
+  IO_STATUS_BLOCK io_status;
+  FILE_ACCESS_INFORMATION access;
+  DWORD duplex_flags = 0;
+
+  if (os_handle == INVALID_HANDLE_VALUE)
+    return UV_EBADF;
+
+  /* In order to avoid closing a stdio file descriptor 0-2, duplicate the
+   * underlying OS handle and forget about the original fd.
+   * We could also opt to use the original OS handle and just never close it,
+   * but then there would be no reliable way to cancel pending read operations
+   * upon close.
+   */
+  if (file <= 2) {
+    if (!DuplicateHandle(INVALID_HANDLE_VALUE,
+                         os_handle,
+                         INVALID_HANDLE_VALUE,
+                         &os_handle,
+                         0,
+                         FALSE,
+                         DUPLICATE_SAME_ACCESS))
+      return uv_translate_sys_error(GetLastError());
+    file = -1;
+  }
+
+  /* Determine what kind of permissions we have on this handle.
+   * Cygwin opens the pipe in message mode, but we can support it,
+   * just query the access flags and set the stream flags accordingly.
+   */
+  nt_status = pNtQueryInformationFile(os_handle,
+                                      &io_status,
+                                      &access,
+                                      sizeof(access),
+                                      FileAccessInformation);
+  if (nt_status != STATUS_SUCCESS)
+    return UV_EINVAL;
+
+  if (pipe->ipc) {
+    if (!(access.AccessFlags & FILE_WRITE_DATA) ||
+        !(access.AccessFlags & FILE_READ_DATA)) {
+      return UV_EINVAL;
+    }
+  }
+
+  if (access.AccessFlags & FILE_WRITE_DATA)
+    duplex_flags |= UV_HANDLE_WRITABLE;
+  if (access.AccessFlags & FILE_READ_DATA)
+    duplex_flags |= UV_HANDLE_READABLE;
+
+  if (os_handle == INVALID_HANDLE_VALUE ||
+      uv_set_pipe_handle(pipe->loop,
+                         pipe,
+                         os_handle,
+                         file,
+                         duplex_flags) == -1) {
+    return UV_EINVAL;
+  }
+
+  uv_pipe_connection_init(pipe);
+
+  if (pipe->ipc) {
+    assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
+    pipe->pipe.conn.ipc_pid = uv_parent_pid();
+    assert(pipe->pipe.conn.ipc_pid != -1);
+  }
+  return 0;
+}
+
+
+static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size) {
+  NTSTATUS nt_status;
+  IO_STATUS_BLOCK io_status;
+  FILE_NAME_INFORMATION tmp_name_info;
+  FILE_NAME_INFORMATION* name_info;
+  WCHAR* name_buf;
+  unsigned int addrlen;
+  unsigned int name_size;
+  unsigned int name_len;
+  int err;
+
+  name_info = NULL;
+
+  if (handle->handle == INVALID_HANDLE_VALUE) {
+    *size = 0;
+    return UV_EINVAL;
+  }
+
+  uv__pipe_pause_read((uv_pipe_t*)handle); /* cast away const warning */
+
+  nt_status = pNtQueryInformationFile(handle->handle,
+                                      &io_status,
+                                      &tmp_name_info,
+                                      sizeof tmp_name_info,
+                                      FileNameInformation);
+  if (nt_status == STATUS_BUFFER_OVERFLOW) {
+    name_size = sizeof(*name_info) + tmp_name_info.FileNameLength;
+    name_info = uv__malloc(name_size);
+    if (!name_info) {
+      *size = 0;
+      err = UV_ENOMEM;
+      goto cleanup;
+    }
+
+    nt_status = pNtQueryInformationFile(handle->handle,
+                                        &io_status,
+                                        name_info,
+                                        name_size,
+                                        FileNameInformation);
+  }
+
+  if (nt_status != STATUS_SUCCESS) {
+    *size = 0;
+    err = uv_translate_sys_error(pRtlNtStatusToDosError(nt_status));
+    goto error;
+  }
+
+  if (!name_info) {
+    /* the struct on stack was used */
+    name_buf = tmp_name_info.FileName;
+    name_len = tmp_name_info.FileNameLength;
+  } else {
+    name_buf = name_info->FileName;
+    name_len = name_info->FileNameLength;
+  }
+
+  if (name_len == 0) {
+    *size = 0;
+    err = 0;
+    goto error;
+  }
+
+  name_len /= sizeof(WCHAR);
+
+  /* check how much space we need */
+  addrlen = WideCharToMultiByte(CP_UTF8,
+                                0,
+                                name_buf,
+                                name_len,
+                                NULL,
+                                0,
+                                NULL,
+                                NULL);
+  if (!addrlen) {
+    *size = 0;
+    err = uv_translate_sys_error(GetLastError());
+    goto error;
+  } else if (pipe_prefix_len + addrlen >= *size) {
+    /* "\\\\.\\pipe" + name */
+    *size = pipe_prefix_len + addrlen + 1;
+    err = UV_ENOBUFS;
+    goto error;
+  }
+
+  memcpy(buffer, pipe_prefix, pipe_prefix_len);
+  addrlen = WideCharToMultiByte(CP_UTF8,
+                                0,
+                                name_buf,
+                                name_len,
+                                buffer+pipe_prefix_len,
+                                *size-pipe_prefix_len,
+                                NULL,
+                                NULL);
+  if (!addrlen) {
+    *size = 0;
+    err = uv_translate_sys_error(GetLastError());
+    goto error;
+  }
+
+  addrlen += pipe_prefix_len;
+  *size = addrlen;
+  buffer[addrlen] = '\0';
+
+  err = 0;
+  goto cleanup;
+
+error:
+  uv__free(name_info);
+
+cleanup:
+  uv__pipe_unpause_read((uv_pipe_t*)handle); /* cast away const warning */
+  return err;
+}
+
+
+int uv_pipe_pending_count(uv_pipe_t* handle) {
+  if (!handle->ipc)
+    return 0;
+  return handle->pipe.conn.pending_ipc_info.queue_len;
+}
+
+
+int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) {
+  if (handle->flags & UV_HANDLE_BOUND)
+    return uv__pipe_getname(handle, buffer, size);
+
+  if (handle->flags & UV_HANDLE_CONNECTION ||
+      handle->handle != INVALID_HANDLE_VALUE) {
+    *size = 0;
+    return 0;
+  }
+
+  return UV_EBADF;
+}
+
+
+int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) {
+  /* emulate unix behaviour */
+  if (handle->flags & UV_HANDLE_BOUND)
+    return UV_ENOTCONN;
+
+  if (handle->handle != INVALID_HANDLE_VALUE)
+    return uv__pipe_getname(handle, buffer, size);
+
+  return UV_EBADF;
+}
+
+
+uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) {
+  if (!handle->ipc)
+    return UV_UNKNOWN_HANDLE;
+  if (handle->pipe.conn.pending_ipc_info.queue_len == 0)
+    return UV_UNKNOWN_HANDLE;
+  else
+    return UV_TCP;
+}
diff --git a/deps/libtuv/src/win/poll.c b/deps/libtuv/src/win/poll.c
new file mode 100644 (file)
index 0000000..d479e52
--- /dev/null
@@ -0,0 +1,646 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <io.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+
+static const GUID uv_msafd_provider_ids[UV_MSAFD_PROVIDER_COUNT] = {
+  {0xe70f1aa0, 0xab8b, 0x11cf,
+      {0x8c, 0xa3, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}},
+  {0xf9eab0c0, 0x26d4, 0x11d0,
+      {0xbb, 0xbf, 0x00, 0xaa, 0x00, 0x6c, 0x34, 0xe4}},
+  {0x9fc48064, 0x7298, 0x43e4,
+      {0xb7, 0xbd, 0x18, 0x1f, 0x20, 0x89, 0x79, 0x2a}}
+};
+
+typedef struct uv_single_fd_set_s {
+  unsigned int fd_count;
+  SOCKET fd_array[1];
+} uv_single_fd_set_t;
+
+
+static OVERLAPPED overlapped_dummy_;
+static uv_once_t overlapped_dummy_init_guard_ = UV_ONCE_INIT;
+
+static AFD_POLL_INFO afd_poll_info_dummy_;
+
+
+static void uv__init_overlapped_dummy(void) {
+  HANDLE event;
+
+  event = CreateEvent(NULL, TRUE, TRUE, NULL);
+  if (event == NULL)
+    uv_fatal_error(GetLastError(), "CreateEvent");
+
+  memset(&overlapped_dummy_, 0, sizeof overlapped_dummy_);
+  overlapped_dummy_.hEvent = (HANDLE) ((uintptr_t) event | 1);
+}
+
+
+static OVERLAPPED* uv__get_overlapped_dummy() {
+  uv_once(&overlapped_dummy_init_guard_, uv__init_overlapped_dummy);
+  return &overlapped_dummy_;
+}
+
+
+static AFD_POLL_INFO* uv__get_afd_poll_info_dummy() {
+  return &afd_poll_info_dummy_;
+}
+
+
+static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
+  uv_req_t* req;
+  AFD_POLL_INFO* afd_poll_info;
+  DWORD result;
+
+  /* Find a yet unsubmitted req to submit. */
+  if (handle->submitted_events_1 == 0) {
+    req = &handle->poll_req_1;
+    afd_poll_info = &handle->afd_poll_info_1;
+    handle->submitted_events_1 = handle->events;
+    handle->mask_events_1 = 0;
+    handle->mask_events_2 = handle->events;
+  } else if (handle->submitted_events_2 == 0) {
+    req = &handle->poll_req_2;
+    afd_poll_info = &handle->afd_poll_info_2;
+    handle->submitted_events_2 = handle->events;
+    handle->mask_events_1 = handle->events;
+    handle->mask_events_2 = 0;
+  } else {
+    /* Just wait until there's an unsubmitted req. */
+    /* This will happen almost immediately as one of the 2 outstanding */
+    /* requests is about to return. When this happens, */
+    /* uv__fast_poll_process_poll_req will be called, and the pending */
+    /* events, if needed, will be processed in a subsequent request. */
+    return;
+  }
+
+  /* Setting Exclusive to TRUE makes the other poll request return if there */
+  /* is any. */
+  afd_poll_info->Exclusive = TRUE;
+  afd_poll_info->NumberOfHandles = 1;
+  afd_poll_info->Timeout.QuadPart = INT64_MAX;
+  afd_poll_info->Handles[0].Handle = (HANDLE) handle->socket;
+  afd_poll_info->Handles[0].Status = 0;
+  afd_poll_info->Handles[0].Events = 0;
+
+  if (handle->events & UV_READABLE) {
+    afd_poll_info->Handles[0].Events |= AFD_POLL_RECEIVE |
+        AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT;
+  } else {
+    if (handle->events & UV_DISCONNECT) {
+      afd_poll_info->Handles[0].Events |= AFD_POLL_DISCONNECT;
+    }
+  }
+  if (handle->events & UV_WRITABLE) {
+    afd_poll_info->Handles[0].Events |= AFD_POLL_SEND | AFD_POLL_CONNECT_FAIL;
+  }
+
+  memset(&req->u.io.overlapped, 0, sizeof req->u.io.overlapped);
+
+  result = uv_msafd_poll((SOCKET) handle->peer_socket,
+                         afd_poll_info,
+                         afd_poll_info,
+                         &req->u.io.overlapped);
+  if (result != 0 && WSAGetLastError() != WSA_IO_PENDING) {
+    /* Queue this req, reporting an error. */
+    SET_REQ_ERROR(req, WSAGetLastError());
+    uv_insert_pending_req(loop, req);
+  }
+}
+
+
+static int uv__fast_poll_cancel_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
+  AFD_POLL_INFO afd_poll_info;
+  DWORD result;
+
+  afd_poll_info.Exclusive = TRUE;
+  afd_poll_info.NumberOfHandles = 1;
+  afd_poll_info.Timeout.QuadPart = INT64_MAX;
+  afd_poll_info.Handles[0].Handle = (HANDLE) handle->socket;
+  afd_poll_info.Handles[0].Status = 0;
+  afd_poll_info.Handles[0].Events = AFD_POLL_ALL;
+
+  result = uv_msafd_poll(handle->socket,
+                         &afd_poll_info,
+                         uv__get_afd_poll_info_dummy(),
+                         uv__get_overlapped_dummy());
+
+  if (result == SOCKET_ERROR) {
+    DWORD error = WSAGetLastError();
+    if (error != WSA_IO_PENDING)
+      return error;
+  }
+
+  return 0;
+}
+
+
+static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
+    uv_req_t* req) {
+  unsigned char mask_events;
+  AFD_POLL_INFO* afd_poll_info;
+
+  if (req == &handle->poll_req_1) {
+    afd_poll_info = &handle->afd_poll_info_1;
+    handle->submitted_events_1 = 0;
+    mask_events = handle->mask_events_1;
+  } else if (req == &handle->poll_req_2) {
+    afd_poll_info = &handle->afd_poll_info_2;
+    handle->submitted_events_2 = 0;
+    mask_events = handle->mask_events_2;
+  } else {
+    assert(0);
+    return;
+  }
+
+  /* Report an error unless the select was just interrupted. */
+  if (!REQ_SUCCESS(req)) {
+    DWORD error = GET_REQ_SOCK_ERROR(req);
+    if (error != WSAEINTR && handle->events != 0) {
+      handle->events = 0; /* Stop the watcher */
+      handle->poll_cb(handle, uv_translate_sys_error(error), 0);
+    }
+
+  } else if (afd_poll_info->NumberOfHandles >= 1) {
+    unsigned char events = 0;
+
+    if ((afd_poll_info->Handles[0].Events & (AFD_POLL_RECEIVE |
+        AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT)) != 0) {
+      events |= UV_READABLE;
+      if ((afd_poll_info->Handles[0].Events & AFD_POLL_DISCONNECT) != 0) {
+        events |= UV_DISCONNECT;
+      }
+    }
+    if ((afd_poll_info->Handles[0].Events & (AFD_POLL_SEND |
+        AFD_POLL_CONNECT_FAIL)) != 0) {
+      events |= UV_WRITABLE;
+    }
+
+    events &= handle->events & ~mask_events;
+
+    if (afd_poll_info->Handles[0].Events & AFD_POLL_LOCAL_CLOSE) {
+      /* Stop polling. */
+      handle->events = 0;
+      if (uv__is_active(handle))
+        uv__handle_stop(handle);
+    }
+
+    if (events != 0) {
+      handle->poll_cb(handle, 0, events);
+    }
+  }
+
+  if ((handle->events & ~(handle->submitted_events_1 |
+      handle->submitted_events_2)) != 0) {
+    uv__fast_poll_submit_poll_req(loop, handle);
+  } else if ((handle->flags & UV__HANDLE_CLOSING) &&
+             handle->submitted_events_1 == 0 &&
+             handle->submitted_events_2 == 0) {
+    uv_want_endgame(loop, (uv_handle_t*) handle);
+  }
+}
+
+
+static int uv__fast_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
+  assert(handle->type == UV_POLL);
+  assert(!(handle->flags & UV__HANDLE_CLOSING));
+  assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0);
+
+  handle->events = events;
+
+  if (handle->events != 0) {
+    uv__handle_start(handle);
+  } else {
+    uv__handle_stop(handle);
+  }
+
+  if ((handle->events & ~(handle->submitted_events_1 |
+      handle->submitted_events_2)) != 0) {
+    uv__fast_poll_submit_poll_req(handle->loop, handle);
+  }
+
+  return 0;
+}
+
+
+static int uv__fast_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
+  handle->events = 0;
+  uv__handle_closing(handle);
+
+  if (handle->submitted_events_1 == 0 &&
+      handle->submitted_events_2 == 0) {
+    uv_want_endgame(loop, (uv_handle_t*) handle);
+    return 0;
+  } else {
+    /* Cancel outstanding poll requests by executing another, unique poll */
+    /* request that forces the outstanding ones to return. */
+    return uv__fast_poll_cancel_poll_req(loop, handle);
+  }
+}
+
+
+static SOCKET uv__fast_poll_create_peer_socket(HANDLE iocp,
+    WSAPROTOCOL_INFOW* protocol_info) {
+  SOCKET sock = 0;
+
+  sock = WSASocketW(protocol_info->iAddressFamily,
+                    protocol_info->iSocketType,
+                    protocol_info->iProtocol,
+                    protocol_info,
+                    0,
+                    WSA_FLAG_OVERLAPPED);
+  if (sock == INVALID_SOCKET) {
+    return INVALID_SOCKET;
+  }
+
+  if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) {
+    goto error;
+  };
+
+  if (CreateIoCompletionPort((HANDLE) sock,
+                             iocp,
+                             (ULONG_PTR) sock,
+                             0) == NULL) {
+    goto error;
+  }
+
+  return sock;
+
+ error:
+  closesocket(sock);
+  return INVALID_SOCKET;
+}
+
+
+static SOCKET uv__fast_poll_get_peer_socket(uv_loop_t* loop,
+    WSAPROTOCOL_INFOW* protocol_info) {
+  int index, i;
+  SOCKET peer_socket;
+
+  index = -1;
+  for (i = 0; (size_t) i < ARRAY_SIZE(uv_msafd_provider_ids); i++) {
+    if (memcmp((void*) &protocol_info->ProviderId,
+               (void*) &uv_msafd_provider_ids[i],
+               sizeof protocol_info->ProviderId) == 0) {
+      index = i;
+    }
+  }
+
+  /* Check if the protocol uses an msafd socket. */
+  if (index < 0) {
+    return INVALID_SOCKET;
+  }
+
+  /* If we didn't (try) to create a peer socket yet, try to make one. Don't */
+  /* try again if the peer socket creation failed earlier for the same */
+  /* protocol. */
+  peer_socket = loop->poll_peer_sockets[index];
+  if (peer_socket == 0) {
+    peer_socket = uv__fast_poll_create_peer_socket(loop->iocp, protocol_info);
+    loop->poll_peer_sockets[index] = peer_socket;
+  }
+
+  return peer_socket;
+}
+
+
+static DWORD WINAPI uv__slow_poll_thread_proc(void* arg) {
+  uv_req_t* req = (uv_req_t*) arg;
+  uv_poll_t* handle = (uv_poll_t*) req->data;
+  unsigned char reported_events;
+  int r;
+  uv_single_fd_set_t rfds, wfds, efds;
+  struct timeval timeout;
+
+  assert(handle->type == UV_POLL);
+  assert(req->type == UV_POLL_REQ);
+
+  if (handle->events & UV_READABLE) {
+    rfds.fd_count = 1;
+    rfds.fd_array[0] = handle->socket;
+  } else {
+    rfds.fd_count = 0;
+  }
+
+  if (handle->events & UV_WRITABLE) {
+    wfds.fd_count = 1;
+    wfds.fd_array[0] = handle->socket;
+    efds.fd_count = 1;
+    efds.fd_array[0] = handle->socket;
+  } else {
+    wfds.fd_count = 0;
+    efds.fd_count = 0;
+  }
+
+  /* Make the select() time out after 3 minutes. If select() hangs because */
+  /* the user closed the socket, we will at least not hang indefinitely. */
+  timeout.tv_sec = 3 * 60;
+  timeout.tv_usec = 0;
+
+  r = select(1, (fd_set*) &rfds, (fd_set*) &wfds, (fd_set*) &efds, &timeout);
+  if (r == SOCKET_ERROR) {
+    /* Queue this req, reporting an error. */
+    SET_REQ_ERROR(&handle->poll_req_1, WSAGetLastError());
+    POST_COMPLETION_FOR_REQ(handle->loop, req);
+    return 0;
+  }
+
+  reported_events = 0;
+
+  if (r > 0) {
+    if (rfds.fd_count > 0) {
+      assert(rfds.fd_count == 1);
+      assert(rfds.fd_array[0] == handle->socket);
+      reported_events |= UV_READABLE;
+    }
+
+    if (wfds.fd_count > 0) {
+      assert(wfds.fd_count == 1);
+      assert(wfds.fd_array[0] == handle->socket);
+      reported_events |= UV_WRITABLE;
+    } else if (efds.fd_count > 0) {
+      assert(efds.fd_count == 1);
+      assert(efds.fd_array[0] == handle->socket);
+      reported_events |= UV_WRITABLE;
+    }
+  }
+
+  SET_REQ_SUCCESS(req);
+  req->u.io.overlapped.InternalHigh = (DWORD) reported_events;
+  POST_COMPLETION_FOR_REQ(handle->loop, req);
+
+  return 0;
+}
+
+
+static void uv__slow_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
+  uv_req_t* req;
+
+  /* Find a yet unsubmitted req to submit. */
+  if (handle->submitted_events_1 == 0) {
+    req = &handle->poll_req_1;
+    handle->submitted_events_1 = handle->events;
+    handle->mask_events_1 = 0;
+    handle->mask_events_2 = handle->events;
+  } else if (handle->submitted_events_2 == 0) {
+    req = &handle->poll_req_2;
+    handle->submitted_events_2 = handle->events;
+    handle->mask_events_1 = handle->events;
+    handle->mask_events_2 = 0;
+  } else {
+    assert(0);
+    return;
+  }
+
+  if (!QueueUserWorkItem(uv__slow_poll_thread_proc,
+                         (void*) req,
+                         WT_EXECUTELONGFUNCTION)) {
+    /* Make this req pending, reporting an error. */
+    SET_REQ_ERROR(req, GetLastError());
+    uv_insert_pending_req(loop, req);
+  }
+}
+
+
+
+static void uv__slow_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
+    uv_req_t* req) {
+  unsigned char mask_events;
+  int err;
+
+  if (req == &handle->poll_req_1) {
+    handle->submitted_events_1 = 0;
+    mask_events = handle->mask_events_1;
+  } else if (req == &handle->poll_req_2) {
+    handle->submitted_events_2 = 0;
+    mask_events = handle->mask_events_2;
+  } else {
+    assert(0);
+    return;
+  }
+
+  if (!REQ_SUCCESS(req)) {
+    /* Error. */
+    if (handle->events != 0) {
+      err = GET_REQ_ERROR(req);
+      handle->events = 0; /* Stop the watcher */
+      handle->poll_cb(handle, uv_translate_sys_error(err), 0);
+    }
+  } else {
+    /* Got some events. */
+    int events = req->u.io.overlapped.InternalHigh & handle->events & ~mask_events;
+    if (events != 0) {
+      handle->poll_cb(handle, 0, events);
+    }
+  }
+
+  if ((handle->events & ~(handle->submitted_events_1 |
+      handle->submitted_events_2)) != 0) {
+    uv__slow_poll_submit_poll_req(loop, handle);
+  } else if ((handle->flags & UV__HANDLE_CLOSING) &&
+             handle->submitted_events_1 == 0 &&
+             handle->submitted_events_2 == 0) {
+    uv_want_endgame(loop, (uv_handle_t*) handle);
+  }
+}
+
+
+static int uv__slow_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
+  assert(handle->type == UV_POLL);
+  assert(!(handle->flags & UV__HANDLE_CLOSING));
+  assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0);
+
+  handle->events = events;
+
+  if (handle->events != 0) {
+    uv__handle_start(handle);
+  } else {
+    uv__handle_stop(handle);
+  }
+
+  if ((handle->events &
+      ~(handle->submitted_events_1 | handle->submitted_events_2)) != 0) {
+    uv__slow_poll_submit_poll_req(handle->loop, handle);
+  }
+
+  return 0;
+}
+
+
+static int uv__slow_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
+  handle->events = 0;
+  uv__handle_closing(handle);
+
+  if (handle->submitted_events_1 == 0 &&
+      handle->submitted_events_2 == 0) {
+    uv_want_endgame(loop, (uv_handle_t*) handle);
+  }
+
+  return 0;
+}
+
+
+int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
+  return uv_poll_init_socket(loop, handle, (SOCKET) uv__get_osfhandle(fd));
+}
+
+
+int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
+    uv_os_sock_t socket) {
+  WSAPROTOCOL_INFOW protocol_info;
+  int len;
+  SOCKET peer_socket, base_socket;
+  DWORD bytes;
+  DWORD yes = 1;
+
+  /* Set the socket to nonblocking mode */
+  if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR)
+    return uv_translate_sys_error(WSAGetLastError());
+
+  /* Try to obtain a base handle for the socket. This increases this chances */
+  /* that we find an AFD handle and are able to use the fast poll mechanism. */
+  /* This will always fail on windows XP/2k3, since they don't support the */
+  /* SIO_BASE_HANDLE ioctl. */
+#ifndef NDEBUG
+  base_socket = INVALID_SOCKET;
+#endif
+
+  if (WSAIoctl(socket,
+               SIO_BASE_HANDLE,
+               NULL,
+               0,
+               &base_socket,
+               sizeof base_socket,
+               &bytes,
+               NULL,
+               NULL) == 0) {
+    assert(base_socket != 0 && base_socket != INVALID_SOCKET);
+    socket = base_socket;
+  }
+
+  uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL);
+  handle->socket = socket;
+  handle->events = 0;
+
+  /* Obtain protocol information about the socket. */
+  len = sizeof protocol_info;
+  if (getsockopt(socket,
+                 SOL_SOCKET,
+                 SO_PROTOCOL_INFOW,
+                 (char*) &protocol_info,
+                 &len) != 0) {
+    return uv_translate_sys_error(WSAGetLastError());
+  }
+
+  /* Get the peer socket that is needed to enable fast poll. If the returned */
+  /* value is NULL, the protocol is not implemented by MSAFD and we'll have */
+  /* to use slow mode. */
+  peer_socket = uv__fast_poll_get_peer_socket(loop, &protocol_info);
+
+  if (peer_socket != INVALID_SOCKET) {
+    /* Initialize fast poll specific fields. */
+    handle->peer_socket = peer_socket;
+  } else {
+    /* Initialize slow poll specific fields. */
+    handle->flags |= UV_HANDLE_POLL_SLOW;
+  }
+
+  /* Initialize 2 poll reqs. */
+  handle->submitted_events_1 = 0;
+  uv_req_init(loop, (uv_req_t*) &(handle->poll_req_1));
+  handle->poll_req_1.type = UV_POLL_REQ;
+  handle->poll_req_1.data = handle;
+
+  handle->submitted_events_2 = 0;
+  uv_req_init(loop, (uv_req_t*) &(handle->poll_req_2));
+  handle->poll_req_2.type = UV_POLL_REQ;
+  handle->poll_req_2.data = handle;
+
+  return 0;
+}
+
+
+int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) {
+  int err;
+
+  if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
+    err = uv__fast_poll_set(handle->loop, handle, events);
+  } else {
+    err = uv__slow_poll_set(handle->loop, handle, events);
+  }
+
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  handle->poll_cb = cb;
+
+  return 0;
+}
+
+
+int uv_poll_stop(uv_poll_t* handle) {
+  int err;
+
+  if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
+    err = uv__fast_poll_set(handle->loop, handle, 0);
+  } else {
+    err = uv__slow_poll_set(handle->loop, handle, 0);
+  }
+
+  return uv_translate_sys_error(err);
+}
+
+
+void uv_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, uv_req_t* req) {
+  if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
+    uv__fast_poll_process_poll_req(loop, handle, req);
+  } else {
+    uv__slow_poll_process_poll_req(loop, handle, req);
+  }
+}
+
+
+int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
+  if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
+    return uv__fast_poll_close(loop, handle);
+  } else {
+    return uv__slow_poll_close(loop, handle);
+  }
+}
+
+
+void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle) {
+  assert(handle->flags & UV__HANDLE_CLOSING);
+  assert(!(handle->flags & UV_HANDLE_CLOSED));
+
+  assert(handle->submitted_events_1 == 0);
+  assert(handle->submitted_events_2 == 0);
+
+  uv__handle_close(handle);
+}
diff --git a/deps/libtuv/src/win/process-stdio.c b/deps/libtuv/src/win/process-stdio.c
new file mode 100644 (file)
index 0000000..032e309
--- /dev/null
@@ -0,0 +1,511 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <io.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+
+
+/*
+ * The `child_stdio_buffer` buffer has the following layout:
+ *   int number_of_fds
+ *   unsigned char crt_flags[number_of_fds]
+ *   HANDLE os_handle[number_of_fds]
+ */
+#define CHILD_STDIO_SIZE(count)                     \
+    (sizeof(int) +                                  \
+     sizeof(unsigned char) * (count) +              \
+     sizeof(uintptr_t) * (count))
+
+#define CHILD_STDIO_COUNT(buffer)                   \
+    *((unsigned int*) (buffer))
+
+#define CHILD_STDIO_CRT_FLAGS(buffer, fd)           \
+    *((unsigned char*) (buffer) + sizeof(int) + fd)
+
+#define CHILD_STDIO_HANDLE(buffer, fd)              \
+    *((HANDLE*) ((unsigned char*) (buffer) +        \
+                 sizeof(int) +                      \
+                 sizeof(unsigned char) *            \
+                 CHILD_STDIO_COUNT((buffer)) +      \
+                 sizeof(HANDLE) * (fd)))
+
+
+/* CRT file descriptor mode flags */
+#define FOPEN       0x01
+#define FEOFLAG     0x02
+#define FCRLF       0x04
+#define FPIPE       0x08
+#define FNOINHERIT  0x10
+#define FAPPEND     0x20
+#define FDEV        0x40
+#define FTEXT       0x80
+
+
+/*
+ * Clear the HANDLE_FLAG_INHERIT flag from all HANDLEs that were inherited
+ * the parent process. Don't check for errors - the stdio handles may not be
+ * valid, or may be closed already. There is no guarantee that this function
+ * does a perfect job.
+ */
+void uv_disable_stdio_inheritance(void) {
+  HANDLE handle;
+  STARTUPINFOW si;
+
+  /* Make the windows stdio handles non-inheritable. */
+  handle = GetStdHandle(STD_INPUT_HANDLE);
+  if (handle != NULL && handle != INVALID_HANDLE_VALUE)
+    SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
+
+  handle = GetStdHandle(STD_OUTPUT_HANDLE);
+  if (handle != NULL && handle != INVALID_HANDLE_VALUE)
+    SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
+
+  handle = GetStdHandle(STD_ERROR_HANDLE);
+  if (handle != NULL && handle != INVALID_HANDLE_VALUE)
+    SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
+
+  /* Make inherited CRT FDs non-inheritable. */
+  GetStartupInfoW(&si);
+  if (uv__stdio_verify(si.lpReserved2, si.cbReserved2))
+    uv__stdio_noinherit(si.lpReserved2);
+}
+
+
+static int uv__create_stdio_pipe_pair(uv_loop_t* loop,
+    uv_pipe_t* server_pipe, HANDLE* child_pipe_ptr, unsigned int flags) {
+  char pipe_name[64];
+  SECURITY_ATTRIBUTES sa;
+  DWORD server_access = 0;
+  DWORD client_access = 0;
+  HANDLE child_pipe = INVALID_HANDLE_VALUE;
+  int err;
+
+  if (flags & UV_READABLE_PIPE) {
+    /* The server needs inbound access too, otherwise CreateNamedPipe() */
+    /* won't give us the FILE_READ_ATTRIBUTES permission. We need that to */
+    /* probe the state of the write buffer when we're trying to shutdown */
+    /* the pipe. */
+    server_access |= PIPE_ACCESS_OUTBOUND | PIPE_ACCESS_INBOUND;
+    client_access |= GENERIC_READ | FILE_WRITE_ATTRIBUTES;
+  }
+  if (flags & UV_WRITABLE_PIPE) {
+    server_access |= PIPE_ACCESS_INBOUND;
+    client_access |= GENERIC_WRITE | FILE_READ_ATTRIBUTES;
+  }
+
+  /* Create server pipe handle. */
+  err = uv_stdio_pipe_server(loop,
+                             server_pipe,
+                             server_access,
+                             pipe_name,
+                             sizeof(pipe_name));
+  if (err)
+    goto error;
+
+  /* Create child pipe handle. */
+  sa.nLength = sizeof sa;
+  sa.lpSecurityDescriptor = NULL;
+  sa.bInheritHandle = TRUE;
+
+  child_pipe = CreateFileA(pipe_name,
+                           client_access,
+                           0,
+                           &sa,
+                           OPEN_EXISTING,
+                           server_pipe->ipc ? FILE_FLAG_OVERLAPPED : 0,
+                           NULL);
+  if (child_pipe == INVALID_HANDLE_VALUE) {
+    err = GetLastError();
+    goto error;
+  }
+
+#ifndef NDEBUG
+  /* Validate that the pipe was opened in the right mode. */
+  {
+    DWORD mode;
+    BOOL r = GetNamedPipeHandleState(child_pipe,
+                                     &mode,
+                                     NULL,
+                                     NULL,
+                                     NULL,
+                                     NULL,
+                                     0);
+    assert(r == TRUE);
+    assert(mode == (PIPE_READMODE_BYTE | PIPE_WAIT));
+  }
+#endif
+
+  /* Do a blocking ConnectNamedPipe.  This should not block because we have */
+  /* both ends of the pipe created. */
+  if (!ConnectNamedPipe(server_pipe->handle, NULL)) {
+    if (GetLastError() != ERROR_PIPE_CONNECTED) {
+      err = GetLastError();
+      goto error;
+    }
+  }
+
+  /* The server end is now readable and/or writable. */
+  if (flags & UV_READABLE_PIPE)
+    server_pipe->flags |= UV_HANDLE_WRITABLE;
+  if (flags & UV_WRITABLE_PIPE)
+    server_pipe->flags |= UV_HANDLE_READABLE;
+
+  *child_pipe_ptr = child_pipe;
+  return 0;
+
+ error:
+  if (server_pipe->handle != INVALID_HANDLE_VALUE) {
+    uv_pipe_cleanup(loop, server_pipe);
+  }
+
+  if (child_pipe != INVALID_HANDLE_VALUE) {
+    CloseHandle(child_pipe);
+  }
+
+  return err;
+}
+
+
+static int uv__duplicate_handle(uv_loop_t* loop, HANDLE handle, HANDLE* dup) {
+  HANDLE current_process;
+
+
+  /* _get_osfhandle will sometimes return -2 in case of an error. This seems */
+  /* to happen when fd <= 2 and the process' corresponding stdio handle is */
+  /* set to NULL. Unfortunately DuplicateHandle will happily duplicate */
+  /* (HANDLE) -2, so this situation goes unnoticed until someone tries to */
+  /* use the duplicate. Therefore we filter out known-invalid handles here. */
+  if (handle == INVALID_HANDLE_VALUE ||
+      handle == NULL ||
+      handle == (HANDLE) -2) {
+    *dup = INVALID_HANDLE_VALUE;
+    return ERROR_INVALID_HANDLE;
+  }
+
+  current_process = GetCurrentProcess();
+
+  if (!DuplicateHandle(current_process,
+                       handle,
+                       current_process,
+                       dup,
+                       0,
+                       TRUE,
+                       DUPLICATE_SAME_ACCESS)) {
+    *dup = INVALID_HANDLE_VALUE;
+    return GetLastError();
+  }
+
+  return 0;
+}
+
+
+static int uv__duplicate_fd(uv_loop_t* loop, int fd, HANDLE* dup) {
+  HANDLE handle;
+
+  if (fd == -1) {
+    *dup = INVALID_HANDLE_VALUE;
+    return ERROR_INVALID_HANDLE;
+  }
+
+  handle = uv__get_osfhandle(fd);
+  return uv__duplicate_handle(loop, handle, dup);
+}
+
+
+int uv__create_nul_handle(HANDLE* handle_ptr,
+    DWORD access) {
+  HANDLE handle;
+  SECURITY_ATTRIBUTES sa;
+
+  sa.nLength = sizeof sa;
+  sa.lpSecurityDescriptor = NULL;
+  sa.bInheritHandle = TRUE;
+
+  handle = CreateFileW(L"NUL",
+                       access,
+                       FILE_SHARE_READ | FILE_SHARE_WRITE,
+                       &sa,
+                       OPEN_EXISTING,
+                       0,
+                       NULL);
+  if (handle == INVALID_HANDLE_VALUE) {
+    return GetLastError();
+  }
+
+  *handle_ptr = handle;
+  return 0;
+}
+
+
+int uv__stdio_create(uv_loop_t* loop,
+                     const uv_process_options_t* options,
+                     BYTE** buffer_ptr) {
+  BYTE* buffer;
+  int count, i;
+  int err;
+
+  count = options->stdio_count;
+
+  if (count < 0 || count > 255) {
+    /* Only support FDs 0-255 */
+    return ERROR_NOT_SUPPORTED;
+  } else if (count < 3) {
+    /* There should always be at least 3 stdio handles. */
+    count = 3;
+  }
+
+  /* Allocate the child stdio buffer */
+  buffer = (BYTE*) uv__malloc(CHILD_STDIO_SIZE(count));
+  if (buffer == NULL) {
+    return ERROR_OUTOFMEMORY;
+  }
+
+  /* Prepopulate the buffer with INVALID_HANDLE_VALUE handles so we can */
+  /* clean up on failure. */
+  CHILD_STDIO_COUNT(buffer) = count;
+  for (i = 0; i < count; i++) {
+    CHILD_STDIO_CRT_FLAGS(buffer, i) = 0;
+    CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE;
+  }
+
+  for (i = 0; i < count; i++) {
+    uv_stdio_container_t fdopt;
+    if (i < options->stdio_count) {
+      fdopt = options->stdio[i];
+    } else {
+      fdopt.flags = UV_IGNORE;
+    }
+
+    switch (fdopt.flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD |
+            UV_INHERIT_STREAM)) {
+      case UV_IGNORE:
+        /* Starting a process with no stdin/stout/stderr can confuse it. */
+        /* So no matter what the user specified, we make sure the first */
+        /* three FDs are always open in their typical modes, e.g. stdin */
+        /* be readable and stdout/err should be writable. For FDs > 2, don't */
+        /* do anything - all handles in the stdio buffer are initialized with */
+        /* INVALID_HANDLE_VALUE, which should be okay. */
+        if (i <= 2) {
+          DWORD access = (i == 0) ? FILE_GENERIC_READ :
+                                    FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES;
+
+          err = uv__create_nul_handle(&CHILD_STDIO_HANDLE(buffer, i),
+                                      access);
+          if (err)
+            goto error;
+
+          CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV;
+        }
+        break;
+
+      case UV_CREATE_PIPE: {
+        /* Create a pair of two connected pipe ends; one end is turned into */
+        /* an uv_pipe_t for use by the parent. The other one is given to */
+        /* the child. */
+        uv_pipe_t* parent_pipe = (uv_pipe_t*) fdopt.data.stream;
+        HANDLE child_pipe = INVALID_HANDLE_VALUE;
+
+        /* Create a new, connected pipe pair. stdio[i].stream should point */
+        /* to an uninitialized, but not connected pipe handle. */
+        assert(fdopt.data.stream->type == UV_NAMED_PIPE);
+        assert(!(fdopt.data.stream->flags & UV_HANDLE_CONNECTION));
+        assert(!(fdopt.data.stream->flags & UV_HANDLE_PIPESERVER));
+
+        err = uv__create_stdio_pipe_pair(loop,
+                                         parent_pipe,
+                                         &child_pipe,
+                                         fdopt.flags);
+        if (err)
+          goto error;
+
+        CHILD_STDIO_HANDLE(buffer, i) = child_pipe;
+        CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE;
+        break;
+      }
+
+      case UV_INHERIT_FD: {
+        /* Inherit a raw FD. */
+        HANDLE child_handle;
+
+        /* Make an inheritable duplicate of the handle. */
+        err = uv__duplicate_fd(loop, fdopt.data.fd, &child_handle);
+        if (err) {
+          /* If fdopt.data.fd is not valid and fd fd <= 2, then ignore the */
+          /* error. */
+          if (fdopt.data.fd <= 2 && err == ERROR_INVALID_HANDLE) {
+            CHILD_STDIO_CRT_FLAGS(buffer, i) = 0;
+            CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE;
+            break;
+          }
+          goto error;
+        }
+
+        /* Figure out what the type is. */
+        switch (GetFileType(child_handle)) {
+          case FILE_TYPE_DISK:
+            CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN;
+            break;
+
+          case FILE_TYPE_PIPE:
+            CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE;
+            break;
+
+          case FILE_TYPE_CHAR:
+          case FILE_TYPE_REMOTE:
+            CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV;
+            break;
+
+          case FILE_TYPE_UNKNOWN:
+            if (GetLastError() != 0) {
+              err = GetLastError();
+              CloseHandle(child_handle);
+              goto error;
+            }
+            CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV;
+            break;
+
+          default:
+            assert(0);
+            return -1;
+        }
+
+        CHILD_STDIO_HANDLE(buffer, i) = child_handle;
+        break;
+      }
+
+      case UV_INHERIT_STREAM: {
+        /* Use an existing stream as the stdio handle for the child. */
+        HANDLE stream_handle, child_handle;
+        unsigned char crt_flags;
+        uv_stream_t* stream = fdopt.data.stream;
+
+        /* Leech the handle out of the stream. */
+        if (stream->type == UV_TTY) {
+          stream_handle = ((uv_tty_t*) stream)->handle;
+          crt_flags = FOPEN | FDEV;
+        } else if (stream->type == UV_NAMED_PIPE &&
+                   stream->flags & UV_HANDLE_CONNECTION) {
+          stream_handle = ((uv_pipe_t*) stream)->handle;
+          crt_flags = FOPEN | FPIPE;
+        } else {
+          stream_handle = INVALID_HANDLE_VALUE;
+          crt_flags = 0;
+        }
+
+        if (stream_handle == NULL ||
+            stream_handle == INVALID_HANDLE_VALUE) {
+          /* The handle is already closed, or not yet created, or the */
+          /* stream type is not supported. */
+          err = ERROR_NOT_SUPPORTED;
+          goto error;
+        }
+
+        /* Make an inheritable copy of the handle. */
+        err = uv__duplicate_handle(loop, stream_handle, &child_handle);
+        if (err)
+          goto error;
+
+        CHILD_STDIO_HANDLE(buffer, i) = child_handle;
+        CHILD_STDIO_CRT_FLAGS(buffer, i) = crt_flags;
+        break;
+      }
+
+      default:
+        assert(0);
+        return -1;
+    }
+  }
+
+  *buffer_ptr  = buffer;
+  return 0;
+
+ error:
+  uv__stdio_destroy(buffer);
+  return err;
+}
+
+
+void uv__stdio_destroy(BYTE* buffer) {
+  int i, count;
+
+  count = CHILD_STDIO_COUNT(buffer);
+  for (i = 0; i < count; i++) {
+    HANDLE handle = CHILD_STDIO_HANDLE(buffer, i);
+    if (handle != INVALID_HANDLE_VALUE) {
+      CloseHandle(handle);
+    }
+  }
+
+  uv__free(buffer);
+}
+
+
+void uv__stdio_noinherit(BYTE* buffer) {
+  int i, count;
+
+  count = CHILD_STDIO_COUNT(buffer);
+  for (i = 0; i < count; i++) {
+    HANDLE handle = CHILD_STDIO_HANDLE(buffer, i);
+    if (handle != INVALID_HANDLE_VALUE) {
+      SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
+    }
+  }
+}
+
+
+int uv__stdio_verify(BYTE* buffer, WORD size) {
+  unsigned int count;
+
+  /* Check the buffer pointer. */
+  if (buffer == NULL)
+    return 0;
+
+  /* Verify that the buffer is at least big enough to hold the count. */
+  if (size < CHILD_STDIO_SIZE(0))
+    return 0;
+
+  /* Verify if the count is within range. */
+  count = CHILD_STDIO_COUNT(buffer);
+  if (count > 256)
+    return 0;
+
+  /* Verify that the buffer size is big enough to hold info for N FDs. */
+  if (size < CHILD_STDIO_SIZE(count))
+    return 0;
+
+  return 1;
+}
+
+
+WORD uv__stdio_size(BYTE* buffer) {
+  return (WORD) CHILD_STDIO_SIZE(CHILD_STDIO_COUNT((buffer)));
+}
+
+
+HANDLE uv__stdio_handle(BYTE* buffer, int fd) {
+  return CHILD_STDIO_HANDLE(buffer, fd);
+}
diff --git a/deps/libtuv/src/win/process.c b/deps/libtuv/src/win/process.c
new file mode 100644 (file)
index 0000000..bdf88d2
--- /dev/null
@@ -0,0 +1,1247 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <io.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <limits.h>
+#include <wchar.h>
+#include <malloc.h>    /* alloca */
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+
+#define SIGKILL         9
+
+
+typedef struct env_var {
+  const WCHAR* const wide;
+  const WCHAR* const wide_eq;
+  const size_t len; /* including null or '=' */
+} env_var_t;
+
+#define E_V(str) { L##str, L##str L"=", sizeof(str) }
+
+static const env_var_t required_vars[] = { /* keep me sorted */
+  E_V("HOMEDRIVE"),
+  E_V("HOMEPATH"),
+  E_V("LOGONSERVER"),
+  E_V("PATH"),
+  E_V("SYSTEMDRIVE"),
+  E_V("SYSTEMROOT"),
+  E_V("TEMP"),
+  E_V("USERDOMAIN"),
+  E_V("USERNAME"),
+  E_V("USERPROFILE"),
+  E_V("WINDIR"),
+};
+static size_t n_required_vars = ARRAY_SIZE(required_vars);
+
+
+static HANDLE uv_global_job_handle_;
+static uv_once_t uv_global_job_handle_init_guard_ = UV_ONCE_INIT;
+
+
+static void uv__init_global_job_handle(void) {
+  /* Create a job object and set it up to kill all contained processes when
+   * it's closed. Since this handle is made non-inheritable and we're not
+   * giving it to anyone, we're the only process holding a reference to it.
+   * That means that if this process exits it is closed and all the processes
+   * it contains are killed. All processes created with uv_spawn that are not
+   * spawned with the UV_PROCESS_DETACHED flag are assigned to this job.
+   *
+   * We're setting the JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag so only the
+   * processes that we explicitly add are affected, and *their* subprocesses
+   * are not. This ensures that our child processes are not limited in their
+   * ability to use job control on Windows versions that don't deal with
+   * nested jobs (prior to Windows 8 / Server 2012). It also lets our child
+   * processes created detached processes without explicitly breaking away
+   * from job control (which uv_spawn doesn't, either).
+   */
+  SECURITY_ATTRIBUTES attr;
+  JOBOBJECT_EXTENDED_LIMIT_INFORMATION info;
+
+  memset(&attr, 0, sizeof attr);
+  attr.bInheritHandle = FALSE;
+
+  memset(&info, 0, sizeof info);
+  info.BasicLimitInformation.LimitFlags =
+      JOB_OBJECT_LIMIT_BREAKAWAY_OK |
+      JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK |
+      JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION |
+      JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
+
+  uv_global_job_handle_ = CreateJobObjectW(&attr, NULL);
+  if (uv_global_job_handle_ == NULL)
+    uv_fatal_error(GetLastError(), "CreateJobObjectW");
+
+  if (!SetInformationJobObject(uv_global_job_handle_,
+                               JobObjectExtendedLimitInformation,
+                               &info,
+                               sizeof info))
+    uv_fatal_error(GetLastError(), "SetInformationJobObject");
+}
+
+
+static int uv_utf8_to_utf16_alloc(const char* s, WCHAR** ws_ptr) {
+  int ws_len, r;
+  WCHAR* ws;
+
+  ws_len = MultiByteToWideChar(CP_UTF8,
+                               0,
+                               s,
+                               -1,
+                               NULL,
+                               0);
+  if (ws_len <= 0) {
+    return GetLastError();
+  }
+
+  ws = (WCHAR*) uv__malloc(ws_len * sizeof(WCHAR));
+  if (ws == NULL) {
+    return ERROR_OUTOFMEMORY;
+  }
+
+  r = MultiByteToWideChar(CP_UTF8,
+                          0,
+                          s,
+                          -1,
+                          ws,
+                          ws_len);
+  assert(r == ws_len);
+
+  *ws_ptr = ws;
+  return 0;
+}
+
+
+static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) {
+  uv__handle_init(loop, (uv_handle_t*) handle, UV_PROCESS);
+  handle->exit_cb = NULL;
+  handle->pid = 0;
+  handle->exit_signal = 0;
+  handle->wait_handle = INVALID_HANDLE_VALUE;
+  handle->process_handle = INVALID_HANDLE_VALUE;
+  handle->child_stdio_buffer = NULL;
+  handle->exit_cb_pending = 0;
+
+  uv_req_init(loop, (uv_req_t*)&handle->exit_req);
+  handle->exit_req.type = UV_PROCESS_EXIT;
+  handle->exit_req.data = handle;
+}
+
+
+/*
+ * Path search functions
+ */
+
+/*
+ * Helper function for search_path
+ */
+static WCHAR* search_path_join_test(const WCHAR* dir,
+                                    size_t dir_len,
+                                    const WCHAR* name,
+                                    size_t name_len,
+                                    const WCHAR* ext,
+                                    size_t ext_len,
+                                    const WCHAR* cwd,
+                                    size_t cwd_len) {
+  WCHAR *result, *result_pos;
+  DWORD attrs;
+  if (dir_len > 2 && dir[0] == L'\\' && dir[1] == L'\\') {
+    /* It's a UNC path so ignore cwd */
+    cwd_len = 0;
+  } else if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) {
+    /* It's a full path without drive letter, use cwd's drive letter only */
+    cwd_len = 2;
+  } else if (dir_len >= 2 && dir[1] == L':' &&
+      (dir_len < 3 || (dir[2] != L'/' && dir[2] != L'\\'))) {
+    /* It's a relative path with drive letter (ext.g. D:../some/file)
+     * Replace drive letter in dir by full cwd if it points to the same drive,
+     * otherwise use the dir only.
+     */
+    if (cwd_len < 2 || _wcsnicmp(cwd, dir, 2) != 0) {
+      cwd_len = 0;
+    } else {
+      dir += 2;
+      dir_len -= 2;
+    }
+  } else if (dir_len > 2 && dir[1] == L':') {
+    /* It's an absolute path with drive letter
+     * Don't use the cwd at all
+     */
+    cwd_len = 0;
+  }
+
+  /* Allocate buffer for output */
+  result = result_pos = (WCHAR*)uv__malloc(sizeof(WCHAR) *
+      (cwd_len + 1 + dir_len + 1 + name_len + 1 + ext_len + 1));
+
+  /* Copy cwd */
+  wcsncpy(result_pos, cwd, cwd_len);
+  result_pos += cwd_len;
+
+  /* Add a path separator if cwd didn't end with one */
+  if (cwd_len && wcsrchr(L"\\/:", result_pos[-1]) == NULL) {
+    result_pos[0] = L'\\';
+    result_pos++;
+  }
+
+  /* Copy dir */
+  wcsncpy(result_pos, dir, dir_len);
+  result_pos += dir_len;
+
+  /* Add a separator if the dir didn't end with one */
+  if (dir_len && wcsrchr(L"\\/:", result_pos[-1]) == NULL) {
+    result_pos[0] = L'\\';
+    result_pos++;
+  }
+
+  /* Copy filename */
+  wcsncpy(result_pos, name, name_len);
+  result_pos += name_len;
+
+  if (ext_len) {
+    /* Add a dot if the filename didn't end with one */
+    if (name_len && result_pos[-1] != '.') {
+      result_pos[0] = L'.';
+      result_pos++;
+    }
+
+    /* Copy extension */
+    wcsncpy(result_pos, ext, ext_len);
+    result_pos += ext_len;
+  }
+
+  /* Null terminator */
+  result_pos[0] = L'\0';
+
+  attrs = GetFileAttributesW(result);
+
+  if (attrs != INVALID_FILE_ATTRIBUTES &&
+      !(attrs & FILE_ATTRIBUTE_DIRECTORY)) {
+    return result;
+  }
+
+  uv__free(result);
+  return NULL;
+}
+
+
+/*
+ * Helper function for search_path
+ */
+static WCHAR* path_search_walk_ext(const WCHAR *dir,
+                                   size_t dir_len,
+                                   const WCHAR *name,
+                                   size_t name_len,
+                                   WCHAR *cwd,
+                                   size_t cwd_len,
+                                   int name_has_ext) {
+  WCHAR* result;
+
+  /* If the name itself has a nonempty extension, try this extension first */
+  if (name_has_ext) {
+    result = search_path_join_test(dir, dir_len,
+                                   name, name_len,
+                                   L"", 0,
+                                   cwd, cwd_len);
+    if (result != NULL) {
+      return result;
+    }
+  }
+
+  /* Try .com extension */
+  result = search_path_join_test(dir, dir_len,
+                                 name, name_len,
+                                 L"com", 3,
+                                 cwd, cwd_len);
+  if (result != NULL) {
+    return result;
+  }
+
+  /* Try .exe extension */
+  result = search_path_join_test(dir, dir_len,
+                                 name, name_len,
+                                 L"exe", 3,
+                                 cwd, cwd_len);
+  if (result != NULL) {
+    return result;
+  }
+
+  return NULL;
+}
+
+
+/*
+ * search_path searches the system path for an executable filename -
+ * the windows API doesn't provide this as a standalone function nor as an
+ * option to CreateProcess.
+ *
+ * It tries to return an absolute filename.
+ *
+ * Furthermore, it tries to follow the semantics that cmd.exe, with this
+ * exception that PATHEXT environment variable isn't used. Since CreateProcess
+ * can start only .com and .exe files, only those extensions are tried. This
+ * behavior equals that of msvcrt's spawn functions.
+ *
+ * - Do not search the path if the filename already contains a path (either
+ *   relative or absolute).
+ *
+ * - If there's really only a filename, check the current directory for file,
+ *   then search all path directories.
+ *
+ * - If filename specified has *any* extension, search for the file with the
+ *   specified extension first.
+ *
+ * - If the literal filename is not found in a directory, try *appending*
+ *   (not replacing) .com first and then .exe.
+ *
+ * - The path variable may contain relative paths; relative paths are relative
+ *   to the cwd.
+ *
+ * - Directories in path may or may not end with a trailing backslash.
+ *
+ * - CMD does not trim leading/trailing whitespace from path/pathex entries
+ *   nor from the environment variables as a whole.
+ *
+ * - When cmd.exe cannot read a directory, it will just skip it and go on
+ *   searching. However, unlike posix-y systems, it will happily try to run a
+ *   file that is not readable/executable; if the spawn fails it will not
+ *   continue searching.
+ *
+ * UNC path support: we are dealing with UNC paths in both the path and the
+ * filename. This is a deviation from what cmd.exe does (it does not let you
+ * start a program by specifying an UNC path on the command line) but this is
+ * really a pointless restriction.
+ *
+ */
+static WCHAR* search_path(const WCHAR *file,
+                            WCHAR *cwd,
+                            const WCHAR *path) {
+  int file_has_dir;
+  WCHAR* result = NULL;
+  WCHAR *file_name_start;
+  WCHAR *dot;
+  const WCHAR *dir_start, *dir_end, *dir_path;
+  size_t dir_len;
+  int name_has_ext;
+
+  size_t file_len = wcslen(file);
+  size_t cwd_len = wcslen(cwd);
+
+  /* If the caller supplies an empty filename,
+   * we're not gonna return c:\windows\.exe -- GFY!
+   */
+  if (file_len == 0
+      || (file_len == 1 && file[0] == L'.')) {
+    return NULL;
+  }
+
+  /* Find the start of the filename so we can split the directory from the */
+  /* name. */
+  for (file_name_start = (WCHAR*)file + file_len;
+       file_name_start > file
+           && file_name_start[-1] != L'\\'
+           && file_name_start[-1] != L'/'
+           && file_name_start[-1] != L':';
+       file_name_start--);
+
+  file_has_dir = file_name_start != file;
+
+  /* Check if the filename includes an extension */
+  dot = wcschr(file_name_start, L'.');
+  name_has_ext = (dot != NULL && dot[1] != L'\0');
+
+  if (file_has_dir) {
+    /* The file has a path inside, don't use path */
+    result = path_search_walk_ext(
+        file, file_name_start - file,
+        file_name_start, file_len - (file_name_start - file),
+        cwd, cwd_len,
+        name_has_ext);
+
+  } else {
+    dir_end = path;
+
+    /* The file is really only a name; look in cwd first, then scan path */
+    result = path_search_walk_ext(L"", 0,
+                                  file, file_len,
+                                  cwd, cwd_len,
+                                  name_has_ext);
+
+    while (result == NULL) {
+      if (*dir_end == L'\0') {
+        break;
+      }
+
+      /* Skip the separator that dir_end now points to */
+      if (dir_end != path || *path == L';') {
+        dir_end++;
+      }
+
+      /* Next slice starts just after where the previous one ended */
+      dir_start = dir_end;
+
+      /* Slice until the next ; or \0 is found */
+      dir_end = wcschr(dir_start, L';');
+      if (dir_end == NULL) {
+        dir_end = wcschr(dir_start, L'\0');
+      }
+
+      /* If the slice is zero-length, don't bother */
+      if (dir_end - dir_start == 0) {
+        continue;
+      }
+
+      dir_path = dir_start;
+      dir_len = dir_end - dir_start;
+
+      /* Adjust if the path is quoted. */
+      if (dir_path[0] == '"' || dir_path[0] == '\'') {
+        ++dir_path;
+        --dir_len;
+      }
+
+      if (dir_path[dir_len - 1] == '"' || dir_path[dir_len - 1] == '\'') {
+        --dir_len;
+      }
+
+      result = path_search_walk_ext(dir_path, dir_len,
+                                    file, file_len,
+                                    cwd, cwd_len,
+                                    name_has_ext);
+    }
+  }
+
+  return result;
+}
+
+
+/*
+ * Quotes command line arguments
+ * Returns a pointer to the end (next char to be written) of the buffer
+ */
+WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target) {
+  size_t len = wcslen(source);
+  size_t i;
+  int quote_hit;
+  WCHAR* start;
+
+  if (len == 0) {
+    /* Need double quotation for empty argument */
+    *(target++) = L'"';
+    *(target++) = L'"';
+    return target;
+  }
+
+  if (NULL == wcspbrk(source, L" \t\"")) {
+    /* No quotation needed */
+    wcsncpy(target, source, len);
+    target += len;
+    return target;
+  }
+
+  if (NULL == wcspbrk(source, L"\"\\")) {
+    /*
+     * No embedded double quotes or backlashes, so I can just wrap
+     * quote marks around the whole thing.
+     */
+    *(target++) = L'"';
+    wcsncpy(target, source, len);
+    target += len;
+    *(target++) = L'"';
+    return target;
+  }
+
+  /*
+   * Expected input/output:
+   *   input : hello"world
+   *   output: "hello\"world"
+   *   input : hello""world
+   *   output: "hello\"\"world"
+   *   input : hello\world
+   *   output: hello\world
+   *   input : hello\\world
+   *   output: hello\\world
+   *   input : hello\"world
+   *   output: "hello\\\"world"
+   *   input : hello\\"world
+   *   output: "hello\\\\\"world"
+   *   input : hello world\
+   *   output: "hello world\\"
+   */
+
+  *(target++) = L'"';
+  start = target;
+  quote_hit = 1;
+
+  for (i = len; i > 0; --i) {
+    *(target++) = source[i - 1];
+
+    if (quote_hit && source[i - 1] == L'\\') {
+      *(target++) = L'\\';
+    } else if(source[i - 1] == L'"') {
+      quote_hit = 1;
+      *(target++) = L'\\';
+    } else {
+      quote_hit = 0;
+    }
+  }
+  target[0] = L'\0';
+  wcsrev(start);
+  *(target++) = L'"';
+  return target;
+}
+
+
+int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) {
+  char** arg;
+  WCHAR* dst = NULL;
+  WCHAR* temp_buffer = NULL;
+  size_t dst_len = 0;
+  size_t temp_buffer_len = 0;
+  WCHAR* pos;
+  int arg_count = 0;
+  int err = 0;
+
+  /* Count the required size. */
+  for (arg = args; *arg; arg++) {
+    DWORD arg_len;
+
+    arg_len = MultiByteToWideChar(CP_UTF8,
+                                  0,
+                                  *arg,
+                                  -1,
+                                  NULL,
+                                  0);
+    if (arg_len == 0) {
+      return GetLastError();
+    }
+
+    dst_len += arg_len;
+
+    if (arg_len > temp_buffer_len)
+      temp_buffer_len = arg_len;
+
+    arg_count++;
+  }
+
+  /* Adjust for potential quotes. Also assume the worst-case scenario */
+  /* that every character needs escaping, so we need twice as much space. */
+  dst_len = dst_len * 2 + arg_count * 2;
+
+  /* Allocate buffer for the final command line. */
+  dst = (WCHAR*) uv__malloc(dst_len * sizeof(WCHAR));
+  if (dst == NULL) {
+    err = ERROR_OUTOFMEMORY;
+    goto error;
+  }
+
+  /* Allocate temporary working buffer. */
+  temp_buffer = (WCHAR*) uv__malloc(temp_buffer_len * sizeof(WCHAR));
+  if (temp_buffer == NULL) {
+    err = ERROR_OUTOFMEMORY;
+    goto error;
+  }
+
+  pos = dst;
+  for (arg = args; *arg; arg++) {
+    DWORD arg_len;
+
+    /* Convert argument to wide char. */
+    arg_len = MultiByteToWideChar(CP_UTF8,
+                                  0,
+                                  *arg,
+                                  -1,
+                                  temp_buffer,
+                                  (int) (dst + dst_len - pos));
+    if (arg_len == 0) {
+      err = GetLastError();
+      goto error;
+    }
+
+    if (verbatim_arguments) {
+      /* Copy verbatim. */
+      wcscpy(pos, temp_buffer);
+      pos += arg_len - 1;
+    } else {
+      /* Quote/escape, if needed. */
+      pos = quote_cmd_arg(temp_buffer, pos);
+    }
+
+    *pos++ = *(arg + 1) ? L' ' : L'\0';
+  }
+
+  uv__free(temp_buffer);
+
+  *dst_ptr = dst;
+  return 0;
+
+error:
+  uv__free(dst);
+  uv__free(temp_buffer);
+  return err;
+}
+
+
+int env_strncmp(const wchar_t* a, int na, const wchar_t* b) {
+  wchar_t* a_eq;
+  wchar_t* b_eq;
+  wchar_t* A;
+  wchar_t* B;
+  int nb;
+  int r;
+
+  if (na < 0) {
+    a_eq = wcschr(a, L'=');
+    assert(a_eq);
+    na = (int)(long)(a_eq - a);
+  } else {
+    na--;
+  }
+  b_eq = wcschr(b, L'=');
+  assert(b_eq);
+  nb = b_eq - b;
+
+  A = alloca((na+1) * sizeof(wchar_t));
+  B = alloca((nb+1) * sizeof(wchar_t));
+
+  r = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, a, na, A, na);
+  assert(r==na);
+  A[na] = L'\0';
+  r = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, b, nb, B, nb);
+  assert(r==nb);
+  B[nb] = L'\0';
+
+  while (1) {
+    wchar_t AA = *A++;
+    wchar_t BB = *B++;
+    if (AA < BB) {
+      return -1;
+    } else if (AA > BB) {
+      return 1;
+    } else if (!AA && !BB) {
+      return 0;
+    }
+  }
+}
+
+
+static int qsort_wcscmp(const void *a, const void *b) {
+  wchar_t* astr = *(wchar_t* const*)a;
+  wchar_t* bstr = *(wchar_t* const*)b;
+  return env_strncmp(astr, -1, bstr);
+}
+
+
+/*
+ * The way windows takes environment variables is different than what C does;
+ * Windows wants a contiguous block of null-terminated strings, terminated
+ * with an additional null.
+ *
+ * Windows has a few "essential" environment variables. winsock will fail
+ * to initialize if SYSTEMROOT is not defined; some APIs make reference to
+ * TEMP. SYSTEMDRIVE is probably also important. We therefore ensure that
+ * these get defined if the input environment block does not contain any
+ * values for them.
+ *
+ * Also add variables known to Cygwin to be required for correct
+ * subprocess operation in many cases:
+ * https://github.com/Alexpux/Cygwin/blob/b266b04fbbd3a595f02ea149e4306d3ab9b1fe3d/winsup/cygwin/environ.cc#L955
+ *
+ */
+int make_program_env(char* env_block[], WCHAR** dst_ptr) {
+  WCHAR* dst;
+  WCHAR* ptr;
+  char** env;
+  size_t env_len = 0;
+  int len;
+  size_t i;
+  DWORD var_size;
+  size_t env_block_count = 1; /* 1 for null-terminator */
+  WCHAR* dst_copy;
+  WCHAR** ptr_copy;
+  WCHAR** env_copy;
+  DWORD* required_vars_value_len = alloca(n_required_vars * sizeof(DWORD*));
+
+  /* first pass: determine size in UTF-16 */
+  for (env = env_block; *env; env++) {
+    int len;
+    if (strchr(*env, '=')) {
+      len = MultiByteToWideChar(CP_UTF8,
+                                0,
+                                *env,
+                                -1,
+                                NULL,
+                                0);
+      if (len <= 0) {
+        return GetLastError();
+      }
+      env_len += len;
+      env_block_count++;
+    }
+  }
+
+  /* second pass: copy to UTF-16 environment block */
+  dst_copy = (WCHAR*)uv__malloc(env_len * sizeof(WCHAR));
+  if (!dst_copy) {
+    return ERROR_OUTOFMEMORY;
+  }
+  env_copy = alloca(env_block_count * sizeof(WCHAR*));
+
+  ptr = dst_copy;
+  ptr_copy = env_copy;
+  for (env = env_block; *env; env++) {
+    if (strchr(*env, '=')) {
+      len = MultiByteToWideChar(CP_UTF8,
+                                0,
+                                *env,
+                                -1,
+                                ptr,
+                                (int) (env_len - (ptr - dst_copy)));
+      if (len <= 0) {
+        DWORD err = GetLastError();
+        uv__free(dst_copy);
+        return err;
+      }
+      *ptr_copy++ = ptr;
+      ptr += len;
+    }
+  }
+  *ptr_copy = NULL;
+  assert(env_len == ptr - dst_copy);
+
+  /* sort our (UTF-16) copy */
+  qsort(env_copy, env_block_count-1, sizeof(wchar_t*), qsort_wcscmp);
+
+  /* third pass: check for required variables */
+  for (ptr_copy = env_copy, i = 0; i < n_required_vars; ) {
+    int cmp;
+    if (!*ptr_copy) {
+      cmp = -1;
+    } else {
+      cmp = env_strncmp(required_vars[i].wide_eq,
+                       required_vars[i].len,
+                        *ptr_copy);
+    }
+    if (cmp < 0) {
+      /* missing required var */
+      var_size = GetEnvironmentVariableW(required_vars[i].wide, NULL, 0);
+      required_vars_value_len[i] = var_size;
+      if (var_size != 0) {
+        env_len += required_vars[i].len;
+        env_len += var_size;
+      }
+      i++;
+    } else {
+      ptr_copy++;
+      if (cmp == 0)
+        i++;
+    }
+  }
+
+  /* final pass: copy, in sort order, and inserting required variables */
+  dst = uv__malloc((1+env_len) * sizeof(WCHAR));
+  if (!dst) {
+    uv__free(dst_copy);
+    return ERROR_OUTOFMEMORY;
+  }
+
+  for (ptr = dst, ptr_copy = env_copy, i = 0;
+       *ptr_copy || i < n_required_vars;
+       ptr += len) {
+    int cmp;
+    if (i >= n_required_vars) {
+      cmp = 1;
+    } else if (!*ptr_copy) {
+      cmp = -1;
+    } else {
+      cmp = env_strncmp(required_vars[i].wide_eq,
+                        required_vars[i].len,
+                        *ptr_copy);
+    }
+    if (cmp < 0) {
+      /* missing required var */
+      len = required_vars_value_len[i];
+      if (len) {
+        wcscpy(ptr, required_vars[i].wide_eq);
+        ptr += required_vars[i].len;
+        var_size = GetEnvironmentVariableW(required_vars[i].wide,
+                                           ptr,
+                                           (int) (env_len - (ptr - dst)));
+        if (var_size != len-1) { /* race condition? */
+          uv_fatal_error(GetLastError(), "GetEnvironmentVariableW");
+        }
+      }
+      i++;
+    } else {
+      /* copy var from env_block */
+      len = wcslen(*ptr_copy) + 1;
+      wmemcpy(ptr, *ptr_copy, len);
+      ptr_copy++;
+      if (cmp == 0)
+        i++;
+    }
+  }
+
+  /* Terminate with an extra NULL. */
+  assert(env_len == (ptr - dst));
+  *ptr = L'\0';
+
+  uv__free(dst_copy);
+  *dst_ptr = dst;
+  return 0;
+}
+
+/*
+ * Attempt to find the value of the PATH environment variable in the child's
+ * preprocessed environment.
+ *
+ * If found, a pointer into `env` is returned. If not found, NULL is returned.
+ */
+static WCHAR* find_path(WCHAR *env) {
+  for (; env != NULL && *env != 0; env += wcslen(env) + 1) {
+    if (wcsncmp(env, L"PATH=", 5) == 0)
+      return &env[5];
+  }
+
+  return NULL;
+}
+
+/*
+ * Called on Windows thread-pool thread to indicate that
+ * a child process has exited.
+ */
+static void CALLBACK exit_wait_callback(void* data, BOOLEAN didTimeout) {
+  uv_process_t* process = (uv_process_t*) data;
+  uv_loop_t* loop = process->loop;
+
+  assert(didTimeout == FALSE);
+  assert(process);
+  assert(!process->exit_cb_pending);
+
+  process->exit_cb_pending = 1;
+
+  /* Post completed */
+  POST_COMPLETION_FOR_REQ(loop, &process->exit_req);
+}
+
+
+/* Called on main thread after a child process has exited. */
+void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
+  int64_t exit_code;
+  DWORD status;
+
+  assert(handle->exit_cb_pending);
+  handle->exit_cb_pending = 0;
+
+  /* If we're closing, don't call the exit callback. Just schedule a close */
+  /* callback now. */
+  if (handle->flags & UV__HANDLE_CLOSING) {
+    uv_want_endgame(loop, (uv_handle_t*) handle);
+    return;
+  }
+
+  /* Unregister from process notification. */
+  if (handle->wait_handle != INVALID_HANDLE_VALUE) {
+    UnregisterWait(handle->wait_handle);
+    handle->wait_handle = INVALID_HANDLE_VALUE;
+  }
+
+  /* Set the handle to inactive: no callbacks will be made after the exit */
+  /* callback.*/
+  uv__handle_stop(handle);
+
+  if (GetExitCodeProcess(handle->process_handle, &status)) {
+    exit_code = status;
+  } else {
+    /* Unable to to obtain the exit code. This should never happen. */
+    exit_code = uv_translate_sys_error(GetLastError());
+  }
+
+  /* Fire the exit callback. */
+  if (handle->exit_cb) {
+    handle->exit_cb(handle, exit_code, handle->exit_signal);
+  }
+}
+
+
+void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
+  uv__handle_closing(handle);
+
+  if (handle->wait_handle != INVALID_HANDLE_VALUE) {
+    /* This blocks until either the wait was cancelled, or the callback has */
+    /* completed. */
+    BOOL r = UnregisterWaitEx(handle->wait_handle, INVALID_HANDLE_VALUE);
+    if (!r) {
+      /* This should never happen, and if it happens, we can't recover... */
+      uv_fatal_error(GetLastError(), "UnregisterWaitEx");
+    }
+
+    handle->wait_handle = INVALID_HANDLE_VALUE;
+  }
+
+  if (!handle->exit_cb_pending) {
+    uv_want_endgame(loop, (uv_handle_t*)handle);
+  }
+}
+
+
+void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle) {
+  assert(!handle->exit_cb_pending);
+  assert(handle->flags & UV__HANDLE_CLOSING);
+  assert(!(handle->flags & UV_HANDLE_CLOSED));
+
+  /* Clean-up the process handle. */
+  CloseHandle(handle->process_handle);
+
+  uv__handle_close(handle);
+}
+
+
+int uv_spawn(uv_loop_t* loop,
+             uv_process_t* process,
+             const uv_process_options_t* options) {
+  int i;
+  int err = 0;
+  WCHAR* path = NULL, *alloc_path = NULL;
+  BOOL result;
+  WCHAR* application_path = NULL, *application = NULL, *arguments = NULL,
+         *env = NULL, *cwd = NULL;
+  STARTUPINFOW startup;
+  PROCESS_INFORMATION info;
+  DWORD process_flags;
+
+  uv_process_init(loop, process);
+  process->exit_cb = options->exit_cb;
+
+  if (options->flags & (UV_PROCESS_SETGID | UV_PROCESS_SETUID)) {
+    return UV_ENOTSUP;
+  }
+
+  if (options->file == NULL ||
+      options->args == NULL) {
+    return UV_EINVAL;
+  }
+
+  assert(options->file != NULL);
+  assert(!(options->flags & ~(UV_PROCESS_DETACHED |
+                              UV_PROCESS_SETGID |
+                              UV_PROCESS_SETUID |
+                              UV_PROCESS_WINDOWS_HIDE |
+                              UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
+
+  err = uv_utf8_to_utf16_alloc(options->file, &application);
+  if (err)
+    goto done;
+
+  err = make_program_args(
+      options->args,
+      options->flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS,
+      &arguments);
+  if (err)
+    goto done;
+
+  if (options->env) {
+     err = make_program_env(options->env, &env);
+     if (err)
+       goto done;
+  }
+
+  if (options->cwd) {
+    /* Explicit cwd */
+    err = uv_utf8_to_utf16_alloc(options->cwd, &cwd);
+    if (err)
+      goto done;
+
+  } else {
+    /* Inherit cwd */
+    DWORD cwd_len, r;
+
+    cwd_len = GetCurrentDirectoryW(0, NULL);
+    if (!cwd_len) {
+      err = GetLastError();
+      goto done;
+    }
+
+    cwd = (WCHAR*) uv__malloc(cwd_len * sizeof(WCHAR));
+    if (cwd == NULL) {
+      err = ERROR_OUTOFMEMORY;
+      goto done;
+    }
+
+    r = GetCurrentDirectoryW(cwd_len, cwd);
+    if (r == 0 || r >= cwd_len) {
+      err = GetLastError();
+      goto done;
+    }
+  }
+
+  /* Get PATH environment variable. */
+  path = find_path(env);
+  if (path == NULL) {
+    DWORD path_len, r;
+
+    path_len = GetEnvironmentVariableW(L"PATH", NULL, 0);
+    if (path_len == 0) {
+      err = GetLastError();
+      goto done;
+    }
+
+    alloc_path = (WCHAR*) uv__malloc(path_len * sizeof(WCHAR));
+    if (alloc_path == NULL) {
+      err = ERROR_OUTOFMEMORY;
+      goto done;
+    }
+    path = alloc_path;
+
+    r = GetEnvironmentVariableW(L"PATH", path, path_len);
+    if (r == 0 || r >= path_len) {
+      err = GetLastError();
+      goto done;
+    }
+  }
+
+  err = uv__stdio_create(loop, options, &process->child_stdio_buffer);
+  if (err)
+    goto done;
+
+  application_path = search_path(application,
+                                 cwd,
+                                 path);
+  if (application_path == NULL) {
+    /* Not found. */
+    err = ERROR_FILE_NOT_FOUND;
+    goto done;
+  }
+
+  startup.cb = sizeof(startup);
+  startup.lpReserved = NULL;
+  startup.lpDesktop = NULL;
+  startup.lpTitle = NULL;
+  startup.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+
+  startup.cbReserved2 = uv__stdio_size(process->child_stdio_buffer);
+  startup.lpReserved2 = (BYTE*) process->child_stdio_buffer;
+
+  startup.hStdInput = uv__stdio_handle(process->child_stdio_buffer, 0);
+  startup.hStdOutput = uv__stdio_handle(process->child_stdio_buffer, 1);
+  startup.hStdError = uv__stdio_handle(process->child_stdio_buffer, 2);
+
+  if (options->flags & UV_PROCESS_WINDOWS_HIDE) {
+    /* Use SW_HIDE to avoid any potential process window. */
+    startup.wShowWindow = SW_HIDE;
+  } else {
+    startup.wShowWindow = SW_SHOWDEFAULT;
+  }
+
+  process_flags = CREATE_UNICODE_ENVIRONMENT;
+
+  if (options->flags & UV_PROCESS_DETACHED) {
+    /* Note that we're not setting the CREATE_BREAKAWAY_FROM_JOB flag. That
+     * means that libuv might not let you create a fully daemonized process
+     * when run under job control. However the type of job control that libuv
+     * itself creates doesn't trickle down to subprocesses so they can still
+     * daemonize.
+     *
+     * A reason to not do this is that CREATE_BREAKAWAY_FROM_JOB makes the
+     * CreateProcess call fail if we're under job control that doesn't allow
+     * breakaway.
+     */
+    process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
+  }
+
+  if (!CreateProcessW(application_path,
+                     arguments,
+                     NULL,
+                     NULL,
+                     1,
+                     process_flags,
+                     env,
+                     cwd,
+                     &startup,
+                     &info)) {
+    /* CreateProcessW failed. */
+    err = GetLastError();
+    goto done;
+  }
+
+  /* Spawn succeeded */
+  /* Beyond this point, failure is reported asynchronously. */
+
+  process->process_handle = info.hProcess;
+  process->pid = info.dwProcessId;
+
+  /* If the process isn't spawned as detached, assign to the global job */
+  /* object so windows will kill it when the parent process dies. */
+  if (!(options->flags & UV_PROCESS_DETACHED)) {
+    uv_once(&uv_global_job_handle_init_guard_, uv__init_global_job_handle);
+
+    if (!AssignProcessToJobObject(uv_global_job_handle_, info.hProcess)) {
+      /* AssignProcessToJobObject might fail if this process is under job
+       * control and the job doesn't have the
+       * JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag set, on a Windows version
+       * that doesn't support nested jobs.
+       *
+       * When that happens we just swallow the error and continue without
+       * establishing a kill-child-on-parent-exit relationship, otherwise
+       * there would be no way for libuv applications run under job control
+       * to spawn processes at all.
+       */
+      DWORD err = GetLastError();
+      if (err != ERROR_ACCESS_DENIED)
+        uv_fatal_error(err, "AssignProcessToJobObject");
+    }
+  }
+
+  /* Set IPC pid to all IPC pipes. */
+  for (i = 0; i < options->stdio_count; i++) {
+    const uv_stdio_container_t* fdopt = &options->stdio[i];
+    if (fdopt->flags & UV_CREATE_PIPE &&
+        fdopt->data.stream->type == UV_NAMED_PIPE &&
+        ((uv_pipe_t*) fdopt->data.stream)->ipc) {
+      ((uv_pipe_t*) fdopt->data.stream)->pipe.conn.ipc_pid = info.dwProcessId;
+    }
+  }
+
+  /* Setup notifications for when the child process exits. */
+  result = RegisterWaitForSingleObject(&process->wait_handle,
+      process->process_handle, exit_wait_callback, (void*)process, INFINITE,
+      WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
+  if (!result) {
+    uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject");
+  }
+
+  CloseHandle(info.hThread);
+
+  assert(!err);
+
+  /* Make the handle active. It will remain active until the exit callback */
+  /* is made or the handle is closed, whichever happens first. */
+  uv__handle_start(process);
+
+  /* Cleanup, whether we succeeded or failed. */
+ done:
+  uv__free(application);
+  uv__free(application_path);
+  uv__free(arguments);
+  uv__free(cwd);
+  uv__free(env);
+  uv__free(alloc_path);
+
+  if (process->child_stdio_buffer != NULL) {
+    /* Clean up child stdio handles. */
+    uv__stdio_destroy(process->child_stdio_buffer);
+    process->child_stdio_buffer = NULL;
+  }
+
+  return uv_translate_sys_error(err);
+}
+
+
+static int uv__kill(HANDLE process_handle, int signum) {
+  switch (signum) {
+    case SIGTERM:
+    case SIGKILL:
+    case SIGINT: {
+      /* Unconditionally terminate the process. On Windows, killed processes */
+      /* normally return 1. */
+      DWORD status;
+      int err;
+
+      if (TerminateProcess(process_handle, 1))
+        return 0;
+
+      /* If the process already exited before TerminateProcess was called, */
+      /* TerminateProcess will fail with ERROR_ACCESS_DENIED. */
+      err = GetLastError();
+      if (err == ERROR_ACCESS_DENIED &&
+          GetExitCodeProcess(process_handle, &status) &&
+          status != STILL_ACTIVE) {
+        return UV_ESRCH;
+      }
+
+      return uv_translate_sys_error(err);
+    }
+
+    case 0: {
+      /* Health check: is the process still alive? */
+      DWORD status;
+
+      if (!GetExitCodeProcess(process_handle, &status))
+        return uv_translate_sys_error(GetLastError());
+
+      if (status != STILL_ACTIVE)
+        return UV_ESRCH;
+
+      return 0;
+    }
+
+    default:
+      /* Unsupported signal. */
+      return UV_ENOSYS;
+  }
+}
+
+
+int uv_process_kill(uv_process_t* process, int signum) {
+  int err;
+
+  if (process->process_handle == INVALID_HANDLE_VALUE) {
+    return UV_EINVAL;
+  }
+
+  err = uv__kill(process->process_handle, signum);
+  if (err) {
+    return err;  /* err is already translated. */
+  }
+
+  process->exit_signal = signum;
+
+  return 0;
+}
+
+
+int uv_kill(int pid, int signum) {
+  int err;
+  HANDLE process_handle = OpenProcess(PROCESS_TERMINATE |
+    PROCESS_QUERY_INFORMATION, FALSE, pid);
+
+  if (process_handle == NULL) {
+    err = GetLastError();
+    if (err == ERROR_INVALID_PARAMETER) {
+      return UV_ESRCH;
+    } else {
+      return uv_translate_sys_error(err);
+    }
+  }
+
+  err = uv__kill(process_handle, signum);
+  CloseHandle(process_handle);
+
+  return err;  /* err is already translated. */
+}
diff --git a/deps/libtuv/src/win/req-inl.h b/deps/libtuv/src/win/req-inl.h
new file mode 100644 (file)
index 0000000..b5e502e
--- /dev/null
@@ -0,0 +1,224 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef UV_WIN_REQ_INL_H_
+#define UV_WIN_REQ_INL_H_
+
+#include <assert.h>
+
+#include "uv.h"
+#include "internal.h"
+
+
+#define SET_REQ_STATUS(req, status)                                     \
+   (req)->u.io.overlapped.Internal = (ULONG_PTR) (status)
+
+#define SET_REQ_ERROR(req, error)                                       \
+  SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error)))
+
+#define SET_REQ_SUCCESS(req)                                            \
+  SET_REQ_STATUS((req), STATUS_SUCCESS)
+
+#define GET_REQ_STATUS(req)                                             \
+  ((NTSTATUS) (req)->u.io.overlapped.Internal)
+
+#define REQ_SUCCESS(req)                                                \
+  (NT_SUCCESS(GET_REQ_STATUS((req))))
+
+#define GET_REQ_ERROR(req)                                              \
+  (pRtlNtStatusToDosError(GET_REQ_STATUS((req))))
+
+#define GET_REQ_SOCK_ERROR(req)                                         \
+  (uv_ntstatus_to_winsock_error(GET_REQ_STATUS((req))))
+
+
+#define REGISTER_HANDLE_REQ(loop, handle, req)                          \
+  do {                                                                  \
+    INCREASE_ACTIVE_COUNT((loop), (handle));                            \
+    uv__req_register((loop), (req));                                    \
+  } while (0)
+
+#define UNREGISTER_HANDLE_REQ(loop, handle, req)                        \
+  do {                                                                  \
+    DECREASE_ACTIVE_COUNT((loop), (handle));                            \
+    uv__req_unregister((loop), (req));                                  \
+  } while (0)
+
+
+#define UV_SUCCEEDED_WITHOUT_IOCP(result)                               \
+  ((result) && (handle->flags & UV_HANDLE_SYNC_BYPASS_IOCP))
+
+#define UV_SUCCEEDED_WITH_IOCP(result)                                  \
+  ((result) || (GetLastError() == ERROR_IO_PENDING))
+
+
+#define POST_COMPLETION_FOR_REQ(loop, req)                              \
+  if (!PostQueuedCompletionStatus((loop)->iocp,                         \
+                                  0,                                    \
+                                  0,                                    \
+                                  &((req)->u.io.overlapped))) {         \
+    uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");       \
+  }
+
+
+INLINE static void uv_req_init(uv_loop_t* loop, uv_req_t* req) {
+  req->type = UV_UNKNOWN_REQ;
+  SET_REQ_SUCCESS(req);
+}
+
+
+INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) {
+  return CONTAINING_RECORD(overlapped, uv_req_t, u.io.overlapped);
+}
+
+
+INLINE static void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
+  req->next_req = NULL;
+  if (loop->pending_reqs_tail) {
+#ifdef _DEBUG
+    /* Ensure the request is not already in the queue, or the queue
+     * will get corrupted.
+     */
+    uv_req_t* current = loop->pending_reqs_tail;
+    do {
+      assert(req != current);
+      current = current->next_req;
+    } while(current != loop->pending_reqs_tail);
+#endif
+
+    req->next_req = loop->pending_reqs_tail->next_req;
+    loop->pending_reqs_tail->next_req = req;
+    loop->pending_reqs_tail = req;
+  } else {
+    req->next_req = req;
+    loop->pending_reqs_tail = req;
+  }
+}
+
+
+#define DELEGATE_STREAM_REQ(loop, req, method, handle_at)                     \
+  do {                                                                        \
+    switch (((uv_handle_t*) (req)->handle_at)->type) {                        \
+      case UV_TCP:                                                            \
+        uv_process_tcp_##method##_req(loop,                                   \
+                                      (uv_tcp_t*) ((req)->handle_at),         \
+                                      req);                                   \
+        break;                                                                \
+                                                                              \
+      case UV_NAMED_PIPE:                                                     \
+        uv_process_pipe_##method##_req(loop,                                  \
+                                       (uv_pipe_t*) ((req)->handle_at),       \
+                                       req);                                  \
+        break;                                                                \
+                                                                              \
+      case UV_TTY:                                                            \
+        uv_process_tty_##method##_req(loop,                                   \
+                                      (uv_tty_t*) ((req)->handle_at),         \
+                                      req);                                   \
+        break;                                                                \
+                                                                              \
+      default:                                                                \
+        assert(0);                                                            \
+    }                                                                         \
+  } while (0)
+
+
+INLINE static int uv_process_reqs(uv_loop_t* loop) {
+  uv_req_t* req;
+  uv_req_t* first;
+  uv_req_t* next;
+
+  if (loop->pending_reqs_tail == NULL)
+    return 0;
+
+  first = loop->pending_reqs_tail->next_req;
+  next = first;
+  loop->pending_reqs_tail = NULL;
+
+  while (next != NULL) {
+    req = next;
+    next = req->next_req != first ? req->next_req : NULL;
+
+    switch (req->type) {
+      case UV_READ:
+        DELEGATE_STREAM_REQ(loop, req, read, data);
+        break;
+
+      case UV_WRITE:
+        DELEGATE_STREAM_REQ(loop, (uv_write_t*) req, write, handle);
+        break;
+
+      case UV_ACCEPT:
+        DELEGATE_STREAM_REQ(loop, req, accept, data);
+        break;
+
+      case UV_CONNECT:
+        DELEGATE_STREAM_REQ(loop, (uv_connect_t*) req, connect, handle);
+        break;
+
+      case UV_SHUTDOWN:
+        /* Tcp shutdown requests don't come here. */
+        assert(((uv_shutdown_t*) req)->handle->type == UV_NAMED_PIPE);
+        uv_process_pipe_shutdown_req(
+            loop,
+            (uv_pipe_t*) ((uv_shutdown_t*) req)->handle,
+            (uv_shutdown_t*) req);
+        break;
+
+      case UV_UDP_RECV:
+        uv_process_udp_recv_req(loop, (uv_udp_t*) req->data, req);
+        break;
+
+      case UV_UDP_SEND:
+        uv_process_udp_send_req(loop,
+                                ((uv_udp_send_t*) req)->handle,
+                                (uv_udp_send_t*) req);
+        break;
+
+      case UV_WAKEUP:
+        uv_process_async_wakeup_req(loop, (uv_async_t*) req->data, req);
+        break;
+
+      case UV_SIGNAL_REQ:
+        uv_process_signal_req(loop, (uv_signal_t*) req->data, req);
+        break;
+
+      case UV_POLL_REQ:
+        uv_process_poll_req(loop, (uv_poll_t*) req->data, req);
+        break;
+
+      case UV_PROCESS_EXIT:
+        uv_process_proc_exit(loop, (uv_process_t*) req->data);
+        break;
+
+      case UV_FS_EVENT_REQ:
+        uv_process_fs_event_req(loop, req, (uv_fs_event_t*) req->data);
+        break;
+
+      default:
+        assert(0);
+    }
+  }
+
+  return 1;
+}
+
+#endif /* UV_WIN_REQ_INL_H_ */
diff --git a/deps/libtuv/src/win/req.c b/deps/libtuv/src/win/req.c
new file mode 100644 (file)
index 0000000..111cc5e
--- /dev/null
@@ -0,0 +1,25 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+
+#include "uv.h"
+#include "internal.h"
diff --git a/deps/libtuv/src/win/signal.c b/deps/libtuv/src/win/signal.c
new file mode 100644 (file)
index 0000000..2c64a55
--- /dev/null
@@ -0,0 +1,356 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <signal.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+
+RB_HEAD(uv_signal_tree_s, uv_signal_s);
+
+static struct uv_signal_tree_s uv__signal_tree = RB_INITIALIZER(uv__signal_tree);
+static ssize_t volatile uv__signal_control_handler_refs = 0;
+static CRITICAL_SECTION uv__signal_lock;
+
+
+void uv_signals_init() {
+  InitializeCriticalSection(&uv__signal_lock);
+}
+
+
+static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
+  /* Compare signums first so all watchers with the same signnum end up */
+  /* adjacent. */
+  if (w1->signum < w2->signum) return -1;
+  if (w1->signum > w2->signum) return 1;
+
+  /* Sort by loop pointer, so we can easily look up the first item after */
+  /* { .signum = x, .loop = NULL } */
+  if ((uintptr_t) w1->loop < (uintptr_t) w2->loop) return -1;
+  if ((uintptr_t) w1->loop > (uintptr_t) w2->loop) return 1;
+
+  if ((uintptr_t) w1 < (uintptr_t) w2) return -1;
+  if ((uintptr_t) w1 > (uintptr_t) w2) return 1;
+
+  return 0;
+}
+
+
+RB_GENERATE_STATIC(uv_signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare);
+
+
+/*
+ * Dispatches signal {signum} to all active uv_signal_t watchers in all loops.
+ * Returns 1 if the signal was dispatched to any watcher, or 0 if there were
+ * no active signal watchers observing this signal.
+ */
+int uv__signal_dispatch(int signum) {
+  uv_signal_t lookup;
+  uv_signal_t* handle;
+  int dispatched = 0;
+
+  EnterCriticalSection(&uv__signal_lock);
+
+  lookup.signum = signum;
+  lookup.loop = NULL;
+
+  for (handle = RB_NFIND(uv_signal_tree_s, &uv__signal_tree, &lookup);
+       handle != NULL && handle->signum == signum;
+       handle = RB_NEXT(uv_signal_tree_s, &uv__signal_tree, handle)) {
+    unsigned long previous = InterlockedExchange(
+            (volatile LONG*) &handle->pending_signum, signum);
+
+    if (!previous) {
+      POST_COMPLETION_FOR_REQ(handle->loop, &handle->signal_req);
+    }
+
+    dispatched = 1;
+  }
+
+  LeaveCriticalSection(&uv__signal_lock);
+
+  return dispatched;
+}
+
+
+static BOOL WINAPI uv__signal_control_handler(DWORD type) {
+  switch (type) {
+    case CTRL_C_EVENT:
+      return uv__signal_dispatch(SIGINT);
+
+    case CTRL_BREAK_EVENT:
+      return uv__signal_dispatch(SIGBREAK);
+
+    case CTRL_CLOSE_EVENT:
+      if (uv__signal_dispatch(SIGHUP)) {
+        /* Windows will terminate the process after the control handler */
+        /* returns. After that it will just terminate our process. Therefore */
+        /* block the signal handler so the main loop has some time to pick */
+        /* up the signal and do something for a few seconds. */
+        Sleep(INFINITE);
+        return TRUE;
+      }
+      return FALSE;
+
+    case CTRL_LOGOFF_EVENT:
+    case CTRL_SHUTDOWN_EVENT:
+      /* These signals are only sent to services. Services have their own */
+      /* notification mechanism, so there's no point in handling these. */
+
+    default:
+      /* We don't handle these. */
+      return FALSE;
+  }
+}
+
+
+static int uv__signal_register_control_handler() {
+  /* When this function is called, the uv__signal_lock must be held. */
+
+  /* If the console control handler has already been hooked, just add a */
+  /* reference. */
+  if (uv__signal_control_handler_refs > 0) {
+    uv__signal_control_handler_refs++;
+    return 0;
+  }
+
+  if (!SetConsoleCtrlHandler(uv__signal_control_handler, TRUE))
+    return GetLastError();
+
+  uv__signal_control_handler_refs++;
+
+  return 0;
+}
+
+
+static void uv__signal_unregister_control_handler() {
+  /* When this function is called, the uv__signal_lock must be held. */
+  BOOL r;
+
+  /* Don't unregister if the number of console control handlers exceeds one. */
+  /* Just remove a reference in that case. */
+  if (uv__signal_control_handler_refs > 1) {
+    uv__signal_control_handler_refs--;
+    return;
+  }
+
+  assert(uv__signal_control_handler_refs == 1);
+
+  r = SetConsoleCtrlHandler(uv__signal_control_handler, FALSE);
+  /* This should never fail; if it does it is probably a bug in libuv. */
+  assert(r);
+
+  uv__signal_control_handler_refs--;
+}
+
+
+static int uv__signal_register(int signum) {
+  switch (signum) {
+    case SIGINT:
+    case SIGBREAK:
+    case SIGHUP:
+      return uv__signal_register_control_handler();
+
+    case SIGWINCH:
+      /* SIGWINCH is generated in tty.c. No need to register anything. */
+      return 0;
+
+    case SIGILL:
+    case SIGABRT_COMPAT:
+    case SIGFPE:
+    case SIGSEGV:
+    case SIGTERM:
+    case SIGABRT:
+      /* Signal is never raised. */
+      return 0;
+
+    default:
+      /* Invalid signal. */
+      return ERROR_INVALID_PARAMETER;
+  }
+}
+
+
+static void uv__signal_unregister(int signum) {
+  switch (signum) {
+    case SIGINT:
+    case SIGBREAK:
+    case SIGHUP:
+      uv__signal_unregister_control_handler();
+      return;
+
+    case SIGWINCH:
+      /* SIGWINCH is generated in tty.c. No need to unregister anything. */
+      return;
+
+    case SIGILL:
+    case SIGABRT_COMPAT:
+    case SIGFPE:
+    case SIGSEGV:
+    case SIGTERM:
+    case SIGABRT:
+      /* Nothing is registered for this signal. */
+      return;
+
+    default:
+      /* Libuv bug. */
+      assert(0 && "Invalid signum");
+      return;
+  }
+}
+
+
+int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) {
+  uv_req_t* req;
+
+  uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL);
+  handle->pending_signum = 0;
+  handle->signum = 0;
+  handle->signal_cb = NULL;
+
+  req = &handle->signal_req;
+  uv_req_init(loop, req);
+  req->type = UV_SIGNAL_REQ;
+  req->data = handle;
+
+  return 0;
+}
+
+
+int uv_signal_stop(uv_signal_t* handle) {
+  uv_signal_t* removed_handle;
+
+  /* If the watcher wasn't started, this is a no-op. */
+  if (handle->signum == 0)
+    return 0;
+
+  EnterCriticalSection(&uv__signal_lock);
+
+  uv__signal_unregister(handle->signum);
+
+  removed_handle = RB_REMOVE(uv_signal_tree_s, &uv__signal_tree, handle);
+  assert(removed_handle == handle);
+
+  LeaveCriticalSection(&uv__signal_lock);
+
+  handle->signum = 0;
+  uv__handle_stop(handle);
+
+  return 0;
+}
+
+
+int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
+  int err;
+
+  /* If the user supplies signum == 0, then return an error already. If the */
+  /* signum is otherwise invalid then uv__signal_register will find out */
+  /* eventually. */
+  if (signum == 0) {
+    return UV_EINVAL;
+  }
+
+  /* Short circuit: if the signal watcher is already watching {signum} don't */
+  /* go through the process of deregistering and registering the handler. */
+  /* Additionally, this avoids pending signals getting lost in the (small) */
+  /* time frame that handle->signum == 0. */
+  if (signum == handle->signum) {
+    handle->signal_cb = signal_cb;
+    return 0;
+  }
+
+  /* If the signal handler was already active, stop it first. */
+  if (handle->signum != 0) {
+    int r = uv_signal_stop(handle);
+    /* uv_signal_stop is infallible. */
+    assert(r == 0);
+  }
+
+  EnterCriticalSection(&uv__signal_lock);
+
+  err = uv__signal_register(signum);
+  if (err) {
+    /* Uh-oh, didn't work. */
+    LeaveCriticalSection(&uv__signal_lock);
+    return uv_translate_sys_error(err);
+  }
+
+  handle->signum = signum;
+  RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle);
+
+  LeaveCriticalSection(&uv__signal_lock);
+
+  handle->signal_cb = signal_cb;
+  uv__handle_start(handle);
+
+  return 0;
+}
+
+
+void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle,
+    uv_req_t* req) {
+  long dispatched_signum;
+
+  assert(handle->type == UV_SIGNAL);
+  assert(req->type == UV_SIGNAL_REQ);
+
+  dispatched_signum = InterlockedExchange(
+          (volatile LONG*) &handle->pending_signum, 0);
+  assert(dispatched_signum != 0);
+
+  /* Check if the pending signal equals the signum that we are watching for. */
+  /* These can get out of sync when the handler is stopped and restarted */
+  /* while the signal_req is pending. */
+  if (dispatched_signum == handle->signum)
+    handle->signal_cb(handle, dispatched_signum);
+
+  if (handle->flags & UV__HANDLE_CLOSING) {
+    /* When it is closing, it must be stopped at this point. */
+    assert(handle->signum == 0);
+    uv_want_endgame(loop, (uv_handle_t*) handle);
+  }
+}
+
+
+void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle) {
+  uv_signal_stop(handle);
+  uv__handle_closing(handle);
+
+  if (handle->pending_signum == 0) {
+    uv_want_endgame(loop, (uv_handle_t*) handle);
+  }
+}
+
+
+void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle) {
+  assert(handle->flags & UV__HANDLE_CLOSING);
+  assert(!(handle->flags & UV_HANDLE_CLOSED));
+
+  assert(handle->signum == 0);
+  assert(handle->pending_signum == 0);
+
+  handle->flags |= UV_HANDLE_CLOSED;
+
+  uv__handle_close(handle);
+}
diff --git a/deps/libtuv/src/win/snprintf.c b/deps/libtuv/src/win/snprintf.c
new file mode 100644 (file)
index 0000000..776c0e3
--- /dev/null
@@ -0,0 +1,42 @@
+/* Copyright the libuv project contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#if defined(_MSC_VER) && _MSC_VER < 1900
+
+#include <stdio.h>
+#include <stdarg.h>
+
+/* Emulate snprintf() on MSVC<2015, _snprintf() doesn't zero-terminate the buffer
+ * on overflow...
+ */
+int snprintf(char* buf, size_t len, const char* fmt, ...) {
+  int n;
+  va_list ap;
+  va_start(ap, fmt);
+
+  n = _vscprintf(fmt, ap);
+  vsnprintf_s(buf, len, _TRUNCATE, fmt, ap);
+
+  va_end(ap);
+  return n;
+}
+
+#endif
diff --git a/deps/libtuv/src/win/stream-inl.h b/deps/libtuv/src/win/stream-inl.h
new file mode 100644 (file)
index 0000000..b7a3c11
--- /dev/null
@@ -0,0 +1,56 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef UV_WIN_STREAM_INL_H_
+#define UV_WIN_STREAM_INL_H_
+
+#include <assert.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+
+INLINE static void uv_stream_init(uv_loop_t* loop,
+                                  uv_stream_t* handle,
+                                  uv_handle_type type) {
+  uv__handle_init(loop, (uv_handle_t*) handle, type);
+  handle->write_queue_size = 0;
+  handle->activecnt = 0;
+}
+
+
+INLINE static void uv_connection_init(uv_stream_t* handle) {
+  handle->flags |= UV_HANDLE_CONNECTION;
+  handle->stream.conn.write_reqs_pending = 0;
+
+  uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req));
+  handle->read_req.event_handle = NULL;
+  handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
+  handle->read_req.type = UV_READ;
+  handle->read_req.data = handle;
+
+  handle->stream.conn.shutdown_req = NULL;
+}
+
+
+#endif /* UV_WIN_STREAM_INL_H_ */
diff --git a/deps/libtuv/src/win/stream.c b/deps/libtuv/src/win/stream.c
new file mode 100644 (file)
index 0000000..a2466e5
--- /dev/null
@@ -0,0 +1,249 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "req-inl.h"
+
+
+int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
+  int err;
+
+  err = ERROR_INVALID_PARAMETER;
+  switch (stream->type) {
+    case UV_TCP:
+      err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb);
+      break;
+    case UV_NAMED_PIPE:
+      err = uv_pipe_listen((uv_pipe_t*)stream, backlog, cb);
+      break;
+    default:
+      assert(0);
+  }
+
+  return uv_translate_sys_error(err);
+}
+
+
+int uv_accept(uv_stream_t* server, uv_stream_t* client) {
+  int err;
+
+  err = ERROR_INVALID_PARAMETER;
+  switch (server->type) {
+    case UV_TCP:
+      err = uv_tcp_accept((uv_tcp_t*)server, (uv_tcp_t*)client);
+      break;
+    case UV_NAMED_PIPE:
+      err = uv_pipe_accept((uv_pipe_t*)server, client);
+      break;
+    default:
+      assert(0);
+  }
+
+  return uv_translate_sys_error(err);
+}
+
+
+int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb,
+    uv_read_cb read_cb) {
+  int err;
+
+  if (handle->flags & UV_HANDLE_READING) {
+    return UV_EALREADY;
+  }
+
+  if (!(handle->flags & UV_HANDLE_READABLE)) {
+    return UV_ENOTCONN;
+  }
+
+  err = ERROR_INVALID_PARAMETER;
+  switch (handle->type) {
+    case UV_TCP:
+      err = uv_tcp_read_start((uv_tcp_t*)handle, alloc_cb, read_cb);
+      break;
+    case UV_NAMED_PIPE:
+      err = uv_pipe_read_start((uv_pipe_t*)handle, alloc_cb, read_cb);
+      break;
+    case UV_TTY:
+      err = uv_tty_read_start((uv_tty_t*) handle, alloc_cb, read_cb);
+      break;
+    default:
+      assert(0);
+  }
+
+  return uv_translate_sys_error(err);
+}
+
+
+int uv_read_stop(uv_stream_t* handle) {
+  int err;
+
+  if (!(handle->flags & UV_HANDLE_READING))
+    return 0;
+
+  err = 0;
+  if (handle->type == UV_TTY) {
+    err = uv_tty_read_stop((uv_tty_t*) handle);
+  } else {
+    if (handle->type == UV_NAMED_PIPE) {
+      uv__pipe_stop_read((uv_pipe_t*) handle);
+    } else {
+      handle->flags &= ~UV_HANDLE_READING;
+    }
+    DECREASE_ACTIVE_COUNT(handle->loop, handle);
+  }
+
+  return uv_translate_sys_error(err);
+}
+
+
+int uv_write(uv_write_t* req,
+             uv_stream_t* handle,
+             const uv_buf_t bufs[],
+             unsigned int nbufs,
+             uv_write_cb cb) {
+  uv_loop_t* loop = handle->loop;
+  int err;
+
+  if (!(handle->flags & UV_HANDLE_WRITABLE)) {
+    return UV_EPIPE;
+  }
+
+  err = ERROR_INVALID_PARAMETER;
+  switch (handle->type) {
+    case UV_TCP:
+      err = uv_tcp_write(loop, req, (uv_tcp_t*) handle, bufs, nbufs, cb);
+      break;
+    case UV_NAMED_PIPE:
+      err = uv_pipe_write(loop, req, (uv_pipe_t*) handle, bufs, nbufs, cb);
+      break;
+    case UV_TTY:
+      err = uv_tty_write(loop, req, (uv_tty_t*) handle, bufs, nbufs, cb);
+      break;
+    default:
+      assert(0);
+  }
+
+  return uv_translate_sys_error(err);
+}
+
+
+int uv_write2(uv_write_t* req,
+              uv_stream_t* handle,
+              const uv_buf_t bufs[],
+              unsigned int nbufs,
+              uv_stream_t* send_handle,
+              uv_write_cb cb) {
+  uv_loop_t* loop = handle->loop;
+  int err;
+
+  if (!(handle->flags & UV_HANDLE_WRITABLE)) {
+    return UV_EPIPE;
+  }
+
+  err = ERROR_INVALID_PARAMETER;
+  switch (handle->type) {
+    case UV_NAMED_PIPE:
+      err = uv_pipe_write2(loop,
+                           req,
+                           (uv_pipe_t*) handle,
+                           bufs,
+                           nbufs,
+                           send_handle,
+                           cb);
+      break;
+    default:
+      assert(0);
+  }
+
+  return uv_translate_sys_error(err);
+}
+
+
+int uv_try_write(uv_stream_t* stream,
+                 const uv_buf_t bufs[],
+                 unsigned int nbufs) {
+  if (stream->flags & UV__HANDLE_CLOSING)
+    return UV_EBADF;
+  if (!(stream->flags & UV_HANDLE_WRITABLE))
+    return UV_EPIPE;
+
+  switch (stream->type) {
+    case UV_TCP:
+      return uv__tcp_try_write((uv_tcp_t*) stream, bufs, nbufs);
+    case UV_TTY:
+      return uv__tty_try_write((uv_tty_t*) stream, bufs, nbufs);
+    case UV_NAMED_PIPE:
+      return UV_EAGAIN;
+    default:
+      assert(0);
+      return UV_ENOSYS;
+  }
+}
+
+
+int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
+  uv_loop_t* loop = handle->loop;
+
+  if (!(handle->flags & UV_HANDLE_WRITABLE)) {
+    return UV_EPIPE;
+  }
+
+  uv_req_init(loop, (uv_req_t*) req);
+  req->type = UV_SHUTDOWN;
+  req->handle = handle;
+  req->cb = cb;
+
+  handle->flags &= ~UV_HANDLE_WRITABLE;
+  handle->stream.conn.shutdown_req = req;
+  handle->reqs_pending++;
+  REGISTER_HANDLE_REQ(loop, handle, req);
+
+  uv_want_endgame(loop, (uv_handle_t*)handle);
+
+  return 0;
+}
+
+
+int uv_is_readable(const uv_stream_t* handle) {
+  return !!(handle->flags & UV_HANDLE_READABLE);
+}
+
+
+int uv_is_writable(const uv_stream_t* handle) {
+  return !!(handle->flags & UV_HANDLE_WRITABLE);
+}
+
+
+int uv_stream_set_blocking(uv_stream_t* handle, int blocking) {
+  if (handle->type != UV_NAMED_PIPE)
+    return UV_EINVAL;
+
+  if (blocking != 0)
+    handle->flags |= UV_HANDLE_BLOCKING_WRITES;
+  else
+    handle->flags &= ~UV_HANDLE_BLOCKING_WRITES;
+
+  return 0;
+}
diff --git a/deps/libtuv/src/win/tcp.c b/deps/libtuv/src/win/tcp.c
new file mode 100644 (file)
index 0000000..0709696
--- /dev/null
@@ -0,0 +1,1510 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "stream-inl.h"
+#include "req-inl.h"
+
+
+/*
+ * Threshold of active tcp streams for which to preallocate tcp read buffers.
+ * (Due to node slab allocator performing poorly under this pattern,
+ *  the optimization is temporarily disabled (threshold=0).  This will be
+ *  revisited once node allocator is improved.)
+ */
+const unsigned int uv_active_tcp_streams_threshold = 0;
+
+/*
+ * Number of simultaneous pending AcceptEx calls.
+ */
+const unsigned int uv_simultaneous_server_accepts = 32;
+
+/* A zero-size buffer for use by uv_tcp_read */
+static char uv_zero_[] = "";
+
+static int uv__tcp_nodelay(uv_tcp_t* handle, SOCKET socket, int enable) {
+  if (setsockopt(socket,
+                 IPPROTO_TCP,
+                 TCP_NODELAY,
+                 (const char*)&enable,
+                 sizeof enable) == -1) {
+    return WSAGetLastError();
+  }
+  return 0;
+}
+
+
+static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsigned int delay) {
+  if (setsockopt(socket,
+                 SOL_SOCKET,
+                 SO_KEEPALIVE,
+                 (const char*)&enable,
+                 sizeof enable) == -1) {
+    return WSAGetLastError();
+  }
+
+  if (enable && setsockopt(socket,
+                           IPPROTO_TCP,
+                           TCP_KEEPALIVE,
+                           (const char*)&delay,
+                           sizeof delay) == -1) {
+    return WSAGetLastError();
+  }
+
+  return 0;
+}
+
+
+static int uv_tcp_set_socket(uv_loop_t* loop,
+                             uv_tcp_t* handle,
+                             SOCKET socket,
+                             int family,
+                             int imported) {
+  DWORD yes = 1;
+  int non_ifs_lsp;
+  int err;
+
+  if (handle->socket != INVALID_SOCKET)
+    return UV_EBUSY;
+
+  /* Set the socket to nonblocking mode */
+  if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {
+    return WSAGetLastError();
+  }
+
+  /* Make the socket non-inheritable */
+  if (!SetHandleInformation((HANDLE) socket, HANDLE_FLAG_INHERIT, 0))
+    return GetLastError();
+
+  /* Associate it with the I/O completion port. */
+  /* Use uv_handle_t pointer as completion key. */
+  if (CreateIoCompletionPort((HANDLE)socket,
+                             loop->iocp,
+                             (ULONG_PTR)socket,
+                             0) == NULL) {
+    if (imported) {
+      handle->flags |= UV_HANDLE_EMULATE_IOCP;
+    } else {
+      return GetLastError();
+    }
+  }
+
+  if (family == AF_INET6) {
+    non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv6;
+  } else {
+    non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv4;
+  }
+
+  if (pSetFileCompletionNotificationModes &&
+      !(handle->flags & UV_HANDLE_EMULATE_IOCP) && !non_ifs_lsp) {
+    if (pSetFileCompletionNotificationModes((HANDLE) socket,
+        FILE_SKIP_SET_EVENT_ON_HANDLE |
+        FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
+      handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP;
+    } else if (GetLastError() != ERROR_INVALID_FUNCTION) {
+      return GetLastError();
+    }
+  }
+
+  if (handle->flags & UV_HANDLE_TCP_NODELAY) {
+    err = uv__tcp_nodelay(handle, socket, 1);
+    if (err)
+      return err;
+  }
+
+  /* TODO: Use stored delay. */
+  if (handle->flags & UV_HANDLE_TCP_KEEPALIVE) {
+    err = uv__tcp_keepalive(handle, socket, 1, 60);
+    if (err)
+      return err;
+  }
+
+  handle->socket = socket;
+
+  if (family == AF_INET6) {
+    handle->flags |= UV_HANDLE_IPV6;
+  } else {
+    assert(!(handle->flags & UV_HANDLE_IPV6));
+  }
+
+  return 0;
+}
+
+
+int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* handle, unsigned int flags) {
+  int domain;
+
+  /* Use the lower 8 bits for the domain */
+  domain = flags & 0xFF;
+  if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
+    return UV_EINVAL;
+
+  if (flags & ~0xFF)
+    return UV_EINVAL;
+
+  uv_stream_init(loop, (uv_stream_t*) handle, UV_TCP);
+  handle->tcp.serv.accept_reqs = NULL;
+  handle->tcp.serv.pending_accepts = NULL;
+  handle->socket = INVALID_SOCKET;
+  handle->reqs_pending = 0;
+  handle->tcp.serv.func_acceptex = NULL;
+  handle->tcp.conn.func_connectex = NULL;
+  handle->tcp.serv.processed_accepts = 0;
+  handle->delayed_error = 0;
+
+  /* If anything fails beyond this point we need to remove the handle from
+   * the handle queue, since it was added by uv__handle_init in uv_stream_init.
+   */
+
+  if (domain != AF_UNSPEC) {
+    SOCKET sock;
+    DWORD err;
+
+    sock = socket(domain, SOCK_STREAM, 0);
+    if (sock == INVALID_SOCKET) {
+      err = WSAGetLastError();
+      QUEUE_REMOVE(&handle->handle_queue);
+      return uv_translate_sys_error(err);
+    }
+
+    err = uv_tcp_set_socket(handle->loop, handle, sock, domain, 0);
+    if (err) {
+      closesocket(sock);
+      QUEUE_REMOVE(&handle->handle_queue);
+      return uv_translate_sys_error(err);
+    }
+
+  }
+
+  return 0;
+}
+
+
+int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
+  return uv_tcp_init_ex(loop, handle, AF_UNSPEC);
+}
+
+
+void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
+  int err;
+  unsigned int i;
+  uv_tcp_accept_t* req;
+
+  if (handle->flags & UV_HANDLE_CONNECTION &&
+      handle->stream.conn.shutdown_req != NULL &&
+      handle->stream.conn.write_reqs_pending == 0) {
+
+    UNREGISTER_HANDLE_REQ(loop, handle, handle->stream.conn.shutdown_req);
+
+    err = 0;
+    if (handle->flags & UV__HANDLE_CLOSING) {
+      err = ERROR_OPERATION_ABORTED;
+    } else if (shutdown(handle->socket, SD_SEND) == SOCKET_ERROR) {
+      err = WSAGetLastError();
+    }
+
+    if (handle->stream.conn.shutdown_req->cb) {
+      handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req,
+                               uv_translate_sys_error(err));
+    }
+
+    handle->stream.conn.shutdown_req = NULL;
+    DECREASE_PENDING_REQ_COUNT(handle);
+    return;
+  }
+
+  if (handle->flags & UV__HANDLE_CLOSING &&
+      handle->reqs_pending == 0) {
+    assert(!(handle->flags & UV_HANDLE_CLOSED));
+
+    if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) {
+      closesocket(handle->socket);
+      handle->socket = INVALID_SOCKET;
+      handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
+    }
+
+    if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->tcp.serv.accept_reqs) {
+      if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+        for (i = 0; i < uv_simultaneous_server_accepts; i++) {
+          req = &handle->tcp.serv.accept_reqs[i];
+          if (req->wait_handle != INVALID_HANDLE_VALUE) {
+            UnregisterWait(req->wait_handle);
+            req->wait_handle = INVALID_HANDLE_VALUE;
+          }
+          if (req->event_handle) {
+            CloseHandle(req->event_handle);
+            req->event_handle = NULL;
+          }
+        }
+      }
+
+      uv__free(handle->tcp.serv.accept_reqs);
+      handle->tcp.serv.accept_reqs = NULL;
+    }
+
+    if (handle->flags & UV_HANDLE_CONNECTION &&
+        handle->flags & UV_HANDLE_EMULATE_IOCP) {
+      if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) {
+        UnregisterWait(handle->read_req.wait_handle);
+        handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
+      }
+      if (handle->read_req.event_handle) {
+        CloseHandle(handle->read_req.event_handle);
+        handle->read_req.event_handle = NULL;
+      }
+    }
+
+    uv__handle_close(handle);
+    loop->active_tcp_streams--;
+  }
+}
+
+
+/* Unlike on Unix, here we don't set SO_REUSEADDR, because it doesn't just
+ * allow binding to addresses that are in use by sockets in TIME_WAIT, it
+ * effectively allows 'stealing' a port which is in use by another application.
+ *
+ * SO_EXCLUSIVEADDRUSE is also not good here because it does check all sockets,
+ * regardless of state, so we'd get an error even if the port is in use by a
+ * socket in TIME_WAIT state.
+ *
+ * See issue #1360.
+ *
+ */
+static int uv_tcp_try_bind(uv_tcp_t* handle,
+                           const struct sockaddr* addr,
+                           unsigned int addrlen,
+                           unsigned int flags) {
+  DWORD err;
+  int r;
+
+  if (handle->socket == INVALID_SOCKET) {
+    SOCKET sock;
+
+    /* Cannot set IPv6-only mode on non-IPv6 socket. */
+    if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6)
+      return ERROR_INVALID_PARAMETER;
+
+    sock = socket(addr->sa_family, SOCK_STREAM, 0);
+    if (sock == INVALID_SOCKET) {
+      return WSAGetLastError();
+    }
+
+    err = uv_tcp_set_socket(handle->loop, handle, sock, addr->sa_family, 0);
+    if (err) {
+      closesocket(sock);
+      return err;
+    }
+  }
+
+#ifdef IPV6_V6ONLY
+  if (addr->sa_family == AF_INET6) {
+    int on;
+
+    on = (flags & UV_TCP_IPV6ONLY) != 0;
+
+    /* TODO: how to handle errors? This may fail if there is no ipv4 stack */
+    /* available, or when run on XP/2003 which have no support for dualstack */
+    /* sockets. For now we're silently ignoring the error. */
+    setsockopt(handle->socket,
+               IPPROTO_IPV6,
+               IPV6_V6ONLY,
+               (const char*)&on,
+               sizeof on);
+  }
+#endif
+
+  r = bind(handle->socket, addr, addrlen);
+
+  if (r == SOCKET_ERROR) {
+    err = WSAGetLastError();
+    if (err == WSAEADDRINUSE) {
+      /* Some errors are not to be reported until connect() or listen() */
+      handle->delayed_error = err;
+    } else {
+      return err;
+    }
+  }
+
+  handle->flags |= UV_HANDLE_BOUND;
+
+  return 0;
+}
+
+
+static void CALLBACK post_completion(void* context, BOOLEAN timed_out) {
+  uv_req_t* req;
+  uv_tcp_t* handle;
+
+  req = (uv_req_t*) context;
+  assert(req != NULL);
+  handle = (uv_tcp_t*)req->data;
+  assert(handle != NULL);
+  assert(!timed_out);
+
+  if (!PostQueuedCompletionStatus(handle->loop->iocp,
+                                  req->u.io.overlapped.InternalHigh,
+                                  0,
+                                  &req->u.io.overlapped)) {
+    uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
+  }
+}
+
+
+static void CALLBACK post_write_completion(void* context, BOOLEAN timed_out) {
+  uv_write_t* req;
+  uv_tcp_t* handle;
+
+  req = (uv_write_t*) context;
+  assert(req != NULL);
+  handle = (uv_tcp_t*)req->handle;
+  assert(handle != NULL);
+  assert(!timed_out);
+
+  if (!PostQueuedCompletionStatus(handle->loop->iocp,
+                                  req->u.io.overlapped.InternalHigh,
+                                  0,
+                                  &req->u.io.overlapped)) {
+    uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
+  }
+}
+
+
+static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
+  uv_loop_t* loop = handle->loop;
+  BOOL success;
+  DWORD bytes;
+  SOCKET accept_socket;
+  short family;
+
+  assert(handle->flags & UV_HANDLE_LISTENING);
+  assert(req->accept_socket == INVALID_SOCKET);
+
+  /* choose family and extension function */
+  if (handle->flags & UV_HANDLE_IPV6) {
+    family = AF_INET6;
+  } else {
+    family = AF_INET;
+  }
+
+  /* Open a socket for the accepted connection. */
+  accept_socket = socket(family, SOCK_STREAM, 0);
+  if (accept_socket == INVALID_SOCKET) {
+    SET_REQ_ERROR(req, WSAGetLastError());
+    uv_insert_pending_req(loop, (uv_req_t*)req);
+    handle->reqs_pending++;
+    return;
+  }
+
+  /* Make the socket non-inheritable */
+  if (!SetHandleInformation((HANDLE) accept_socket, HANDLE_FLAG_INHERIT, 0)) {
+    SET_REQ_ERROR(req, GetLastError());
+    uv_insert_pending_req(loop, (uv_req_t*)req);
+    handle->reqs_pending++;
+    closesocket(accept_socket);
+    return;
+  }
+
+  /* Prepare the overlapped structure. */
+  memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
+  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+    req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
+  }
+
+  success = handle->tcp.serv.func_acceptex(handle->socket,
+                                          accept_socket,
+                                          (void*)req->accept_buffer,
+                                          0,
+                                          sizeof(struct sockaddr_storage),
+                                          sizeof(struct sockaddr_storage),
+                                          &bytes,
+                                          &req->u.io.overlapped);
+
+  if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
+    /* Process the req without IOCP. */
+    req->accept_socket = accept_socket;
+    handle->reqs_pending++;
+    uv_insert_pending_req(loop, (uv_req_t*)req);
+  } else if (UV_SUCCEEDED_WITH_IOCP(success)) {
+    /* The req will be processed with IOCP. */
+    req->accept_socket = accept_socket;
+    handle->reqs_pending++;
+    if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
+        req->wait_handle == INVALID_HANDLE_VALUE &&
+        !RegisterWaitForSingleObject(&req->wait_handle,
+          req->event_handle, post_completion, (void*) req,
+          INFINITE, WT_EXECUTEINWAITTHREAD)) {
+      SET_REQ_ERROR(req, GetLastError());
+      uv_insert_pending_req(loop, (uv_req_t*)req);
+      handle->reqs_pending++;
+      return;
+    }
+  } else {
+    /* Make this req pending reporting an error. */
+    SET_REQ_ERROR(req, WSAGetLastError());
+    uv_insert_pending_req(loop, (uv_req_t*)req);
+    handle->reqs_pending++;
+    /* Destroy the preallocated client socket. */
+    closesocket(accept_socket);
+    /* Destroy the event handle */
+    if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+      CloseHandle(req->u.io.overlapped.hEvent);
+      req->event_handle = NULL;
+    }
+  }
+}
+
+
+static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
+  uv_read_t* req;
+  uv_buf_t buf;
+  int result;
+  DWORD bytes, flags;
+
+  assert(handle->flags & UV_HANDLE_READING);
+  assert(!(handle->flags & UV_HANDLE_READ_PENDING));
+
+  req = &handle->read_req;
+  memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
+
+  /*
+   * Preallocate a read buffer if the number of active streams is below
+   * the threshold.
+  */
+  if (loop->active_tcp_streams < uv_active_tcp_streams_threshold) {
+    handle->flags &= ~UV_HANDLE_ZERO_READ;
+    handle->tcp.conn.read_buffer = uv_buf_init(NULL, 0);
+    handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->tcp.conn.read_buffer);
+    if (handle->tcp.conn.read_buffer.base == NULL ||
+        handle->tcp.conn.read_buffer.len == 0) {
+      handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &handle->tcp.conn.read_buffer);
+      return;
+    }
+    assert(handle->tcp.conn.read_buffer.base != NULL);
+    buf = handle->tcp.conn.read_buffer;
+  } else {
+    handle->flags |= UV_HANDLE_ZERO_READ;
+    buf.base = (char*) &uv_zero_;
+    buf.len = 0;
+  }
+
+  /* Prepare the overlapped structure. */
+  memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
+  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+    assert(req->event_handle);
+    req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
+  }
+
+  flags = 0;
+  result = WSARecv(handle->socket,
+                   (WSABUF*)&buf,
+                   1,
+                   &bytes,
+                   &flags,
+                   &req->u.io.overlapped,
+                   NULL);
+
+  if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
+    /* Process the req without IOCP. */
+    handle->flags |= UV_HANDLE_READ_PENDING;
+    req->u.io.overlapped.InternalHigh = bytes;
+    handle->reqs_pending++;
+    uv_insert_pending_req(loop, (uv_req_t*)req);
+  } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
+    /* The req will be processed with IOCP. */
+    handle->flags |= UV_HANDLE_READ_PENDING;
+    handle->reqs_pending++;
+    if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
+        req->wait_handle == INVALID_HANDLE_VALUE &&
+        !RegisterWaitForSingleObject(&req->wait_handle,
+          req->event_handle, post_completion, (void*) req,
+          INFINITE, WT_EXECUTEINWAITTHREAD)) {
+      SET_REQ_ERROR(req, GetLastError());
+      uv_insert_pending_req(loop, (uv_req_t*)req);
+    }
+  } else {
+    /* Make this req pending reporting an error. */
+    SET_REQ_ERROR(req, WSAGetLastError());
+    uv_insert_pending_req(loop, (uv_req_t*)req);
+    handle->reqs_pending++;
+  }
+}
+
+
+int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
+  uv_loop_t* loop = handle->loop;
+  unsigned int i, simultaneous_accepts;
+  uv_tcp_accept_t* req;
+  int err;
+
+  assert(backlog > 0);
+
+  if (handle->flags & UV_HANDLE_LISTENING) {
+    handle->stream.serv.connection_cb = cb;
+  }
+
+  if (handle->flags & UV_HANDLE_READING) {
+    return WSAEISCONN;
+  }
+
+  if (handle->delayed_error) {
+    return handle->delayed_error;
+  }
+
+  if (!(handle->flags & UV_HANDLE_BOUND)) {
+    err = uv_tcp_try_bind(handle,
+                          (const struct sockaddr*) &uv_addr_ip4_any_,
+                          sizeof(uv_addr_ip4_any_),
+                          0);
+    if (err)
+      return err;
+    if (handle->delayed_error)
+      return handle->delayed_error;
+  }
+
+  if (!handle->tcp.serv.func_acceptex) {
+    if (!uv_get_acceptex_function(handle->socket, &handle->tcp.serv.func_acceptex)) {
+      return WSAEAFNOSUPPORT;
+    }
+  }
+
+  if (!(handle->flags & UV_HANDLE_SHARED_TCP_SOCKET) &&
+      listen(handle->socket, backlog) == SOCKET_ERROR) {
+    return WSAGetLastError();
+  }
+
+  handle->flags |= UV_HANDLE_LISTENING;
+  handle->stream.serv.connection_cb = cb;
+  INCREASE_ACTIVE_COUNT(loop, handle);
+
+  simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1
+    : uv_simultaneous_server_accepts;
+
+  if(!handle->tcp.serv.accept_reqs) {
+    handle->tcp.serv.accept_reqs = (uv_tcp_accept_t*)
+      uv__malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t));
+    if (!handle->tcp.serv.accept_reqs) {
+      uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+    }
+
+    for (i = 0; i < simultaneous_accepts; i++) {
+      req = &handle->tcp.serv.accept_reqs[i];
+      uv_req_init(loop, (uv_req_t*)req);
+      req->type = UV_ACCEPT;
+      req->accept_socket = INVALID_SOCKET;
+      req->data = handle;
+
+      req->wait_handle = INVALID_HANDLE_VALUE;
+      if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+        req->event_handle = CreateEvent(NULL, 0, 0, NULL);
+        if (!req->event_handle) {
+          uv_fatal_error(GetLastError(), "CreateEvent");
+        }
+      } else {
+        req->event_handle = NULL;
+      }
+
+      uv_tcp_queue_accept(handle, req);
+    }
+
+    /* Initialize other unused requests too, because uv_tcp_endgame */
+    /* doesn't know how how many requests were initialized, so it will */
+    /* try to clean up {uv_simultaneous_server_accepts} requests. */
+    for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) {
+      req = &handle->tcp.serv.accept_reqs[i];
+      uv_req_init(loop, (uv_req_t*) req);
+      req->type = UV_ACCEPT;
+      req->accept_socket = INVALID_SOCKET;
+      req->data = handle;
+      req->wait_handle = INVALID_HANDLE_VALUE;
+      req->event_handle = NULL;
+    }
+  }
+
+  return 0;
+}
+
+
+int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
+  uv_loop_t* loop = server->loop;
+  int err = 0;
+  int family;
+
+  uv_tcp_accept_t* req = server->tcp.serv.pending_accepts;
+
+  if (!req) {
+    /* No valid connections found, so we error out. */
+    return WSAEWOULDBLOCK;
+  }
+
+  if (req->accept_socket == INVALID_SOCKET) {
+    return WSAENOTCONN;
+  }
+
+  if (server->flags & UV_HANDLE_IPV6) {
+    family = AF_INET6;
+  } else {
+    family = AF_INET;
+  }
+
+  err = uv_tcp_set_socket(client->loop,
+                          client,
+                          req->accept_socket,
+                          family,
+                          0);
+  if (err) {
+    closesocket(req->accept_socket);
+  } else {
+    uv_connection_init((uv_stream_t*) client);
+    /* AcceptEx() implicitly binds the accepted socket. */
+    client->flags |= UV_HANDLE_BOUND | UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
+  }
+
+  /* Prepare the req to pick up a new connection */
+  server->tcp.serv.pending_accepts = req->next_pending;
+  req->next_pending = NULL;
+  req->accept_socket = INVALID_SOCKET;
+
+  if (!(server->flags & UV__HANDLE_CLOSING)) {
+    /* Check if we're in a middle of changing the number of pending accepts. */
+    if (!(server->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING)) {
+      uv_tcp_queue_accept(server, req);
+    } else {
+      /* We better be switching to a single pending accept. */
+      assert(server->flags & UV_HANDLE_TCP_SINGLE_ACCEPT);
+
+      server->tcp.serv.processed_accepts++;
+
+      if (server->tcp.serv.processed_accepts >= uv_simultaneous_server_accepts) {
+        server->tcp.serv.processed_accepts = 0;
+        /*
+         * All previously queued accept requests are now processed.
+         * We now switch to queueing just a single accept.
+         */
+        uv_tcp_queue_accept(server, &server->tcp.serv.accept_reqs[0]);
+        server->flags &= ~UV_HANDLE_TCP_ACCEPT_STATE_CHANGING;
+        server->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
+      }
+    }
+  }
+
+  loop->active_tcp_streams++;
+
+  return err;
+}
+
+
+int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
+    uv_read_cb read_cb) {
+  uv_loop_t* loop = handle->loop;
+
+  handle->flags |= UV_HANDLE_READING;
+  handle->read_cb = read_cb;
+  handle->alloc_cb = alloc_cb;
+  INCREASE_ACTIVE_COUNT(loop, handle);
+
+  /* If reading was stopped and then started again, there could still be a */
+  /* read request pending. */
+  if (!(handle->flags & UV_HANDLE_READ_PENDING)) {
+    if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
+        !handle->read_req.event_handle) {
+      handle->read_req.event_handle = CreateEvent(NULL, 0, 0, NULL);
+      if (!handle->read_req.event_handle) {
+        uv_fatal_error(GetLastError(), "CreateEvent");
+      }
+    }
+    uv_tcp_queue_read(loop, handle);
+  }
+
+  return 0;
+}
+
+
+static int uv_tcp_try_connect(uv_connect_t* req,
+                              uv_tcp_t* handle,
+                              const struct sockaddr* addr,
+                              unsigned int addrlen,
+                              uv_connect_cb cb) {
+  uv_loop_t* loop = handle->loop;
+  const struct sockaddr* bind_addr;
+  BOOL success;
+  DWORD bytes;
+  int err;
+
+  if (handle->delayed_error) {
+    return handle->delayed_error;
+  }
+
+  if (!(handle->flags & UV_HANDLE_BOUND)) {
+    if (addrlen == sizeof(uv_addr_ip4_any_)) {
+      bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_;
+    } else if (addrlen == sizeof(uv_addr_ip6_any_)) {
+      bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_;
+    } else {
+      abort();
+    }
+    err = uv_tcp_try_bind(handle, bind_addr, addrlen, 0);
+    if (err)
+      return err;
+    if (handle->delayed_error)
+      return handle->delayed_error;
+  }
+
+  if (!handle->tcp.conn.func_connectex) {
+    if (!uv_get_connectex_function(handle->socket, &handle->tcp.conn.func_connectex)) {
+      return WSAEAFNOSUPPORT;
+    }
+  }
+
+  uv_req_init(loop, (uv_req_t*) req);
+  req->type = UV_CONNECT;
+  req->handle = (uv_stream_t*) handle;
+  req->cb = cb;
+  memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
+
+  success = handle->tcp.conn.func_connectex(handle->socket,
+                                           addr,
+                                           addrlen,
+                                           NULL,
+                                           0,
+                                           &bytes,
+                                           &req->u.io.overlapped);
+
+  if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
+    /* Process the req without IOCP. */
+    handle->reqs_pending++;
+    REGISTER_HANDLE_REQ(loop, handle, req);
+    uv_insert_pending_req(loop, (uv_req_t*)req);
+  } else if (UV_SUCCEEDED_WITH_IOCP(success)) {
+    /* The req will be processed with IOCP. */
+    handle->reqs_pending++;
+    REGISTER_HANDLE_REQ(loop, handle, req);
+  } else {
+    return WSAGetLastError();
+  }
+
+  return 0;
+}
+
+
+int uv_tcp_getsockname(const uv_tcp_t* handle,
+                       struct sockaddr* name,
+                       int* namelen) {
+  int result;
+
+  if (handle->socket == INVALID_SOCKET) {
+    return UV_EINVAL;
+  }
+
+  if (handle->delayed_error) {
+    return uv_translate_sys_error(handle->delayed_error);
+  }
+
+  result = getsockname(handle->socket, name, namelen);
+  if (result != 0) {
+    return uv_translate_sys_error(WSAGetLastError());
+  }
+
+  return 0;
+}
+
+
+int uv_tcp_getpeername(const uv_tcp_t* handle,
+                       struct sockaddr* name,
+                       int* namelen) {
+  int result;
+
+  if (handle->socket == INVALID_SOCKET) {
+    return UV_EINVAL;
+  }
+
+  if (handle->delayed_error) {
+    return uv_translate_sys_error(handle->delayed_error);
+  }
+
+  result = getpeername(handle->socket, name, namelen);
+  if (result != 0) {
+    return uv_translate_sys_error(WSAGetLastError());
+  }
+
+  return 0;
+}
+
+
+int uv_tcp_write(uv_loop_t* loop,
+                 uv_write_t* req,
+                 uv_tcp_t* handle,
+                 const uv_buf_t bufs[],
+                 unsigned int nbufs,
+                 uv_write_cb cb) {
+  int result;
+  DWORD bytes;
+
+  uv_req_init(loop, (uv_req_t*) req);
+  req->type = UV_WRITE;
+  req->handle = (uv_stream_t*) handle;
+  req->cb = cb;
+
+  /* Prepare the overlapped structure. */
+  memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
+  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+    req->event_handle = CreateEvent(NULL, 0, 0, NULL);
+    if (!req->event_handle) {
+      uv_fatal_error(GetLastError(), "CreateEvent");
+    }
+    req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
+    req->wait_handle = INVALID_HANDLE_VALUE;
+  }
+
+  result = WSASend(handle->socket,
+                   (WSABUF*) bufs,
+                   nbufs,
+                   &bytes,
+                   0,
+                   &req->u.io.overlapped,
+                   NULL);
+
+  if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
+    /* Request completed immediately. */
+    req->u.io.queued_bytes = 0;
+    handle->reqs_pending++;
+    handle->stream.conn.write_reqs_pending++;
+    REGISTER_HANDLE_REQ(loop, handle, req);
+    uv_insert_pending_req(loop, (uv_req_t*) req);
+  } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
+    /* Request queued by the kernel. */
+    req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs);
+    handle->reqs_pending++;
+    handle->stream.conn.write_reqs_pending++;
+    REGISTER_HANDLE_REQ(loop, handle, req);
+    handle->write_queue_size += req->u.io.queued_bytes;
+    if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
+        !RegisterWaitForSingleObject(&req->wait_handle,
+          req->event_handle, post_write_completion, (void*) req,
+          INFINITE, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) {
+      SET_REQ_ERROR(req, GetLastError());
+      uv_insert_pending_req(loop, (uv_req_t*)req);
+    }
+  } else {
+    /* Send failed due to an error, report it later */
+    req->u.io.queued_bytes = 0;
+    handle->reqs_pending++;
+    handle->stream.conn.write_reqs_pending++;
+    REGISTER_HANDLE_REQ(loop, handle, req);
+    SET_REQ_ERROR(req, WSAGetLastError());
+    uv_insert_pending_req(loop, (uv_req_t*) req);
+  }
+
+  return 0;
+}
+
+
+int uv__tcp_try_write(uv_tcp_t* handle,
+                     const uv_buf_t bufs[],
+                     unsigned int nbufs) {
+  int result;
+  DWORD bytes;
+
+  if (handle->stream.conn.write_reqs_pending > 0)
+    return UV_EAGAIN;
+
+  result = WSASend(handle->socket,
+                   (WSABUF*) bufs,
+                   nbufs,
+                   &bytes,
+                   0,
+                   NULL,
+                   NULL);
+
+  if (result == SOCKET_ERROR)
+    return uv_translate_sys_error(WSAGetLastError());
+  else
+    return bytes;
+}
+
+
+void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
+    uv_req_t* req) {
+  DWORD bytes, flags, err;
+  uv_buf_t buf;
+
+  assert(handle->type == UV_TCP);
+
+  handle->flags &= ~UV_HANDLE_READ_PENDING;
+
+  if (!REQ_SUCCESS(req)) {
+    /* An error occurred doing the read. */
+    if ((handle->flags & UV_HANDLE_READING) ||
+        !(handle->flags & UV_HANDLE_ZERO_READ)) {
+      handle->flags &= ~UV_HANDLE_READING;
+      DECREASE_ACTIVE_COUNT(loop, handle);
+      buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
+            uv_buf_init(NULL, 0) : handle->tcp.conn.read_buffer;
+
+      err = GET_REQ_SOCK_ERROR(req);
+
+      if (err == WSAECONNABORTED) {
+        /*
+         * Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix.
+         */
+        err = WSAECONNRESET;
+      }
+
+      handle->read_cb((uv_stream_t*)handle,
+                      uv_translate_sys_error(err),
+                      &buf);
+    }
+  } else {
+    if (!(handle->flags & UV_HANDLE_ZERO_READ)) {
+      /* The read was done with a non-zero buffer length. */
+      if (req->u.io.overlapped.InternalHigh > 0) {
+        /* Successful read */
+        handle->read_cb((uv_stream_t*)handle,
+                        req->u.io.overlapped.InternalHigh,
+                        &handle->tcp.conn.read_buffer);
+        /* Read again only if bytes == buf.len */
+        if (req->u.io.overlapped.InternalHigh < handle->tcp.conn.read_buffer.len) {
+          goto done;
+        }
+      } else {
+        /* Connection closed */
+        if (handle->flags & UV_HANDLE_READING) {
+          handle->flags &= ~UV_HANDLE_READING;
+          DECREASE_ACTIVE_COUNT(loop, handle);
+        }
+        handle->flags &= ~UV_HANDLE_READABLE;
+
+        buf.base = 0;
+        buf.len = 0;
+        handle->read_cb((uv_stream_t*)handle, UV_EOF, &handle->tcp.conn.read_buffer);
+        goto done;
+      }
+    }
+
+    /* Do nonblocking reads until the buffer is empty */
+    while (handle->flags & UV_HANDLE_READING) {
+      buf = uv_buf_init(NULL, 0);
+      handle->alloc_cb((uv_handle_t*) handle, 65536, &buf);
+      if (buf.base == NULL || buf.len == 0) {
+        handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf);
+        break;
+      }
+      assert(buf.base != NULL);
+
+      flags = 0;
+      if (WSARecv(handle->socket,
+                  (WSABUF*)&buf,
+                  1,
+                  &bytes,
+                  &flags,
+                  NULL,
+                  NULL) != SOCKET_ERROR) {
+        if (bytes > 0) {
+          /* Successful read */
+          handle->read_cb((uv_stream_t*)handle, bytes, &buf);
+          /* Read again only if bytes == buf.len */
+          if (bytes < buf.len) {
+            break;
+          }
+        } else {
+          /* Connection closed */
+          handle->flags &= ~(UV_HANDLE_READING | UV_HANDLE_READABLE);
+          DECREASE_ACTIVE_COUNT(loop, handle);
+
+          handle->read_cb((uv_stream_t*)handle, UV_EOF, &buf);
+          break;
+        }
+      } else {
+        err = WSAGetLastError();
+        if (err == WSAEWOULDBLOCK) {
+          /* Read buffer was completely empty, report a 0-byte read. */
+          handle->read_cb((uv_stream_t*)handle, 0, &buf);
+        } else {
+          /* Ouch! serious error. */
+          handle->flags &= ~UV_HANDLE_READING;
+          DECREASE_ACTIVE_COUNT(loop, handle);
+
+          if (err == WSAECONNABORTED) {
+            /* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with */
+            /* Unix. */
+            err = WSAECONNRESET;
+          }
+
+          handle->read_cb((uv_stream_t*)handle,
+                          uv_translate_sys_error(err),
+                          &buf);
+        }
+        break;
+      }
+    }
+
+done:
+    /* Post another read if still reading and not closing. */
+    if ((handle->flags & UV_HANDLE_READING) &&
+        !(handle->flags & UV_HANDLE_READ_PENDING)) {
+      uv_tcp_queue_read(loop, handle);
+    }
+  }
+
+  DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
+    uv_write_t* req) {
+  int err;
+
+  assert(handle->type == UV_TCP);
+
+  assert(handle->write_queue_size >= req->u.io.queued_bytes);
+  handle->write_queue_size -= req->u.io.queued_bytes;
+
+  UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+    if (req->wait_handle != INVALID_HANDLE_VALUE) {
+      UnregisterWait(req->wait_handle);
+      req->wait_handle = INVALID_HANDLE_VALUE;
+    }
+    if (req->event_handle) {
+      CloseHandle(req->event_handle);
+      req->event_handle = NULL;
+    }
+  }
+
+  if (req->cb) {
+    err = uv_translate_sys_error(GET_REQ_SOCK_ERROR(req));
+    if (err == UV_ECONNABORTED) {
+      /* use UV_ECANCELED for consistency with Unix */
+      err = UV_ECANCELED;
+    }
+    req->cb(req, err);
+  }
+
+  handle->stream.conn.write_reqs_pending--;
+  if (handle->stream.conn.shutdown_req != NULL &&
+      handle->stream.conn.write_reqs_pending == 0) {
+    uv_want_endgame(loop, (uv_handle_t*)handle);
+  }
+
+  DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
+    uv_req_t* raw_req) {
+  uv_tcp_accept_t* req = (uv_tcp_accept_t*) raw_req;
+  int err;
+
+  assert(handle->type == UV_TCP);
+
+  /* If handle->accepted_socket is not a valid socket, then */
+  /* uv_queue_accept must have failed. This is a serious error. We stop */
+  /* accepting connections and report this error to the connection */
+  /* callback. */
+  if (req->accept_socket == INVALID_SOCKET) {
+    if (handle->flags & UV_HANDLE_LISTENING) {
+      handle->flags &= ~UV_HANDLE_LISTENING;
+      DECREASE_ACTIVE_COUNT(loop, handle);
+      if (handle->stream.serv.connection_cb) {
+        err = GET_REQ_SOCK_ERROR(req);
+        handle->stream.serv.connection_cb((uv_stream_t*)handle,
+                                      uv_translate_sys_error(err));
+      }
+    }
+  } else if (REQ_SUCCESS(req) &&
+      setsockopt(req->accept_socket,
+                  SOL_SOCKET,
+                  SO_UPDATE_ACCEPT_CONTEXT,
+                  (char*)&handle->socket,
+                  sizeof(handle->socket)) == 0) {
+    req->next_pending = handle->tcp.serv.pending_accepts;
+    handle->tcp.serv.pending_accepts = req;
+
+    /* Accept and SO_UPDATE_ACCEPT_CONTEXT were successful. */
+    if (handle->stream.serv.connection_cb) {
+      handle->stream.serv.connection_cb((uv_stream_t*)handle, 0);
+    }
+  } else {
+    /* Error related to accepted socket is ignored because the server */
+    /* socket may still be healthy. If the server socket is broken */
+    /* uv_queue_accept will detect it. */
+    closesocket(req->accept_socket);
+    req->accept_socket = INVALID_SOCKET;
+    if (handle->flags & UV_HANDLE_LISTENING) {
+      uv_tcp_queue_accept(handle, req);
+    }
+  }
+
+  DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
+    uv_connect_t* req) {
+  int err;
+
+  assert(handle->type == UV_TCP);
+
+  UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+  err = 0;
+  if (REQ_SUCCESS(req)) {
+    if (setsockopt(handle->socket,
+                    SOL_SOCKET,
+                    SO_UPDATE_CONNECT_CONTEXT,
+                    NULL,
+                    0) == 0) {
+      uv_connection_init((uv_stream_t*)handle);
+      handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
+      loop->active_tcp_streams++;
+    } else {
+      err = WSAGetLastError();
+    }
+  } else {
+    err = GET_REQ_SOCK_ERROR(req);
+  }
+  req->cb(req, uv_translate_sys_error(err));
+
+  DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+int uv_tcp_import(uv_tcp_t* tcp, uv__ipc_socket_info_ex* socket_info_ex,
+    int tcp_connection) {
+  int err;
+  SOCKET socket = WSASocketW(FROM_PROTOCOL_INFO,
+                             FROM_PROTOCOL_INFO,
+                             FROM_PROTOCOL_INFO,
+                             &socket_info_ex->socket_info,
+                             0,
+                             WSA_FLAG_OVERLAPPED);
+
+  if (socket == INVALID_SOCKET) {
+    return WSAGetLastError();
+  }
+
+  err = uv_tcp_set_socket(tcp->loop,
+                          tcp,
+                          socket,
+                          socket_info_ex->socket_info.iAddressFamily,
+                          1);
+  if (err) {
+    closesocket(socket);
+    return err;
+  }
+
+  if (tcp_connection) {
+    uv_connection_init((uv_stream_t*)tcp);
+    tcp->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
+  }
+
+  tcp->flags |= UV_HANDLE_BOUND;
+  tcp->flags |= UV_HANDLE_SHARED_TCP_SOCKET;
+
+  tcp->delayed_error = socket_info_ex->delayed_error;
+
+  tcp->loop->active_tcp_streams++;
+  return 0;
+}
+
+
+int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
+  int err;
+
+  if (handle->socket != INVALID_SOCKET) {
+    err = uv__tcp_nodelay(handle, handle->socket, enable);
+    if (err)
+      return err;
+  }
+
+  if (enable) {
+    handle->flags |= UV_HANDLE_TCP_NODELAY;
+  } else {
+    handle->flags &= ~UV_HANDLE_TCP_NODELAY;
+  }
+
+  return 0;
+}
+
+
+int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
+  int err;
+
+  if (handle->socket != INVALID_SOCKET) {
+    err = uv__tcp_keepalive(handle, handle->socket, enable, delay);
+    if (err)
+      return err;
+  }
+
+  if (enable) {
+    handle->flags |= UV_HANDLE_TCP_KEEPALIVE;
+  } else {
+    handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
+  }
+
+  /* TODO: Store delay if handle->socket isn't created yet. */
+
+  return 0;
+}
+
+
+int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
+    LPWSAPROTOCOL_INFOW protocol_info) {
+  if (!(handle->flags & UV_HANDLE_CONNECTION)) {
+    /*
+     * We're about to share the socket with another process.  Because
+     * this is a listening socket, we assume that the other process will
+     * be accepting connections on it.  So, before sharing the socket
+     * with another process, we call listen here in the parent process.
+     */
+
+    if (!(handle->flags & UV_HANDLE_LISTENING)) {
+      if (!(handle->flags & UV_HANDLE_BOUND)) {
+        return ERROR_INVALID_PARAMETER;
+      }
+
+      if (!(handle->delayed_error)) {
+        if (listen(handle->socket, SOMAXCONN) == SOCKET_ERROR) {
+          handle->delayed_error = WSAGetLastError();
+        }
+      }
+    }
+  }
+
+  if (WSADuplicateSocketW(handle->socket, pid, protocol_info)) {
+    return WSAGetLastError();
+  }
+
+  handle->flags |= UV_HANDLE_SHARED_TCP_SOCKET;
+
+  return 0;
+}
+
+
+int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
+  if (handle->flags & UV_HANDLE_CONNECTION) {
+    return UV_EINVAL;
+  }
+
+  /* Check if we're already in the desired mode. */
+  if ((enable && !(handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) ||
+      (!enable && handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) {
+    return 0;
+  }
+
+  /* Don't allow switching from single pending accept to many. */
+  if (enable) {
+    return UV_ENOTSUP;
+  }
+
+  /* Check if we're in a middle of changing the number of pending accepts. */
+  if (handle->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING) {
+    return 0;
+  }
+
+  handle->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
+
+  /* Flip the changing flag if we have already queued multiple accepts. */
+  if (handle->flags & UV_HANDLE_LISTENING) {
+    handle->flags |= UV_HANDLE_TCP_ACCEPT_STATE_CHANGING;
+  }
+
+  return 0;
+}
+
+
+static int uv_tcp_try_cancel_io(uv_tcp_t* tcp) {
+  SOCKET socket = tcp->socket;
+  int non_ifs_lsp;
+
+  /* Check if we have any non-IFS LSPs stacked on top of TCP */
+  non_ifs_lsp = (tcp->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 :
+                                                uv_tcp_non_ifs_lsp_ipv4;
+
+  /* If there are non-ifs LSPs then try to obtain a base handle for the */
+  /* socket. This will always fail on Windows XP/3k. */
+  if (non_ifs_lsp) {
+    DWORD bytes;
+    if (WSAIoctl(socket,
+                 SIO_BASE_HANDLE,
+                 NULL,
+                 0,
+                 &socket,
+                 sizeof socket,
+                 &bytes,
+                 NULL,
+                 NULL) != 0) {
+      /* Failed. We can't do CancelIo. */
+      return -1;
+    }
+  }
+
+  assert(socket != 0 && socket != INVALID_SOCKET);
+
+  if (!CancelIo((HANDLE) socket)) {
+    return GetLastError();
+  }
+
+  /* It worked. */
+  return 0;
+}
+
+
+void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
+  int close_socket = 1;
+
+  if (tcp->flags & UV_HANDLE_READ_PENDING) {
+    /* In order for winsock to do a graceful close there must not be any */
+    /* any pending reads, or the socket must be shut down for writing */
+    if (!(tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET)) {
+      /* Just do shutdown on non-shared sockets, which ensures graceful close. */
+      shutdown(tcp->socket, SD_SEND);
+
+    } else if (uv_tcp_try_cancel_io(tcp) == 0) {
+      /* In case of a shared socket, we try to cancel all outstanding I/O, */
+      /* If that works, don't close the socket yet - wait for the read req to */
+      /* return and close the socket in uv_tcp_endgame. */
+      close_socket = 0;
+
+    } else {
+      /* When cancelling isn't possible - which could happen when an LSP is */
+      /* present on an old Windows version, we will have to close the socket */
+      /* with a read pending. That is not nice because trailing sent bytes */
+      /* may not make it to the other side. */
+    }
+
+  } else if ((tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET) &&
+             tcp->tcp.serv.accept_reqs != NULL) {
+    /* Under normal circumstances closesocket() will ensure that all pending */
+    /* accept reqs are canceled. However, when the socket is shared the */
+    /* presence of another reference to the socket in another process will */
+    /* keep the accept reqs going, so we have to ensure that these are */
+    /* canceled. */
+    if (uv_tcp_try_cancel_io(tcp) != 0) {
+      /* When cancellation is not possible, there is another option: we can */
+      /* close the incoming sockets, which will also cancel the accept */
+      /* operations. However this is not cool because we might inadvertently */
+      /* close a socket that just accepted a new connection, which will */
+      /* cause the connection to be aborted. */
+      unsigned int i;
+      for (i = 0; i < uv_simultaneous_server_accepts; i++) {
+        uv_tcp_accept_t* req = &tcp->tcp.serv.accept_reqs[i];
+        if (req->accept_socket != INVALID_SOCKET &&
+            !HasOverlappedIoCompleted(&req->u.io.overlapped)) {
+          closesocket(req->accept_socket);
+          req->accept_socket = INVALID_SOCKET;
+        }
+      }
+    }
+  }
+
+  if (tcp->flags & UV_HANDLE_READING) {
+    tcp->flags &= ~UV_HANDLE_READING;
+    DECREASE_ACTIVE_COUNT(loop, tcp);
+  }
+
+  if (tcp->flags & UV_HANDLE_LISTENING) {
+    tcp->flags &= ~UV_HANDLE_LISTENING;
+    DECREASE_ACTIVE_COUNT(loop, tcp);
+  }
+
+  if (close_socket) {
+    closesocket(tcp->socket);
+    tcp->socket = INVALID_SOCKET;
+    tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
+  }
+
+  tcp->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
+  uv__handle_closing(tcp);
+
+  if (tcp->reqs_pending == 0) {
+    uv_want_endgame(tcp->loop, (uv_handle_t*)tcp);
+  }
+}
+
+
+int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
+  WSAPROTOCOL_INFOW protocol_info;
+  int opt_len;
+  int err;
+
+  /* Detect the address family of the socket. */
+  opt_len = (int) sizeof protocol_info;
+  if (getsockopt(sock,
+                 SOL_SOCKET,
+                 SO_PROTOCOL_INFOW,
+                 (char*) &protocol_info,
+                 &opt_len) == SOCKET_ERROR) {
+    return uv_translate_sys_error(GetLastError());
+  }
+
+  err = uv_tcp_set_socket(handle->loop,
+                          handle,
+                          sock,
+                          protocol_info.iAddressFamily,
+                          1);
+  if (err) {
+    return uv_translate_sys_error(err);
+  }
+
+  return 0;
+}
+
+
+/* This function is an egress point, i.e. it returns libuv errors rather than
+ * system errors.
+ */
+int uv__tcp_bind(uv_tcp_t* handle,
+                 const struct sockaddr* addr,
+                 unsigned int addrlen,
+                 unsigned int flags) {
+  int err;
+
+  err = uv_tcp_try_bind(handle, addr, addrlen, flags);
+  if (err)
+    return uv_translate_sys_error(err);
+
+  return 0;
+}
+
+
+/* This function is an egress point, i.e. it returns libuv errors rather than
+ * system errors.
+ */
+int uv__tcp_connect(uv_connect_t* req,
+                    uv_tcp_t* handle,
+                    const struct sockaddr* addr,
+                    unsigned int addrlen,
+                    uv_connect_cb cb) {
+  int err;
+
+  err = uv_tcp_try_connect(req, handle, addr, addrlen, cb);
+  if (err)
+    return uv_translate_sys_error(err);
+
+  return 0;
+}
diff --git a/deps/libtuv/src/win/thread.c b/deps/libtuv/src/win/thread.c
new file mode 100644 (file)
index 0000000..91684e9
--- /dev/null
@@ -0,0 +1,697 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "internal.h"
+
+
+#define HAVE_CONDVAR_API() (pInitializeConditionVariable != NULL)
+
+static int uv_cond_fallback_init(uv_cond_t* cond);
+static void uv_cond_fallback_destroy(uv_cond_t* cond);
+static void uv_cond_fallback_signal(uv_cond_t* cond);
+static void uv_cond_fallback_broadcast(uv_cond_t* cond);
+static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex);
+static int uv_cond_fallback_timedwait(uv_cond_t* cond,
+    uv_mutex_t* mutex, uint64_t timeout);
+
+static int uv_cond_condvar_init(uv_cond_t* cond);
+static void uv_cond_condvar_destroy(uv_cond_t* cond);
+static void uv_cond_condvar_signal(uv_cond_t* cond);
+static void uv_cond_condvar_broadcast(uv_cond_t* cond);
+static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex);
+static int uv_cond_condvar_timedwait(uv_cond_t* cond,
+    uv_mutex_t* mutex, uint64_t timeout);
+
+
+static void uv__once_inner(uv_once_t* guard, void (*callback)(void)) {
+  DWORD result;
+  HANDLE existing_event, created_event;
+
+  created_event = CreateEvent(NULL, 1, 0, NULL);
+  if (created_event == 0) {
+    /* Could fail in a low-memory situation? */
+    uv_fatal_error(GetLastError(), "CreateEvent");
+  }
+
+  existing_event = InterlockedCompareExchangePointer(&guard->event,
+                                                     created_event,
+                                                     NULL);
+
+  if (existing_event == NULL) {
+    /* We won the race */
+    callback();
+
+    result = SetEvent(created_event);
+    assert(result);
+    guard->ran = 1;
+
+  } else {
+    /* We lost the race. Destroy the event we created and wait for the */
+    /* existing one to become signaled. */
+    CloseHandle(created_event);
+    result = WaitForSingleObject(existing_event, INFINITE);
+    assert(result == WAIT_OBJECT_0);
+  }
+}
+
+
+void uv_once(uv_once_t* guard, void (*callback)(void)) {
+  /* Fast case - avoid WaitForSingleObject. */
+  if (guard->ran) {
+    return;
+  }
+
+  uv__once_inner(guard, callback);
+}
+
+
+/* Verify that uv_thread_t can be stored in a TLS slot. */
+STATIC_ASSERT(sizeof(uv_thread_t) <= sizeof(void*));
+
+static uv_key_t uv__current_thread_key;
+static uv_once_t uv__current_thread_init_guard = UV_ONCE_INIT;
+
+
+static void uv__init_current_thread_key(void) {
+  if (uv_key_create(&uv__current_thread_key))
+    abort();
+}
+
+
+struct thread_ctx {
+  void (*entry)(void* arg);
+  void* arg;
+  uv_thread_t self;
+};
+
+
+static UINT __stdcall uv__thread_start(void* arg) {
+  struct thread_ctx *ctx_p;
+  struct thread_ctx ctx;
+
+  ctx_p = arg;
+  ctx = *ctx_p;
+  uv__free(ctx_p);
+
+  uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key);
+  uv_key_set(&uv__current_thread_key, (void*) ctx.self);
+
+  ctx.entry(ctx.arg);
+
+  return 0;
+}
+
+
+int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
+  struct thread_ctx* ctx;
+  int err;
+  HANDLE thread;
+
+  ctx = uv__malloc(sizeof(*ctx));
+  if (ctx == NULL)
+    return UV_ENOMEM;
+
+  ctx->entry = entry;
+  ctx->arg = arg;
+
+  /* Create the thread in suspended state so we have a chance to pass
+   * its own creation handle to it */   
+  thread = (HANDLE) _beginthreadex(NULL,
+                                   0,
+                                   uv__thread_start,
+                                   ctx,
+                                   CREATE_SUSPENDED,
+                                   NULL);
+  if (thread == NULL) {
+    err = errno;
+    uv__free(ctx);
+  } else {
+    err = 0;
+    *tid = thread;
+    ctx->self = thread;
+    ResumeThread(thread);
+  }
+
+  switch (err) {
+    case 0:
+      return 0;
+    case EACCES:
+      return UV_EACCES;
+    case EAGAIN:
+      return UV_EAGAIN;
+    case EINVAL:
+      return UV_EINVAL;
+  }
+
+  return UV_EIO;
+}
+
+
+uv_thread_t uv_thread_self(void) {
+  uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key);
+  return (uv_thread_t) uv_key_get(&uv__current_thread_key);
+}
+
+
+int uv_thread_join(uv_thread_t *tid) {
+  if (WaitForSingleObject(*tid, INFINITE))
+    return uv_translate_sys_error(GetLastError());
+  else {
+    CloseHandle(*tid);
+    *tid = 0;
+    return 0;
+  }
+}
+
+
+int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) {
+  return *t1 == *t2;
+}
+
+
+int uv_mutex_init(uv_mutex_t* mutex) {
+  InitializeCriticalSection(mutex);
+  return 0;
+}
+
+
+void uv_mutex_destroy(uv_mutex_t* mutex) {
+  DeleteCriticalSection(mutex);
+}
+
+
+void uv_mutex_lock(uv_mutex_t* mutex) {
+  EnterCriticalSection(mutex);
+}
+
+
+int uv_mutex_trylock(uv_mutex_t* mutex) {
+  if (TryEnterCriticalSection(mutex))
+    return 0;
+  else
+    return UV_EBUSY;
+}
+
+
+void uv_mutex_unlock(uv_mutex_t* mutex) {
+  LeaveCriticalSection(mutex);
+}
+
+
+int uv_rwlock_init(uv_rwlock_t* rwlock) {
+  /* Initialize the semaphore that acts as the write lock. */
+  HANDLE handle = CreateSemaphoreW(NULL, 1, 1, NULL);
+  if (handle == NULL)
+    return uv_translate_sys_error(GetLastError());
+  rwlock->state_.write_semaphore_ = handle;
+
+  /* Initialize the critical section protecting the reader count. */
+  InitializeCriticalSection(&rwlock->state_.num_readers_lock_);
+
+  /* Initialize the reader count. */
+  rwlock->state_.num_readers_ = 0;
+
+  return 0;
+}
+
+
+void uv_rwlock_destroy(uv_rwlock_t* rwlock) {
+  DeleteCriticalSection(&rwlock->state_.num_readers_lock_);
+  CloseHandle(rwlock->state_.write_semaphore_);
+}
+
+
+void uv_rwlock_rdlock(uv_rwlock_t* rwlock) {
+  /* Acquire the lock that protects the reader count. */
+  EnterCriticalSection(&rwlock->state_.num_readers_lock_);
+
+  /* Increase the reader count, and lock for write if this is the first
+   * reader.
+   */
+  if (++rwlock->state_.num_readers_ == 1) {
+    DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, INFINITE);
+    if (r != WAIT_OBJECT_0)
+      uv_fatal_error(GetLastError(), "WaitForSingleObject");
+  }
+
+  /* Release the lock that protects the reader count. */
+  LeaveCriticalSection(&rwlock->state_.num_readers_lock_);
+}
+
+
+int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) {
+  int err;
+
+  if (!TryEnterCriticalSection(&rwlock->state_.num_readers_lock_))
+    return UV_EBUSY;
+
+  err = 0;
+
+  if (rwlock->state_.num_readers_ == 0) {
+    /* Currently there are no other readers, which means that the write lock
+     * needs to be acquired.
+     */
+    DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, 0);
+    if (r == WAIT_OBJECT_0)
+      rwlock->state_.num_readers_++;
+    else if (r == WAIT_TIMEOUT)
+      err = UV_EBUSY;
+    else if (r == WAIT_FAILED)
+      uv_fatal_error(GetLastError(), "WaitForSingleObject");
+
+  } else {
+    /* The write lock has already been acquired because there are other
+     * active readers.
+     */
+    rwlock->state_.num_readers_++;
+  }
+
+  LeaveCriticalSection(&rwlock->state_.num_readers_lock_);
+  return err;
+}
+
+
+void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) {
+  EnterCriticalSection(&rwlock->state_.num_readers_lock_);
+
+  if (--rwlock->state_.num_readers_ == 0) {
+    if (!ReleaseSemaphore(rwlock->state_.write_semaphore_, 1, NULL))
+      uv_fatal_error(GetLastError(), "ReleaseSemaphore");
+  }
+
+  LeaveCriticalSection(&rwlock->state_.num_readers_lock_);
+}
+
+
+void uv_rwlock_wrlock(uv_rwlock_t* rwlock) {
+  DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, INFINITE);
+  if (r != WAIT_OBJECT_0)
+    uv_fatal_error(GetLastError(), "WaitForSingleObject");
+}
+
+
+int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) {
+  DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, 0);
+  if (r == WAIT_OBJECT_0)
+    return 0;
+  else if (r == WAIT_TIMEOUT)
+    return UV_EBUSY;
+  else
+    uv_fatal_error(GetLastError(), "WaitForSingleObject");
+}
+
+
+void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) {
+  if (!ReleaseSemaphore(rwlock->state_.write_semaphore_, 1, NULL))
+    uv_fatal_error(GetLastError(), "ReleaseSemaphore");
+}
+
+
+int uv_sem_init(uv_sem_t* sem, unsigned int value) {
+  *sem = CreateSemaphore(NULL, value, INT_MAX, NULL);
+  if (*sem == NULL)
+    return uv_translate_sys_error(GetLastError());
+  else
+    return 0;
+}
+
+
+void uv_sem_destroy(uv_sem_t* sem) {
+  if (!CloseHandle(*sem))
+    abort();
+}
+
+
+void uv_sem_post(uv_sem_t* sem) {
+  if (!ReleaseSemaphore(*sem, 1, NULL))
+    abort();
+}
+
+
+void uv_sem_wait(uv_sem_t* sem) {
+  if (WaitForSingleObject(*sem, INFINITE) != WAIT_OBJECT_0)
+    abort();
+}
+
+
+int uv_sem_trywait(uv_sem_t* sem) {
+  DWORD r = WaitForSingleObject(*sem, 0);
+
+  if (r == WAIT_OBJECT_0)
+    return 0;
+
+  if (r == WAIT_TIMEOUT)
+    return UV_EAGAIN;
+
+  abort();
+  return -1; /* Satisfy the compiler. */
+}
+
+
+/* This condition variable implementation is based on the SetEvent solution
+ * (section 3.2) at http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
+ * We could not use the SignalObjectAndWait solution (section 3.4) because
+ * it want the 2nd argument (type uv_mutex_t) of uv_cond_wait() and
+ * uv_cond_timedwait() to be HANDLEs, but we use CRITICAL_SECTIONs.
+ */
+
+static int uv_cond_fallback_init(uv_cond_t* cond) {
+  int err;
+
+  /* Initialize the count to 0. */
+  cond->fallback.waiters_count = 0;
+
+  InitializeCriticalSection(&cond->fallback.waiters_count_lock);
+
+  /* Create an auto-reset event. */
+  cond->fallback.signal_event = CreateEvent(NULL,  /* no security */
+                                            FALSE, /* auto-reset event */
+                                            FALSE, /* non-signaled initially */
+                                            NULL); /* unnamed */
+  if (!cond->fallback.signal_event) {
+    err = GetLastError();
+    goto error2;
+  }
+
+  /* Create a manual-reset event. */
+  cond->fallback.broadcast_event = CreateEvent(NULL,  /* no security */
+                                               TRUE,  /* manual-reset */
+                                               FALSE, /* non-signaled */
+                                               NULL); /* unnamed */
+  if (!cond->fallback.broadcast_event) {
+    err = GetLastError();
+    goto error;
+  }
+
+  return 0;
+
+error:
+  CloseHandle(cond->fallback.signal_event);
+error2:
+  DeleteCriticalSection(&cond->fallback.waiters_count_lock);
+  return uv_translate_sys_error(err);
+}
+
+
+static int uv_cond_condvar_init(uv_cond_t* cond) {
+  pInitializeConditionVariable(&cond->cond_var);
+  return 0;
+}
+
+
+int uv_cond_init(uv_cond_t* cond) {
+  uv__once_init();
+
+  if (HAVE_CONDVAR_API())
+    return uv_cond_condvar_init(cond);
+  else
+    return uv_cond_fallback_init(cond);
+}
+
+
+static void uv_cond_fallback_destroy(uv_cond_t* cond) {
+  if (!CloseHandle(cond->fallback.broadcast_event))
+    abort();
+  if (!CloseHandle(cond->fallback.signal_event))
+    abort();
+  DeleteCriticalSection(&cond->fallback.waiters_count_lock);
+}
+
+
+static void uv_cond_condvar_destroy(uv_cond_t* cond) {
+  /* nothing to do */
+}
+
+
+void uv_cond_destroy(uv_cond_t* cond) {
+  if (HAVE_CONDVAR_API())
+    uv_cond_condvar_destroy(cond);
+  else
+    uv_cond_fallback_destroy(cond);
+}
+
+
+static void uv_cond_fallback_signal(uv_cond_t* cond) {
+  int have_waiters;
+
+  /* Avoid race conditions. */
+  EnterCriticalSection(&cond->fallback.waiters_count_lock);
+  have_waiters = cond->fallback.waiters_count > 0;
+  LeaveCriticalSection(&cond->fallback.waiters_count_lock);
+
+  if (have_waiters)
+    SetEvent(cond->fallback.signal_event);
+}
+
+
+static void uv_cond_condvar_signal(uv_cond_t* cond) {
+  pWakeConditionVariable(&cond->cond_var);
+}
+
+
+void uv_cond_signal(uv_cond_t* cond) {
+  if (HAVE_CONDVAR_API())
+    uv_cond_condvar_signal(cond);
+  else
+    uv_cond_fallback_signal(cond);
+}
+
+
+static void uv_cond_fallback_broadcast(uv_cond_t* cond) {
+  int have_waiters;
+
+  /* Avoid race conditions. */
+  EnterCriticalSection(&cond->fallback.waiters_count_lock);
+  have_waiters = cond->fallback.waiters_count > 0;
+  LeaveCriticalSection(&cond->fallback.waiters_count_lock);
+
+  if (have_waiters)
+    SetEvent(cond->fallback.broadcast_event);
+}
+
+
+static void uv_cond_condvar_broadcast(uv_cond_t* cond) {
+  pWakeAllConditionVariable(&cond->cond_var);
+}
+
+
+void uv_cond_broadcast(uv_cond_t* cond) {
+  if (HAVE_CONDVAR_API())
+    uv_cond_condvar_broadcast(cond);
+  else
+    uv_cond_fallback_broadcast(cond);
+}
+
+
+static int uv_cond_wait_helper(uv_cond_t* cond, uv_mutex_t* mutex,
+    DWORD dwMilliseconds) {
+  DWORD result;
+  int last_waiter;
+  HANDLE handles[2] = {
+    cond->fallback.signal_event,
+    cond->fallback.broadcast_event
+  };
+
+  /* Avoid race conditions. */
+  EnterCriticalSection(&cond->fallback.waiters_count_lock);
+  cond->fallback.waiters_count++;
+  LeaveCriticalSection(&cond->fallback.waiters_count_lock);
+
+  /* It's ok to release the <mutex> here since Win32 manual-reset events */
+  /* maintain state when used with <SetEvent>. This avoids the "lost wakeup" */
+  /* bug. */
+  uv_mutex_unlock(mutex);
+
+  /* Wait for either event to become signaled due to <uv_cond_signal> being */
+  /* called or <uv_cond_broadcast> being called. */
+  result = WaitForMultipleObjects(2, handles, FALSE, dwMilliseconds);
+
+  EnterCriticalSection(&cond->fallback.waiters_count_lock);
+  cond->fallback.waiters_count--;
+  last_waiter = result == WAIT_OBJECT_0 + 1
+      && cond->fallback.waiters_count == 0;
+  LeaveCriticalSection(&cond->fallback.waiters_count_lock);
+
+  /* Some thread called <pthread_cond_broadcast>. */
+  if (last_waiter) {
+    /* We're the last waiter to be notified or to stop waiting, so reset the */
+    /* the manual-reset event. */
+    ResetEvent(cond->fallback.broadcast_event);
+  }
+
+  /* Reacquire the <mutex>. */
+  uv_mutex_lock(mutex);
+
+  if (result == WAIT_OBJECT_0 || result == WAIT_OBJECT_0 + 1)
+    return 0;
+
+  if (result == WAIT_TIMEOUT)
+    return UV_ETIMEDOUT;
+
+  abort();
+  return -1; /* Satisfy the compiler. */
+}
+
+
+static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
+  if (uv_cond_wait_helper(cond, mutex, INFINITE))
+    abort();
+}
+
+
+static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
+  if (!pSleepConditionVariableCS(&cond->cond_var, mutex, INFINITE))
+    abort();
+}
+
+
+void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
+  if (HAVE_CONDVAR_API())
+    uv_cond_condvar_wait(cond, mutex);
+  else
+    uv_cond_fallback_wait(cond, mutex);
+}
+
+
+static int uv_cond_fallback_timedwait(uv_cond_t* cond,
+    uv_mutex_t* mutex, uint64_t timeout) {
+  return uv_cond_wait_helper(cond, mutex, (DWORD)(timeout / 1e6));
+}
+
+
+static int uv_cond_condvar_timedwait(uv_cond_t* cond,
+    uv_mutex_t* mutex, uint64_t timeout) {
+  if (pSleepConditionVariableCS(&cond->cond_var, mutex, (DWORD)(timeout / 1e6)))
+    return 0;
+  if (GetLastError() != ERROR_TIMEOUT)
+    abort();
+  return UV_ETIMEDOUT;
+}
+
+
+int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex,
+    uint64_t timeout) {
+  if (HAVE_CONDVAR_API())
+    return uv_cond_condvar_timedwait(cond, mutex, timeout);
+  else
+    return uv_cond_fallback_timedwait(cond, mutex, timeout);
+}
+
+
+int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
+  int err;
+
+  barrier->n = count;
+  barrier->count = 0;
+
+  err = uv_mutex_init(&barrier->mutex);
+  if (err)
+    return err;
+
+  err = uv_sem_init(&barrier->turnstile1, 0);
+  if (err)
+    goto error2;
+
+  err = uv_sem_init(&barrier->turnstile2, 1);
+  if (err)
+    goto error;
+
+  return 0;
+
+error:
+  uv_sem_destroy(&barrier->turnstile1);
+error2:
+  uv_mutex_destroy(&barrier->mutex);
+  return err;
+
+}
+
+
+void uv_barrier_destroy(uv_barrier_t* barrier) {
+  uv_sem_destroy(&barrier->turnstile2);
+  uv_sem_destroy(&barrier->turnstile1);
+  uv_mutex_destroy(&barrier->mutex);
+}
+
+
+int uv_barrier_wait(uv_barrier_t* barrier) {
+  int serial_thread;
+
+  uv_mutex_lock(&barrier->mutex);
+  if (++barrier->count == barrier->n) {
+    uv_sem_wait(&barrier->turnstile2);
+    uv_sem_post(&barrier->turnstile1);
+  }
+  uv_mutex_unlock(&barrier->mutex);
+
+  uv_sem_wait(&barrier->turnstile1);
+  uv_sem_post(&barrier->turnstile1);
+
+  uv_mutex_lock(&barrier->mutex);
+  serial_thread = (--barrier->count == 0);
+  if (serial_thread) {
+    uv_sem_wait(&barrier->turnstile1);
+    uv_sem_post(&barrier->turnstile2);
+  }
+  uv_mutex_unlock(&barrier->mutex);
+
+  uv_sem_wait(&barrier->turnstile2);
+  uv_sem_post(&barrier->turnstile2);
+  return serial_thread;
+}
+
+
+int uv_key_create(uv_key_t* key) {
+  key->tls_index = TlsAlloc();
+  if (key->tls_index == TLS_OUT_OF_INDEXES)
+    return UV_ENOMEM;
+  return 0;
+}
+
+
+void uv_key_delete(uv_key_t* key) {
+  if (TlsFree(key->tls_index) == FALSE)
+    abort();
+  key->tls_index = TLS_OUT_OF_INDEXES;
+}
+
+
+void* uv_key_get(uv_key_t* key) {
+  void* value;
+
+  value = TlsGetValue(key->tls_index);
+  if (value == NULL)
+    if (GetLastError() != ERROR_SUCCESS)
+      abort();
+
+  return value;
+}
+
+
+void uv_key_set(uv_key_t* key, void* value) {
+  if (TlsSetValue(key->tls_index, value) == FALSE)
+    abort();
+}
diff --git a/deps/libtuv/src/win/timer.c b/deps/libtuv/src/win/timer.c
new file mode 100644 (file)
index 0000000..27ca771
--- /dev/null
@@ -0,0 +1,195 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <limits.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "tree.h"
+#include "handle-inl.h"
+
+
+/* The number of milliseconds in one second. */
+#define UV__MILLISEC 1000
+
+
+void uv_update_time(uv_loop_t* loop) {
+  uint64_t new_time = uv__hrtime(UV__MILLISEC);
+  assert(new_time >= loop->time);
+  loop->time = new_time;
+}
+
+
+static int uv_timer_compare(uv_timer_t* a, uv_timer_t* b) {
+  if (a->due < b->due)
+    return -1;
+  if (a->due > b->due)
+    return 1;
+  /*
+   *  compare start_id when both has the same due. start_id is
+   *  allocated with loop->timer_counter in uv_timer_start().
+   */
+  if (a->start_id < b->start_id)
+    return -1;
+  if (a->start_id > b->start_id)
+    return 1;
+  return 0;
+}
+
+
+RB_GENERATE_STATIC(uv_timer_tree_s, uv_timer_s, tree_entry, uv_timer_compare);
+
+
+int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
+  uv__handle_init(loop, (uv_handle_t*) handle, UV_TIMER);
+  handle->timer_cb = NULL;
+  handle->repeat = 0;
+
+  return 0;
+}
+
+
+void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle) {
+  if (handle->flags & UV__HANDLE_CLOSING) {
+    assert(!(handle->flags & UV_HANDLE_CLOSED));
+    uv__handle_close(handle);
+  }
+}
+
+
+static uint64_t get_clamped_due_time(uint64_t loop_time, uint64_t timeout) {
+  uint64_t clamped_timeout;
+
+  clamped_timeout = loop_time + timeout;
+  if (clamped_timeout < timeout)
+    clamped_timeout = (uint64_t) -1;
+
+  return clamped_timeout;
+}
+
+
+int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, uint64_t timeout,
+    uint64_t repeat) {
+  uv_loop_t* loop = handle->loop;
+  uv_timer_t* old;
+
+  if (timer_cb == NULL)
+    return UV_EINVAL;
+
+  if (uv__is_active(handle))
+    uv_timer_stop(handle);
+
+  handle->timer_cb = timer_cb;
+  handle->due = get_clamped_due_time(loop->time, timeout);
+  handle->repeat = repeat;
+  uv__handle_start(handle);
+
+  /* start_id is the second index to be compared in uv__timer_cmp() */
+  handle->start_id = handle->loop->timer_counter++;
+
+  old = RB_INSERT(uv_timer_tree_s, &loop->timers, handle);
+  assert(old == NULL);
+
+  return 0;
+}
+
+
+int uv_timer_stop(uv_timer_t* handle) {
+  uv_loop_t* loop = handle->loop;
+
+  if (!uv__is_active(handle))
+    return 0;
+
+  RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
+  uv__handle_stop(handle);
+
+  return 0;
+}
+
+
+int uv_timer_again(uv_timer_t* handle) {
+  /* If timer_cb is NULL that means that the timer was never started. */
+  if (!handle->timer_cb) {
+    return UV_EINVAL;
+  }
+
+  if (handle->repeat) {
+    uv_timer_stop(handle);
+    uv_timer_start(handle, handle->timer_cb, handle->repeat, handle->repeat);
+  }
+
+  return 0;
+}
+
+
+void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) {
+  assert(handle->type == UV_TIMER);
+  handle->repeat = repeat;
+}
+
+
+uint64_t uv_timer_get_repeat(const uv_timer_t* handle) {
+  assert(handle->type == UV_TIMER);
+  return handle->repeat;
+}
+
+
+DWORD uv__next_timeout(const uv_loop_t* loop) {
+  uv_timer_t* timer;
+  int64_t delta;
+
+  /* Check if there are any running timers
+   * Need to cast away const first, since RB_MIN doesn't know what we are
+   * going to do with this return value, it can't be marked const
+   */
+  timer = RB_MIN(uv_timer_tree_s, &((uv_loop_t*)loop)->timers);
+  if (timer) {
+    delta = timer->due - loop->time;
+    if (delta >= UINT_MAX - 1) {
+      /* A timeout value of UINT_MAX means infinite, so that's no good. */
+      return UINT_MAX - 1;
+    } else if (delta < 0) {
+      /* Negative timeout values are not allowed */
+      return 0;
+    } else {
+      return (DWORD)delta;
+    }
+  } else {
+    /* No timers */
+    return INFINITE;
+  }
+}
+
+
+void uv_process_timers(uv_loop_t* loop) {
+  uv_timer_t* timer;
+
+  /* Call timer callbacks */
+  for (timer = RB_MIN(uv_timer_tree_s, &loop->timers);
+       timer != NULL && timer->due <= loop->time;
+       timer = RB_MIN(uv_timer_tree_s, &loop->timers)) {
+
+    uv_timer_stop(timer);
+    uv_timer_again(timer);
+    timer->timer_cb((uv_timer_t*) timer);
+  }
+}
diff --git a/deps/libtuv/src/win/tty.c b/deps/libtuv/src/win/tty.c
new file mode 100644 (file)
index 0000000..1b7adf6
--- /dev/null
@@ -0,0 +1,2282 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <io.h>
+#include <string.h>
+#include <stdlib.h>
+
+#if defined(_MSC_VER) && _MSC_VER < 1600
+# include "stdint-msvc2008.h"
+#else
+# include <stdint.h>
+#endif
+
+#ifndef COMMON_LVB_REVERSE_VIDEO
+# define COMMON_LVB_REVERSE_VIDEO 0x4000
+#endif
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "stream-inl.h"
+#include "req-inl.h"
+
+#ifndef InterlockedOr
+# define InterlockedOr _InterlockedOr
+#endif
+
+#define UNICODE_REPLACEMENT_CHARACTER (0xfffd)
+
+#define ANSI_NORMAL           0x00
+#define ANSI_ESCAPE_SEEN      0x02
+#define ANSI_CSI              0x04
+#define ANSI_ST_CONTROL       0x08
+#define ANSI_IGNORE           0x10
+#define ANSI_IN_ARG           0x20
+#define ANSI_IN_STRING        0x40
+#define ANSI_BACKSLASH_SEEN   0x80
+
+#define MAX_INPUT_BUFFER_LENGTH 8192
+#define MAX_CONSOLE_CHAR 8192
+
+#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
+#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
+#endif
+
+static void uv_tty_capture_initial_style(CONSOLE_SCREEN_BUFFER_INFO* info);
+static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info);
+static int uv__cancel_read_console(uv_tty_t* handle);
+
+
+/* Null uv_buf_t */
+static const uv_buf_t uv_null_buf_ = { 0, NULL };
+
+enum uv__read_console_status_e {
+  NOT_STARTED,
+  IN_PROGRESS,
+  TRAP_REQUESTED,
+  COMPLETED
+};
+
+static volatile LONG uv__read_console_status = NOT_STARTED;
+static volatile LONG uv__restore_screen_state;
+static CONSOLE_SCREEN_BUFFER_INFO uv__saved_screen_state;
+
+
+/*
+ * The console virtual window.
+ *
+ * Normally cursor movement in windows is relative to the console screen buffer,
+ * e.g. the application is allowed to overwrite the 'history'. This is very
+ * inconvenient, it makes absolute cursor movement pretty useless. There is
+ * also the concept of 'client rect' which is defined by the actual size of
+ * the console window and the scroll position of the screen buffer, but it's
+ * very volatile because it changes when the user scrolls.
+ *
+ * To make cursor movement behave sensibly we define a virtual window to which
+ * cursor movement is confined. The virtual window is always as wide as the
+ * console screen buffer, but it's height is defined by the size of the
+ * console window. The top of the virtual window aligns with the position
+ * of the caret when the first stdout/err handle is created, unless that would
+ * mean that it would extend beyond the bottom of the screen buffer -  in that
+ * that case it's located as far down as possible.
+ *
+ * When the user writes a long text or many newlines, such that the output
+ * reaches beyond the bottom of the virtual window, the virtual window is
+ * shifted downwards, but not resized.
+ *
+ * Since all tty i/o happens on the same console, this window is shared
+ * between all stdout/stderr handles.
+ */
+
+static int uv_tty_virtual_offset = -1;
+static int uv_tty_virtual_height = -1;
+static int uv_tty_virtual_width = -1;
+
+/* We use a semaphore rather than a mutex or critical section because in some
+   cases (uv__cancel_read_console) we need take the lock in the main thread and
+   release it in another thread. Using a semaphore ensures that in such
+   scenario the main thread will still block when trying to acquire the lock. */
+static uv_sem_t uv_tty_output_lock;
+
+static HANDLE uv_tty_output_handle = INVALID_HANDLE_VALUE;
+
+static WORD uv_tty_default_text_attributes =
+    FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
+
+static char uv_tty_default_fg_color = 7;
+static char uv_tty_default_bg_color = 0;
+static char uv_tty_default_fg_bright = 0;
+static char uv_tty_default_bg_bright = 0;
+static char uv_tty_default_inverse = 0;
+
+typedef enum {
+  UV_SUPPORTED,
+  UV_UNCHECKED,
+  UV_UNSUPPORTED
+} uv_vtermstate_t;
+/* Determine whether or not ANSI support is enabled. */
+static uv_vtermstate_t uv__vterm_state = UV_UNCHECKED;
+static void uv__determine_vterm_state(HANDLE handle);
+
+void uv_console_init() {
+  if (uv_sem_init(&uv_tty_output_lock, 1))
+    abort();
+}
+
+
+int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
+  HANDLE handle;
+  CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
+
+  handle = (HANDLE) uv__get_osfhandle(fd);
+  if (handle == INVALID_HANDLE_VALUE)
+    return UV_EBADF;
+
+  if (fd <= 2) {
+    /* In order to avoid closing a stdio file descriptor 0-2, duplicate the
+     * underlying OS handle and forget about the original fd.
+     * We could also opt to use the original OS handle and just never close it,
+     * but then there would be no reliable way to cancel pending read operations
+     * upon close.
+     */
+    if (!DuplicateHandle(INVALID_HANDLE_VALUE,
+                         handle,
+                         INVALID_HANDLE_VALUE,
+                         &handle,
+                         0,
+                         FALSE,
+                         DUPLICATE_SAME_ACCESS))
+      return uv_translate_sys_error(GetLastError());
+    fd = -1;
+  }
+
+  if (!readable) {
+    /* Obtain the screen buffer info with the output handle. */
+    if (!GetConsoleScreenBufferInfo(handle, &screen_buffer_info)) {
+      return uv_translate_sys_error(GetLastError());
+    }
+
+    /* Obtain the the tty_output_lock because the virtual window state is */
+    /* shared between all uv_tty_t handles. */
+    uv_sem_wait(&uv_tty_output_lock);
+
+    if (uv__vterm_state == UV_UNCHECKED)
+      uv__determine_vterm_state(handle);
+
+    /* Store the global tty output handle. This handle is used by TTY read */
+    /* streams to update the virtual window when a CONSOLE_BUFFER_SIZE_EVENT */
+    /* is received. */
+    uv_tty_output_handle = handle;
+
+    /* Remember the original console text attributes. */
+    uv_tty_capture_initial_style(&screen_buffer_info);
+
+    uv_tty_update_virtual_window(&screen_buffer_info);
+
+    uv_sem_post(&uv_tty_output_lock);
+  }
+
+
+  uv_stream_init(loop, (uv_stream_t*) tty, UV_TTY);
+  uv_connection_init((uv_stream_t*) tty);
+
+  tty->handle = handle;
+  tty->u.fd = fd;
+  tty->reqs_pending = 0;
+  tty->flags |= UV_HANDLE_BOUND;
+
+  if (readable) {
+    /* Initialize TTY input specific fields. */
+    tty->flags |= UV_HANDLE_TTY_READABLE | UV_HANDLE_READABLE;
+    /* TODO: remove me in v2.x. */
+    tty->tty.rd.unused_ = NULL;
+    tty->tty.rd.read_line_buffer = uv_null_buf_;
+    tty->tty.rd.read_raw_wait = NULL;
+
+    /* Init keycode-to-vt100 mapper state. */
+    tty->tty.rd.last_key_len = 0;
+    tty->tty.rd.last_key_offset = 0;
+    tty->tty.rd.last_utf16_high_surrogate = 0;
+    memset(&tty->tty.rd.last_input_record, 0, sizeof tty->tty.rd.last_input_record);
+  } else {
+    /* TTY output specific fields. */
+    tty->flags |= UV_HANDLE_WRITABLE;
+
+    /* Init utf8-to-utf16 conversion state. */
+    tty->tty.wr.utf8_bytes_left = 0;
+    tty->tty.wr.utf8_codepoint = 0;
+
+    /* Initialize eol conversion state */
+    tty->tty.wr.previous_eol = 0;
+
+    /* Init ANSI parser state. */
+    tty->tty.wr.ansi_parser_state = ANSI_NORMAL;
+  }
+
+  return 0;
+}
+
+
+/* Set the default console text attributes based on how the console was
+ * configured when libuv started.
+ */
+static void uv_tty_capture_initial_style(CONSOLE_SCREEN_BUFFER_INFO* info) {
+  static int style_captured = 0;
+
+  /* Only do this once.
+     Assumption: Caller has acquired uv_tty_output_lock. */
+  if (style_captured)
+    return;
+
+  /* Save raw win32 attributes. */
+  uv_tty_default_text_attributes = info->wAttributes;
+
+  /* Convert black text on black background to use white text. */
+  if (uv_tty_default_text_attributes == 0)
+    uv_tty_default_text_attributes = 7;
+
+  /* Convert Win32 attributes to ANSI colors. */
+  uv_tty_default_fg_color = 0;
+  uv_tty_default_bg_color = 0;
+  uv_tty_default_fg_bright = 0;
+  uv_tty_default_bg_bright = 0;
+  uv_tty_default_inverse = 0;
+
+  if (uv_tty_default_text_attributes & FOREGROUND_RED)
+    uv_tty_default_fg_color |= 1;
+
+  if (uv_tty_default_text_attributes & FOREGROUND_GREEN)
+    uv_tty_default_fg_color |= 2;
+
+  if (uv_tty_default_text_attributes & FOREGROUND_BLUE)
+    uv_tty_default_fg_color |= 4;
+
+  if (uv_tty_default_text_attributes & BACKGROUND_RED)
+    uv_tty_default_bg_color |= 1;
+
+  if (uv_tty_default_text_attributes & BACKGROUND_GREEN)
+    uv_tty_default_bg_color |= 2;
+
+  if (uv_tty_default_text_attributes & BACKGROUND_BLUE)
+    uv_tty_default_bg_color |= 4;
+
+  if (uv_tty_default_text_attributes & FOREGROUND_INTENSITY)
+    uv_tty_default_fg_bright = 1;
+
+  if (uv_tty_default_text_attributes & BACKGROUND_INTENSITY)
+    uv_tty_default_bg_bright = 1;
+
+  if (uv_tty_default_text_attributes & COMMON_LVB_REVERSE_VIDEO)
+    uv_tty_default_inverse = 1;
+
+  style_captured = 1;
+}
+
+
+int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
+  DWORD flags;
+  unsigned char was_reading;
+  uv_alloc_cb alloc_cb;
+  uv_read_cb read_cb;
+  int err;
+
+  if (!(tty->flags & UV_HANDLE_TTY_READABLE)) {
+    return UV_EINVAL;
+  }
+
+  if (!!mode == !!(tty->flags & UV_HANDLE_TTY_RAW)) {
+    return 0;
+  }
+
+  switch (mode) {
+    case UV_TTY_MODE_NORMAL:
+      flags = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
+      break;
+    case UV_TTY_MODE_RAW:
+      flags = ENABLE_WINDOW_INPUT;
+      break;
+    case UV_TTY_MODE_IO:
+      return UV_ENOTSUP;
+    default:
+      return UV_EINVAL;
+  }
+
+  /* If currently reading, stop, and restart reading. */
+  if (tty->flags & UV_HANDLE_READING) {
+    was_reading = 1;
+    alloc_cb = tty->alloc_cb;
+    read_cb = tty->read_cb;
+    err = uv_tty_read_stop(tty);
+    if (err) {
+      return uv_translate_sys_error(err);
+    }
+  } else {
+    was_reading = 0;
+  }
+
+  uv_sem_wait(&uv_tty_output_lock);
+  if (!SetConsoleMode(tty->handle, flags)) {
+    err = uv_translate_sys_error(GetLastError());
+    uv_sem_post(&uv_tty_output_lock);
+    return err;
+  }
+  uv_sem_post(&uv_tty_output_lock);
+
+  /* Update flag. */
+  tty->flags &= ~UV_HANDLE_TTY_RAW;
+  tty->flags |= mode ? UV_HANDLE_TTY_RAW : 0;
+
+  /* If we just stopped reading, restart. */
+  if (was_reading) {
+    err = uv_tty_read_start(tty, alloc_cb, read_cb);
+    if (err) {
+      return uv_translate_sys_error(err);
+    }
+  }
+
+  return 0;
+}
+
+
+int uv_is_tty(uv_file file) {
+  DWORD result;
+  return GetConsoleMode((HANDLE) _get_osfhandle(file), &result) != 0;
+}
+
+
+int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) {
+  CONSOLE_SCREEN_BUFFER_INFO info;
+
+  if (!GetConsoleScreenBufferInfo(tty->handle, &info)) {
+    return uv_translate_sys_error(GetLastError());
+  }
+
+  uv_sem_wait(&uv_tty_output_lock);
+  uv_tty_update_virtual_window(&info);
+  uv_sem_post(&uv_tty_output_lock);
+
+  *width = uv_tty_virtual_width;
+  *height = uv_tty_virtual_height;
+
+  return 0;
+}
+
+
+static void CALLBACK uv_tty_post_raw_read(void* data, BOOLEAN didTimeout) {
+  uv_loop_t* loop;
+  uv_tty_t* handle;
+  uv_req_t* req;
+
+  assert(data);
+  assert(!didTimeout);
+
+  req = (uv_req_t*) data;
+  handle = (uv_tty_t*) req->data;
+  loop = handle->loop;
+
+  UnregisterWait(handle->tty.rd.read_raw_wait);
+  handle->tty.rd.read_raw_wait = NULL;
+
+  SET_REQ_SUCCESS(req);
+  POST_COMPLETION_FOR_REQ(loop, req);
+}
+
+
+static void uv_tty_queue_read_raw(uv_loop_t* loop, uv_tty_t* handle) {
+  uv_read_t* req;
+  BOOL r;
+
+  assert(handle->flags & UV_HANDLE_READING);
+  assert(!(handle->flags & UV_HANDLE_READ_PENDING));
+
+  assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE);
+
+  handle->tty.rd.read_line_buffer = uv_null_buf_;
+
+  req = &handle->read_req;
+  memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
+
+  r = RegisterWaitForSingleObject(&handle->tty.rd.read_raw_wait,
+                                  handle->handle,
+                                  uv_tty_post_raw_read,
+                                  (void*) req,
+                                  INFINITE,
+                                  WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
+  if (!r) {
+    handle->tty.rd.read_raw_wait = NULL;
+    SET_REQ_ERROR(req, GetLastError());
+    uv_insert_pending_req(loop, (uv_req_t*)req);
+  }
+
+  handle->flags |= UV_HANDLE_READ_PENDING;
+  handle->reqs_pending++;
+}
+
+
+static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
+  uv_loop_t* loop;
+  uv_tty_t* handle;
+  uv_req_t* req;
+  DWORD bytes, read_bytes;
+  WCHAR utf16[MAX_INPUT_BUFFER_LENGTH / 3];
+  DWORD chars, read_chars;
+  LONG status;
+  COORD pos;
+  BOOL read_console_success;
+
+  assert(data);
+
+  req = (uv_req_t*) data;
+  handle = (uv_tty_t*) req->data;
+  loop = handle->loop;
+
+  assert(handle->tty.rd.read_line_buffer.base != NULL);
+  assert(handle->tty.rd.read_line_buffer.len > 0);
+
+  /* ReadConsole can't handle big buffers. */
+  if (handle->tty.rd.read_line_buffer.len < MAX_INPUT_BUFFER_LENGTH) {
+    bytes = handle->tty.rd.read_line_buffer.len;
+  } else {
+    bytes = MAX_INPUT_BUFFER_LENGTH;
+  }
+
+  /* At last, unicode! */
+  /* One utf-16 codeunit never takes more than 3 utf-8 codeunits to encode */
+  chars = bytes / 3;
+
+  status = InterlockedExchange(&uv__read_console_status, IN_PROGRESS);
+  if (status == TRAP_REQUESTED) {
+    SET_REQ_SUCCESS(req);
+    req->u.io.overlapped.InternalHigh = 0;
+    POST_COMPLETION_FOR_REQ(loop, req);
+    return 0;
+  }
+
+  read_console_success = ReadConsoleW(handle->handle,
+                                      (void*) utf16,
+                                      chars,
+                                      &read_chars,
+                                      NULL);
+
+  if (read_console_success) {
+    read_bytes = WideCharToMultiByte(CP_UTF8,
+                                     0,
+                                     utf16,
+                                     read_chars,
+                                     handle->tty.rd.read_line_buffer.base,
+                                     bytes,
+                                     NULL,
+                                     NULL);
+    SET_REQ_SUCCESS(req);
+    req->u.io.overlapped.InternalHigh = read_bytes;
+  } else {
+    SET_REQ_ERROR(req, GetLastError());
+  }
+
+  status = InterlockedExchange(&uv__read_console_status, COMPLETED);
+
+  if (status ==  TRAP_REQUESTED) {
+    /* If we canceled the read by sending a VK_RETURN event, restore the
+       screen state to undo the visual effect of the VK_RETURN */
+    if (read_console_success && InterlockedOr(&uv__restore_screen_state, 0)) {
+      HANDLE active_screen_buffer;
+      active_screen_buffer = CreateFileA("conout$",
+                                         GENERIC_READ | GENERIC_WRITE,
+                                         FILE_SHARE_READ | FILE_SHARE_WRITE,
+                                         NULL,
+                                         OPEN_EXISTING,
+                                         FILE_ATTRIBUTE_NORMAL,
+                                         NULL);
+      if (active_screen_buffer != INVALID_HANDLE_VALUE) {
+        pos = uv__saved_screen_state.dwCursorPosition;
+
+        /* If the cursor was at the bottom line of the screen buffer, the
+           VK_RETURN would have caused the buffer contents to scroll up by one
+           line. The right position to reset the cursor to is therefore one line
+           higher */
+        if (pos.Y == uv__saved_screen_state.dwSize.Y - 1)
+          pos.Y--;
+
+        SetConsoleCursorPosition(active_screen_buffer, pos);
+        CloseHandle(active_screen_buffer);
+      }
+    }
+    uv_sem_post(&uv_tty_output_lock);
+  }
+  POST_COMPLETION_FOR_REQ(loop, req);
+  return 0;
+}
+
+
+static void uv_tty_queue_read_line(uv_loop_t* loop, uv_tty_t* handle) {
+  uv_read_t* req;
+  BOOL r;
+
+  assert(handle->flags & UV_HANDLE_READING);
+  assert(!(handle->flags & UV_HANDLE_READ_PENDING));
+  assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE);
+
+  req = &handle->read_req;
+  memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
+
+  handle->tty.rd.read_line_buffer = uv_buf_init(NULL, 0);
+  handle->alloc_cb((uv_handle_t*) handle, 8192, &handle->tty.rd.read_line_buffer);
+  if (handle->tty.rd.read_line_buffer.base == NULL ||
+      handle->tty.rd.read_line_buffer.len == 0) {
+    handle->read_cb((uv_stream_t*) handle,
+                    UV_ENOBUFS,
+                    &handle->tty.rd.read_line_buffer);
+    return;
+  }
+  assert(handle->tty.rd.read_line_buffer.base != NULL);
+
+  /* Reset flags  No locking is required since there cannot be a line read
+     in progress. We are also relying on the memory barrier provided by
+     QueueUserWorkItem*/
+  uv__restore_screen_state = FALSE;
+  uv__read_console_status = NOT_STARTED;
+  r = QueueUserWorkItem(uv_tty_line_read_thread,
+                        (void*) req,
+                        WT_EXECUTELONGFUNCTION);
+  if (!r) {
+    SET_REQ_ERROR(req, GetLastError());
+    uv_insert_pending_req(loop, (uv_req_t*)req);
+  }
+
+  handle->flags |= UV_HANDLE_READ_PENDING;
+  handle->reqs_pending++;
+}
+
+
+static void uv_tty_queue_read(uv_loop_t* loop, uv_tty_t* handle) {
+  if (handle->flags & UV_HANDLE_TTY_RAW) {
+    uv_tty_queue_read_raw(loop, handle);
+  } else {
+    uv_tty_queue_read_line(loop, handle);
+  }
+}
+
+
+static const char* get_vt100_fn_key(DWORD code, char shift, char ctrl,
+    size_t* len) {
+#define VK_CASE(vk, normal_str, shift_str, ctrl_str, shift_ctrl_str)          \
+    case (vk):                                                                \
+      if (shift && ctrl) {                                                    \
+        *len = sizeof shift_ctrl_str;                                         \
+        return "\033" shift_ctrl_str;                                         \
+      } else if (shift) {                                                     \
+        *len = sizeof shift_str ;                                             \
+        return "\033" shift_str;                                              \
+      } else if (ctrl) {                                                      \
+        *len = sizeof ctrl_str;                                               \
+        return "\033" ctrl_str;                                               \
+      } else {                                                                \
+        *len = sizeof normal_str;                                             \
+        return "\033" normal_str;                                             \
+      }
+
+  switch (code) {
+    /* These mappings are the same as Cygwin's. Unmodified and alt-modified */
+    /* keypad keys comply with linux console, modifiers comply with xterm */
+    /* modifier usage. F1..f12 and shift-f1..f10 comply with linux console, */
+    /* f6..f12 with and without modifiers comply with rxvt. */
+    VK_CASE(VK_INSERT,  "[2~",  "[2;2~", "[2;5~", "[2;6~")
+    VK_CASE(VK_END,     "[4~",  "[4;2~", "[4;5~", "[4;6~")
+    VK_CASE(VK_DOWN,    "[B",   "[1;2B", "[1;5B", "[1;6B")
+    VK_CASE(VK_NEXT,    "[6~",  "[6;2~", "[6;5~", "[6;6~")
+    VK_CASE(VK_LEFT,    "[D",   "[1;2D", "[1;5D", "[1;6D")
+    VK_CASE(VK_CLEAR,   "[G",   "[1;2G", "[1;5G", "[1;6G")
+    VK_CASE(VK_RIGHT,   "[C",   "[1;2C", "[1;5C", "[1;6C")
+    VK_CASE(VK_UP,      "[A",   "[1;2A", "[1;5A", "[1;6A")
+    VK_CASE(VK_HOME,    "[1~",  "[1;2~", "[1;5~", "[1;6~")
+    VK_CASE(VK_PRIOR,   "[5~",  "[5;2~", "[5;5~", "[5;6~")
+    VK_CASE(VK_DELETE,  "[3~",  "[3;2~", "[3;5~", "[3;6~")
+    VK_CASE(VK_NUMPAD0, "[2~",  "[2;2~", "[2;5~", "[2;6~")
+    VK_CASE(VK_NUMPAD1, "[4~",  "[4;2~", "[4;5~", "[4;6~")
+    VK_CASE(VK_NUMPAD2, "[B",   "[1;2B", "[1;5B", "[1;6B")
+    VK_CASE(VK_NUMPAD3, "[6~",  "[6;2~", "[6;5~", "[6;6~")
+    VK_CASE(VK_NUMPAD4, "[D",   "[1;2D", "[1;5D", "[1;6D")
+    VK_CASE(VK_NUMPAD5, "[G",   "[1;2G", "[1;5G", "[1;6G")
+    VK_CASE(VK_NUMPAD6, "[C",   "[1;2C", "[1;5C", "[1;6C")
+    VK_CASE(VK_NUMPAD7, "[A",   "[1;2A", "[1;5A", "[1;6A")
+    VK_CASE(VK_NUMPAD8, "[1~",  "[1;2~", "[1;5~", "[1;6~")
+    VK_CASE(VK_NUMPAD9, "[5~",  "[5;2~", "[5;5~", "[5;6~")
+    VK_CASE(VK_DECIMAL, "[3~",  "[3;2~", "[3;5~", "[3;6~")
+    VK_CASE(VK_F1,      "[[A",  "[23~",  "[11^",  "[23^" )
+    VK_CASE(VK_F2,      "[[B",  "[24~",  "[12^",  "[24^" )
+    VK_CASE(VK_F3,      "[[C",  "[25~",  "[13^",  "[25^" )
+    VK_CASE(VK_F4,      "[[D",  "[26~",  "[14^",  "[26^" )
+    VK_CASE(VK_F5,      "[[E",  "[28~",  "[15^",  "[28^" )
+    VK_CASE(VK_F6,      "[17~", "[29~",  "[17^",  "[29^" )
+    VK_CASE(VK_F7,      "[18~", "[31~",  "[18^",  "[31^" )
+    VK_CASE(VK_F8,      "[19~", "[32~",  "[19^",  "[32^" )
+    VK_CASE(VK_F9,      "[20~", "[33~",  "[20^",  "[33^" )
+    VK_CASE(VK_F10,     "[21~", "[34~",  "[21^",  "[34^" )
+    VK_CASE(VK_F11,     "[23~", "[23$",  "[23^",  "[23@" )
+    VK_CASE(VK_F12,     "[24~", "[24$",  "[24^",  "[24@" )
+
+    default:
+      *len = 0;
+      return NULL;
+  }
+#undef VK_CASE
+}
+
+
+void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
+    uv_req_t* req) {
+  /* Shortcut for handle->tty.rd.last_input_record.Event.KeyEvent. */
+#define KEV handle->tty.rd.last_input_record.Event.KeyEvent
+
+  DWORD records_left, records_read;
+  uv_buf_t buf;
+  off_t buf_used;
+
+  assert(handle->type == UV_TTY);
+  assert(handle->flags & UV_HANDLE_TTY_READABLE);
+  handle->flags &= ~UV_HANDLE_READ_PENDING;
+
+  if (!(handle->flags & UV_HANDLE_READING) ||
+      !(handle->flags & UV_HANDLE_TTY_RAW)) {
+    goto out;
+  }
+
+  if (!REQ_SUCCESS(req)) {
+    /* An error occurred while waiting for the event. */
+    if ((handle->flags & UV_HANDLE_READING)) {
+      handle->flags &= ~UV_HANDLE_READING;
+      handle->read_cb((uv_stream_t*)handle,
+                      uv_translate_sys_error(GET_REQ_ERROR(req)),
+                      &uv_null_buf_);
+    }
+    goto out;
+  }
+
+  /* Fetch the number of events  */
+  if (!GetNumberOfConsoleInputEvents(handle->handle, &records_left)) {
+    handle->flags &= ~UV_HANDLE_READING;
+    DECREASE_ACTIVE_COUNT(loop, handle);
+    handle->read_cb((uv_stream_t*)handle,
+                    uv_translate_sys_error(GetLastError()),
+                    &uv_null_buf_);
+    goto out;
+  }
+
+  /* Windows sends a lot of events that we're not interested in, so buf */
+  /* will be allocated on demand, when there's actually something to emit. */
+  buf = uv_null_buf_;
+  buf_used = 0;
+
+  while ((records_left > 0 || handle->tty.rd.last_key_len > 0) &&
+         (handle->flags & UV_HANDLE_READING)) {
+    if (handle->tty.rd.last_key_len == 0) {
+      /* Read the next input record */
+      if (!ReadConsoleInputW(handle->handle,
+                             &handle->tty.rd.last_input_record,
+                             1,
+                             &records_read)) {
+        handle->flags &= ~UV_HANDLE_READING;
+        DECREASE_ACTIVE_COUNT(loop, handle);
+        handle->read_cb((uv_stream_t*) handle,
+                        uv_translate_sys_error(GetLastError()),
+                        &buf);
+        goto out;
+      }
+      records_left--;
+
+      /* If the window was resized, recompute the virtual window size. This */
+      /* will trigger a SIGWINCH signal if the window size changed in an */
+      /* way that matters to libuv. */
+      if (handle->tty.rd.last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) {
+        CONSOLE_SCREEN_BUFFER_INFO info;
+
+        uv_sem_wait(&uv_tty_output_lock);
+
+        if (uv_tty_output_handle != INVALID_HANDLE_VALUE &&
+            GetConsoleScreenBufferInfo(uv_tty_output_handle, &info)) {
+          uv_tty_update_virtual_window(&info);
+        }
+
+        uv_sem_post(&uv_tty_output_lock);
+
+        continue;
+      }
+
+      /* Ignore other events that are not key or resize events. */
+      if (handle->tty.rd.last_input_record.EventType != KEY_EVENT) {
+        continue;
+      }
+
+      /* Ignore keyup events, unless the left alt key was held and a valid */
+      /* unicode character was emitted. */
+      if (!KEV.bKeyDown && !(((KEV.dwControlKeyState & LEFT_ALT_PRESSED) ||
+          KEV.wVirtualKeyCode==VK_MENU) && KEV.uChar.UnicodeChar != 0)) {
+        continue;
+      }
+
+      /* Ignore keypresses to numpad number keys if the left alt is held */
+      /* because the user is composing a character, or windows simulating */
+      /* this. */
+      if ((KEV.dwControlKeyState & LEFT_ALT_PRESSED) &&
+          !(KEV.dwControlKeyState & ENHANCED_KEY) &&
+          (KEV.wVirtualKeyCode == VK_INSERT ||
+          KEV.wVirtualKeyCode == VK_END ||
+          KEV.wVirtualKeyCode == VK_DOWN ||
+          KEV.wVirtualKeyCode == VK_NEXT ||
+          KEV.wVirtualKeyCode == VK_LEFT ||
+          KEV.wVirtualKeyCode == VK_CLEAR ||
+          KEV.wVirtualKeyCode == VK_RIGHT ||
+          KEV.wVirtualKeyCode == VK_HOME ||
+          KEV.wVirtualKeyCode == VK_UP ||
+          KEV.wVirtualKeyCode == VK_PRIOR ||
+          KEV.wVirtualKeyCode == VK_NUMPAD0 ||
+          KEV.wVirtualKeyCode == VK_NUMPAD1 ||
+          KEV.wVirtualKeyCode == VK_NUMPAD2 ||
+          KEV.wVirtualKeyCode == VK_NUMPAD3 ||
+          KEV.wVirtualKeyCode == VK_NUMPAD4 ||
+          KEV.wVirtualKeyCode == VK_NUMPAD5 ||
+          KEV.wVirtualKeyCode == VK_NUMPAD6 ||
+          KEV.wVirtualKeyCode == VK_NUMPAD7 ||
+          KEV.wVirtualKeyCode == VK_NUMPAD8 ||
+          KEV.wVirtualKeyCode == VK_NUMPAD9)) {
+        continue;
+      }
+
+      if (KEV.uChar.UnicodeChar != 0) {
+        int prefix_len, char_len;
+
+        /* Character key pressed */
+        if (KEV.uChar.UnicodeChar >= 0xD800 &&
+            KEV.uChar.UnicodeChar < 0xDC00) {
+          /* UTF-16 high surrogate */
+          handle->tty.rd.last_utf16_high_surrogate = KEV.uChar.UnicodeChar;
+          continue;
+        }
+
+        /* Prefix with \u033 if alt was held, but alt was not used as part */
+        /* a compose sequence. */
+        if ((KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
+            && !(KEV.dwControlKeyState & (LEFT_CTRL_PRESSED |
+            RIGHT_CTRL_PRESSED)) && KEV.bKeyDown) {
+          handle->tty.rd.last_key[0] = '\033';
+          prefix_len = 1;
+        } else {
+          prefix_len = 0;
+        }
+
+        if (KEV.uChar.UnicodeChar >= 0xDC00 &&
+            KEV.uChar.UnicodeChar < 0xE000) {
+          /* UTF-16 surrogate pair */
+          WCHAR utf16_buffer[2] = { handle->tty.rd.last_utf16_high_surrogate,
+                                    KEV.uChar.UnicodeChar};
+          char_len = WideCharToMultiByte(CP_UTF8,
+                                         0,
+                                         utf16_buffer,
+                                         2,
+                                         &handle->tty.rd.last_key[prefix_len],
+                                         sizeof handle->tty.rd.last_key,
+                                         NULL,
+                                         NULL);
+        } else {
+          /* Single UTF-16 character */
+          char_len = WideCharToMultiByte(CP_UTF8,
+                                         0,
+                                         &KEV.uChar.UnicodeChar,
+                                         1,
+                                         &handle->tty.rd.last_key[prefix_len],
+                                         sizeof handle->tty.rd.last_key,
+                                         NULL,
+                                         NULL);
+        }
+
+        /* Whatever happened, the last character wasn't a high surrogate. */
+        handle->tty.rd.last_utf16_high_surrogate = 0;
+
+        /* If the utf16 character(s) couldn't be converted something must */
+        /* be wrong. */
+        if (!char_len) {
+          handle->flags &= ~UV_HANDLE_READING;
+          DECREASE_ACTIVE_COUNT(loop, handle);
+          handle->read_cb((uv_stream_t*) handle,
+                          uv_translate_sys_error(GetLastError()),
+                          &buf);
+          goto out;
+        }
+
+        handle->tty.rd.last_key_len = (unsigned char) (prefix_len + char_len);
+        handle->tty.rd.last_key_offset = 0;
+        continue;
+
+      } else {
+        /* Function key pressed */
+        const char* vt100;
+        size_t prefix_len, vt100_len;
+
+        vt100 = get_vt100_fn_key(KEV.wVirtualKeyCode,
+                                  !!(KEV.dwControlKeyState & SHIFT_PRESSED),
+                                  !!(KEV.dwControlKeyState & (
+                                    LEFT_CTRL_PRESSED |
+                                    RIGHT_CTRL_PRESSED)),
+                                  &vt100_len);
+
+        /* If we were unable to map to a vt100 sequence, just ignore. */
+        if (!vt100) {
+          continue;
+        }
+
+        /* Prefix with \x033 when the alt key was held. */
+        if (KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) {
+          handle->tty.rd.last_key[0] = '\033';
+          prefix_len = 1;
+        } else {
+          prefix_len = 0;
+        }
+
+        /* Copy the vt100 sequence to the handle buffer. */
+        assert(prefix_len + vt100_len < sizeof handle->tty.rd.last_key);
+        memcpy(&handle->tty.rd.last_key[prefix_len], vt100, vt100_len);
+
+        handle->tty.rd.last_key_len = (unsigned char) (prefix_len + vt100_len);
+        handle->tty.rd.last_key_offset = 0;
+        continue;
+      }
+    } else {
+      /* Copy any bytes left from the last keypress to the user buffer. */
+      if (handle->tty.rd.last_key_offset < handle->tty.rd.last_key_len) {
+        /* Allocate a buffer if needed */
+        if (buf_used == 0) {
+          buf = uv_buf_init(NULL, 0);
+          handle->alloc_cb((uv_handle_t*) handle, 1024, &buf);
+          if (buf.base == NULL || buf.len == 0) {
+            handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf);
+            goto out;
+          }
+          assert(buf.base != NULL);
+        }
+
+        buf.base[buf_used++] = handle->tty.rd.last_key[handle->tty.rd.last_key_offset++];
+
+        /* If the buffer is full, emit it */
+        if ((size_t) buf_used == buf.len) {
+          handle->read_cb((uv_stream_t*) handle, buf_used, &buf);
+          buf = uv_null_buf_;
+          buf_used = 0;
+        }
+
+        continue;
+      }
+
+      /* Apply dwRepeat from the last input record. */
+      if (--KEV.wRepeatCount > 0) {
+        handle->tty.rd.last_key_offset = 0;
+        continue;
+      }
+
+      handle->tty.rd.last_key_len = 0;
+      continue;
+    }
+  }
+
+  /* Send the buffer back to the user */
+  if (buf_used > 0) {
+    handle->read_cb((uv_stream_t*) handle, buf_used, &buf);
+  }
+
+ out:
+  /* Wait for more input events. */
+  if ((handle->flags & UV_HANDLE_READING) &&
+      !(handle->flags & UV_HANDLE_READ_PENDING)) {
+    uv_tty_queue_read(loop, handle);
+  }
+
+  DECREASE_PENDING_REQ_COUNT(handle);
+
+#undef KEV
+}
+
+
+
+void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
+    uv_req_t* req) {
+  uv_buf_t buf;
+
+  assert(handle->type == UV_TTY);
+  assert(handle->flags & UV_HANDLE_TTY_READABLE);
+
+  buf = handle->tty.rd.read_line_buffer;
+
+  handle->flags &= ~UV_HANDLE_READ_PENDING;
+  handle->tty.rd.read_line_buffer = uv_null_buf_;
+
+  if (!REQ_SUCCESS(req)) {
+    /* Read was not successful */
+    if (handle->flags & UV_HANDLE_READING) {
+      /* Real error */
+      handle->flags &= ~UV_HANDLE_READING;
+      DECREASE_ACTIVE_COUNT(loop, handle);
+      handle->read_cb((uv_stream_t*) handle,
+                      uv_translate_sys_error(GET_REQ_ERROR(req)),
+                      &buf);
+    } else {
+      /* The read was cancelled, or whatever we don't care */
+      handle->read_cb((uv_stream_t*) handle, 0, &buf);
+    }
+
+  } else {
+    if (!(handle->flags & UV_HANDLE_CANCELLATION_PENDING)) {
+      /* Read successful */
+      /* TODO: read unicode, convert to utf-8 */
+      DWORD bytes = req->u.io.overlapped.InternalHigh;
+      handle->read_cb((uv_stream_t*) handle, bytes, &buf);
+    } else {
+      handle->flags &= ~UV_HANDLE_CANCELLATION_PENDING;
+      handle->read_cb((uv_stream_t*) handle, 0, &buf);
+    }
+  }
+
+  /* Wait for more input events. */
+  if ((handle->flags & UV_HANDLE_READING) &&
+      !(handle->flags & UV_HANDLE_READ_PENDING)) {
+    uv_tty_queue_read(loop, handle);
+  }
+
+  DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle,
+    uv_req_t* req) {
+  assert(handle->type == UV_TTY);
+  assert(handle->flags & UV_HANDLE_TTY_READABLE);
+
+  /* If the read_line_buffer member is zero, it must have been an raw read. */
+  /* Otherwise it was a line-buffered read. */
+  /* FIXME: This is quite obscure. Use a flag or something. */
+  if (handle->tty.rd.read_line_buffer.len == 0) {
+    uv_process_tty_read_raw_req(loop, handle, req);
+  } else {
+    uv_process_tty_read_line_req(loop, handle, req);
+  }
+}
+
+
+int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
+    uv_read_cb read_cb) {
+  uv_loop_t* loop = handle->loop;
+
+  if (!(handle->flags & UV_HANDLE_TTY_READABLE)) {
+    return ERROR_INVALID_PARAMETER;
+  }
+
+  handle->flags |= UV_HANDLE_READING;
+  INCREASE_ACTIVE_COUNT(loop, handle);
+  handle->read_cb = read_cb;
+  handle->alloc_cb = alloc_cb;
+
+  /* If reading was stopped and then started again, there could still be a */
+  /* read request pending. */
+  if (handle->flags & UV_HANDLE_READ_PENDING) {
+    return 0;
+  }
+
+  /* Maybe the user stopped reading half-way while processing key events. */
+  /* Short-circuit if this could be the case. */
+  if (handle->tty.rd.last_key_len > 0) {
+    SET_REQ_SUCCESS(&handle->read_req);
+    uv_insert_pending_req(handle->loop, (uv_req_t*) &handle->read_req);
+    /* Make sure no attempt is made to insert it again until it's handled. */
+    handle->flags |= UV_HANDLE_READ_PENDING;
+    handle->reqs_pending++;
+    return 0;
+  }
+
+  uv_tty_queue_read(loop, handle);
+
+  return 0;
+}
+
+
+int uv_tty_read_stop(uv_tty_t* handle) {
+  INPUT_RECORD record;
+  DWORD written, err;
+
+  handle->flags &= ~UV_HANDLE_READING;
+  DECREASE_ACTIVE_COUNT(handle->loop, handle);
+
+  if (!(handle->flags & UV_HANDLE_READ_PENDING))
+    return 0;
+
+  if (handle->flags & UV_HANDLE_TTY_RAW) {
+    /* Cancel raw read */
+    /* Write some bullshit event to force the console wait to return. */
+    memset(&record, 0, sizeof record);
+    if (!WriteConsoleInputW(handle->handle, &record, 1, &written)) {
+      return GetLastError();
+    }
+  } else if (!(handle->flags & UV_HANDLE_CANCELLATION_PENDING)) {
+    /* Cancel line-buffered read if not already pending */
+    err = uv__cancel_read_console(handle);
+    if (err)
+      return err;
+
+    handle->flags |= UV_HANDLE_CANCELLATION_PENDING;
+  }
+
+  return 0;
+}
+
+static int uv__cancel_read_console(uv_tty_t* handle) {
+  HANDLE active_screen_buffer = INVALID_HANDLE_VALUE;
+  INPUT_RECORD record;
+  DWORD written;
+  DWORD err = 0;
+  LONG status;
+
+  assert(!(handle->flags & UV_HANDLE_CANCELLATION_PENDING));
+
+  /* Hold the output lock during the cancellation, to ensure that further
+     writes don't interfere with the screen state. It will be the ReadConsole
+     thread's responsibility to release the lock. */
+  uv_sem_wait(&uv_tty_output_lock);
+  status = InterlockedExchange(&uv__read_console_status, TRAP_REQUESTED);
+  if (status != IN_PROGRESS) {
+    /* Either we have managed to set a trap for the other thread before
+       ReadConsole is called, or ReadConsole has returned because the user
+       has pressed ENTER. In either case, there is nothing else to do. */
+    uv_sem_post(&uv_tty_output_lock);
+    return 0;
+  }
+
+  /* Save screen state before sending the VK_RETURN event */
+  active_screen_buffer = CreateFileA("conout$",
+                                     GENERIC_READ | GENERIC_WRITE,
+                                     FILE_SHARE_READ | FILE_SHARE_WRITE,
+                                     NULL,
+                                     OPEN_EXISTING,
+                                     FILE_ATTRIBUTE_NORMAL,
+                                     NULL);
+
+  if (active_screen_buffer != INVALID_HANDLE_VALUE &&
+      GetConsoleScreenBufferInfo(active_screen_buffer,
+                                 &uv__saved_screen_state)) {
+    InterlockedOr(&uv__restore_screen_state, 1);
+  }
+
+  /* Write enter key event to force the console wait to return. */
+  record.EventType = KEY_EVENT;
+  record.Event.KeyEvent.bKeyDown = TRUE;
+  record.Event.KeyEvent.wRepeatCount = 1;
+  record.Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
+  record.Event.KeyEvent.wVirtualScanCode =
+    MapVirtualKeyW(VK_RETURN, MAPVK_VK_TO_VSC);
+  record.Event.KeyEvent.uChar.UnicodeChar = L'\r';
+  record.Event.KeyEvent.dwControlKeyState = 0;
+  if (!WriteConsoleInputW(handle->handle, &record, 1, &written))
+    err = GetLastError();
+
+  if (active_screen_buffer != INVALID_HANDLE_VALUE)
+    CloseHandle(active_screen_buffer);
+
+  return err;
+}
+
+
+static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info) {
+  int old_virtual_width = uv_tty_virtual_width;
+  int old_virtual_height = uv_tty_virtual_height;
+
+  uv_tty_virtual_width = info->dwSize.X;
+  uv_tty_virtual_height = info->srWindow.Bottom - info->srWindow.Top + 1;
+
+  /* Recompute virtual window offset row. */
+  if (uv_tty_virtual_offset == -1) {
+    uv_tty_virtual_offset = info->dwCursorPosition.Y;
+  } else if (uv_tty_virtual_offset < info->dwCursorPosition.Y -
+             uv_tty_virtual_height + 1) {
+    /* If suddenly find the cursor outside of the virtual window, it must */
+    /* have somehow scrolled. Update the virtual window offset. */
+    uv_tty_virtual_offset = info->dwCursorPosition.Y -
+                            uv_tty_virtual_height + 1;
+  }
+  if (uv_tty_virtual_offset + uv_tty_virtual_height > info->dwSize.Y) {
+    uv_tty_virtual_offset = info->dwSize.Y - uv_tty_virtual_height;
+  }
+  if (uv_tty_virtual_offset < 0) {
+    uv_tty_virtual_offset = 0;
+  }
+
+  /* If the virtual window size changed, emit a SIGWINCH signal. Don't emit */
+  /* if this was the first time the virtual window size was computed. */
+  if (old_virtual_width != -1 && old_virtual_height != -1 &&
+      (uv_tty_virtual_width != old_virtual_width ||
+       uv_tty_virtual_height != old_virtual_height)) {
+    uv__signal_dispatch(SIGWINCH);
+  }
+}
+
+
+static COORD uv_tty_make_real_coord(uv_tty_t* handle,
+    CONSOLE_SCREEN_BUFFER_INFO* info, int x, unsigned char x_relative, int y,
+    unsigned char y_relative) {
+  COORD result;
+
+  uv_tty_update_virtual_window(info);
+
+  /* Adjust y position */
+  if (y_relative) {
+    y = info->dwCursorPosition.Y + y;
+  } else {
+    y = uv_tty_virtual_offset + y;
+  }
+  /* Clip y to virtual client rectangle */
+  if (y < uv_tty_virtual_offset) {
+    y = uv_tty_virtual_offset;
+  } else if (y >= uv_tty_virtual_offset + uv_tty_virtual_height) {
+    y = uv_tty_virtual_offset + uv_tty_virtual_height - 1;
+  }
+
+  /* Adjust x */
+  if (x_relative) {
+    x = info->dwCursorPosition.X + x;
+  }
+  /* Clip x */
+  if (x < 0) {
+    x = 0;
+  } else if (x >= uv_tty_virtual_width) {
+    x = uv_tty_virtual_width - 1;
+  }
+
+  result.X = (unsigned short) x;
+  result.Y = (unsigned short) y;
+  return result;
+}
+
+
+static int uv_tty_emit_text(uv_tty_t* handle, WCHAR buffer[], DWORD length,
+    DWORD* error) {
+  DWORD written;
+
+  if (*error != ERROR_SUCCESS) {
+    return -1;
+  }
+
+  if (!WriteConsoleW(handle->handle,
+                     (void*) buffer,
+                     length,
+                     &written,
+                     NULL)) {
+    *error = GetLastError();
+    return -1;
+  }
+
+  return 0;
+}
+
+
+static int uv_tty_move_caret(uv_tty_t* handle, int x, unsigned char x_relative,
+    int y, unsigned char y_relative, DWORD* error) {
+  CONSOLE_SCREEN_BUFFER_INFO info;
+  COORD pos;
+
+  if (*error != ERROR_SUCCESS) {
+    return -1;
+  }
+
+ retry:
+  if (!GetConsoleScreenBufferInfo(handle->handle, &info)) {
+    *error = GetLastError();
+  }
+
+  pos = uv_tty_make_real_coord(handle, &info, x, x_relative, y, y_relative);
+
+  if (!SetConsoleCursorPosition(handle->handle, pos)) {
+    if (GetLastError() == ERROR_INVALID_PARAMETER) {
+      /* The console may be resized - retry */
+      goto retry;
+    } else {
+      *error = GetLastError();
+      return -1;
+    }
+  }
+
+  return 0;
+}
+
+
+static int uv_tty_reset(uv_tty_t* handle, DWORD* error) {
+  const COORD origin = {0, 0};
+  const WORD char_attrs = uv_tty_default_text_attributes;
+  CONSOLE_SCREEN_BUFFER_INFO info;
+  DWORD count, written;
+
+  if (*error != ERROR_SUCCESS) {
+    return -1;
+  }
+
+  /* Reset original text attributes. */
+  if (!SetConsoleTextAttribute(handle->handle, char_attrs)) {
+    *error = GetLastError();
+    return -1;
+  }
+
+  /* Move the cursor position to (0, 0). */
+  if (!SetConsoleCursorPosition(handle->handle, origin)) {
+    *error = GetLastError();
+    return -1;
+  }
+
+  /* Clear the screen buffer. */
+ retry:
+  if (!GetConsoleScreenBufferInfo(handle->handle, &info)) {
+    *error = GetLastError();
+    return -1;
+  }
+
+  count = info.dwSize.X * info.dwSize.Y;
+
+  if (!(FillConsoleOutputCharacterW(handle->handle,
+                                    L'\x20',
+                                    count,
+                                    origin,
+                                    &written) &&
+        FillConsoleOutputAttribute(handle->handle,
+                                   char_attrs,
+                                   written,
+                                   origin,
+                                   &written))) {
+    if (GetLastError() == ERROR_INVALID_PARAMETER) {
+      /* The console may be resized - retry */
+      goto retry;
+    } else {
+      *error = GetLastError();
+      return -1;
+    }
+  }
+
+  /* Move the virtual window up to the top. */
+  uv_tty_virtual_offset = 0;
+  uv_tty_update_virtual_window(&info);
+
+  return 0;
+}
+
+
+static int uv_tty_clear(uv_tty_t* handle, int dir, char entire_screen,
+    DWORD* error) {
+  CONSOLE_SCREEN_BUFFER_INFO info;
+  COORD start, end;
+  DWORD count, written;
+
+  int x1, x2, y1, y2;
+  int x1r, x2r, y1r, y2r;
+
+  if (*error != ERROR_SUCCESS) {
+    return -1;
+  }
+
+  if (dir == 0) {
+    /* Clear from current position */
+    x1 = 0;
+    x1r = 1;
+  } else {
+    /* Clear from column 0 */
+    x1 = 0;
+    x1r = 0;
+  }
+
+  if (dir == 1) {
+    /* Clear to current position */
+    x2 = 0;
+    x2r = 1;
+  } else {
+    /* Clear to end of row. We pretend the console is 65536 characters wide, */
+    /* uv_tty_make_real_coord will clip it to the actual console width. */
+    x2 = 0xffff;
+    x2r = 0;
+  }
+
+  if (!entire_screen) {
+    /* Stay on our own row */
+    y1 = y2 = 0;
+    y1r = y2r = 1;
+  } else {
+    /* Apply columns direction to row */
+    y1 = x1;
+    y1r = x1r;
+    y2 = x2;
+    y2r = x2r;
+  }
+
+ retry:
+  if (!GetConsoleScreenBufferInfo(handle->handle, &info)) {
+    *error = GetLastError();
+    return -1;
+  }
+
+  start = uv_tty_make_real_coord(handle, &info, x1, x1r, y1, y1r);
+  end = uv_tty_make_real_coord(handle, &info, x2, x2r, y2, y2r);
+  count = (end.Y * info.dwSize.X + end.X) -
+          (start.Y * info.dwSize.X + start.X) + 1;
+
+  if (!(FillConsoleOutputCharacterW(handle->handle,
+                              L'\x20',
+                              count,
+                              start,
+                              &written) &&
+        FillConsoleOutputAttribute(handle->handle,
+                                   info.wAttributes,
+                                   written,
+                                   start,
+                                   &written))) {
+    if (GetLastError() == ERROR_INVALID_PARAMETER) {
+      /* The console may be resized - retry */
+      goto retry;
+    } else {
+      *error = GetLastError();
+      return -1;
+    }
+  }
+
+  return 0;
+}
+
+#define FLIP_FGBG                                                             \
+    do {                                                                      \
+      WORD fg = info.wAttributes & 0xF;                                       \
+      WORD bg = info.wAttributes & 0xF0;                                      \
+      info.wAttributes &= 0xFF00;                                             \
+      info.wAttributes |= fg << 4;                                            \
+      info.wAttributes |= bg >> 4;                                            \
+    } while (0)
+
+static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
+  unsigned short argc = handle->tty.wr.ansi_csi_argc;
+  unsigned short* argv = handle->tty.wr.ansi_csi_argv;
+  int i;
+  CONSOLE_SCREEN_BUFFER_INFO info;
+
+  char fg_color = -1, bg_color = -1;
+  char fg_bright = -1, bg_bright = -1;
+  char inverse = -1;
+
+  if (argc == 0) {
+    /* Reset mode */
+    fg_color = uv_tty_default_fg_color;
+    bg_color = uv_tty_default_bg_color;
+    fg_bright = uv_tty_default_fg_bright;
+    bg_bright = uv_tty_default_bg_bright;
+    inverse = uv_tty_default_inverse;
+  }
+
+  for (i = 0; i < argc; i++) {
+    short arg = argv[i];
+
+    if (arg == 0) {
+      /* Reset mode */
+      fg_color = uv_tty_default_fg_color;
+      bg_color = uv_tty_default_bg_color;
+      fg_bright = uv_tty_default_fg_bright;
+      bg_bright = uv_tty_default_bg_bright;
+      inverse = uv_tty_default_inverse;
+
+    } else if (arg == 1) {
+      /* Foreground bright on */
+      fg_bright = 1;
+
+    } else if (arg == 2) {
+      /* Both bright off */
+      fg_bright = 0;
+      bg_bright = 0;
+
+    } else if (arg == 5) {
+      /* Background bright on */
+      bg_bright = 1;
+
+    } else if (arg == 7) {
+      /* Inverse: on */
+      inverse = 1;
+
+    } else if (arg == 21 || arg == 22) {
+      /* Foreground bright off */
+      fg_bright = 0;
+
+    } else if (arg == 25) {
+      /* Background bright off */
+      bg_bright = 0;
+
+    } else if (arg == 27) {
+      /* Inverse: off */
+      inverse = 0;
+
+    } else if (arg >= 30 && arg <= 37) {
+      /* Set foreground color */
+      fg_color = arg - 30;
+
+    } else if (arg == 39) {
+      /* Default text color */
+      fg_color = uv_tty_default_fg_color;
+      fg_bright = uv_tty_default_fg_bright;
+
+    } else if (arg >= 40 && arg <= 47) {
+      /* Set background color */
+      bg_color = arg - 40;
+
+    } else if (arg ==  49) {
+      /* Default background color */
+      bg_color = uv_tty_default_bg_color;
+      bg_bright = uv_tty_default_bg_bright;
+
+    } else if (arg >= 90 && arg <= 97) {
+      /* Set bold foreground color */
+      fg_bright = 1;
+      fg_color = arg - 90;
+
+    } else if (arg >= 100 && arg <= 107) {
+      /* Set bold background color */
+      bg_bright = 1;
+      bg_color = arg - 100;
+
+    }
+  }
+
+  if (fg_color == -1 && bg_color == -1 && fg_bright == -1 &&
+      bg_bright == -1 && inverse == -1) {
+    /* Nothing changed */
+    return 0;
+  }
+
+  if (!GetConsoleScreenBufferInfo(handle->handle, &info)) {
+    *error = GetLastError();
+    return -1;
+  }
+
+  if ((info.wAttributes & COMMON_LVB_REVERSE_VIDEO) > 0) {
+    FLIP_FGBG;
+  }
+
+  if (fg_color != -1) {
+    info.wAttributes &= ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
+    if (fg_color & 1) info.wAttributes |= FOREGROUND_RED;
+    if (fg_color & 2) info.wAttributes |= FOREGROUND_GREEN;
+    if (fg_color & 4) info.wAttributes |= FOREGROUND_BLUE;
+  }
+
+  if (fg_bright != -1) {
+    if (fg_bright) {
+      info.wAttributes |= FOREGROUND_INTENSITY;
+    } else {
+      info.wAttributes &= ~FOREGROUND_INTENSITY;
+    }
+  }
+
+  if (bg_color != -1) {
+    info.wAttributes &= ~(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
+    if (bg_color & 1) info.wAttributes |= BACKGROUND_RED;
+    if (bg_color & 2) info.wAttributes |= BACKGROUND_GREEN;
+    if (bg_color & 4) info.wAttributes |= BACKGROUND_BLUE;
+  }
+
+  if (bg_bright != -1) {
+    if (bg_bright) {
+      info.wAttributes |= BACKGROUND_INTENSITY;
+    } else {
+      info.wAttributes &= ~BACKGROUND_INTENSITY;
+    }
+  }
+
+  if (inverse != -1) {
+    if (inverse) {
+      info.wAttributes |= COMMON_LVB_REVERSE_VIDEO;
+    } else {
+      info.wAttributes &= ~COMMON_LVB_REVERSE_VIDEO;
+    }
+  }
+
+  if ((info.wAttributes & COMMON_LVB_REVERSE_VIDEO) > 0) {
+    FLIP_FGBG;
+  }
+
+  if (!SetConsoleTextAttribute(handle->handle, info.wAttributes)) {
+    *error = GetLastError();
+    return -1;
+  }
+
+  return 0;
+}
+
+
+static int uv_tty_save_state(uv_tty_t* handle, unsigned char save_attributes,
+    DWORD* error) {
+  CONSOLE_SCREEN_BUFFER_INFO info;
+
+  if (*error != ERROR_SUCCESS) {
+    return -1;
+  }
+
+  if (!GetConsoleScreenBufferInfo(handle->handle, &info)) {
+    *error = GetLastError();
+    return -1;
+  }
+
+  uv_tty_update_virtual_window(&info);
+
+  handle->tty.wr.saved_position.X = info.dwCursorPosition.X;
+  handle->tty.wr.saved_position.Y = info.dwCursorPosition.Y - uv_tty_virtual_offset;
+  handle->flags |= UV_HANDLE_TTY_SAVED_POSITION;
+
+  if (save_attributes) {
+    handle->tty.wr.saved_attributes = info.wAttributes &
+        (FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);
+    handle->flags |= UV_HANDLE_TTY_SAVED_ATTRIBUTES;
+  }
+
+  return 0;
+}
+
+
+static int uv_tty_restore_state(uv_tty_t* handle,
+    unsigned char restore_attributes, DWORD* error) {
+  CONSOLE_SCREEN_BUFFER_INFO info;
+  WORD new_attributes;
+
+  if (*error != ERROR_SUCCESS) {
+    return -1;
+  }
+
+  if (handle->flags & UV_HANDLE_TTY_SAVED_POSITION) {
+    if (uv_tty_move_caret(handle,
+                          handle->tty.wr.saved_position.X,
+                          0,
+                          handle->tty.wr.saved_position.Y,
+                          0,
+                          error) != 0) {
+      return -1;
+    }
+  }
+
+  if (restore_attributes &&
+      (handle->flags & UV_HANDLE_TTY_SAVED_ATTRIBUTES)) {
+    if (!GetConsoleScreenBufferInfo(handle->handle, &info)) {
+      *error = GetLastError();
+      return -1;
+    }
+
+    new_attributes = info.wAttributes;
+    new_attributes &= ~(FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);
+    new_attributes |= handle->tty.wr.saved_attributes;
+
+    if (!SetConsoleTextAttribute(handle->handle, new_attributes)) {
+      *error = GetLastError();
+      return -1;
+    }
+  }
+
+  return 0;
+}
+
+static int uv_tty_set_cursor_visibility(uv_tty_t* handle,
+                                        BOOL visible,
+                                        DWORD* error) {
+  CONSOLE_CURSOR_INFO cursor_info;
+
+  if (!GetConsoleCursorInfo(handle->handle, &cursor_info)) {
+    *error = GetLastError();
+    return -1;
+  }
+
+  cursor_info.bVisible = visible;
+
+  if (!SetConsoleCursorInfo(handle->handle, &cursor_info)) {
+    *error = GetLastError();
+    return -1;
+  }
+
+  return 0;
+}
+
+static int uv_tty_write_bufs(uv_tty_t* handle,
+                             const uv_buf_t bufs[],
+                             unsigned int nbufs,
+                             DWORD* error) {
+  /* We can only write 8k characters at a time. Windows can't handle */
+  /* much more characters in a single console write anyway. */
+  WCHAR utf16_buf[MAX_CONSOLE_CHAR];
+  WCHAR* utf16_buffer;
+  DWORD utf16_buf_used = 0;
+  unsigned int i, len, max_len, pos;
+  int allocate = 0;
+
+#define FLUSH_TEXT()                                                 \
+  do {                                                               \
+    pos = 0;                                                         \
+    do {                                                             \
+      len = utf16_buf_used - pos;                                    \
+      if (len > MAX_CONSOLE_CHAR)                                    \
+        len = MAX_CONSOLE_CHAR;                                      \
+      uv_tty_emit_text(handle, &utf16_buffer[pos], len, error);      \
+      pos += len;                                                    \
+    } while (pos < utf16_buf_used);                                  \
+    if (allocate) {                                                  \
+      uv__free(utf16_buffer);                                        \
+      allocate = 0;                                                  \
+      utf16_buffer = utf16_buf;                                      \
+    }                                                                \
+    utf16_buf_used = 0;                                              \
+ } while (0)
+
+#define ENSURE_BUFFER_SPACE(wchars_needed)                          \
+  if (wchars_needed > ARRAY_SIZE(utf16_buf) - utf16_buf_used) {     \
+    FLUSH_TEXT();                                                   \
+  }
+
+  /* Cache for fast access */
+  unsigned char utf8_bytes_left = handle->tty.wr.utf8_bytes_left;
+  unsigned int utf8_codepoint = handle->tty.wr.utf8_codepoint;
+  unsigned char previous_eol = handle->tty.wr.previous_eol;
+  unsigned char ansi_parser_state = handle->tty.wr.ansi_parser_state;
+
+  /* Store the error here. If we encounter an error, stop trying to do i/o */
+  /* but keep parsing the buffer so we leave the parser in a consistent */
+  /* state. */
+  *error = ERROR_SUCCESS;
+
+  utf16_buffer = utf16_buf;
+
+  uv_sem_wait(&uv_tty_output_lock);
+
+  for (i = 0; i < nbufs; i++) {
+    uv_buf_t buf = bufs[i];
+    unsigned int j;
+
+    if (uv__vterm_state == UV_SUPPORTED && buf.len > 0) {
+      utf16_buf_used = MultiByteToWideChar(CP_UTF8,
+                                           0,
+                                           buf.base,
+                                           buf.len,
+                                           NULL,
+                                           0);
+
+      if (utf16_buf_used == 0) {
+        *error = GetLastError();
+        break;
+      }
+
+      max_len = (utf16_buf_used + 1) * sizeof(WCHAR);
+      allocate = max_len > MAX_CONSOLE_CHAR;
+      if (allocate)
+        utf16_buffer = uv__malloc(max_len);
+      if (!MultiByteToWideChar(CP_UTF8,
+                               0,
+                               buf.base,
+                               buf.len,
+                               utf16_buffer,
+                               utf16_buf_used)) {
+        if (allocate)
+          uv__free(utf16_buffer);
+        *error = GetLastError();
+        break;
+      }
+
+      FLUSH_TEXT();
+
+      continue;
+    }
+
+    for (j = 0; j < buf.len; j++) {
+      unsigned char c = buf.base[j];
+
+      /* Run the character through the utf8 decoder We happily accept non */
+      /* shortest form encodings and invalid code points - there's no real */
+      /* harm that can be done. */
+      if (utf8_bytes_left == 0) {
+        /* Read utf-8 start byte */
+        DWORD first_zero_bit;
+        unsigned char not_c = ~c;
+#ifdef _MSC_VER /* msvc */
+        if (_BitScanReverse(&first_zero_bit, not_c)) {
+#else /* assume gcc */
+        if (c != 0) {
+          first_zero_bit = (sizeof(int) * 8) - 1 - __builtin_clz(not_c);
+#endif
+          if (first_zero_bit == 7) {
+            /* Ascii - pass right through */
+            utf8_codepoint = (unsigned int) c;
+
+          } else if (first_zero_bit <= 5) {
+            /* Multibyte sequence */
+            utf8_codepoint = (0xff >> (8 - first_zero_bit)) & c;
+            utf8_bytes_left = (char) (6 - first_zero_bit);
+
+          } else {
+            /* Invalid continuation */
+            utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER;
+          }
+
+        } else {
+          /* 0xff -- invalid */
+          utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER;
+        }
+
+      } else if ((c & 0xc0) == 0x80) {
+        /* Valid continuation of utf-8 multibyte sequence */
+        utf8_bytes_left--;
+        utf8_codepoint <<= 6;
+        utf8_codepoint |= ((unsigned int) c & 0x3f);
+
+      } else {
+        /* Start byte where continuation was expected. */
+        utf8_bytes_left = 0;
+        utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER;
+        /* Patch buf offset so this character will be parsed again as a */
+        /* start byte. */
+        j--;
+      }
+
+      /* Maybe we need to parse more bytes to find a character. */
+      if (utf8_bytes_left != 0) {
+        continue;
+      }
+
+      /* Parse vt100/ansi escape codes */
+      if (ansi_parser_state == ANSI_NORMAL) {
+        switch (utf8_codepoint) {
+          case '\033':
+            ansi_parser_state = ANSI_ESCAPE_SEEN;
+            continue;
+
+          case 0233:
+            ansi_parser_state = ANSI_CSI;
+            handle->tty.wr.ansi_csi_argc = 0;
+            continue;
+        }
+
+      } else if (ansi_parser_state == ANSI_ESCAPE_SEEN) {
+        switch (utf8_codepoint) {
+          case '[':
+            ansi_parser_state = ANSI_CSI;
+            handle->tty.wr.ansi_csi_argc = 0;
+            continue;
+
+          case '^':
+          case '_':
+          case 'P':
+          case ']':
+            /* Not supported, but we'll have to parse until we see a stop */
+            /* code, e.g. ESC \ or BEL. */
+            ansi_parser_state = ANSI_ST_CONTROL;
+            continue;
+
+          case '\033':
+            /* Ignore double escape. */
+            continue;
+
+          case 'c':
+            /* Full console reset. */
+            FLUSH_TEXT();
+            uv_tty_reset(handle, error);
+            ansi_parser_state = ANSI_NORMAL;
+            continue;
+
+          case '7':
+            /* Save the cursor position and text attributes. */
+            FLUSH_TEXT();
+            uv_tty_save_state(handle, 1, error);
+            ansi_parser_state = ANSI_NORMAL;
+            continue;
+
+           case '8':
+            /* Restore the cursor position and text attributes */
+            FLUSH_TEXT();
+            uv_tty_restore_state(handle, 1, error);
+            ansi_parser_state = ANSI_NORMAL;
+            continue;
+
+          default:
+            if (utf8_codepoint >= '@' && utf8_codepoint <= '_') {
+              /* Single-char control. */
+              ansi_parser_state = ANSI_NORMAL;
+              continue;
+            } else {
+              /* Invalid - proceed as normal, */
+              ansi_parser_state = ANSI_NORMAL;
+            }
+        }
+
+      } else if (ansi_parser_state & ANSI_CSI) {
+        if (!(ansi_parser_state & ANSI_IGNORE)) {
+          if (utf8_codepoint >= '0' && utf8_codepoint <= '9') {
+            /* Parsing a numerical argument */
+
+            if (!(ansi_parser_state & ANSI_IN_ARG)) {
+              /* We were not currently parsing a number */
+
+              /* Check for too many arguments */
+              if (handle->tty.wr.ansi_csi_argc >= ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) {
+                ansi_parser_state |= ANSI_IGNORE;
+                continue;
+              }
+
+              ansi_parser_state |= ANSI_IN_ARG;
+              handle->tty.wr.ansi_csi_argc++;
+              handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] =
+                  (unsigned short) utf8_codepoint - '0';
+              continue;
+            } else {
+              /* We were already parsing a number. Parse next digit. */
+              uint32_t value = 10 *
+                  handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1];
+
+              /* Check for overflow. */
+              if (value > UINT16_MAX) {
+                ansi_parser_state |= ANSI_IGNORE;
+                continue;
+              }
+
+               handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] =
+                   (unsigned short) value + (utf8_codepoint - '0');
+               continue;
+            }
+
+          } else if (utf8_codepoint == ';') {
+            /* Denotes the end of an argument. */
+            if (ansi_parser_state & ANSI_IN_ARG) {
+              ansi_parser_state &= ~ANSI_IN_ARG;
+              continue;
+
+            } else {
+              /* If ANSI_IN_ARG is not set, add another argument and */
+              /* default it to 0. */
+              /* Check for too many arguments */
+              if (handle->tty.wr.ansi_csi_argc >= ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) {
+                ansi_parser_state |= ANSI_IGNORE;
+                continue;
+              }
+
+              handle->tty.wr.ansi_csi_argc++;
+              handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] = 0;
+              continue;
+            }
+
+          } else if (utf8_codepoint == '?' && !(ansi_parser_state & ANSI_IN_ARG) &&
+                     handle->tty.wr.ansi_csi_argc == 0) {
+            /* Ignores '?' if it is the first character after CSI[ */
+            /* This is an extension character from the VT100 codeset */
+            /* that is supported and used by most ANSI terminals today. */
+            continue;
+
+          } else if (utf8_codepoint >= '@' && utf8_codepoint <= '~' &&
+                     (handle->tty.wr.ansi_csi_argc > 0 || utf8_codepoint != '[')) {
+            int x, y, d;
+
+            /* Command byte */
+            switch (utf8_codepoint) {
+              case 'A':
+                /* cursor up */
+                FLUSH_TEXT();
+                y = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1);
+                uv_tty_move_caret(handle, 0, 1, y, 1, error);
+                break;
+
+              case 'B':
+                /* cursor down */
+                FLUSH_TEXT();
+                y = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1;
+                uv_tty_move_caret(handle, 0, 1, y, 1, error);
+                break;
+
+              case 'C':
+                /* cursor forward */
+                FLUSH_TEXT();
+                x = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1;
+                uv_tty_move_caret(handle, x, 1, 0, 1, error);
+                break;
+
+              case 'D':
+                /* cursor back */
+                FLUSH_TEXT();
+                x = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1);
+                uv_tty_move_caret(handle, x, 1, 0, 1, error);
+                break;
+
+              case 'E':
+                /* cursor next line */
+                FLUSH_TEXT();
+                y = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1;
+                uv_tty_move_caret(handle, 0, 0, y, 1, error);
+                break;
+
+              case 'F':
+                /* cursor previous line */
+                FLUSH_TEXT();
+                y = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1);
+                uv_tty_move_caret(handle, 0, 0, y, 1, error);
+                break;
+
+              case 'G':
+                /* cursor horizontal move absolute */
+                FLUSH_TEXT();
+                x = (handle->tty.wr.ansi_csi_argc >= 1 && handle->tty.wr.ansi_csi_argv[0])
+                  ? handle->tty.wr.ansi_csi_argv[0] - 1 : 0;
+                uv_tty_move_caret(handle, x, 0, 0, 1, error);
+                break;
+
+              case 'H':
+              case 'f':
+                /* cursor move absolute */
+                FLUSH_TEXT();
+                y = (handle->tty.wr.ansi_csi_argc >= 1 && handle->tty.wr.ansi_csi_argv[0])
+                  ? handle->tty.wr.ansi_csi_argv[0] - 1 : 0;
+                x = (handle->tty.wr.ansi_csi_argc >= 2 && handle->tty.wr.ansi_csi_argv[1])
+                  ? handle->tty.wr.ansi_csi_argv[1] - 1 : 0;
+                uv_tty_move_caret(handle, x, 0, y, 0, error);
+                break;
+
+              case 'J':
+                /* Erase screen */
+                FLUSH_TEXT();
+                d = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 0;
+                if (d >= 0 && d <= 2) {
+                  uv_tty_clear(handle, d, 1, error);
+                }
+                break;
+
+              case 'K':
+                /* Erase line */
+                FLUSH_TEXT();
+                d = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 0;
+                if (d >= 0 && d <= 2) {
+                  uv_tty_clear(handle, d, 0, error);
+                }
+                break;
+
+              case 'm':
+                /* Set style */
+                FLUSH_TEXT();
+                uv_tty_set_style(handle, error);
+                break;
+
+              case 's':
+                /* Save the cursor position. */
+                FLUSH_TEXT();
+                uv_tty_save_state(handle, 0, error);
+                break;
+
+              case 'u':
+                /* Restore the cursor position */
+                FLUSH_TEXT();
+                uv_tty_restore_state(handle, 0, error);
+                break;
+
+              case 'l':
+                /* Hide the cursor */
+                if (handle->tty.wr.ansi_csi_argc == 1 &&
+                    handle->tty.wr.ansi_csi_argv[0] == 25) {
+                  FLUSH_TEXT();
+                  uv_tty_set_cursor_visibility(handle, 0, error);
+                }
+                break;
+
+              case 'h':
+                /* Show the cursor */
+                if (handle->tty.wr.ansi_csi_argc == 1 &&
+                    handle->tty.wr.ansi_csi_argv[0] == 25) {
+                  FLUSH_TEXT();
+                  uv_tty_set_cursor_visibility(handle, 1, error);
+                }
+                break;
+            }
+
+            /* Sequence ended - go back to normal state. */
+            ansi_parser_state = ANSI_NORMAL;
+            continue;
+
+          } else {
+            /* We don't support commands that use private mode characters or */
+            /* intermediaries. Ignore the rest of the sequence. */
+            ansi_parser_state |= ANSI_IGNORE;
+            continue;
+          }
+        } else {
+          /* We're ignoring this command. Stop only on command character. */
+          if (utf8_codepoint >= '@' && utf8_codepoint <= '~') {
+            ansi_parser_state = ANSI_NORMAL;
+          }
+          continue;
+        }
+
+      } else if (ansi_parser_state & ANSI_ST_CONTROL) {
+        /* Unsupported control code */
+        /* Ignore everything until we see BEL or ESC \ */
+        if (ansi_parser_state & ANSI_IN_STRING) {
+          if (!(ansi_parser_state & ANSI_BACKSLASH_SEEN)) {
+            if (utf8_codepoint == '"') {
+              ansi_parser_state &= ~ANSI_IN_STRING;
+            } else if (utf8_codepoint == '\\') {
+              ansi_parser_state |= ANSI_BACKSLASH_SEEN;
+            }
+          } else {
+            ansi_parser_state &= ~ANSI_BACKSLASH_SEEN;
+          }
+        } else {
+          if (utf8_codepoint == '\007' || (utf8_codepoint == '\\' &&
+              (ansi_parser_state & ANSI_ESCAPE_SEEN))) {
+            /* End of sequence */
+            ansi_parser_state = ANSI_NORMAL;
+          } else if (utf8_codepoint == '\033') {
+            /* Escape character */
+            ansi_parser_state |= ANSI_ESCAPE_SEEN;
+          } else if (utf8_codepoint == '"') {
+             /* String starting */
+            ansi_parser_state |= ANSI_IN_STRING;
+            ansi_parser_state &= ~ANSI_ESCAPE_SEEN;
+            ansi_parser_state &= ~ANSI_BACKSLASH_SEEN;
+          } else {
+            ansi_parser_state &= ~ANSI_ESCAPE_SEEN;
+          }
+        }
+        continue;
+      } else {
+        /* Inconsistent state */
+        abort();
+      }
+
+      /* We wouldn't mind emitting utf-16 surrogate pairs. Too bad, the */
+      /* windows console doesn't really support UTF-16, so just emit the */
+      /* replacement character. */
+      if (utf8_codepoint > 0xffff) {
+        utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER;
+      }
+
+      if (utf8_codepoint == 0x0a || utf8_codepoint == 0x0d) {
+        /* EOL conversion - emit \r\n when we see \n. */
+
+        if (utf8_codepoint == 0x0a && previous_eol != 0x0d) {
+          /* \n was not preceded by \r; print \r\n. */
+          ENSURE_BUFFER_SPACE(2);
+          utf16_buf[utf16_buf_used++] = L'\r';
+          utf16_buf[utf16_buf_used++] = L'\n';
+        } else if (utf8_codepoint == 0x0d && previous_eol == 0x0a) {
+          /* \n was followed by \r; do not print the \r, since */
+          /* the source was either \r\n\r (so the second \r is */
+          /* redundant) or was \n\r (so the \n was processed */
+          /* by the last case and an \r automatically inserted). */
+        } else {
+          /* \r without \n; print \r as-is. */
+          ENSURE_BUFFER_SPACE(1);
+          utf16_buf[utf16_buf_used++] = (WCHAR) utf8_codepoint;
+        }
+
+        previous_eol = (char) utf8_codepoint;
+
+      } else if (utf8_codepoint <= 0xffff) {
+        /* Encode character into utf-16 buffer. */
+        ENSURE_BUFFER_SPACE(1);
+        utf16_buf[utf16_buf_used++] = (WCHAR) utf8_codepoint;
+        previous_eol = 0;
+      }
+    }
+  }
+
+  /* Flush remaining characters */
+  FLUSH_TEXT();
+
+  /* Copy cached values back to struct. */
+  handle->tty.wr.utf8_bytes_left = utf8_bytes_left;
+  handle->tty.wr.utf8_codepoint = utf8_codepoint;
+  handle->tty.wr.previous_eol = previous_eol;
+  handle->tty.wr.ansi_parser_state = ansi_parser_state;
+
+  uv_sem_post(&uv_tty_output_lock);
+
+  if (*error == STATUS_SUCCESS) {
+    return 0;
+  } else {
+    return -1;
+  }
+
+#undef FLUSH_TEXT
+}
+
+
+int uv_tty_write(uv_loop_t* loop,
+                 uv_write_t* req,
+                 uv_tty_t* handle,
+                 const uv_buf_t bufs[],
+                 unsigned int nbufs,
+                 uv_write_cb cb) {
+  DWORD error;
+
+  uv_req_init(loop, (uv_req_t*) req);
+  req->type = UV_WRITE;
+  req->handle = (uv_stream_t*) handle;
+  req->cb = cb;
+
+  handle->reqs_pending++;
+  handle->stream.conn.write_reqs_pending++;
+  REGISTER_HANDLE_REQ(loop, handle, req);
+
+  req->u.io.queued_bytes = 0;
+
+  if (!uv_tty_write_bufs(handle, bufs, nbufs, &error)) {
+    SET_REQ_SUCCESS(req);
+  } else {
+    SET_REQ_ERROR(req, error);
+  }
+
+  uv_insert_pending_req(loop, (uv_req_t*) req);
+
+  return 0;
+}
+
+
+int uv__tty_try_write(uv_tty_t* handle,
+                      const uv_buf_t bufs[],
+                      unsigned int nbufs) {
+  DWORD error;
+
+  if (handle->stream.conn.write_reqs_pending > 0)
+    return UV_EAGAIN;
+
+  if (uv_tty_write_bufs(handle, bufs, nbufs, &error))
+    return uv_translate_sys_error(error);
+
+  return uv__count_bufs(bufs, nbufs);
+}
+
+
+void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
+  uv_write_t* req) {
+  int err;
+
+  handle->write_queue_size -= req->u.io.queued_bytes;
+  UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+  if (req->cb) {
+    err = GET_REQ_ERROR(req);
+    req->cb(req, uv_translate_sys_error(err));
+  }
+
+  handle->stream.conn.write_reqs_pending--;
+  if (handle->stream.conn.shutdown_req != NULL &&
+      handle->stream.conn.write_reqs_pending == 0) {
+    uv_want_endgame(loop, (uv_handle_t*)handle);
+  }
+
+  DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_tty_close(uv_tty_t* handle) {
+  assert(handle->u.fd == -1 || handle->u.fd > 2);
+  if (handle->u.fd == -1)
+    CloseHandle(handle->handle);
+  else
+    close(handle->u.fd);
+
+  if (handle->flags & UV_HANDLE_READING)
+    uv_tty_read_stop(handle);
+
+  handle->u.fd = -1;
+  handle->handle = INVALID_HANDLE_VALUE;
+  handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
+  uv__handle_closing(handle);
+
+  if (handle->reqs_pending == 0) {
+    uv_want_endgame(handle->loop, (uv_handle_t*) handle);
+  }
+}
+
+
+void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
+  if (!(handle->flags & UV_HANDLE_TTY_READABLE) &&
+      handle->stream.conn.shutdown_req != NULL &&
+      handle->stream.conn.write_reqs_pending == 0) {
+    UNREGISTER_HANDLE_REQ(loop, handle, handle->stream.conn.shutdown_req);
+
+    /* TTY shutdown is really just a no-op */
+    if (handle->stream.conn.shutdown_req->cb) {
+      if (handle->flags & UV__HANDLE_CLOSING) {
+        handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, UV_ECANCELED);
+      } else {
+        handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, 0);
+      }
+    }
+
+    handle->stream.conn.shutdown_req = NULL;
+
+    DECREASE_PENDING_REQ_COUNT(handle);
+    return;
+  }
+
+  if (handle->flags & UV__HANDLE_CLOSING &&
+      handle->reqs_pending == 0) {
+    /* The wait handle used for raw reading should be unregistered when the */
+    /* wait callback runs. */
+    assert(!(handle->flags & UV_HANDLE_TTY_READABLE) ||
+           handle->tty.rd.read_raw_wait == NULL);
+
+    assert(!(handle->flags & UV_HANDLE_CLOSED));
+    uv__handle_close(handle);
+  }
+}
+
+
+/* TODO: remove me */
+void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle,
+    uv_req_t* raw_req) {
+  abort();
+}
+
+
+/* TODO: remove me */
+void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle,
+    uv_connect_t* req) {
+  abort();
+}
+
+
+int uv_tty_reset_mode(void) {
+  /* Not necessary to do anything. */
+  return 0;
+}
+
+/* Determine whether or not this version of windows supports
+ * proper ANSI color codes. Should be supported as of windows
+ * 10 version 1511, build number 10.0.10586.
+ */
+static void uv__determine_vterm_state(HANDLE handle) {
+  DWORD dwMode = 0;
+
+  if (!GetConsoleMode(handle, &dwMode)) {
+    uv__vterm_state = UV_UNSUPPORTED;
+    return;
+  }
+
+  dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
+  if (!SetConsoleMode(handle, dwMode)) {
+    uv__vterm_state = UV_UNSUPPORTED;
+    return;
+  }
+
+  uv__vterm_state = UV_SUPPORTED;
+}
diff --git a/deps/libtuv/src/win/udp.c b/deps/libtuv/src/win/udp.c
new file mode 100644 (file)
index 0000000..9bf1453
--- /dev/null
@@ -0,0 +1,928 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "internal.h"
+#include "handle-inl.h"
+#include "stream-inl.h"
+#include "req-inl.h"
+
+
+/*
+ * Threshold of active udp streams for which to preallocate udp read buffers.
+ */
+const unsigned int uv_active_udp_streams_threshold = 0;
+
+/* A zero-size buffer for use by uv_udp_read */
+static char uv_zero_[] = "";
+
+int uv_udp_getsockname(const uv_udp_t* handle,
+                       struct sockaddr* name,
+                       int* namelen) {
+  int result;
+
+  if (handle->socket == INVALID_SOCKET) {
+    return UV_EINVAL;
+  }
+
+  result = getsockname(handle->socket, name, namelen);
+  if (result != 0) {
+    return uv_translate_sys_error(WSAGetLastError());
+  }
+
+  return 0;
+}
+
+
+static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket,
+    int family) {
+  DWORD yes = 1;
+  WSAPROTOCOL_INFOW info;
+  int opt_len;
+
+  if (handle->socket != INVALID_SOCKET)
+    return UV_EBUSY;
+
+  /* Set the socket to nonblocking mode */
+  if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {
+    return WSAGetLastError();
+  }
+
+  /* Make the socket non-inheritable */
+  if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) {
+    return GetLastError();
+  }
+
+  /* Associate it with the I/O completion port. */
+  /* Use uv_handle_t pointer as completion key. */
+  if (CreateIoCompletionPort((HANDLE)socket,
+                             loop->iocp,
+                             (ULONG_PTR)socket,
+                             0) == NULL) {
+    return GetLastError();
+  }
+
+  if (pSetFileCompletionNotificationModes) {
+    /* All known Windows that support SetFileCompletionNotificationModes */
+    /* have a bug that makes it impossible to use this function in */
+    /* conjunction with datagram sockets. We can work around that but only */
+    /* if the user is using the default UDP driver (AFD) and has no other */
+    /* LSPs stacked on top. Here we check whether that is the case. */
+    opt_len = (int) sizeof info;
+    if (getsockopt(socket,
+                   SOL_SOCKET,
+                   SO_PROTOCOL_INFOW,
+                   (char*) &info,
+                   &opt_len) == SOCKET_ERROR) {
+      return GetLastError();
+    }
+
+    if (info.ProtocolChain.ChainLen == 1) {
+      if (pSetFileCompletionNotificationModes((HANDLE)socket,
+          FILE_SKIP_SET_EVENT_ON_HANDLE |
+          FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
+        handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP;
+        handle->func_wsarecv = uv_wsarecv_workaround;
+        handle->func_wsarecvfrom = uv_wsarecvfrom_workaround;
+      } else if (GetLastError() != ERROR_INVALID_FUNCTION) {
+        return GetLastError();
+      }
+    }
+  }
+
+  handle->socket = socket;
+
+  if (family == AF_INET6) {
+    handle->flags |= UV_HANDLE_IPV6;
+  } else {
+    assert(!(handle->flags & UV_HANDLE_IPV6));
+  }
+
+  return 0;
+}
+
+
+int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
+  int domain;
+
+  /* Use the lower 8 bits for the domain */
+  domain = flags & 0xFF;
+  if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
+    return UV_EINVAL;
+
+  if (flags & ~0xFF)
+    return UV_EINVAL;
+
+  uv__handle_init(loop, (uv_handle_t*) handle, UV_UDP);
+  handle->socket = INVALID_SOCKET;
+  handle->reqs_pending = 0;
+  handle->activecnt = 0;
+  handle->func_wsarecv = WSARecv;
+  handle->func_wsarecvfrom = WSARecvFrom;
+  handle->send_queue_size = 0;
+  handle->send_queue_count = 0;
+  uv_req_init(loop, (uv_req_t*) &(handle->recv_req));
+  handle->recv_req.type = UV_UDP_RECV;
+  handle->recv_req.data = handle;
+
+  /* If anything fails beyond this point we need to remove the handle from
+   * the handle queue, since it was added by uv__handle_init.
+   */
+
+  if (domain != AF_UNSPEC) {
+    SOCKET sock;
+    DWORD err;
+
+    sock = socket(domain, SOCK_DGRAM, 0);
+    if (sock == INVALID_SOCKET) {
+      err = WSAGetLastError();
+      QUEUE_REMOVE(&handle->handle_queue);
+      return uv_translate_sys_error(err);
+    }
+
+    err = uv_udp_set_socket(handle->loop, handle, sock, domain);
+    if (err) {
+      closesocket(sock);
+      QUEUE_REMOVE(&handle->handle_queue);
+      return uv_translate_sys_error(err);
+    }
+  }
+
+  return 0;
+}
+
+
+int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
+  return uv_udp_init_ex(loop, handle, AF_UNSPEC);
+}
+
+
+void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) {
+  uv_udp_recv_stop(handle);
+  closesocket(handle->socket);
+  handle->socket = INVALID_SOCKET;
+
+  uv__handle_closing(handle);
+
+  if (handle->reqs_pending == 0) {
+    uv_want_endgame(loop, (uv_handle_t*) handle);
+  }
+}
+
+
+void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) {
+  if (handle->flags & UV__HANDLE_CLOSING &&
+      handle->reqs_pending == 0) {
+    assert(!(handle->flags & UV_HANDLE_CLOSED));
+    uv__handle_close(handle);
+  }
+}
+
+
+static int uv_udp_maybe_bind(uv_udp_t* handle,
+                             const struct sockaddr* addr,
+                             unsigned int addrlen,
+                             unsigned int flags) {
+  int r;
+  int err;
+  DWORD no = 0;
+
+  if (handle->flags & UV_HANDLE_BOUND)
+    return 0;
+
+  if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6) {
+    /* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */
+    return ERROR_INVALID_PARAMETER;
+  }
+
+  if (handle->socket == INVALID_SOCKET) {
+    SOCKET sock = socket(addr->sa_family, SOCK_DGRAM, 0);
+    if (sock == INVALID_SOCKET) {
+      return WSAGetLastError();
+    }
+
+    err = uv_udp_set_socket(handle->loop, handle, sock, addr->sa_family);
+    if (err) {
+      closesocket(sock);
+      return err;
+    }
+  }
+
+  if (flags & UV_UDP_REUSEADDR) {
+    DWORD yes = 1;
+    /* Set SO_REUSEADDR on the socket. */
+    if (setsockopt(handle->socket,
+                   SOL_SOCKET,
+                   SO_REUSEADDR,
+                   (char*) &yes,
+                   sizeof yes) == SOCKET_ERROR) {
+      err = WSAGetLastError();
+      return err;
+    }
+  }
+
+  if (addr->sa_family == AF_INET6)
+    handle->flags |= UV_HANDLE_IPV6;
+
+  if (addr->sa_family == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) {
+    /* On windows IPV6ONLY is on by default. */
+    /* If the user doesn't specify it libuv turns it off. */
+
+    /* TODO: how to handle errors? This may fail if there is no ipv4 stack */
+    /* available, or when run on XP/2003 which have no support for dualstack */
+    /* sockets. For now we're silently ignoring the error. */
+    setsockopt(handle->socket,
+               IPPROTO_IPV6,
+               IPV6_V6ONLY,
+               (char*) &no,
+               sizeof no);
+  }
+
+  r = bind(handle->socket, addr, addrlen);
+  if (r == SOCKET_ERROR) {
+    return WSAGetLastError();
+  }
+
+  handle->flags |= UV_HANDLE_BOUND;
+
+  return 0;
+}
+
+
+static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
+  uv_req_t* req;
+  uv_buf_t buf;
+  DWORD bytes, flags;
+  int result;
+
+  assert(handle->flags & UV_HANDLE_READING);
+  assert(!(handle->flags & UV_HANDLE_READ_PENDING));
+
+  req = &handle->recv_req;
+  memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
+
+  /*
+   * Preallocate a read buffer if the number of active streams is below
+   * the threshold.
+  */
+  if (loop->active_udp_streams < uv_active_udp_streams_threshold) {
+    handle->flags &= ~UV_HANDLE_ZERO_READ;
+
+    handle->recv_buffer = uv_buf_init(NULL, 0);
+    handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->recv_buffer);
+    if (handle->recv_buffer.base == NULL || handle->recv_buffer.len == 0) {
+      handle->recv_cb(handle, UV_ENOBUFS, &handle->recv_buffer, NULL, 0);
+      return;
+    }
+    assert(handle->recv_buffer.base != NULL);
+
+    buf = handle->recv_buffer;
+    memset(&handle->recv_from, 0, sizeof handle->recv_from);
+    handle->recv_from_len = sizeof handle->recv_from;
+    flags = 0;
+
+    result = handle->func_wsarecvfrom(handle->socket,
+                                      (WSABUF*) &buf,
+                                      1,
+                                      &bytes,
+                                      &flags,
+                                      (struct sockaddr*) &handle->recv_from,
+                                      &handle->recv_from_len,
+                                      &req->u.io.overlapped,
+                                      NULL);
+
+    if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
+      /* Process the req without IOCP. */
+      handle->flags |= UV_HANDLE_READ_PENDING;
+      req->u.io.overlapped.InternalHigh = bytes;
+      handle->reqs_pending++;
+      uv_insert_pending_req(loop, req);
+    } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
+      /* The req will be processed with IOCP. */
+      handle->flags |= UV_HANDLE_READ_PENDING;
+      handle->reqs_pending++;
+    } else {
+      /* Make this req pending reporting an error. */
+      SET_REQ_ERROR(req, WSAGetLastError());
+      uv_insert_pending_req(loop, req);
+      handle->reqs_pending++;
+    }
+
+  } else {
+    handle->flags |= UV_HANDLE_ZERO_READ;
+
+    buf.base = (char*) uv_zero_;
+    buf.len = 0;
+    flags = MSG_PEEK;
+
+    result = handle->func_wsarecv(handle->socket,
+                                  (WSABUF*) &buf,
+                                  1,
+                                  &bytes,
+                                  &flags,
+                                  &req->u.io.overlapped,
+                                  NULL);
+
+    if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
+      /* Process the req without IOCP. */
+      handle->flags |= UV_HANDLE_READ_PENDING;
+      req->u.io.overlapped.InternalHigh = bytes;
+      handle->reqs_pending++;
+      uv_insert_pending_req(loop, req);
+    } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
+      /* The req will be processed with IOCP. */
+      handle->flags |= UV_HANDLE_READ_PENDING;
+      handle->reqs_pending++;
+    } else {
+      /* Make this req pending reporting an error. */
+      SET_REQ_ERROR(req, WSAGetLastError());
+      uv_insert_pending_req(loop, req);
+      handle->reqs_pending++;
+    }
+  }
+}
+
+
+int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
+    uv_udp_recv_cb recv_cb) {
+  uv_loop_t* loop = handle->loop;
+  int err;
+
+  if (handle->flags & UV_HANDLE_READING) {
+    return WSAEALREADY;
+  }
+
+  err = uv_udp_maybe_bind(handle,
+                          (const struct sockaddr*) &uv_addr_ip4_any_,
+                          sizeof(uv_addr_ip4_any_),
+                          0);
+  if (err)
+    return err;
+
+  handle->flags |= UV_HANDLE_READING;
+  INCREASE_ACTIVE_COUNT(loop, handle);
+  loop->active_udp_streams++;
+
+  handle->recv_cb = recv_cb;
+  handle->alloc_cb = alloc_cb;
+
+  /* If reading was stopped and then started again, there could still be a */
+  /* recv request pending. */
+  if (!(handle->flags & UV_HANDLE_READ_PENDING))
+    uv_udp_queue_recv(loop, handle);
+
+  return 0;
+}
+
+
+int uv__udp_recv_stop(uv_udp_t* handle) {
+  if (handle->flags & UV_HANDLE_READING) {
+    handle->flags &= ~UV_HANDLE_READING;
+    handle->loop->active_udp_streams--;
+    DECREASE_ACTIVE_COUNT(loop, handle);
+  }
+
+  return 0;
+}
+
+
+static int uv__send(uv_udp_send_t* req,
+                    uv_udp_t* handle,
+                    const uv_buf_t bufs[],
+                    unsigned int nbufs,
+                    const struct sockaddr* addr,
+                    unsigned int addrlen,
+                    uv_udp_send_cb cb) {
+  uv_loop_t* loop = handle->loop;
+  DWORD result, bytes;
+
+  uv_req_init(loop, (uv_req_t*) req);
+  req->type = UV_UDP_SEND;
+  req->handle = handle;
+  req->cb = cb;
+  memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
+
+  result = WSASendTo(handle->socket,
+                     (WSABUF*)bufs,
+                     nbufs,
+                     &bytes,
+                     0,
+                     addr,
+                     addrlen,
+                     &req->u.io.overlapped,
+                     NULL);
+
+  if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
+    /* Request completed immediately. */
+    req->u.io.queued_bytes = 0;
+    handle->reqs_pending++;
+    handle->send_queue_size += req->u.io.queued_bytes;
+    handle->send_queue_count++;
+    REGISTER_HANDLE_REQ(loop, handle, req);
+    uv_insert_pending_req(loop, (uv_req_t*)req);
+  } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
+    /* Request queued by the kernel. */
+    req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs);
+    handle->reqs_pending++;
+    handle->send_queue_size += req->u.io.queued_bytes;
+    handle->send_queue_count++;
+    REGISTER_HANDLE_REQ(loop, handle, req);
+  } else {
+    /* Send failed due to an error. */
+    return WSAGetLastError();
+  }
+
+  return 0;
+}
+
+
+void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle,
+    uv_req_t* req) {
+  uv_buf_t buf;
+  int partial;
+
+  assert(handle->type == UV_UDP);
+
+  handle->flags &= ~UV_HANDLE_READ_PENDING;
+
+  if (!REQ_SUCCESS(req)) {
+    DWORD err = GET_REQ_SOCK_ERROR(req);
+    if (err == WSAEMSGSIZE) {
+      /* Not a real error, it just indicates that the received packet */
+      /* was bigger than the receive buffer. */
+    } else if (err == WSAECONNRESET || err == WSAENETRESET) {
+      /* A previous sendto operation failed; ignore this error. If */
+      /* zero-reading we need to call WSARecv/WSARecvFrom _without_ the */
+      /* MSG_PEEK flag to clear out the error queue. For nonzero reads, */
+      /* immediately queue a new receive. */
+      if (!(handle->flags & UV_HANDLE_ZERO_READ)) {
+        goto done;
+      }
+    } else {
+      /* A real error occurred. Report the error to the user only if we're */
+      /* currently reading. */
+      if (handle->flags & UV_HANDLE_READING) {
+        uv_udp_recv_stop(handle);
+        buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
+              uv_buf_init(NULL, 0) : handle->recv_buffer;
+        handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0);
+      }
+      goto done;
+    }
+  }
+
+  if (!(handle->flags & UV_HANDLE_ZERO_READ)) {
+    /* Successful read */
+    partial = !REQ_SUCCESS(req);
+    handle->recv_cb(handle,
+                    req->u.io.overlapped.InternalHigh,
+                    &handle->recv_buffer,
+                    (const struct sockaddr*) &handle->recv_from,
+                    partial ? UV_UDP_PARTIAL : 0);
+  } else if (handle->flags & UV_HANDLE_READING) {
+    DWORD bytes, err, flags;
+    struct sockaddr_storage from;
+    int from_len;
+
+    /* Do a nonblocking receive */
+    /* TODO: try to read multiple datagrams at once. FIONREAD maybe? */
+    buf = uv_buf_init(NULL, 0);
+    handle->alloc_cb((uv_handle_t*) handle, 65536, &buf);
+    if (buf.base == NULL || buf.len == 0) {
+      handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0);
+      goto done;
+    }
+    assert(buf.base != NULL);
+
+    memset(&from, 0, sizeof from);
+    from_len = sizeof from;
+
+    flags = 0;
+
+    if (WSARecvFrom(handle->socket,
+                    (WSABUF*)&buf,
+                    1,
+                    &bytes,
+                    &flags,
+                    (struct sockaddr*) &from,
+                    &from_len,
+                    NULL,
+                    NULL) != SOCKET_ERROR) {
+
+      /* Message received */
+      handle->recv_cb(handle, bytes, &buf, (const struct sockaddr*) &from, 0);
+    } else {
+      err = WSAGetLastError();
+      if (err == WSAEMSGSIZE) {
+        /* Message truncated */
+        handle->recv_cb(handle,
+                        bytes,
+                        &buf,
+                        (const struct sockaddr*) &from,
+                        UV_UDP_PARTIAL);
+      } else if (err == WSAEWOULDBLOCK) {
+        /* Kernel buffer empty */
+        handle->recv_cb(handle, 0, &buf, NULL, 0);
+      } else if (err == WSAECONNRESET || err == WSAENETRESET) {
+        /* WSAECONNRESET/WSANETRESET is ignored because this just indicates
+         * that a previous sendto operation failed.
+         */
+        handle->recv_cb(handle, 0, &buf, NULL, 0);
+      } else {
+        /* Any other error that we want to report back to the user. */
+        uv_udp_recv_stop(handle);
+        handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0);
+      }
+    }
+  }
+
+done:
+  /* Post another read if still reading and not closing. */
+  if ((handle->flags & UV_HANDLE_READING) &&
+      !(handle->flags & UV_HANDLE_READ_PENDING)) {
+    uv_udp_queue_recv(loop, handle);
+  }
+
+  DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
+    uv_udp_send_t* req) {
+  int err;
+
+  assert(handle->type == UV_UDP);
+
+  assert(handle->send_queue_size >= req->u.io.queued_bytes);
+  assert(handle->send_queue_count >= 1);
+  handle->send_queue_size -= req->u.io.queued_bytes;
+  handle->send_queue_count--;
+
+  UNREGISTER_HANDLE_REQ(loop, handle, req);
+
+  if (req->cb) {
+    err = 0;
+    if (!REQ_SUCCESS(req)) {
+      err = GET_REQ_SOCK_ERROR(req);
+    }
+    req->cb(req, uv_translate_sys_error(err));
+  }
+
+  DECREASE_PENDING_REQ_COUNT(handle);
+}
+
+
+static int uv__udp_set_membership4(uv_udp_t* handle,
+                                   const struct sockaddr_in* multicast_addr,
+                                   const char* interface_addr,
+                                   uv_membership membership) {
+  int err;
+  int optname;
+  struct ip_mreq mreq;
+
+  if (handle->flags & UV_HANDLE_IPV6)
+    return UV_EINVAL;
+
+  /* If the socket is unbound, bind to inaddr_any. */
+  err = uv_udp_maybe_bind(handle,
+                          (const struct sockaddr*) &uv_addr_ip4_any_,
+                          sizeof(uv_addr_ip4_any_),
+                          UV_UDP_REUSEADDR);
+  if (err)
+    return uv_translate_sys_error(err);
+
+  memset(&mreq, 0, sizeof mreq);
+
+  if (interface_addr) {
+    err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr);
+    if (err)
+      return err;
+  } else {
+    mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+  }
+
+  mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr;
+
+  switch (membership) {
+    case UV_JOIN_GROUP:
+      optname = IP_ADD_MEMBERSHIP;
+      break;
+    case UV_LEAVE_GROUP:
+      optname = IP_DROP_MEMBERSHIP;
+      break;
+    default:
+      return UV_EINVAL;
+  }
+
+  if (setsockopt(handle->socket,
+                 IPPROTO_IP,
+                 optname,
+                 (char*) &mreq,
+                 sizeof mreq) == SOCKET_ERROR) {
+    return uv_translate_sys_error(WSAGetLastError());
+  }
+
+  return 0;
+}
+
+
+int uv__udp_set_membership6(uv_udp_t* handle,
+                            const struct sockaddr_in6* multicast_addr,
+                            const char* interface_addr,
+                            uv_membership membership) {
+  int optname;
+  int err;
+  struct ipv6_mreq mreq;
+  struct sockaddr_in6 addr6;
+
+  if ((handle->flags & UV_HANDLE_BOUND) && !(handle->flags & UV_HANDLE_IPV6))
+    return UV_EINVAL;
+
+  err = uv_udp_maybe_bind(handle,
+                          (const struct sockaddr*) &uv_addr_ip6_any_,
+                          sizeof(uv_addr_ip6_any_),
+                          UV_UDP_REUSEADDR);
+
+  if (err)
+    return uv_translate_sys_error(err);
+
+  memset(&mreq, 0, sizeof(mreq));
+
+  if (interface_addr) {
+    if (uv_ip6_addr(interface_addr, 0, &addr6))
+      return UV_EINVAL;
+    mreq.ipv6mr_interface = addr6.sin6_scope_id;
+  } else {
+    mreq.ipv6mr_interface = 0;
+  }
+
+  mreq.ipv6mr_multiaddr = multicast_addr->sin6_addr;
+
+  switch (membership) {
+  case UV_JOIN_GROUP:
+    optname = IPV6_ADD_MEMBERSHIP;
+    break;
+  case UV_LEAVE_GROUP:
+    optname = IPV6_DROP_MEMBERSHIP;
+    break;
+  default:
+    return UV_EINVAL;
+  }
+
+  if (setsockopt(handle->socket,
+                 IPPROTO_IPV6,
+                 optname,
+                 (char*) &mreq,
+                 sizeof mreq) == SOCKET_ERROR) {
+    return uv_translate_sys_error(WSAGetLastError());
+  }
+
+  return 0;
+}
+
+
+int uv_udp_set_membership(uv_udp_t* handle,
+                          const char* multicast_addr,
+                          const char* interface_addr,
+                          uv_membership membership) {
+  struct sockaddr_in addr4;
+  struct sockaddr_in6 addr6;
+
+  if (uv_ip4_addr(multicast_addr, 0, &addr4) == 0)
+    return uv__udp_set_membership4(handle, &addr4, interface_addr, membership);
+  else if (uv_ip6_addr(multicast_addr, 0, &addr6) == 0)
+    return uv__udp_set_membership6(handle, &addr6, interface_addr, membership);
+  else
+    return UV_EINVAL;
+}
+
+
+int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) {
+  struct sockaddr_storage addr_st;
+  struct sockaddr_in* addr4;
+  struct sockaddr_in6* addr6;
+
+  addr4 = (struct sockaddr_in*) &addr_st;
+  addr6 = (struct sockaddr_in6*) &addr_st;
+
+  if (!interface_addr) {
+    memset(&addr_st, 0, sizeof addr_st);
+    if (handle->flags & UV_HANDLE_IPV6) {
+      addr_st.ss_family = AF_INET6;
+      addr6->sin6_scope_id = 0;
+    } else {
+      addr_st.ss_family = AF_INET;
+      addr4->sin_addr.s_addr = htonl(INADDR_ANY);
+    }
+  } else if (uv_ip4_addr(interface_addr, 0, addr4) == 0) {
+    /* nothing, address was parsed */
+  } else if (uv_ip6_addr(interface_addr, 0, addr6) == 0) {
+    /* nothing, address was parsed */
+  } else {
+    return UV_EINVAL;
+  }
+
+  if (!(handle->flags & UV_HANDLE_BOUND))
+    return UV_EBADF;
+
+  if (addr_st.ss_family == AF_INET) {
+    if (setsockopt(handle->socket,
+                   IPPROTO_IP,
+                   IP_MULTICAST_IF,
+                   (char*) &addr4->sin_addr,
+                   sizeof(addr4->sin_addr)) == SOCKET_ERROR) {
+      return uv_translate_sys_error(WSAGetLastError());
+    }
+  } else if (addr_st.ss_family == AF_INET6) {
+    if (setsockopt(handle->socket,
+                   IPPROTO_IPV6,
+                   IPV6_MULTICAST_IF,
+                   (char*) &addr6->sin6_scope_id,
+                   sizeof(addr6->sin6_scope_id)) == SOCKET_ERROR) {
+      return uv_translate_sys_error(WSAGetLastError());
+    }
+  } else {
+    assert(0 && "unexpected address family");
+    abort();
+  }
+
+  return 0;
+}
+
+
+int uv_udp_set_broadcast(uv_udp_t* handle, int value) {
+  BOOL optval = (BOOL) value;
+
+  if (!(handle->flags & UV_HANDLE_BOUND))
+    return UV_EBADF;
+
+  if (setsockopt(handle->socket,
+                 SOL_SOCKET,
+                 SO_BROADCAST,
+                 (char*) &optval,
+                 sizeof optval)) {
+    return uv_translate_sys_error(WSAGetLastError());
+  }
+
+  return 0;
+}
+
+
+int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
+  WSAPROTOCOL_INFOW protocol_info;
+  int opt_len;
+  int err;
+
+  /* Detect the address family of the socket. */
+  opt_len = (int) sizeof protocol_info;
+  if (getsockopt(sock,
+                 SOL_SOCKET,
+                 SO_PROTOCOL_INFOW,
+                 (char*) &protocol_info,
+                 &opt_len) == SOCKET_ERROR) {
+    return uv_translate_sys_error(GetLastError());
+  }
+
+  err = uv_udp_set_socket(handle->loop,
+                          handle,
+                          sock,
+                          protocol_info.iAddressFamily);
+  return uv_translate_sys_error(err);
+}
+
+
+#define SOCKOPT_SETTER(name, option4, option6, validate)                      \
+  int uv_udp_set_##name(uv_udp_t* handle, int value) {                        \
+    DWORD optval = (DWORD) value;                                             \
+                                                                              \
+    if (!(validate(value))) {                                                 \
+      return UV_EINVAL;                                                       \
+    }                                                                         \
+                                                                              \
+    if (!(handle->flags & UV_HANDLE_BOUND))                                   \
+      return UV_EBADF;                                                        \
+                                                                              \
+    if (!(handle->flags & UV_HANDLE_IPV6)) {                                  \
+      /* Set IPv4 socket option */                                            \
+      if (setsockopt(handle->socket,                                          \
+                     IPPROTO_IP,                                              \
+                     option4,                                                 \
+                     (char*) &optval,                                         \
+                     sizeof optval)) {                                        \
+        return uv_translate_sys_error(WSAGetLastError());                     \
+      }                                                                       \
+    } else {                                                                  \
+      /* Set IPv6 socket option */                                            \
+      if (setsockopt(handle->socket,                                          \
+                     IPPROTO_IPV6,                                            \
+                     option6,                                                 \
+                     (char*) &optval,                                         \
+                     sizeof optval)) {                                        \
+        return uv_translate_sys_error(WSAGetLastError());                     \
+      }                                                                       \
+    }                                                                         \
+    return 0;                                                                 \
+  }
+
+#define VALIDATE_TTL(value) ((value) >= 1 && (value) <= 255)
+#define VALIDATE_MULTICAST_TTL(value) ((value) >= -1 && (value) <= 255)
+#define VALIDATE_MULTICAST_LOOP(value) (1)
+
+SOCKOPT_SETTER(ttl,
+               IP_TTL,
+               IPV6_HOPLIMIT,
+               VALIDATE_TTL)
+SOCKOPT_SETTER(multicast_ttl,
+               IP_MULTICAST_TTL,
+               IPV6_MULTICAST_HOPS,
+               VALIDATE_MULTICAST_TTL)
+SOCKOPT_SETTER(multicast_loop,
+               IP_MULTICAST_LOOP,
+               IPV6_MULTICAST_LOOP,
+               VALIDATE_MULTICAST_LOOP)
+
+#undef SOCKOPT_SETTER
+#undef VALIDATE_TTL
+#undef VALIDATE_MULTICAST_TTL
+#undef VALIDATE_MULTICAST_LOOP
+
+
+/* This function is an egress point, i.e. it returns libuv errors rather than
+ * system errors.
+ */
+int uv__udp_bind(uv_udp_t* handle,
+                 const struct sockaddr* addr,
+                 unsigned int addrlen,
+                 unsigned int flags) {
+  int err;
+
+  err = uv_udp_maybe_bind(handle, addr, addrlen, flags);
+  if (err)
+    return uv_translate_sys_error(err);
+
+  return 0;
+}
+
+
+/* This function is an egress point, i.e. it returns libuv errors rather than
+ * system errors.
+ */
+int uv__udp_send(uv_udp_send_t* req,
+                 uv_udp_t* handle,
+                 const uv_buf_t bufs[],
+                 unsigned int nbufs,
+                 const struct sockaddr* addr,
+                 unsigned int addrlen,
+                 uv_udp_send_cb send_cb) {
+  const struct sockaddr* bind_addr;
+  int err;
+
+  if (!(handle->flags & UV_HANDLE_BOUND)) {
+    if (addrlen == sizeof(uv_addr_ip4_any_)) {
+      bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_;
+    } else if (addrlen == sizeof(uv_addr_ip6_any_)) {
+      bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_;
+    } else {
+      abort();
+    }
+    err = uv_udp_maybe_bind(handle, bind_addr, addrlen, 0);
+    if (err)
+      return uv_translate_sys_error(err);
+  }
+
+  err = uv__send(req, handle, bufs, nbufs, addr, addrlen, send_cb);
+  if (err)
+    return uv_translate_sys_error(err);
+
+  return 0;
+}
+
+
+int uv__udp_try_send(uv_udp_t* handle,
+                     const uv_buf_t bufs[],
+                     unsigned int nbufs,
+                     const struct sockaddr* addr,
+                     unsigned int addrlen) {
+  return UV_ENOSYS;
+}
diff --git a/deps/libtuv/src/win/util.c b/deps/libtuv/src/win/util.c
new file mode 100644 (file)
index 0000000..050058a
--- /dev/null
@@ -0,0 +1,1389 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <direct.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <wchar.h>
+
+#include "uv.h"
+#include "internal.h"
+
+#include <winsock2.h>
+#include <winperf.h>
+#include <iphlpapi.h>
+#include <psapi.h>
+#include <tlhelp32.h>
+#include <windows.h>
+#include <userenv.h>
+
+
+/*
+ * Max title length; the only thing MSDN tells us about the maximum length
+ * of the console title is that it is smaller than 64K. However in practice
+ * it is much smaller, and there is no way to figure out what the exact length
+ * of the title is or can be, at least not on XP. To make it even more
+ * annoying, GetConsoleTitle fails when the buffer to be read into is bigger
+ * than the actual maximum length. So we make a conservative guess here;
+ * just don't put the novel you're writing in the title, unless the plot
+ * survives truncation.
+ */
+#define MAX_TITLE_LENGTH 8192
+
+/* The number of nanoseconds in one second. */
+#define UV__NANOSEC 1000000000
+
+/* Max user name length, from iphlpapi.h */
+#ifndef UNLEN
+# define UNLEN 256
+#endif
+
+/* Cached copy of the process title, plus a mutex guarding it. */
+static char *process_title;
+static CRITICAL_SECTION process_title_lock;
+
+/* Cached copy of the process id, written once. */
+static DWORD current_pid = 0;
+
+
+/* Interval (in seconds) of the high-resolution clock. */
+static double hrtime_interval_ = 0;
+
+
+/*
+ * One-time initialization code for functionality defined in util.c.
+ */
+void uv__util_init() {
+  LARGE_INTEGER perf_frequency;
+
+  /* Initialize process title access mutex. */
+  InitializeCriticalSection(&process_title_lock);
+
+  /* Retrieve high-resolution timer frequency
+   * and precompute its reciprocal.
+   */
+  if (QueryPerformanceFrequency(&perf_frequency)) {
+    hrtime_interval_ = 1.0 / perf_frequency.QuadPart;
+  } else {
+    hrtime_interval_= 0;
+  }
+}
+
+
+int uv_exepath(char* buffer, size_t* size_ptr) {
+  int utf8_len, utf16_buffer_len, utf16_len;
+  WCHAR* utf16_buffer;
+  int err;
+
+  if (buffer == NULL || size_ptr == NULL || *size_ptr == 0) {
+    return UV_EINVAL;
+  }
+
+  if (*size_ptr > 32768) {
+    /* Windows paths can never be longer than this. */
+    utf16_buffer_len = 32768;
+  } else {
+    utf16_buffer_len = (int) *size_ptr;
+  }
+
+  utf16_buffer = (WCHAR*) uv__malloc(sizeof(WCHAR) * utf16_buffer_len);
+  if (!utf16_buffer) {
+    return UV_ENOMEM;
+  }
+
+  /* Get the path as UTF-16. */
+  utf16_len = GetModuleFileNameW(NULL, utf16_buffer, utf16_buffer_len);
+  if (utf16_len <= 0) {
+    err = GetLastError();
+    goto error;
+  }
+
+  /* utf16_len contains the length, *not* including the terminating null. */
+  utf16_buffer[utf16_len] = L'\0';
+
+  /* Convert to UTF-8 */
+  utf8_len = WideCharToMultiByte(CP_UTF8,
+                                 0,
+                                 utf16_buffer,
+                                 -1,
+                                 buffer,
+                                 (int) *size_ptr,
+                                 NULL,
+                                 NULL);
+  if (utf8_len == 0) {
+    err = GetLastError();
+    goto error;
+  }
+
+  uv__free(utf16_buffer);
+
+  /* utf8_len *does* include the terminating null at this point, but the */
+  /* returned size shouldn't. */
+  *size_ptr = utf8_len - 1;
+  return 0;
+
+ error:
+  uv__free(utf16_buffer);
+  return uv_translate_sys_error(err);
+}
+
+
+int uv_cwd(char* buffer, size_t* size) {
+  DWORD utf16_len;
+  WCHAR utf16_buffer[MAX_PATH];
+  int r;
+
+  if (buffer == NULL || size == NULL) {
+    return UV_EINVAL;
+  }
+
+  utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
+  if (utf16_len == 0) {
+    return uv_translate_sys_error(GetLastError());
+  } else if (utf16_len > MAX_PATH) {
+    /* This should be impossible;  however the CRT has a code path to deal */
+    /* with this scenario, so I added a check anyway. */
+    return UV_EIO;
+  }
+
+  /* utf16_len contains the length, *not* including the terminating null. */
+  utf16_buffer[utf16_len] = L'\0';
+
+  /* The returned directory should not have a trailing slash, unless it */
+  /* points at a drive root, like c:\. Remove it if needed.*/
+  if (utf16_buffer[utf16_len - 1] == L'\\' &&
+      !(utf16_len == 3 && utf16_buffer[1] == L':')) {
+    utf16_len--;
+    utf16_buffer[utf16_len] = L'\0';
+  }
+
+  /* Check how much space we need */
+  r = WideCharToMultiByte(CP_UTF8,
+                          0,
+                          utf16_buffer,
+                          -1,
+                          NULL,
+                          0,
+                          NULL,
+                          NULL);
+  if (r == 0) {
+    return uv_translate_sys_error(GetLastError());
+  } else if (r > (int) *size) {
+    *size = r;
+    return UV_ENOBUFS;
+  }
+
+  /* Convert to UTF-8 */
+  r = WideCharToMultiByte(CP_UTF8,
+                          0,
+                          utf16_buffer,
+                          -1,
+                          buffer,
+                          *size > INT_MAX ? INT_MAX : (int) *size,
+                          NULL,
+                          NULL);
+  if (r == 0) {
+    return uv_translate_sys_error(GetLastError());
+  }
+
+  *size = r - 1;
+  return 0;
+}
+
+
+int uv_chdir(const char* dir) {
+  WCHAR utf16_buffer[MAX_PATH];
+  size_t utf16_len;
+  WCHAR drive_letter, env_var[4];
+
+  if (dir == NULL) {
+    return UV_EINVAL;
+  }
+
+  if (MultiByteToWideChar(CP_UTF8,
+                          0,
+                          dir,
+                          -1,
+                          utf16_buffer,
+                          MAX_PATH) == 0) {
+    DWORD error = GetLastError();
+    /* The maximum length of the current working directory is 260 chars, */
+    /* including terminating null. If it doesn't fit, the path name must be */
+    /* too long. */
+    if (error == ERROR_INSUFFICIENT_BUFFER) {
+      return UV_ENAMETOOLONG;
+    } else {
+      return uv_translate_sys_error(error);
+    }
+  }
+
+  if (!SetCurrentDirectoryW(utf16_buffer)) {
+    return uv_translate_sys_error(GetLastError());
+  }
+
+  /* Windows stores the drive-local path in an "hidden" environment variable, */
+  /* which has the form "=C:=C:\Windows". SetCurrentDirectory does not */
+  /* update this, so we'll have to do it. */
+  utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
+  if (utf16_len == 0) {
+    return uv_translate_sys_error(GetLastError());
+  } else if (utf16_len > MAX_PATH) {
+    return UV_EIO;
+  }
+
+  /* The returned directory should not have a trailing slash, unless it */
+  /* points at a drive root, like c:\. Remove it if needed. */
+  if (utf16_buffer[utf16_len - 1] == L'\\' &&
+      !(utf16_len == 3 && utf16_buffer[1] == L':')) {
+    utf16_len--;
+    utf16_buffer[utf16_len] = L'\0';
+  }
+
+  if (utf16_len < 2 || utf16_buffer[1] != L':') {
+    /* Doesn't look like a drive letter could be there - probably an UNC */
+    /* path. TODO: Need to handle win32 namespaces like \\?\C:\ ? */
+    drive_letter = 0;
+  } else if (utf16_buffer[0] >= L'A' && utf16_buffer[0] <= L'Z') {
+    drive_letter = utf16_buffer[0];
+  } else if (utf16_buffer[0] >= L'a' && utf16_buffer[0] <= L'z') {
+    /* Convert to uppercase. */
+    drive_letter = utf16_buffer[0] - L'a' + L'A';
+  } else {
+    /* Not valid. */
+    drive_letter = 0;
+  }
+
+  if (drive_letter != 0) {
+    /* Construct the environment variable name and set it. */
+    env_var[0] = L'=';
+    env_var[1] = drive_letter;
+    env_var[2] = L':';
+    env_var[3] = L'\0';
+
+    if (!SetEnvironmentVariableW(env_var, utf16_buffer)) {
+      return uv_translate_sys_error(GetLastError());
+    }
+  }
+
+  return 0;
+}
+
+
+void uv_loadavg(double avg[3]) {
+  /* Can't be implemented */
+  avg[0] = avg[1] = avg[2] = 0;
+}
+
+
+uint64_t uv_get_free_memory(void) {
+  MEMORYSTATUSEX memory_status;
+  memory_status.dwLength = sizeof(memory_status);
+
+  if (!GlobalMemoryStatusEx(&memory_status)) {
+     return -1;
+  }
+
+  return (uint64_t)memory_status.ullAvailPhys;
+}
+
+
+uint64_t uv_get_total_memory(void) {
+  MEMORYSTATUSEX memory_status;
+  memory_status.dwLength = sizeof(memory_status);
+
+  if (!GlobalMemoryStatusEx(&memory_status)) {
+    return -1;
+  }
+
+  return (uint64_t)memory_status.ullTotalPhys;
+}
+
+
+int uv_parent_pid() {
+  int parent_pid = -1;
+  HANDLE handle;
+  PROCESSENTRY32 pe;
+  DWORD current_pid = GetCurrentProcessId();
+
+  pe.dwSize = sizeof(PROCESSENTRY32);
+  handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+
+  if (Process32First(handle, &pe)) {
+    do {
+      if (pe.th32ProcessID == current_pid) {
+        parent_pid = pe.th32ParentProcessID;
+        break;
+      }
+    } while( Process32Next(handle, &pe));
+  }
+
+  CloseHandle(handle);
+  return parent_pid;
+}
+
+
+int uv_current_pid() {
+  if (current_pid == 0) {
+    current_pid = GetCurrentProcessId();
+  }
+  return current_pid;
+}
+
+
+char** uv_setup_args(int argc, char** argv) {
+  return argv;
+}
+
+
+int uv_set_process_title(const char* title) {
+  int err;
+  int length;
+  WCHAR* title_w = NULL;
+
+  uv__once_init();
+
+  /* Find out how big the buffer for the wide-char title must be */
+  length = MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0);
+  if (!length) {
+    err = GetLastError();
+    goto done;
+  }
+
+  /* Convert to wide-char string */
+  title_w = (WCHAR*)uv__malloc(sizeof(WCHAR) * length);
+  if (!title_w) {
+    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+  }
+
+  length = MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w, length);
+  if (!length) {
+    err = GetLastError();
+    goto done;
+  }
+
+  /* If the title must be truncated insert a \0 terminator there */
+  if (length > MAX_TITLE_LENGTH) {
+    title_w[MAX_TITLE_LENGTH - 1] = L'\0';
+  }
+
+  if (!SetConsoleTitleW(title_w)) {
+    err = GetLastError();
+    goto done;
+  }
+
+  EnterCriticalSection(&process_title_lock);
+  uv__free(process_title);
+  process_title = uv__strdup(title);
+  LeaveCriticalSection(&process_title_lock);
+
+  err = 0;
+
+done:
+  uv__free(title_w);
+  return uv_translate_sys_error(err);
+}
+
+
+static int uv__get_process_title() {
+  WCHAR title_w[MAX_TITLE_LENGTH];
+
+  if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) {
+    return -1;
+  }
+
+  if (uv__convert_utf16_to_utf8(title_w, -1, &process_title) != 0)
+    return -1;
+
+  return 0;
+}
+
+
+int uv_get_process_title(char* buffer, size_t size) {
+  size_t len;
+
+  if (buffer == NULL || size == 0)
+    return UV_EINVAL;
+
+  uv__once_init();
+
+  EnterCriticalSection(&process_title_lock);
+  /*
+   * If the process_title was never read before nor explicitly set,
+   * we must query it with getConsoleTitleW
+   */
+  if (!process_title && uv__get_process_title() == -1) {
+    LeaveCriticalSection(&process_title_lock);
+    return uv_translate_sys_error(GetLastError());
+  }
+
+  assert(process_title);
+  len = strlen(process_title) + 1;
+
+  if (size < len) {
+    LeaveCriticalSection(&process_title_lock);
+    return UV_ENOBUFS;
+  }
+
+  memcpy(buffer, process_title, len);
+  LeaveCriticalSection(&process_title_lock);
+
+  return 0;
+}
+
+
+uint64_t uv_hrtime(void) {
+  uv__once_init();
+  return uv__hrtime(UV__NANOSEC);
+}
+
+uint64_t uv__hrtime(double scale) {
+  LARGE_INTEGER counter;
+
+  /* If the performance interval is zero, there's no support. */
+  if (hrtime_interval_ == 0) {
+    return 0;
+  }
+
+  if (!QueryPerformanceCounter(&counter)) {
+    return 0;
+  }
+
+  /* Because we have no guarantee about the order of magnitude of the
+   * performance counter interval, integer math could cause this computation
+   * to overflow. Therefore we resort to floating point math.
+   */
+  return (uint64_t) ((double) counter.QuadPart * hrtime_interval_ * scale);
+}
+
+
+int uv_resident_set_memory(size_t* rss) {
+  HANDLE current_process;
+  PROCESS_MEMORY_COUNTERS pmc;
+
+  current_process = GetCurrentProcess();
+
+  if (!GetProcessMemoryInfo(current_process, &pmc, sizeof(pmc))) {
+    return uv_translate_sys_error(GetLastError());
+  }
+
+  *rss = pmc.WorkingSetSize;
+
+  return 0;
+}
+
+
+int uv_uptime(double* uptime) {
+  BYTE stack_buffer[4096];
+  BYTE* malloced_buffer = NULL;
+  BYTE* buffer = (BYTE*) stack_buffer;
+  size_t buffer_size = sizeof(stack_buffer);
+  DWORD data_size;
+
+  PERF_DATA_BLOCK* data_block;
+  PERF_OBJECT_TYPE* object_type;
+  PERF_COUNTER_DEFINITION* counter_definition;
+
+  DWORD i;
+
+  for (;;) {
+    LONG result;
+
+    data_size = (DWORD) buffer_size;
+    result = RegQueryValueExW(HKEY_PERFORMANCE_DATA,
+                              L"2",
+                              NULL,
+                              NULL,
+                              buffer,
+                              &data_size);
+    if (result == ERROR_SUCCESS) {
+      break;
+    } else if (result != ERROR_MORE_DATA) {
+      *uptime = 0;
+      return uv_translate_sys_error(result);
+    }
+
+    buffer_size *= 2;
+    /* Don't let the buffer grow infinitely. */
+    if (buffer_size > 1 << 20) {
+      goto internalError;
+    }
+
+    uv__free(malloced_buffer);
+
+    buffer = malloced_buffer = (BYTE*) uv__malloc(buffer_size);
+    if (malloced_buffer == NULL) {
+      *uptime = 0;
+      return UV_ENOMEM;
+    }
+  }
+
+  if (data_size < sizeof(*data_block))
+    goto internalError;
+
+  data_block = (PERF_DATA_BLOCK*) buffer;
+
+  if (wmemcmp(data_block->Signature, L"PERF", 4) != 0)
+    goto internalError;
+
+  if (data_size < data_block->HeaderLength + sizeof(*object_type))
+    goto internalError;
+
+  object_type = (PERF_OBJECT_TYPE*) (buffer + data_block->HeaderLength);
+
+  if (object_type->NumInstances != PERF_NO_INSTANCES)
+    goto internalError;
+
+  counter_definition = (PERF_COUNTER_DEFINITION*) (buffer +
+      data_block->HeaderLength + object_type->HeaderLength);
+  for (i = 0; i < object_type->NumCounters; i++) {
+    if ((BYTE*) counter_definition + sizeof(*counter_definition) >
+        buffer + data_size) {
+      break;
+    }
+
+    if (counter_definition->CounterNameTitleIndex == 674 &&
+        counter_definition->CounterSize == sizeof(uint64_t)) {
+      if (counter_definition->CounterOffset + sizeof(uint64_t) > data_size ||
+          !(counter_definition->CounterType & PERF_OBJECT_TIMER)) {
+        goto internalError;
+      } else {
+        BYTE* address = (BYTE*) object_type + object_type->DefinitionLength +
+                        counter_definition->CounterOffset;
+        uint64_t value = *((uint64_t*) address);
+        *uptime = (double) (object_type->PerfTime.QuadPart - value) /
+                  (double) object_type->PerfFreq.QuadPart;
+        uv__free(malloced_buffer);
+        return 0;
+      }
+    }
+
+    counter_definition = (PERF_COUNTER_DEFINITION*)
+        ((BYTE*) counter_definition + counter_definition->ByteLength);
+  }
+
+  /* If we get here, the uptime value was not found. */
+  uv__free(malloced_buffer);
+  *uptime = 0;
+  return UV_ENOSYS;
+
+ internalError:
+  uv__free(malloced_buffer);
+  *uptime = 0;
+  return UV_EIO;
+}
+
+
+int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) {
+  uv_cpu_info_t* cpu_infos;
+  SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi;
+  DWORD sppi_size;
+  SYSTEM_INFO system_info;
+  DWORD cpu_count, r, i;
+  NTSTATUS status;
+  ULONG result_size;
+  int err;
+  uv_cpu_info_t* cpu_info;
+
+  cpu_infos = NULL;
+  cpu_count = 0;
+  sppi = NULL;
+
+  uv__once_init();
+
+  GetSystemInfo(&system_info);
+  cpu_count = system_info.dwNumberOfProcessors;
+
+  cpu_infos = uv__calloc(cpu_count, sizeof *cpu_infos);
+  if (cpu_infos == NULL) {
+    err = ERROR_OUTOFMEMORY;
+    goto error;
+  }
+
+  sppi_size = cpu_count * sizeof(*sppi);
+  sppi = uv__malloc(sppi_size);
+  if (sppi == NULL) {
+    err = ERROR_OUTOFMEMORY;
+    goto error;
+  }
+
+  status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation,
+                                     sppi,
+                                     sppi_size,
+                                     &result_size);
+  if (!NT_SUCCESS(status)) {
+    err = pRtlNtStatusToDosError(status);
+    goto error;
+  }
+
+  assert(result_size == sppi_size);
+
+  for (i = 0; i < cpu_count; i++) {
+    WCHAR key_name[128];
+    HKEY processor_key;
+    DWORD cpu_speed;
+    DWORD cpu_speed_size = sizeof(cpu_speed);
+    WCHAR cpu_brand[256];
+    DWORD cpu_brand_size = sizeof(cpu_brand);
+    size_t len;
+
+    len = _snwprintf(key_name,
+                     ARRAY_SIZE(key_name),
+                     L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d",
+                     i);
+
+    assert(len > 0 && len < ARRAY_SIZE(key_name));
+
+    r = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+                      key_name,
+                      0,
+                      KEY_QUERY_VALUE,
+                      &processor_key);
+    if (r != ERROR_SUCCESS) {
+      err = GetLastError();
+      goto error;
+    }
+
+    if (RegQueryValueExW(processor_key,
+                         L"~MHz",
+                         NULL,
+                         NULL,
+                         (BYTE*) &cpu_speed,
+                         &cpu_speed_size) != ERROR_SUCCESS) {
+      err = GetLastError();
+      RegCloseKey(processor_key);
+      goto error;
+    }
+
+    if (RegQueryValueExW(processor_key,
+                         L"ProcessorNameString",
+                         NULL,
+                         NULL,
+                         (BYTE*) &cpu_brand,
+                         &cpu_brand_size) != ERROR_SUCCESS) {
+      err = GetLastError();
+      RegCloseKey(processor_key);
+      goto error;
+    }
+
+    RegCloseKey(processor_key);
+
+    cpu_info = &cpu_infos[i];
+    cpu_info->speed = cpu_speed;
+    cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000;
+    cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart -
+        sppi[i].IdleTime.QuadPart) / 10000;
+    cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000;
+    cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000;
+    cpu_info->cpu_times.nice = 0;
+
+    uv__convert_utf16_to_utf8(cpu_brand,
+                              cpu_brand_size / sizeof(WCHAR),
+                              &(cpu_info->model));
+  }
+
+  uv__free(sppi);
+
+  *cpu_count_ptr = cpu_count;
+  *cpu_infos_ptr = cpu_infos;
+
+  return 0;
+
+ error:
+  /* This is safe because the cpu_infos array is zeroed on allocation. */
+  for (i = 0; i < cpu_count; i++)
+    uv__free(cpu_infos[i].model);
+
+  uv__free(cpu_infos);
+  uv__free(sppi);
+
+  return uv_translate_sys_error(err);
+}
+
+
+void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
+  int i;
+
+  for (i = 0; i < count; i++) {
+    uv__free(cpu_infos[i].model);
+  }
+
+  uv__free(cpu_infos);
+}
+
+
+static int is_windows_version_or_greater(DWORD os_major,
+                                         DWORD os_minor,
+                                         WORD service_pack_major,
+                                         WORD service_pack_minor) {
+  OSVERSIONINFOEX osvi;
+  DWORDLONG condition_mask = 0;
+  int op = VER_GREATER_EQUAL;
+
+  /* Initialize the OSVERSIONINFOEX structure. */
+  ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+  osvi.dwMajorVersion = os_major;
+  osvi.dwMinorVersion = os_minor;
+  osvi.wServicePackMajor = service_pack_major;
+  osvi.wServicePackMinor = service_pack_minor;
+
+  /* Initialize the condition mask. */
+  VER_SET_CONDITION(condition_mask, VER_MAJORVERSION, op);
+  VER_SET_CONDITION(condition_mask, VER_MINORVERSION, op);
+  VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMAJOR, op);
+  VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMINOR, op);
+
+  /* Perform the test. */
+  return (int) VerifyVersionInfo(
+    &osvi,
+    VER_MAJORVERSION | VER_MINORVERSION |
+    VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
+    condition_mask);
+}
+
+
+static int address_prefix_match(int family,
+                                struct sockaddr* address,
+                                struct sockaddr* prefix_address,
+                                int prefix_len) {
+  uint8_t* address_data;
+  uint8_t* prefix_address_data;
+  int i;
+
+  assert(address->sa_family == family);
+  assert(prefix_address->sa_family == family);
+
+  if (family == AF_INET6) {
+    address_data = (uint8_t*) &(((struct sockaddr_in6 *) address)->sin6_addr);
+    prefix_address_data =
+      (uint8_t*) &(((struct sockaddr_in6 *) prefix_address)->sin6_addr);
+  } else {
+    address_data = (uint8_t*) &(((struct sockaddr_in *) address)->sin_addr);
+    prefix_address_data =
+      (uint8_t*) &(((struct sockaddr_in *) prefix_address)->sin_addr);
+  }
+
+  for (i = 0; i < prefix_len >> 3; i++) {
+    if (address_data[i] != prefix_address_data[i])
+      return 0;
+  }
+
+  if (prefix_len % 8)
+    return prefix_address_data[i] ==
+      (address_data[i] & (0xff << (8 - prefix_len % 8)));
+
+  return 1;
+}
+
+
+int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
+    int* count_ptr) {
+  IP_ADAPTER_ADDRESSES* win_address_buf;
+  ULONG win_address_buf_size;
+  IP_ADAPTER_ADDRESSES* adapter;
+
+  uv_interface_address_t* uv_address_buf;
+  char* name_buf;
+  size_t uv_address_buf_size;
+  uv_interface_address_t* uv_address;
+
+  int count;
+
+  int is_vista_or_greater;
+  ULONG flags;
+
+  is_vista_or_greater = is_windows_version_or_greater(6, 0, 0, 0);
+  if (is_vista_or_greater) {
+    flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
+      GAA_FLAG_SKIP_DNS_SERVER;
+  } else {
+    /* We need at least XP SP1. */
+    if (!is_windows_version_or_greater(5, 1, 1, 0))
+      return UV_ENOTSUP;
+
+    flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
+      GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_PREFIX;
+  }
+
+
+  /* Fetch the size of the adapters reported by windows, and then get the */
+  /* list itself. */
+  win_address_buf_size = 0;
+  win_address_buf = NULL;
+
+  for (;;) {
+    ULONG r;
+
+    /* If win_address_buf is 0, then GetAdaptersAddresses will fail with */
+    /* ERROR_BUFFER_OVERFLOW, and the required buffer size will be stored in */
+    /* win_address_buf_size. */
+    r = GetAdaptersAddresses(AF_UNSPEC,
+                             flags,
+                             NULL,
+                             win_address_buf,
+                             &win_address_buf_size);
+
+    if (r == ERROR_SUCCESS)
+      break;
+
+    uv__free(win_address_buf);
+
+    switch (r) {
+      case ERROR_BUFFER_OVERFLOW:
+        /* This happens when win_address_buf is NULL or too small to hold */
+        /* all adapters. */
+        win_address_buf = uv__malloc(win_address_buf_size);
+        if (win_address_buf == NULL)
+          return UV_ENOMEM;
+
+        continue;
+
+      case ERROR_NO_DATA: {
+        /* No adapters were found. */
+        uv_address_buf = uv__malloc(1);
+        if (uv_address_buf == NULL)
+          return UV_ENOMEM;
+
+        *count_ptr = 0;
+        *addresses_ptr = uv_address_buf;
+
+        return 0;
+      }
+
+      case ERROR_ADDRESS_NOT_ASSOCIATED:
+        return UV_EAGAIN;
+
+      case ERROR_INVALID_PARAMETER:
+        /* MSDN says:
+         *   "This error is returned for any of the following conditions: the
+         *   SizePointer parameter is NULL, the Address parameter is not
+         *   AF_INET, AF_INET6, or AF_UNSPEC, or the address information for
+         *   the parameters requested is greater than ULONG_MAX."
+         * Since the first two conditions are not met, it must be that the
+         * adapter data is too big.
+         */
+        return UV_ENOBUFS;
+
+      default:
+        /* Other (unspecified) errors can happen, but we don't have any */
+        /* special meaning for them. */
+        assert(r != ERROR_SUCCESS);
+        return uv_translate_sys_error(r);
+    }
+  }
+
+  /* Count the number of enabled interfaces and compute how much space is */
+  /* needed to store their info. */
+  count = 0;
+  uv_address_buf_size = 0;
+
+  for (adapter = win_address_buf;
+       adapter != NULL;
+       adapter = adapter->Next) {
+    IP_ADAPTER_UNICAST_ADDRESS* unicast_address;
+    int name_size;
+
+    /* Interfaces that are not 'up' should not be reported. Also skip */
+    /* interfaces that have no associated unicast address, as to avoid */
+    /* allocating space for the name for this interface. */
+    if (adapter->OperStatus != IfOperStatusUp ||
+        adapter->FirstUnicastAddress == NULL)
+      continue;
+
+    /* Compute the size of the interface name. */
+    name_size = WideCharToMultiByte(CP_UTF8,
+                                    0,
+                                    adapter->FriendlyName,
+                                    -1,
+                                    NULL,
+                                    0,
+                                    NULL,
+                                    FALSE);
+    if (name_size <= 0) {
+      uv__free(win_address_buf);
+      return uv_translate_sys_error(GetLastError());
+    }
+    uv_address_buf_size += name_size;
+
+    /* Count the number of addresses associated with this interface, and */
+    /* compute the size. */
+    for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*)
+                           adapter->FirstUnicastAddress;
+         unicast_address != NULL;
+         unicast_address = unicast_address->Next) {
+      count++;
+      uv_address_buf_size += sizeof(uv_interface_address_t);
+    }
+  }
+
+  /* Allocate space to store interface data plus adapter names. */
+  uv_address_buf = uv__malloc(uv_address_buf_size);
+  if (uv_address_buf == NULL) {
+    uv__free(win_address_buf);
+    return UV_ENOMEM;
+  }
+
+  /* Compute the start of the uv_interface_address_t array, and the place in */
+  /* the buffer where the interface names will be stored. */
+  uv_address = uv_address_buf;
+  name_buf = (char*) (uv_address_buf + count);
+
+  /* Fill out the output buffer. */
+  for (adapter = win_address_buf;
+       adapter != NULL;
+       adapter = adapter->Next) {
+    IP_ADAPTER_UNICAST_ADDRESS* unicast_address;
+    int name_size;
+    size_t max_name_size;
+
+    if (adapter->OperStatus != IfOperStatusUp ||
+        adapter->FirstUnicastAddress == NULL)
+      continue;
+
+    /* Convert the interface name to UTF8. */
+    max_name_size = (char*) uv_address_buf + uv_address_buf_size - name_buf;
+    if (max_name_size > (size_t) INT_MAX)
+      max_name_size = INT_MAX;
+    name_size = WideCharToMultiByte(CP_UTF8,
+                                    0,
+                                    adapter->FriendlyName,
+                                    -1,
+                                    name_buf,
+                                    (int) max_name_size,
+                                    NULL,
+                                    FALSE);
+    if (name_size <= 0) {
+      uv__free(win_address_buf);
+      uv__free(uv_address_buf);
+      return uv_translate_sys_error(GetLastError());
+    }
+
+    /* Add an uv_interface_address_t element for every unicast address. */
+    for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*)
+                           adapter->FirstUnicastAddress;
+         unicast_address != NULL;
+         unicast_address = unicast_address->Next) {
+      struct sockaddr* sa;
+      ULONG prefix_len;
+
+      sa = unicast_address->Address.lpSockaddr;
+
+      /* XP has no OnLinkPrefixLength field. */
+      if (is_vista_or_greater) {
+        prefix_len =
+          ((IP_ADAPTER_UNICAST_ADDRESS_LH*) unicast_address)->OnLinkPrefixLength;
+      } else {
+        /* Prior to Windows Vista the FirstPrefix pointed to the list with
+         * single prefix for each IP address assigned to the adapter.
+         * Order of FirstPrefix does not match order of FirstUnicastAddress,
+         * so we need to find corresponding prefix.
+         */
+        IP_ADAPTER_PREFIX* prefix;
+        prefix_len = 0;
+
+        for (prefix = adapter->FirstPrefix; prefix; prefix = prefix->Next) {
+          /* We want the longest matching prefix. */
+          if (prefix->Address.lpSockaddr->sa_family != sa->sa_family ||
+              prefix->PrefixLength <= prefix_len)
+            continue;
+
+          if (address_prefix_match(sa->sa_family, sa,
+              prefix->Address.lpSockaddr, prefix->PrefixLength)) {
+            prefix_len = prefix->PrefixLength;
+          }
+        }
+
+        /* If there is no matching prefix information, return a single-host
+         * subnet mask (e.g. 255.255.255.255 for IPv4).
+         */
+        if (!prefix_len)
+          prefix_len = (sa->sa_family == AF_INET6) ? 128 : 32;
+      }
+
+      memset(uv_address, 0, sizeof *uv_address);
+
+      uv_address->name = name_buf;
+
+      if (adapter->PhysicalAddressLength == sizeof(uv_address->phys_addr)) {
+        memcpy(uv_address->phys_addr,
+               adapter->PhysicalAddress,
+               sizeof(uv_address->phys_addr));
+      }
+
+      uv_address->is_internal =
+          (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK);
+
+      if (sa->sa_family == AF_INET6) {
+        uv_address->address.address6 = *((struct sockaddr_in6 *) sa);
+
+        uv_address->netmask.netmask6.sin6_family = AF_INET6;
+        memset(uv_address->netmask.netmask6.sin6_addr.s6_addr, 0xff, prefix_len >> 3);
+        /* This check ensures that we don't write past the size of the data. */
+        if (prefix_len % 8) {
+          uv_address->netmask.netmask6.sin6_addr.s6_addr[prefix_len >> 3] =
+              0xff << (8 - prefix_len % 8);
+        }
+
+      } else {
+        uv_address->address.address4 = *((struct sockaddr_in *) sa);
+
+        uv_address->netmask.netmask4.sin_family = AF_INET;
+        uv_address->netmask.netmask4.sin_addr.s_addr = (prefix_len > 0) ?
+            htonl(0xffffffff << (32 - prefix_len)) : 0;
+      }
+
+      uv_address++;
+    }
+
+    name_buf += name_size;
+  }
+
+  uv__free(win_address_buf);
+
+  *addresses_ptr = uv_address_buf;
+  *count_ptr = count;
+
+  return 0;
+}
+
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses,
+    int count) {
+  uv__free(addresses);
+}
+
+
+int uv_getrusage(uv_rusage_t *uv_rusage) {
+  FILETIME createTime, exitTime, kernelTime, userTime;
+  SYSTEMTIME kernelSystemTime, userSystemTime;
+  PROCESS_MEMORY_COUNTERS memCounters;
+  IO_COUNTERS ioCounters;
+  int ret;
+
+  ret = GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime);
+  if (ret == 0) {
+    return uv_translate_sys_error(GetLastError());
+  }
+
+  ret = FileTimeToSystemTime(&kernelTime, &kernelSystemTime);
+  if (ret == 0) {
+    return uv_translate_sys_error(GetLastError());
+  }
+
+  ret = FileTimeToSystemTime(&userTime, &userSystemTime);
+  if (ret == 0) {
+    return uv_translate_sys_error(GetLastError());
+  }
+
+  ret = GetProcessMemoryInfo(GetCurrentProcess(),
+                             &memCounters,
+                             sizeof(memCounters));
+  if (ret == 0) {
+    return uv_translate_sys_error(GetLastError());
+  }
+
+  ret = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
+  if (ret == 0) {
+    return uv_translate_sys_error(GetLastError());
+  }
+
+  memset(uv_rusage, 0, sizeof(*uv_rusage));
+
+  uv_rusage->ru_utime.tv_sec = userSystemTime.wHour * 3600 +
+                               userSystemTime.wMinute * 60 +
+                               userSystemTime.wSecond;
+  uv_rusage->ru_utime.tv_usec = userSystemTime.wMilliseconds * 1000;
+
+  uv_rusage->ru_stime.tv_sec = kernelSystemTime.wHour * 3600 +
+                               kernelSystemTime.wMinute * 60 +
+                               kernelSystemTime.wSecond;
+  uv_rusage->ru_stime.tv_usec = kernelSystemTime.wMilliseconds * 1000;
+
+  uv_rusage->ru_majflt = (uint64_t) memCounters.PageFaultCount;
+  uv_rusage->ru_maxrss = (uint64_t) memCounters.PeakWorkingSetSize / 1024;
+
+  uv_rusage->ru_oublock = (uint64_t) ioCounters.WriteOperationCount;
+  uv_rusage->ru_inblock = (uint64_t) ioCounters.ReadOperationCount;
+
+  return 0;
+}
+
+
+int uv_os_homedir(char* buffer, size_t* size) {
+  uv_passwd_t pwd;
+  wchar_t path[MAX_PATH];
+  DWORD bufsize;
+  size_t len;
+  int r;
+
+  if (buffer == NULL || size == NULL || *size == 0)
+    return UV_EINVAL;
+
+  /* Check if the USERPROFILE environment variable is set first */
+  len = GetEnvironmentVariableW(L"USERPROFILE", path, MAX_PATH);
+
+  if (len == 0) {
+    r = GetLastError();
+
+    /* Don't return an error if USERPROFILE was not found */
+    if (r != ERROR_ENVVAR_NOT_FOUND)
+      return uv_translate_sys_error(r);
+  } else if (len > MAX_PATH) {
+    /* This should not be possible */
+    return UV_EIO;
+  } else {
+    /* Check how much space we need */
+    bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
+
+    if (bufsize == 0) {
+      return uv_translate_sys_error(GetLastError());
+    } else if (bufsize > *size) {
+      *size = bufsize;
+      return UV_ENOBUFS;
+    }
+
+    /* Convert to UTF-8 */
+    bufsize = WideCharToMultiByte(CP_UTF8,
+                                  0,
+                                  path,
+                                  -1,
+                                  buffer,
+                                  *size,
+                                  NULL,
+                                  NULL);
+
+    if (bufsize == 0)
+      return uv_translate_sys_error(GetLastError());
+
+    *size = bufsize - 1;
+    return 0;
+  }
+
+  /* USERPROFILE is not set, so call uv__getpwuid_r() */
+  r = uv__getpwuid_r(&pwd);
+
+  if (r != 0) {
+    return r;
+  }
+
+  len = strlen(pwd.homedir);
+
+  if (len >= *size) {
+    *size = len + 1;
+    uv_os_free_passwd(&pwd);
+    return UV_ENOBUFS;
+  }
+
+  memcpy(buffer, pwd.homedir, len + 1);
+  *size = len;
+  uv_os_free_passwd(&pwd);
+
+  return 0;
+}
+
+
+int uv_os_tmpdir(char* buffer, size_t* size) {
+  wchar_t path[MAX_PATH + 1];
+  DWORD bufsize;
+  size_t len;
+
+  if (buffer == NULL || size == NULL || *size == 0)
+    return UV_EINVAL;
+
+  len = GetTempPathW(MAX_PATH + 1, path);
+
+  if (len == 0) {
+    return uv_translate_sys_error(GetLastError());
+  } else if (len > MAX_PATH + 1) {
+    /* This should not be possible */
+    return UV_EIO;
+  }
+
+  /* The returned directory should not have a trailing slash, unless it */
+  /* points at a drive root, like c:\. Remove it if needed.*/
+  if (path[len - 1] == L'\\' &&
+      !(len == 3 && path[1] == L':')) {
+    len--;
+    path[len] = L'\0';
+  }
+
+  /* Check how much space we need */
+  bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
+
+  if (bufsize == 0) {
+    return uv_translate_sys_error(GetLastError());
+  } else if (bufsize > *size) {
+    *size = bufsize;
+    return UV_ENOBUFS;
+  }
+
+  /* Convert to UTF-8 */
+  bufsize = WideCharToMultiByte(CP_UTF8,
+                                0,
+                                path,
+                                -1,
+                                buffer,
+                                *size,
+                                NULL,
+                                NULL);
+
+  if (bufsize == 0)
+    return uv_translate_sys_error(GetLastError());
+
+  *size = bufsize - 1;
+  return 0;
+}
+
+
+void uv_os_free_passwd(uv_passwd_t* pwd) {
+  if (pwd == NULL)
+    return;
+
+  uv__free(pwd->username);
+  uv__free(pwd->homedir);
+  pwd->username = NULL;
+  pwd->homedir = NULL;
+}
+
+
+/*
+ * Converts a UTF-16 string into a UTF-8 one. The resulting string is
+ * null-terminated.
+ *
+ * If utf16 is null terminated, utf16len can be set to -1, otherwise it must
+ * be specified.
+ */
+int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8) {
+  DWORD bufsize;
+
+  if (utf16 == NULL)
+    return UV_EINVAL;
+
+  /* Check how much space we need */
+  bufsize = WideCharToMultiByte(CP_UTF8,
+                                0,
+                                utf16,
+                                utf16len,
+                                NULL,
+                                0,
+                                NULL,
+                                NULL);
+
+  if (bufsize == 0)
+    return uv_translate_sys_error(GetLastError());
+
+  /* Allocate the destination buffer adding an extra byte for the terminating
+   * NULL. If utf16len is not -1 WideCharToMultiByte will not add it, so
+   * we do it ourselves always, just in case. */
+  *utf8 = uv__malloc(bufsize + 1);
+
+  if (*utf8 == NULL)
+    return UV_ENOMEM;
+
+  /* Convert to UTF-8 */
+  bufsize = WideCharToMultiByte(CP_UTF8,
+                                0,
+                                utf16,
+                                utf16len,
+                                *utf8,
+                                bufsize,
+                                NULL,
+                                NULL);
+
+  if (bufsize == 0) {
+    uv__free(*utf8);
+    *utf8 = NULL;
+    return uv_translate_sys_error(GetLastError());
+  }
+
+  (*utf8)[bufsize] = '\0';
+  return 0;
+}
+
+
+int uv__getpwuid_r(uv_passwd_t* pwd) {
+  HANDLE token;
+  wchar_t username[UNLEN + 1];
+  wchar_t path[MAX_PATH];
+  DWORD bufsize;
+  int r;
+
+  if (pwd == NULL)
+    return UV_EINVAL;
+
+  /* Get the home directory using GetUserProfileDirectoryW() */
+  if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0)
+    return uv_translate_sys_error(GetLastError());
+
+  bufsize = sizeof(path);
+  if (!GetUserProfileDirectoryW(token, path, &bufsize)) {
+    r = GetLastError();
+    CloseHandle(token);
+
+    /* This should not be possible */
+    if (r == ERROR_INSUFFICIENT_BUFFER)
+      return UV_ENOMEM;
+
+    return uv_translate_sys_error(r);
+  }
+
+  CloseHandle(token);
+
+  /* Get the username using GetUserNameW() */
+  bufsize = sizeof(username);
+  if (!GetUserNameW(username, &bufsize)) {
+    r = GetLastError();
+
+    /* This should not be possible */
+    if (r == ERROR_INSUFFICIENT_BUFFER)
+      return UV_ENOMEM;
+
+    return uv_translate_sys_error(r);
+  }
+
+  pwd->homedir = NULL;
+  r = uv__convert_utf16_to_utf8(path, -1, &pwd->homedir);
+
+  if (r != 0)
+    return r;
+
+  pwd->username = NULL;
+  r = uv__convert_utf16_to_utf8(username, -1, &pwd->username);
+
+  if (r != 0) {
+    uv__free(pwd->homedir);
+    return r;
+  }
+
+  pwd->shell = NULL;
+  pwd->uid = -1;
+  pwd->gid = -1;
+
+  return 0;
+}
+
+
+int uv_os_get_passwd(uv_passwd_t* pwd) {
+  return uv__getpwuid_r(pwd);
+}
diff --git a/deps/libtuv/src/win/winapi.c b/deps/libtuv/src/win/winapi.c
new file mode 100644 (file)
index 0000000..1fa179b
--- /dev/null
@@ -0,0 +1,159 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+
+#include "uv.h"
+#include "internal.h"
+
+
+/* Ntdll function pointers */
+sRtlNtStatusToDosError pRtlNtStatusToDosError;
+sNtDeviceIoControlFile pNtDeviceIoControlFile;
+sNtQueryInformationFile pNtQueryInformationFile;
+sNtSetInformationFile pNtSetInformationFile;
+sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
+sNtQueryDirectoryFile pNtQueryDirectoryFile;
+sNtQuerySystemInformation pNtQuerySystemInformation;
+
+
+/* Kernel32 function pointers */
+sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
+sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
+sCreateSymbolicLinkW pCreateSymbolicLinkW;
+sCancelIoEx pCancelIoEx;
+sInitializeConditionVariable pInitializeConditionVariable;
+sSleepConditionVariableCS pSleepConditionVariableCS;
+sSleepConditionVariableSRW pSleepConditionVariableSRW;
+sWakeAllConditionVariable pWakeAllConditionVariable;
+sWakeConditionVariable pWakeConditionVariable;
+sCancelSynchronousIo pCancelSynchronousIo;
+sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW;
+
+
+/* Powrprof.dll function pointer */
+sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
+
+
+void uv_winapi_init() {
+  HMODULE ntdll_module;
+  HMODULE kernel32_module;
+  HMODULE powrprof_module;
+
+  ntdll_module = GetModuleHandleA("ntdll.dll");
+  if (ntdll_module == NULL) {
+    uv_fatal_error(GetLastError(), "GetModuleHandleA");
+  }
+
+  pRtlNtStatusToDosError = (sRtlNtStatusToDosError) GetProcAddress(
+      ntdll_module,
+      "RtlNtStatusToDosError");
+  if (pRtlNtStatusToDosError == NULL) {
+    uv_fatal_error(GetLastError(), "GetProcAddress");
+  }
+
+  pNtDeviceIoControlFile = (sNtDeviceIoControlFile) GetProcAddress(
+      ntdll_module,
+      "NtDeviceIoControlFile");
+  if (pNtDeviceIoControlFile == NULL) {
+    uv_fatal_error(GetLastError(), "GetProcAddress");
+  }
+
+  pNtQueryInformationFile = (sNtQueryInformationFile) GetProcAddress(
+      ntdll_module,
+      "NtQueryInformationFile");
+  if (pNtQueryInformationFile == NULL) {
+    uv_fatal_error(GetLastError(), "GetProcAddress");
+  }
+
+  pNtSetInformationFile = (sNtSetInformationFile) GetProcAddress(
+      ntdll_module,
+      "NtSetInformationFile");
+  if (pNtSetInformationFile == NULL) {
+    uv_fatal_error(GetLastError(), "GetProcAddress");
+  }
+
+  pNtQueryVolumeInformationFile = (sNtQueryVolumeInformationFile)
+      GetProcAddress(ntdll_module, "NtQueryVolumeInformationFile");
+  if (pNtQueryVolumeInformationFile == NULL) {
+    uv_fatal_error(GetLastError(), "GetProcAddress");
+  }
+
+  pNtQueryDirectoryFile = (sNtQueryDirectoryFile)
+      GetProcAddress(ntdll_module, "NtQueryDirectoryFile");
+  if (pNtQueryVolumeInformationFile == NULL) {
+    uv_fatal_error(GetLastError(), "GetProcAddress");
+  }
+
+  pNtQuerySystemInformation = (sNtQuerySystemInformation) GetProcAddress(
+      ntdll_module,
+      "NtQuerySystemInformation");
+  if (pNtQuerySystemInformation == NULL) {
+    uv_fatal_error(GetLastError(), "GetProcAddress");
+  }
+
+  kernel32_module = GetModuleHandleA("kernel32.dll");
+  if (kernel32_module == NULL) {
+    uv_fatal_error(GetLastError(), "GetModuleHandleA");
+  }
+
+  pGetQueuedCompletionStatusEx = (sGetQueuedCompletionStatusEx) GetProcAddress(
+      kernel32_module,
+      "GetQueuedCompletionStatusEx");
+
+  pSetFileCompletionNotificationModes = (sSetFileCompletionNotificationModes)
+    GetProcAddress(kernel32_module, "SetFileCompletionNotificationModes");
+
+  pCreateSymbolicLinkW = (sCreateSymbolicLinkW)
+    GetProcAddress(kernel32_module, "CreateSymbolicLinkW");
+
+  pCancelIoEx = (sCancelIoEx)
+    GetProcAddress(kernel32_module, "CancelIoEx");
+
+  pInitializeConditionVariable = (sInitializeConditionVariable)
+    GetProcAddress(kernel32_module, "InitializeConditionVariable");
+
+  pSleepConditionVariableCS = (sSleepConditionVariableCS)
+    GetProcAddress(kernel32_module, "SleepConditionVariableCS");
+
+  pSleepConditionVariableSRW = (sSleepConditionVariableSRW)
+    GetProcAddress(kernel32_module, "SleepConditionVariableSRW");
+
+  pWakeAllConditionVariable = (sWakeAllConditionVariable)
+    GetProcAddress(kernel32_module, "WakeAllConditionVariable");
+
+  pWakeConditionVariable = (sWakeConditionVariable)
+    GetProcAddress(kernel32_module, "WakeConditionVariable");
+
+  pCancelSynchronousIo = (sCancelSynchronousIo)
+    GetProcAddress(kernel32_module, "CancelSynchronousIo");
+
+  pGetFinalPathNameByHandleW = (sGetFinalPathNameByHandleW)
+    GetProcAddress(kernel32_module, "GetFinalPathNameByHandleW");
+
+
+  powrprof_module = LoadLibraryA("powrprof.dll");
+  if (powrprof_module != NULL) {
+    pPowerRegisterSuspendResumeNotification = (sPowerRegisterSuspendResumeNotification)
+      GetProcAddress(powrprof_module, "PowerRegisterSuspendResumeNotification");
+  }
+
+}
diff --git a/deps/libtuv/src/win/winapi.h b/deps/libtuv/src/win/winapi.h
new file mode 100644 (file)
index 0000000..341fcd0
--- /dev/null
@@ -0,0 +1,4748 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef UV_WIN_WINAPI_H_
+#define UV_WIN_WINAPI_H_
+
+#include <windows.h>
+
+
+/*
+ * Ntdll headers
+ */
+#ifndef STATUS_SEVERITY_SUCCESS
+# define STATUS_SEVERITY_SUCCESS 0x0
+#endif
+
+#ifndef STATUS_SEVERITY_INFORMATIONAL
+# define STATUS_SEVERITY_INFORMATIONAL 0x1
+#endif
+
+#ifndef STATUS_SEVERITY_WARNING
+# define STATUS_SEVERITY_WARNING 0x2
+#endif
+
+#ifndef STATUS_SEVERITY_ERROR
+# define STATUS_SEVERITY_ERROR 0x3
+#endif
+
+#ifndef FACILITY_NTWIN32
+# define FACILITY_NTWIN32 0x7
+#endif
+
+#ifndef NT_SUCCESS
+# define NT_SUCCESS(status) (((NTSTATUS) (status)) >= 0)
+#endif
+
+#ifndef NT_INFORMATION
+# define NT_INFORMATION(status) ((((ULONG) (status)) >> 30) == 1)
+#endif
+
+#ifndef NT_WARNING
+# define NT_WARNING(status) ((((ULONG) (status)) >> 30) == 2)
+#endif
+
+#ifndef NT_ERROR
+# define NT_ERROR(status) ((((ULONG) (status)) >> 30) == 3)
+#endif
+
+#ifndef STATUS_SUCCESS
+# define STATUS_SUCCESS ((NTSTATUS) 0x00000000L)
+#endif
+
+#ifndef STATUS_WAIT_0
+# define STATUS_WAIT_0 ((NTSTATUS) 0x00000000L)
+#endif
+
+#ifndef STATUS_WAIT_1
+# define STATUS_WAIT_1 ((NTSTATUS) 0x00000001L)
+#endif
+
+#ifndef STATUS_WAIT_2
+# define STATUS_WAIT_2 ((NTSTATUS) 0x00000002L)
+#endif
+
+#ifndef STATUS_WAIT_3
+# define STATUS_WAIT_3 ((NTSTATUS) 0x00000003L)
+#endif
+
+#ifndef STATUS_WAIT_63
+# define STATUS_WAIT_63 ((NTSTATUS) 0x0000003FL)
+#endif
+
+#ifndef STATUS_ABANDONED
+# define STATUS_ABANDONED ((NTSTATUS) 0x00000080L)
+#endif
+
+#ifndef STATUS_ABANDONED_WAIT_0
+# define STATUS_ABANDONED_WAIT_0 ((NTSTATUS) 0x00000080L)
+#endif
+
+#ifndef STATUS_ABANDONED_WAIT_63
+# define STATUS_ABANDONED_WAIT_63 ((NTSTATUS) 0x000000BFL)
+#endif
+
+#ifndef STATUS_USER_APC
+# define STATUS_USER_APC ((NTSTATUS) 0x000000C0L)
+#endif
+
+#ifndef STATUS_KERNEL_APC
+# define STATUS_KERNEL_APC ((NTSTATUS) 0x00000100L)
+#endif
+
+#ifndef STATUS_ALERTED
+# define STATUS_ALERTED ((NTSTATUS) 0x00000101L)
+#endif
+
+#ifndef STATUS_TIMEOUT
+# define STATUS_TIMEOUT ((NTSTATUS) 0x00000102L)
+#endif
+
+#ifndef STATUS_PENDING
+# define STATUS_PENDING ((NTSTATUS) 0x00000103L)
+#endif
+
+#ifndef STATUS_REPARSE
+# define STATUS_REPARSE ((NTSTATUS) 0x00000104L)
+#endif
+
+#ifndef STATUS_MORE_ENTRIES
+# define STATUS_MORE_ENTRIES ((NTSTATUS) 0x00000105L)
+#endif
+
+#ifndef STATUS_NOT_ALL_ASSIGNED
+# define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS) 0x00000106L)
+#endif
+
+#ifndef STATUS_SOME_NOT_MAPPED
+# define STATUS_SOME_NOT_MAPPED ((NTSTATUS) 0x00000107L)
+#endif
+
+#ifndef STATUS_OPLOCK_BREAK_IN_PROGRESS
+# define STATUS_OPLOCK_BREAK_IN_PROGRESS ((NTSTATUS) 0x00000108L)
+#endif
+
+#ifndef STATUS_VOLUME_MOUNTED
+# define STATUS_VOLUME_MOUNTED ((NTSTATUS) 0x00000109L)
+#endif
+
+#ifndef STATUS_RXACT_COMMITTED
+# define STATUS_RXACT_COMMITTED ((NTSTATUS) 0x0000010AL)
+#endif
+
+#ifndef STATUS_NOTIFY_CLEANUP
+# define STATUS_NOTIFY_CLEANUP ((NTSTATUS) 0x0000010BL)
+#endif
+
+#ifndef STATUS_NOTIFY_ENUM_DIR
+# define STATUS_NOTIFY_ENUM_DIR ((NTSTATUS) 0x0000010CL)
+#endif
+
+#ifndef STATUS_NO_QUOTAS_FOR_ACCOUNT
+# define STATUS_NO_QUOTAS_FOR_ACCOUNT ((NTSTATUS) 0x0000010DL)
+#endif
+
+#ifndef STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED
+# define STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED ((NTSTATUS) 0x0000010EL)
+#endif
+
+#ifndef STATUS_PAGE_FAULT_TRANSITION
+# define STATUS_PAGE_FAULT_TRANSITION ((NTSTATUS) 0x00000110L)
+#endif
+
+#ifndef STATUS_PAGE_FAULT_DEMAND_ZERO
+# define STATUS_PAGE_FAULT_DEMAND_ZERO ((NTSTATUS) 0x00000111L)
+#endif
+
+#ifndef STATUS_PAGE_FAULT_COPY_ON_WRITE
+# define STATUS_PAGE_FAULT_COPY_ON_WRITE ((NTSTATUS) 0x00000112L)
+#endif
+
+#ifndef STATUS_PAGE_FAULT_GUARD_PAGE
+# define STATUS_PAGE_FAULT_GUARD_PAGE ((NTSTATUS) 0x00000113L)
+#endif
+
+#ifndef STATUS_PAGE_FAULT_PAGING_FILE
+# define STATUS_PAGE_FAULT_PAGING_FILE ((NTSTATUS) 0x00000114L)
+#endif
+
+#ifndef STATUS_CACHE_PAGE_LOCKED
+# define STATUS_CACHE_PAGE_LOCKED ((NTSTATUS) 0x00000115L)
+#endif
+
+#ifndef STATUS_CRASH_DUMP
+# define STATUS_CRASH_DUMP ((NTSTATUS) 0x00000116L)
+#endif
+
+#ifndef STATUS_BUFFER_ALL_ZEROS
+# define STATUS_BUFFER_ALL_ZEROS ((NTSTATUS) 0x00000117L)
+#endif
+
+#ifndef STATUS_REPARSE_OBJECT
+# define STATUS_REPARSE_OBJECT ((NTSTATUS) 0x00000118L)
+#endif
+
+#ifndef STATUS_RESOURCE_REQUIREMENTS_CHANGED
+# define STATUS_RESOURCE_REQUIREMENTS_CHANGED ((NTSTATUS) 0x00000119L)
+#endif
+
+#ifndef STATUS_TRANSLATION_COMPLETE
+# define STATUS_TRANSLATION_COMPLETE ((NTSTATUS) 0x00000120L)
+#endif
+
+#ifndef STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY
+# define STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY ((NTSTATUS) 0x00000121L)
+#endif
+
+#ifndef STATUS_NOTHING_TO_TERMINATE
+# define STATUS_NOTHING_TO_TERMINATE ((NTSTATUS) 0x00000122L)
+#endif
+
+#ifndef STATUS_PROCESS_NOT_IN_JOB
+# define STATUS_PROCESS_NOT_IN_JOB ((NTSTATUS) 0x00000123L)
+#endif
+
+#ifndef STATUS_PROCESS_IN_JOB
+# define STATUS_PROCESS_IN_JOB ((NTSTATUS) 0x00000124L)
+#endif
+
+#ifndef STATUS_VOLSNAP_HIBERNATE_READY
+# define STATUS_VOLSNAP_HIBERNATE_READY ((NTSTATUS) 0x00000125L)
+#endif
+
+#ifndef STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY
+# define STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY ((NTSTATUS) 0x00000126L)
+#endif
+
+#ifndef STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED
+# define STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED ((NTSTATUS) 0x00000127L)
+#endif
+
+#ifndef STATUS_INTERRUPT_STILL_CONNECTED
+# define STATUS_INTERRUPT_STILL_CONNECTED ((NTSTATUS) 0x00000128L)
+#endif
+
+#ifndef STATUS_PROCESS_CLONED
+# define STATUS_PROCESS_CLONED ((NTSTATUS) 0x00000129L)
+#endif
+
+#ifndef STATUS_FILE_LOCKED_WITH_ONLY_READERS
+# define STATUS_FILE_LOCKED_WITH_ONLY_READERS ((NTSTATUS) 0x0000012AL)
+#endif
+
+#ifndef STATUS_FILE_LOCKED_WITH_WRITERS
+# define STATUS_FILE_LOCKED_WITH_WRITERS ((NTSTATUS) 0x0000012BL)
+#endif
+
+#ifndef STATUS_RESOURCEMANAGER_READ_ONLY
+# define STATUS_RESOURCEMANAGER_READ_ONLY ((NTSTATUS) 0x00000202L)
+#endif
+
+#ifndef STATUS_RING_PREVIOUSLY_EMPTY
+# define STATUS_RING_PREVIOUSLY_EMPTY ((NTSTATUS) 0x00000210L)
+#endif
+
+#ifndef STATUS_RING_PREVIOUSLY_FULL
+# define STATUS_RING_PREVIOUSLY_FULL ((NTSTATUS) 0x00000211L)
+#endif
+
+#ifndef STATUS_RING_PREVIOUSLY_ABOVE_QUOTA
+# define STATUS_RING_PREVIOUSLY_ABOVE_QUOTA ((NTSTATUS) 0x00000212L)
+#endif
+
+#ifndef STATUS_RING_NEWLY_EMPTY
+# define STATUS_RING_NEWLY_EMPTY ((NTSTATUS) 0x00000213L)
+#endif
+
+#ifndef STATUS_RING_SIGNAL_OPPOSITE_ENDPOINT
+# define STATUS_RING_SIGNAL_OPPOSITE_ENDPOINT ((NTSTATUS) 0x00000214L)
+#endif
+
+#ifndef STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE
+# define STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE ((NTSTATUS) 0x00000215L)
+#endif
+
+#ifndef STATUS_OPLOCK_HANDLE_CLOSED
+# define STATUS_OPLOCK_HANDLE_CLOSED ((NTSTATUS) 0x00000216L)
+#endif
+
+#ifndef STATUS_WAIT_FOR_OPLOCK
+# define STATUS_WAIT_FOR_OPLOCK ((NTSTATUS) 0x00000367L)
+#endif
+
+#ifndef STATUS_OBJECT_NAME_EXISTS
+# define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS) 0x40000000L)
+#endif
+
+#ifndef STATUS_THREAD_WAS_SUSPENDED
+# define STATUS_THREAD_WAS_SUSPENDED ((NTSTATUS) 0x40000001L)
+#endif
+
+#ifndef STATUS_WORKING_SET_LIMIT_RANGE
+# define STATUS_WORKING_SET_LIMIT_RANGE ((NTSTATUS) 0x40000002L)
+#endif
+
+#ifndef STATUS_IMAGE_NOT_AT_BASE
+# define STATUS_IMAGE_NOT_AT_BASE ((NTSTATUS) 0x40000003L)
+#endif
+
+#ifndef STATUS_RXACT_STATE_CREATED
+# define STATUS_RXACT_STATE_CREATED ((NTSTATUS) 0x40000004L)
+#endif
+
+#ifndef STATUS_SEGMENT_NOTIFICATION
+# define STATUS_SEGMENT_NOTIFICATION ((NTSTATUS) 0x40000005L)
+#endif
+
+#ifndef STATUS_LOCAL_USER_SESSION_KEY
+# define STATUS_LOCAL_USER_SESSION_KEY ((NTSTATUS) 0x40000006L)
+#endif
+
+#ifndef STATUS_BAD_CURRENT_DIRECTORY
+# define STATUS_BAD_CURRENT_DIRECTORY ((NTSTATUS) 0x40000007L)
+#endif
+
+#ifndef STATUS_SERIAL_MORE_WRITES
+# define STATUS_SERIAL_MORE_WRITES ((NTSTATUS) 0x40000008L)
+#endif
+
+#ifndef STATUS_REGISTRY_RECOVERED
+# define STATUS_REGISTRY_RECOVERED ((NTSTATUS) 0x40000009L)
+#endif
+
+#ifndef STATUS_FT_READ_RECOVERY_FROM_BACKUP
+# define STATUS_FT_READ_RECOVERY_FROM_BACKUP ((NTSTATUS) 0x4000000AL)
+#endif
+
+#ifndef STATUS_FT_WRITE_RECOVERY
+# define STATUS_FT_WRITE_RECOVERY ((NTSTATUS) 0x4000000BL)
+#endif
+
+#ifndef STATUS_SERIAL_COUNTER_TIMEOUT
+# define STATUS_SERIAL_COUNTER_TIMEOUT ((NTSTATUS) 0x4000000CL)
+#endif
+
+#ifndef STATUS_NULL_LM_PASSWORD
+# define STATUS_NULL_LM_PASSWORD ((NTSTATUS) 0x4000000DL)
+#endif
+
+#ifndef STATUS_IMAGE_MACHINE_TYPE_MISMATCH
+# define STATUS_IMAGE_MACHINE_TYPE_MISMATCH ((NTSTATUS) 0x4000000EL)
+#endif
+
+#ifndef STATUS_RECEIVE_PARTIAL
+# define STATUS_RECEIVE_PARTIAL ((NTSTATUS) 0x4000000FL)
+#endif
+
+#ifndef STATUS_RECEIVE_EXPEDITED
+# define STATUS_RECEIVE_EXPEDITED ((NTSTATUS) 0x40000010L)
+#endif
+
+#ifndef STATUS_RECEIVE_PARTIAL_EXPEDITED
+# define STATUS_RECEIVE_PARTIAL_EXPEDITED ((NTSTATUS) 0x40000011L)
+#endif
+
+#ifndef STATUS_EVENT_DONE
+# define STATUS_EVENT_DONE ((NTSTATUS) 0x40000012L)
+#endif
+
+#ifndef STATUS_EVENT_PENDING
+# define STATUS_EVENT_PENDING ((NTSTATUS) 0x40000013L)
+#endif
+
+#ifndef STATUS_CHECKING_FILE_SYSTEM
+# define STATUS_CHECKING_FILE_SYSTEM ((NTSTATUS) 0x40000014L)
+#endif
+
+#ifndef STATUS_FATAL_APP_EXIT
+# define STATUS_FATAL_APP_EXIT ((NTSTATUS) 0x40000015L)
+#endif
+
+#ifndef STATUS_PREDEFINED_HANDLE
+# define STATUS_PREDEFINED_HANDLE ((NTSTATUS) 0x40000016L)
+#endif
+
+#ifndef STATUS_WAS_UNLOCKED
+# define STATUS_WAS_UNLOCKED ((NTSTATUS) 0x40000017L)
+#endif
+
+#ifndef STATUS_SERVICE_NOTIFICATION
+# define STATUS_SERVICE_NOTIFICATION ((NTSTATUS) 0x40000018L)
+#endif
+
+#ifndef STATUS_WAS_LOCKED
+# define STATUS_WAS_LOCKED ((NTSTATUS) 0x40000019L)
+#endif
+
+#ifndef STATUS_LOG_HARD_ERROR
+# define STATUS_LOG_HARD_ERROR ((NTSTATUS) 0x4000001AL)
+#endif
+
+#ifndef STATUS_ALREADY_WIN32
+# define STATUS_ALREADY_WIN32 ((NTSTATUS) 0x4000001BL)
+#endif
+
+#ifndef STATUS_WX86_UNSIMULATE
+# define STATUS_WX86_UNSIMULATE ((NTSTATUS) 0x4000001CL)
+#endif
+
+#ifndef STATUS_WX86_CONTINUE
+# define STATUS_WX86_CONTINUE ((NTSTATUS) 0x4000001DL)
+#endif
+
+#ifndef STATUS_WX86_SINGLE_STEP
+# define STATUS_WX86_SINGLE_STEP ((NTSTATUS) 0x4000001EL)
+#endif
+
+#ifndef STATUS_WX86_BREAKPOINT
+# define STATUS_WX86_BREAKPOINT ((NTSTATUS) 0x4000001FL)
+#endif
+
+#ifndef STATUS_WX86_EXCEPTION_CONTINUE
+# define STATUS_WX86_EXCEPTION_CONTINUE ((NTSTATUS) 0x40000020L)
+#endif
+
+#ifndef STATUS_WX86_EXCEPTION_LASTCHANCE
+# define STATUS_WX86_EXCEPTION_LASTCHANCE ((NTSTATUS) 0x40000021L)
+#endif
+
+#ifndef STATUS_WX86_EXCEPTION_CHAIN
+# define STATUS_WX86_EXCEPTION_CHAIN ((NTSTATUS) 0x40000022L)
+#endif
+
+#ifndef STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE
+# define STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE ((NTSTATUS) 0x40000023L)
+#endif
+
+#ifndef STATUS_NO_YIELD_PERFORMED
+# define STATUS_NO_YIELD_PERFORMED ((NTSTATUS) 0x40000024L)
+#endif
+
+#ifndef STATUS_TIMER_RESUME_IGNORED
+# define STATUS_TIMER_RESUME_IGNORED ((NTSTATUS) 0x40000025L)
+#endif
+
+#ifndef STATUS_ARBITRATION_UNHANDLED
+# define STATUS_ARBITRATION_UNHANDLED ((NTSTATUS) 0x40000026L)
+#endif
+
+#ifndef STATUS_CARDBUS_NOT_SUPPORTED
+# define STATUS_CARDBUS_NOT_SUPPORTED ((NTSTATUS) 0x40000027L)
+#endif
+
+#ifndef STATUS_WX86_CREATEWX86TIB
+# define STATUS_WX86_CREATEWX86TIB ((NTSTATUS) 0x40000028L)
+#endif
+
+#ifndef STATUS_MP_PROCESSOR_MISMATCH
+# define STATUS_MP_PROCESSOR_MISMATCH ((NTSTATUS) 0x40000029L)
+#endif
+
+#ifndef STATUS_HIBERNATED
+# define STATUS_HIBERNATED ((NTSTATUS) 0x4000002AL)
+#endif
+
+#ifndef STATUS_RESUME_HIBERNATION
+# define STATUS_RESUME_HIBERNATION ((NTSTATUS) 0x4000002BL)
+#endif
+
+#ifndef STATUS_FIRMWARE_UPDATED
+# define STATUS_FIRMWARE_UPDATED ((NTSTATUS) 0x4000002CL)
+#endif
+
+#ifndef STATUS_DRIVERS_LEAKING_LOCKED_PAGES
+# define STATUS_DRIVERS_LEAKING_LOCKED_PAGES ((NTSTATUS) 0x4000002DL)
+#endif
+
+#ifndef STATUS_MESSAGE_RETRIEVED
+# define STATUS_MESSAGE_RETRIEVED ((NTSTATUS) 0x4000002EL)
+#endif
+
+#ifndef STATUS_SYSTEM_POWERSTATE_TRANSITION
+# define STATUS_SYSTEM_POWERSTATE_TRANSITION ((NTSTATUS) 0x4000002FL)
+#endif
+
+#ifndef STATUS_ALPC_CHECK_COMPLETION_LIST
+# define STATUS_ALPC_CHECK_COMPLETION_LIST ((NTSTATUS) 0x40000030L)
+#endif
+
+#ifndef STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION
+# define STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION ((NTSTATUS) 0x40000031L)
+#endif
+
+#ifndef STATUS_ACCESS_AUDIT_BY_POLICY
+# define STATUS_ACCESS_AUDIT_BY_POLICY ((NTSTATUS) 0x40000032L)
+#endif
+
+#ifndef STATUS_ABANDON_HIBERFILE
+# define STATUS_ABANDON_HIBERFILE ((NTSTATUS) 0x40000033L)
+#endif
+
+#ifndef STATUS_BIZRULES_NOT_ENABLED
+# define STATUS_BIZRULES_NOT_ENABLED ((NTSTATUS) 0x40000034L)
+#endif
+
+#ifndef STATUS_GUARD_PAGE_VIOLATION
+# define STATUS_GUARD_PAGE_VIOLATION ((NTSTATUS) 0x80000001L)
+#endif
+
+#ifndef STATUS_DATATYPE_MISALIGNMENT
+# define STATUS_DATATYPE_MISALIGNMENT ((NTSTATUS) 0x80000002L)
+#endif
+
+#ifndef STATUS_BREAKPOINT
+# define STATUS_BREAKPOINT ((NTSTATUS) 0x80000003L)
+#endif
+
+#ifndef STATUS_SINGLE_STEP
+# define STATUS_SINGLE_STEP ((NTSTATUS) 0x80000004L)
+#endif
+
+#ifndef STATUS_BUFFER_OVERFLOW
+# define STATUS_BUFFER_OVERFLOW ((NTSTATUS) 0x80000005L)
+#endif
+
+#ifndef STATUS_NO_MORE_FILES
+# define STATUS_NO_MORE_FILES ((NTSTATUS) 0x80000006L)
+#endif
+
+#ifndef STATUS_WAKE_SYSTEM_DEBUGGER
+# define STATUS_WAKE_SYSTEM_DEBUGGER ((NTSTATUS) 0x80000007L)
+#endif
+
+#ifndef STATUS_HANDLES_CLOSED
+# define STATUS_HANDLES_CLOSED ((NTSTATUS) 0x8000000AL)
+#endif
+
+#ifndef STATUS_NO_INHERITANCE
+# define STATUS_NO_INHERITANCE ((NTSTATUS) 0x8000000BL)
+#endif
+
+#ifndef STATUS_GUID_SUBSTITUTION_MADE
+# define STATUS_GUID_SUBSTITUTION_MADE ((NTSTATUS) 0x8000000CL)
+#endif
+
+#ifndef STATUS_PARTIAL_COPY
+# define STATUS_PARTIAL_COPY ((NTSTATUS) 0x8000000DL)
+#endif
+
+#ifndef STATUS_DEVICE_PAPER_EMPTY
+# define STATUS_DEVICE_PAPER_EMPTY ((NTSTATUS) 0x8000000EL)
+#endif
+
+#ifndef STATUS_DEVICE_POWERED_OFF
+# define STATUS_DEVICE_POWERED_OFF ((NTSTATUS) 0x8000000FL)
+#endif
+
+#ifndef STATUS_DEVICE_OFF_LINE
+# define STATUS_DEVICE_OFF_LINE ((NTSTATUS) 0x80000010L)
+#endif
+
+#ifndef STATUS_DEVICE_BUSY
+# define STATUS_DEVICE_BUSY ((NTSTATUS) 0x80000011L)
+#endif
+
+#ifndef STATUS_NO_MORE_EAS
+# define STATUS_NO_MORE_EAS ((NTSTATUS) 0x80000012L)
+#endif
+
+#ifndef STATUS_INVALID_EA_NAME
+# define STATUS_INVALID_EA_NAME ((NTSTATUS) 0x80000013L)
+#endif
+
+#ifndef STATUS_EA_LIST_INCONSISTENT
+# define STATUS_EA_LIST_INCONSISTENT ((NTSTATUS) 0x80000014L)
+#endif
+
+#ifndef STATUS_INVALID_EA_FLAG
+# define STATUS_INVALID_EA_FLAG ((NTSTATUS) 0x80000015L)
+#endif
+
+#ifndef STATUS_VERIFY_REQUIRED
+# define STATUS_VERIFY_REQUIRED ((NTSTATUS) 0x80000016L)
+#endif
+
+#ifndef STATUS_EXTRANEOUS_INFORMATION
+# define STATUS_EXTRANEOUS_INFORMATION ((NTSTATUS) 0x80000017L)
+#endif
+
+#ifndef STATUS_RXACT_COMMIT_NECESSARY
+# define STATUS_RXACT_COMMIT_NECESSARY ((NTSTATUS) 0x80000018L)
+#endif
+
+#ifndef STATUS_NO_MORE_ENTRIES
+# define STATUS_NO_MORE_ENTRIES ((NTSTATUS) 0x8000001AL)
+#endif
+
+#ifndef STATUS_FILEMARK_DETECTED
+# define STATUS_FILEMARK_DETECTED ((NTSTATUS) 0x8000001BL)
+#endif
+
+#ifndef STATUS_MEDIA_CHANGED
+# define STATUS_MEDIA_CHANGED ((NTSTATUS) 0x8000001CL)
+#endif
+
+#ifndef STATUS_BUS_RESET
+# define STATUS_BUS_RESET ((NTSTATUS) 0x8000001DL)
+#endif
+
+#ifndef STATUS_END_OF_MEDIA
+# define STATUS_END_OF_MEDIA ((NTSTATUS) 0x8000001EL)
+#endif
+
+#ifndef STATUS_BEGINNING_OF_MEDIA
+# define STATUS_BEGINNING_OF_MEDIA ((NTSTATUS) 0x8000001FL)
+#endif
+
+#ifndef STATUS_MEDIA_CHECK
+# define STATUS_MEDIA_CHECK ((NTSTATUS) 0x80000020L)
+#endif
+
+#ifndef STATUS_SETMARK_DETECTED
+# define STATUS_SETMARK_DETECTED ((NTSTATUS) 0x80000021L)
+#endif
+
+#ifndef STATUS_NO_DATA_DETECTED
+# define STATUS_NO_DATA_DETECTED ((NTSTATUS) 0x80000022L)
+#endif
+
+#ifndef STATUS_REDIRECTOR_HAS_OPEN_HANDLES
+# define STATUS_REDIRECTOR_HAS_OPEN_HANDLES ((NTSTATUS) 0x80000023L)
+#endif
+
+#ifndef STATUS_SERVER_HAS_OPEN_HANDLES
+# define STATUS_SERVER_HAS_OPEN_HANDLES ((NTSTATUS) 0x80000024L)
+#endif
+
+#ifndef STATUS_ALREADY_DISCONNECTED
+# define STATUS_ALREADY_DISCONNECTED ((NTSTATUS) 0x80000025L)
+#endif
+
+#ifndef STATUS_LONGJUMP
+# define STATUS_LONGJUMP ((NTSTATUS) 0x80000026L)
+#endif
+
+#ifndef STATUS_CLEANER_CARTRIDGE_INSTALLED
+# define STATUS_CLEANER_CARTRIDGE_INSTALLED ((NTSTATUS) 0x80000027L)
+#endif
+
+#ifndef STATUS_PLUGPLAY_QUERY_VETOED
+# define STATUS_PLUGPLAY_QUERY_VETOED ((NTSTATUS) 0x80000028L)
+#endif
+
+#ifndef STATUS_UNWIND_CONSOLIDATE
+# define STATUS_UNWIND_CONSOLIDATE ((NTSTATUS) 0x80000029L)
+#endif
+
+#ifndef STATUS_REGISTRY_HIVE_RECOVERED
+# define STATUS_REGISTRY_HIVE_RECOVERED ((NTSTATUS) 0x8000002AL)
+#endif
+
+#ifndef STATUS_DLL_MIGHT_BE_INSECURE
+# define STATUS_DLL_MIGHT_BE_INSECURE ((NTSTATUS) 0x8000002BL)
+#endif
+
+#ifndef STATUS_DLL_MIGHT_BE_INCOMPATIBLE
+# define STATUS_DLL_MIGHT_BE_INCOMPATIBLE ((NTSTATUS) 0x8000002CL)
+#endif
+
+#ifndef STATUS_STOPPED_ON_SYMLINK
+# define STATUS_STOPPED_ON_SYMLINK ((NTSTATUS) 0x8000002DL)
+#endif
+
+#ifndef STATUS_CANNOT_GRANT_REQUESTED_OPLOCK
+# define STATUS_CANNOT_GRANT_REQUESTED_OPLOCK ((NTSTATUS) 0x8000002EL)
+#endif
+
+#ifndef STATUS_NO_ACE_CONDITION
+# define STATUS_NO_ACE_CONDITION ((NTSTATUS) 0x8000002FL)
+#endif
+
+#ifndef STATUS_UNSUCCESSFUL
+# define STATUS_UNSUCCESSFUL ((NTSTATUS) 0xC0000001L)
+#endif
+
+#ifndef STATUS_NOT_IMPLEMENTED
+# define STATUS_NOT_IMPLEMENTED ((NTSTATUS) 0xC0000002L)
+#endif
+
+#ifndef STATUS_INVALID_INFO_CLASS
+# define STATUS_INVALID_INFO_CLASS ((NTSTATUS) 0xC0000003L)
+#endif
+
+#ifndef STATUS_INFO_LENGTH_MISMATCH
+# define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xC0000004L)
+#endif
+
+#ifndef STATUS_ACCESS_VIOLATION
+# define STATUS_ACCESS_VIOLATION ((NTSTATUS) 0xC0000005L)
+#endif
+
+#ifndef STATUS_IN_PAGE_ERROR
+# define STATUS_IN_PAGE_ERROR ((NTSTATUS) 0xC0000006L)
+#endif
+
+#ifndef STATUS_PAGEFILE_QUOTA
+# define STATUS_PAGEFILE_QUOTA ((NTSTATUS) 0xC0000007L)
+#endif
+
+#ifndef STATUS_INVALID_HANDLE
+# define STATUS_INVALID_HANDLE ((NTSTATUS) 0xC0000008L)
+#endif
+
+#ifndef STATUS_BAD_INITIAL_STACK
+# define STATUS_BAD_INITIAL_STACK ((NTSTATUS) 0xC0000009L)
+#endif
+
+#ifndef STATUS_BAD_INITIAL_PC
+# define STATUS_BAD_INITIAL_PC ((NTSTATUS) 0xC000000AL)
+#endif
+
+#ifndef STATUS_INVALID_CID
+# define STATUS_INVALID_CID ((NTSTATUS) 0xC000000BL)
+#endif
+
+#ifndef STATUS_TIMER_NOT_CANCELED
+# define STATUS_TIMER_NOT_CANCELED ((NTSTATUS) 0xC000000CL)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER
+# define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xC000000DL)
+#endif
+
+#ifndef STATUS_NO_SUCH_DEVICE
+# define STATUS_NO_SUCH_DEVICE ((NTSTATUS) 0xC000000EL)
+#endif
+
+#ifndef STATUS_NO_SUCH_FILE
+# define STATUS_NO_SUCH_FILE ((NTSTATUS) 0xC000000FL)
+#endif
+
+#ifndef STATUS_INVALID_DEVICE_REQUEST
+# define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS) 0xC0000010L)
+#endif
+
+#ifndef STATUS_END_OF_FILE
+# define STATUS_END_OF_FILE ((NTSTATUS) 0xC0000011L)
+#endif
+
+#ifndef STATUS_WRONG_VOLUME
+# define STATUS_WRONG_VOLUME ((NTSTATUS) 0xC0000012L)
+#endif
+
+#ifndef STATUS_NO_MEDIA_IN_DEVICE
+# define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS) 0xC0000013L)
+#endif
+
+#ifndef STATUS_UNRECOGNIZED_MEDIA
+# define STATUS_UNRECOGNIZED_MEDIA ((NTSTATUS) 0xC0000014L)
+#endif
+
+#ifndef STATUS_NONEXISTENT_SECTOR
+# define STATUS_NONEXISTENT_SECTOR ((NTSTATUS) 0xC0000015L)
+#endif
+
+#ifndef STATUS_MORE_PROCESSING_REQUIRED
+# define STATUS_MORE_PROCESSING_REQUIRED ((NTSTATUS) 0xC0000016L)
+#endif
+
+#ifndef STATUS_NO_MEMORY
+# define STATUS_NO_MEMORY ((NTSTATUS) 0xC0000017L)
+#endif
+
+#ifndef STATUS_CONFLICTING_ADDRESSES
+# define STATUS_CONFLICTING_ADDRESSES ((NTSTATUS) 0xC0000018L)
+#endif
+
+#ifndef STATUS_NOT_MAPPED_VIEW
+# define STATUS_NOT_MAPPED_VIEW ((NTSTATUS) 0xC0000019L)
+#endif
+
+#ifndef STATUS_UNABLE_TO_FREE_VM
+# define STATUS_UNABLE_TO_FREE_VM ((NTSTATUS) 0xC000001AL)
+#endif
+
+#ifndef STATUS_UNABLE_TO_DELETE_SECTION
+# define STATUS_UNABLE_TO_DELETE_SECTION ((NTSTATUS) 0xC000001BL)
+#endif
+
+#ifndef STATUS_INVALID_SYSTEM_SERVICE
+# define STATUS_INVALID_SYSTEM_SERVICE ((NTSTATUS) 0xC000001CL)
+#endif
+
+#ifndef STATUS_ILLEGAL_INSTRUCTION
+# define STATUS_ILLEGAL_INSTRUCTION ((NTSTATUS) 0xC000001DL)
+#endif
+
+#ifndef STATUS_INVALID_LOCK_SEQUENCE
+# define STATUS_INVALID_LOCK_SEQUENCE ((NTSTATUS) 0xC000001EL)
+#endif
+
+#ifndef STATUS_INVALID_VIEW_SIZE
+# define STATUS_INVALID_VIEW_SIZE ((NTSTATUS) 0xC000001FL)
+#endif
+
+#ifndef STATUS_INVALID_FILE_FOR_SECTION
+# define STATUS_INVALID_FILE_FOR_SECTION ((NTSTATUS) 0xC0000020L)
+#endif
+
+#ifndef STATUS_ALREADY_COMMITTED
+# define STATUS_ALREADY_COMMITTED ((NTSTATUS) 0xC0000021L)
+#endif
+
+#ifndef STATUS_ACCESS_DENIED
+# define STATUS_ACCESS_DENIED ((NTSTATUS) 0xC0000022L)
+#endif
+
+#ifndef STATUS_BUFFER_TOO_SMALL
+# define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xC0000023L)
+#endif
+
+#ifndef STATUS_OBJECT_TYPE_MISMATCH
+# define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS) 0xC0000024L)
+#endif
+
+#ifndef STATUS_NONCONTINUABLE_EXCEPTION
+# define STATUS_NONCONTINUABLE_EXCEPTION ((NTSTATUS) 0xC0000025L)
+#endif
+
+#ifndef STATUS_INVALID_DISPOSITION
+# define STATUS_INVALID_DISPOSITION ((NTSTATUS) 0xC0000026L)
+#endif
+
+#ifndef STATUS_UNWIND
+# define STATUS_UNWIND ((NTSTATUS) 0xC0000027L)
+#endif
+
+#ifndef STATUS_BAD_STACK
+# define STATUS_BAD_STACK ((NTSTATUS) 0xC0000028L)
+#endif
+
+#ifndef STATUS_INVALID_UNWIND_TARGET
+# define STATUS_INVALID_UNWIND_TARGET ((NTSTATUS) 0xC0000029L)
+#endif
+
+#ifndef STATUS_NOT_LOCKED
+# define STATUS_NOT_LOCKED ((NTSTATUS) 0xC000002AL)
+#endif
+
+#ifndef STATUS_PARITY_ERROR
+# define STATUS_PARITY_ERROR ((NTSTATUS) 0xC000002BL)
+#endif
+
+#ifndef STATUS_UNABLE_TO_DECOMMIT_VM
+# define STATUS_UNABLE_TO_DECOMMIT_VM ((NTSTATUS) 0xC000002CL)
+#endif
+
+#ifndef STATUS_NOT_COMMITTED
+# define STATUS_NOT_COMMITTED ((NTSTATUS) 0xC000002DL)
+#endif
+
+#ifndef STATUS_INVALID_PORT_ATTRIBUTES
+# define STATUS_INVALID_PORT_ATTRIBUTES ((NTSTATUS) 0xC000002EL)
+#endif
+
+#ifndef STATUS_PORT_MESSAGE_TOO_LONG
+# define STATUS_PORT_MESSAGE_TOO_LONG ((NTSTATUS) 0xC000002FL)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_MIX
+# define STATUS_INVALID_PARAMETER_MIX ((NTSTATUS) 0xC0000030L)
+#endif
+
+#ifndef STATUS_INVALID_QUOTA_LOWER
+# define STATUS_INVALID_QUOTA_LOWER ((NTSTATUS) 0xC0000031L)
+#endif
+
+#ifndef STATUS_DISK_CORRUPT_ERROR
+# define STATUS_DISK_CORRUPT_ERROR ((NTSTATUS) 0xC0000032L)
+#endif
+
+#ifndef STATUS_OBJECT_NAME_INVALID
+# define STATUS_OBJECT_NAME_INVALID ((NTSTATUS) 0xC0000033L)
+#endif
+
+#ifndef STATUS_OBJECT_NAME_NOT_FOUND
+# define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS) 0xC0000034L)
+#endif
+
+#ifndef STATUS_OBJECT_NAME_COLLISION
+# define STATUS_OBJECT_NAME_COLLISION ((NTSTATUS) 0xC0000035L)
+#endif
+
+#ifndef STATUS_PORT_DISCONNECTED
+# define STATUS_PORT_DISCONNECTED ((NTSTATUS) 0xC0000037L)
+#endif
+
+#ifndef STATUS_DEVICE_ALREADY_ATTACHED
+# define STATUS_DEVICE_ALREADY_ATTACHED ((NTSTATUS) 0xC0000038L)
+#endif
+
+#ifndef STATUS_OBJECT_PATH_INVALID
+# define STATUS_OBJECT_PATH_INVALID ((NTSTATUS) 0xC0000039L)
+#endif
+
+#ifndef STATUS_OBJECT_PATH_NOT_FOUND
+# define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS) 0xC000003AL)
+#endif
+
+#ifndef STATUS_OBJECT_PATH_SYNTAX_BAD
+# define STATUS_OBJECT_PATH_SYNTAX_BAD ((NTSTATUS) 0xC000003BL)
+#endif
+
+#ifndef STATUS_DATA_OVERRUN
+# define STATUS_DATA_OVERRUN ((NTSTATUS) 0xC000003CL)
+#endif
+
+#ifndef STATUS_DATA_LATE_ERROR
+# define STATUS_DATA_LATE_ERROR ((NTSTATUS) 0xC000003DL)
+#endif
+
+#ifndef STATUS_DATA_ERROR
+# define STATUS_DATA_ERROR ((NTSTATUS) 0xC000003EL)
+#endif
+
+#ifndef STATUS_CRC_ERROR
+# define STATUS_CRC_ERROR ((NTSTATUS) 0xC000003FL)
+#endif
+
+#ifndef STATUS_SECTION_TOO_BIG
+# define STATUS_SECTION_TOO_BIG ((NTSTATUS) 0xC0000040L)
+#endif
+
+#ifndef STATUS_PORT_CONNECTION_REFUSED
+# define STATUS_PORT_CONNECTION_REFUSED ((NTSTATUS) 0xC0000041L)
+#endif
+
+#ifndef STATUS_INVALID_PORT_HANDLE
+# define STATUS_INVALID_PORT_HANDLE ((NTSTATUS) 0xC0000042L)
+#endif
+
+#ifndef STATUS_SHARING_VIOLATION
+# define STATUS_SHARING_VIOLATION ((NTSTATUS) 0xC0000043L)
+#endif
+
+#ifndef STATUS_QUOTA_EXCEEDED
+# define STATUS_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000044L)
+#endif
+
+#ifndef STATUS_INVALID_PAGE_PROTECTION
+# define STATUS_INVALID_PAGE_PROTECTION ((NTSTATUS) 0xC0000045L)
+#endif
+
+#ifndef STATUS_MUTANT_NOT_OWNED
+# define STATUS_MUTANT_NOT_OWNED ((NTSTATUS) 0xC0000046L)
+#endif
+
+#ifndef STATUS_SEMAPHORE_LIMIT_EXCEEDED
+# define STATUS_SEMAPHORE_LIMIT_EXCEEDED ((NTSTATUS) 0xC0000047L)
+#endif
+
+#ifndef STATUS_PORT_ALREADY_SET
+# define STATUS_PORT_ALREADY_SET ((NTSTATUS) 0xC0000048L)
+#endif
+
+#ifndef STATUS_SECTION_NOT_IMAGE
+# define STATUS_SECTION_NOT_IMAGE ((NTSTATUS) 0xC0000049L)
+#endif
+
+#ifndef STATUS_SUSPEND_COUNT_EXCEEDED
+# define STATUS_SUSPEND_COUNT_EXCEEDED ((NTSTATUS) 0xC000004AL)
+#endif
+
+#ifndef STATUS_THREAD_IS_TERMINATING
+# define STATUS_THREAD_IS_TERMINATING ((NTSTATUS) 0xC000004BL)
+#endif
+
+#ifndef STATUS_BAD_WORKING_SET_LIMIT
+# define STATUS_BAD_WORKING_SET_LIMIT ((NTSTATUS) 0xC000004CL)
+#endif
+
+#ifndef STATUS_INCOMPATIBLE_FILE_MAP
+# define STATUS_INCOMPATIBLE_FILE_MAP ((NTSTATUS) 0xC000004DL)
+#endif
+
+#ifndef STATUS_SECTION_PROTECTION
+# define STATUS_SECTION_PROTECTION ((NTSTATUS) 0xC000004EL)
+#endif
+
+#ifndef STATUS_EAS_NOT_SUPPORTED
+# define STATUS_EAS_NOT_SUPPORTED ((NTSTATUS) 0xC000004FL)
+#endif
+
+#ifndef STATUS_EA_TOO_LARGE
+# define STATUS_EA_TOO_LARGE ((NTSTATUS) 0xC0000050L)
+#endif
+
+#ifndef STATUS_NONEXISTENT_EA_ENTRY
+# define STATUS_NONEXISTENT_EA_ENTRY ((NTSTATUS) 0xC0000051L)
+#endif
+
+#ifndef STATUS_NO_EAS_ON_FILE
+# define STATUS_NO_EAS_ON_FILE ((NTSTATUS) 0xC0000052L)
+#endif
+
+#ifndef STATUS_EA_CORRUPT_ERROR
+# define STATUS_EA_CORRUPT_ERROR ((NTSTATUS) 0xC0000053L)
+#endif
+
+#ifndef STATUS_FILE_LOCK_CONFLICT
+# define STATUS_FILE_LOCK_CONFLICT ((NTSTATUS) 0xC0000054L)
+#endif
+
+#ifndef STATUS_LOCK_NOT_GRANTED
+# define STATUS_LOCK_NOT_GRANTED ((NTSTATUS) 0xC0000055L)
+#endif
+
+#ifndef STATUS_DELETE_PENDING
+# define STATUS_DELETE_PENDING ((NTSTATUS) 0xC0000056L)
+#endif
+
+#ifndef STATUS_CTL_FILE_NOT_SUPPORTED
+# define STATUS_CTL_FILE_NOT_SUPPORTED ((NTSTATUS) 0xC0000057L)
+#endif
+
+#ifndef STATUS_UNKNOWN_REVISION
+# define STATUS_UNKNOWN_REVISION ((NTSTATUS) 0xC0000058L)
+#endif
+
+#ifndef STATUS_REVISION_MISMATCH
+# define STATUS_REVISION_MISMATCH ((NTSTATUS) 0xC0000059L)
+#endif
+
+#ifndef STATUS_INVALID_OWNER
+# define STATUS_INVALID_OWNER ((NTSTATUS) 0xC000005AL)
+#endif
+
+#ifndef STATUS_INVALID_PRIMARY_GROUP
+# define STATUS_INVALID_PRIMARY_GROUP ((NTSTATUS) 0xC000005BL)
+#endif
+
+#ifndef STATUS_NO_IMPERSONATION_TOKEN
+# define STATUS_NO_IMPERSONATION_TOKEN ((NTSTATUS) 0xC000005CL)
+#endif
+
+#ifndef STATUS_CANT_DISABLE_MANDATORY
+# define STATUS_CANT_DISABLE_MANDATORY ((NTSTATUS) 0xC000005DL)
+#endif
+
+#ifndef STATUS_NO_LOGON_SERVERS
+# define STATUS_NO_LOGON_SERVERS ((NTSTATUS) 0xC000005EL)
+#endif
+
+#ifndef STATUS_NO_SUCH_LOGON_SESSION
+# define STATUS_NO_SUCH_LOGON_SESSION ((NTSTATUS) 0xC000005FL)
+#endif
+
+#ifndef STATUS_NO_SUCH_PRIVILEGE
+# define STATUS_NO_SUCH_PRIVILEGE ((NTSTATUS) 0xC0000060L)
+#endif
+
+#ifndef STATUS_PRIVILEGE_NOT_HELD
+# define STATUS_PRIVILEGE_NOT_HELD ((NTSTATUS) 0xC0000061L)
+#endif
+
+#ifndef STATUS_INVALID_ACCOUNT_NAME
+# define STATUS_INVALID_ACCOUNT_NAME ((NTSTATUS) 0xC0000062L)
+#endif
+
+#ifndef STATUS_USER_EXISTS
+# define STATUS_USER_EXISTS ((NTSTATUS) 0xC0000063L)
+#endif
+
+#ifndef STATUS_NO_SUCH_USER
+# define STATUS_NO_SUCH_USER ((NTSTATUS) 0xC0000064L)
+#endif
+
+#ifndef STATUS_GROUP_EXISTS
+# define STATUS_GROUP_EXISTS ((NTSTATUS) 0xC0000065L)
+#endif
+
+#ifndef STATUS_NO_SUCH_GROUP
+# define STATUS_NO_SUCH_GROUP ((NTSTATUS) 0xC0000066L)
+#endif
+
+#ifndef STATUS_MEMBER_IN_GROUP
+# define STATUS_MEMBER_IN_GROUP ((NTSTATUS) 0xC0000067L)
+#endif
+
+#ifndef STATUS_MEMBER_NOT_IN_GROUP
+# define STATUS_MEMBER_NOT_IN_GROUP ((NTSTATUS) 0xC0000068L)
+#endif
+
+#ifndef STATUS_LAST_ADMIN
+# define STATUS_LAST_ADMIN ((NTSTATUS) 0xC0000069L)
+#endif
+
+#ifndef STATUS_WRONG_PASSWORD
+# define STATUS_WRONG_PASSWORD ((NTSTATUS) 0xC000006AL)
+#endif
+
+#ifndef STATUS_ILL_FORMED_PASSWORD
+# define STATUS_ILL_FORMED_PASSWORD ((NTSTATUS) 0xC000006BL)
+#endif
+
+#ifndef STATUS_PASSWORD_RESTRICTION
+# define STATUS_PASSWORD_RESTRICTION ((NTSTATUS) 0xC000006CL)
+#endif
+
+#ifndef STATUS_LOGON_FAILURE
+# define STATUS_LOGON_FAILURE ((NTSTATUS) 0xC000006DL)
+#endif
+
+#ifndef STATUS_ACCOUNT_RESTRICTION
+# define STATUS_ACCOUNT_RESTRICTION ((NTSTATUS) 0xC000006EL)
+#endif
+
+#ifndef STATUS_INVALID_LOGON_HOURS
+# define STATUS_INVALID_LOGON_HOURS ((NTSTATUS) 0xC000006FL)
+#endif
+
+#ifndef STATUS_INVALID_WORKSTATION
+# define STATUS_INVALID_WORKSTATION ((NTSTATUS) 0xC0000070L)
+#endif
+
+#ifndef STATUS_PASSWORD_EXPIRED
+# define STATUS_PASSWORD_EXPIRED ((NTSTATUS) 0xC0000071L)
+#endif
+
+#ifndef STATUS_ACCOUNT_DISABLED
+# define STATUS_ACCOUNT_DISABLED ((NTSTATUS) 0xC0000072L)
+#endif
+
+#ifndef STATUS_NONE_MAPPED
+# define STATUS_NONE_MAPPED ((NTSTATUS) 0xC0000073L)
+#endif
+
+#ifndef STATUS_TOO_MANY_LUIDS_REQUESTED
+# define STATUS_TOO_MANY_LUIDS_REQUESTED ((NTSTATUS) 0xC0000074L)
+#endif
+
+#ifndef STATUS_LUIDS_EXHAUSTED
+# define STATUS_LUIDS_EXHAUSTED ((NTSTATUS) 0xC0000075L)
+#endif
+
+#ifndef STATUS_INVALID_SUB_AUTHORITY
+# define STATUS_INVALID_SUB_AUTHORITY ((NTSTATUS) 0xC0000076L)
+#endif
+
+#ifndef STATUS_INVALID_ACL
+# define STATUS_INVALID_ACL ((NTSTATUS) 0xC0000077L)
+#endif
+
+#ifndef STATUS_INVALID_SID
+# define STATUS_INVALID_SID ((NTSTATUS) 0xC0000078L)
+#endif
+
+#ifndef STATUS_INVALID_SECURITY_DESCR
+# define STATUS_INVALID_SECURITY_DESCR ((NTSTATUS) 0xC0000079L)
+#endif
+
+#ifndef STATUS_PROCEDURE_NOT_FOUND
+# define STATUS_PROCEDURE_NOT_FOUND ((NTSTATUS) 0xC000007AL)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_FORMAT
+# define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS) 0xC000007BL)
+#endif
+
+#ifndef STATUS_NO_TOKEN
+# define STATUS_NO_TOKEN ((NTSTATUS) 0xC000007CL)
+#endif
+
+#ifndef STATUS_BAD_INHERITANCE_ACL
+# define STATUS_BAD_INHERITANCE_ACL ((NTSTATUS) 0xC000007DL)
+#endif
+
+#ifndef STATUS_RANGE_NOT_LOCKED
+# define STATUS_RANGE_NOT_LOCKED ((NTSTATUS) 0xC000007EL)
+#endif
+
+#ifndef STATUS_DISK_FULL
+# define STATUS_DISK_FULL ((NTSTATUS) 0xC000007FL)
+#endif
+
+#ifndef STATUS_SERVER_DISABLED
+# define STATUS_SERVER_DISABLED ((NTSTATUS) 0xC0000080L)
+#endif
+
+#ifndef STATUS_SERVER_NOT_DISABLED
+# define STATUS_SERVER_NOT_DISABLED ((NTSTATUS) 0xC0000081L)
+#endif
+
+#ifndef STATUS_TOO_MANY_GUIDS_REQUESTED
+# define STATUS_TOO_MANY_GUIDS_REQUESTED ((NTSTATUS) 0xC0000082L)
+#endif
+
+#ifndef STATUS_GUIDS_EXHAUSTED
+# define STATUS_GUIDS_EXHAUSTED ((NTSTATUS) 0xC0000083L)
+#endif
+
+#ifndef STATUS_INVALID_ID_AUTHORITY
+# define STATUS_INVALID_ID_AUTHORITY ((NTSTATUS) 0xC0000084L)
+#endif
+
+#ifndef STATUS_AGENTS_EXHAUSTED
+# define STATUS_AGENTS_EXHAUSTED ((NTSTATUS) 0xC0000085L)
+#endif
+
+#ifndef STATUS_INVALID_VOLUME_LABEL
+# define STATUS_INVALID_VOLUME_LABEL ((NTSTATUS) 0xC0000086L)
+#endif
+
+#ifndef STATUS_SECTION_NOT_EXTENDED
+# define STATUS_SECTION_NOT_EXTENDED ((NTSTATUS) 0xC0000087L)
+#endif
+
+#ifndef STATUS_NOT_MAPPED_DATA
+# define STATUS_NOT_MAPPED_DATA ((NTSTATUS) 0xC0000088L)
+#endif
+
+#ifndef STATUS_RESOURCE_DATA_NOT_FOUND
+# define STATUS_RESOURCE_DATA_NOT_FOUND ((NTSTATUS) 0xC0000089L)
+#endif
+
+#ifndef STATUS_RESOURCE_TYPE_NOT_FOUND
+# define STATUS_RESOURCE_TYPE_NOT_FOUND ((NTSTATUS) 0xC000008AL)
+#endif
+
+#ifndef STATUS_RESOURCE_NAME_NOT_FOUND
+# define STATUS_RESOURCE_NAME_NOT_FOUND ((NTSTATUS) 0xC000008BL)
+#endif
+
+#ifndef STATUS_ARRAY_BOUNDS_EXCEEDED
+# define STATUS_ARRAY_BOUNDS_EXCEEDED ((NTSTATUS) 0xC000008CL)
+#endif
+
+#ifndef STATUS_FLOAT_DENORMAL_OPERAND
+# define STATUS_FLOAT_DENORMAL_OPERAND ((NTSTATUS) 0xC000008DL)
+#endif
+
+#ifndef STATUS_FLOAT_DIVIDE_BY_ZERO
+# define STATUS_FLOAT_DIVIDE_BY_ZERO ((NTSTATUS) 0xC000008EL)
+#endif
+
+#ifndef STATUS_FLOAT_INEXACT_RESULT
+# define STATUS_FLOAT_INEXACT_RESULT ((NTSTATUS) 0xC000008FL)
+#endif
+
+#ifndef STATUS_FLOAT_INVALID_OPERATION
+# define STATUS_FLOAT_INVALID_OPERATION ((NTSTATUS) 0xC0000090L)
+#endif
+
+#ifndef STATUS_FLOAT_OVERFLOW
+# define STATUS_FLOAT_OVERFLOW ((NTSTATUS) 0xC0000091L)
+#endif
+
+#ifndef STATUS_FLOAT_STACK_CHECK
+# define STATUS_FLOAT_STACK_CHECK ((NTSTATUS) 0xC0000092L)
+#endif
+
+#ifndef STATUS_FLOAT_UNDERFLOW
+# define STATUS_FLOAT_UNDERFLOW ((NTSTATUS) 0xC0000093L)
+#endif
+
+#ifndef STATUS_INTEGER_DIVIDE_BY_ZERO
+# define STATUS_INTEGER_DIVIDE_BY_ZERO ((NTSTATUS) 0xC0000094L)
+#endif
+
+#ifndef STATUS_INTEGER_OVERFLOW
+# define STATUS_INTEGER_OVERFLOW ((NTSTATUS) 0xC0000095L)
+#endif
+
+#ifndef STATUS_PRIVILEGED_INSTRUCTION
+# define STATUS_PRIVILEGED_INSTRUCTION ((NTSTATUS) 0xC0000096L)
+#endif
+
+#ifndef STATUS_TOO_MANY_PAGING_FILES
+# define STATUS_TOO_MANY_PAGING_FILES ((NTSTATUS) 0xC0000097L)
+#endif
+
+#ifndef STATUS_FILE_INVALID
+# define STATUS_FILE_INVALID ((NTSTATUS) 0xC0000098L)
+#endif
+
+#ifndef STATUS_ALLOTTED_SPACE_EXCEEDED
+# define STATUS_ALLOTTED_SPACE_EXCEEDED ((NTSTATUS) 0xC0000099L)
+#endif
+
+#ifndef STATUS_INSUFFICIENT_RESOURCES
+# define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS) 0xC000009AL)
+#endif
+
+#ifndef STATUS_DFS_EXIT_PATH_FOUND
+# define STATUS_DFS_EXIT_PATH_FOUND ((NTSTATUS) 0xC000009BL)
+#endif
+
+#ifndef STATUS_DEVICE_DATA_ERROR
+# define STATUS_DEVICE_DATA_ERROR ((NTSTATUS) 0xC000009CL)
+#endif
+
+#ifndef STATUS_DEVICE_NOT_CONNECTED
+# define STATUS_DEVICE_NOT_CONNECTED ((NTSTATUS) 0xC000009DL)
+#endif
+
+#ifndef STATUS_DEVICE_POWER_FAILURE
+# define STATUS_DEVICE_POWER_FAILURE ((NTSTATUS) 0xC000009EL)
+#endif
+
+#ifndef STATUS_FREE_VM_NOT_AT_BASE
+# define STATUS_FREE_VM_NOT_AT_BASE ((NTSTATUS) 0xC000009FL)
+#endif
+
+#ifndef STATUS_MEMORY_NOT_ALLOCATED
+# define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS) 0xC00000A0L)
+#endif
+
+#ifndef STATUS_WORKING_SET_QUOTA
+# define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xC00000A1L)
+#endif
+
+#ifndef STATUS_MEDIA_WRITE_PROTECTED
+# define STATUS_MEDIA_WRITE_PROTECTED ((NTSTATUS) 0xC00000A2L)
+#endif
+
+#ifndef STATUS_DEVICE_NOT_READY
+# define STATUS_DEVICE_NOT_READY ((NTSTATUS) 0xC00000A3L)
+#endif
+
+#ifndef STATUS_INVALID_GROUP_ATTRIBUTES
+# define STATUS_INVALID_GROUP_ATTRIBUTES ((NTSTATUS) 0xC00000A4L)
+#endif
+
+#ifndef STATUS_BAD_IMPERSONATION_LEVEL
+# define STATUS_BAD_IMPERSONATION_LEVEL ((NTSTATUS) 0xC00000A5L)
+#endif
+
+#ifndef STATUS_CANT_OPEN_ANONYMOUS
+# define STATUS_CANT_OPEN_ANONYMOUS ((NTSTATUS) 0xC00000A6L)
+#endif
+
+#ifndef STATUS_BAD_VALIDATION_CLASS
+# define STATUS_BAD_VALIDATION_CLASS ((NTSTATUS) 0xC00000A7L)
+#endif
+
+#ifndef STATUS_BAD_TOKEN_TYPE
+# define STATUS_BAD_TOKEN_TYPE ((NTSTATUS) 0xC00000A8L)
+#endif
+
+#ifndef STATUS_BAD_MASTER_BOOT_RECORD
+# define STATUS_BAD_MASTER_BOOT_RECORD ((NTSTATUS) 0xC00000A9L)
+#endif
+
+#ifndef STATUS_INSTRUCTION_MISALIGNMENT
+# define STATUS_INSTRUCTION_MISALIGNMENT ((NTSTATUS) 0xC00000AAL)
+#endif
+
+#ifndef STATUS_INSTANCE_NOT_AVAILABLE
+# define STATUS_INSTANCE_NOT_AVAILABLE ((NTSTATUS) 0xC00000ABL)
+#endif
+
+#ifndef STATUS_PIPE_NOT_AVAILABLE
+# define STATUS_PIPE_NOT_AVAILABLE ((NTSTATUS) 0xC00000ACL)
+#endif
+
+#ifndef STATUS_INVALID_PIPE_STATE
+# define STATUS_INVALID_PIPE_STATE ((NTSTATUS) 0xC00000ADL)
+#endif
+
+#ifndef STATUS_PIPE_BUSY
+# define STATUS_PIPE_BUSY ((NTSTATUS) 0xC00000AEL)
+#endif
+
+#ifndef STATUS_ILLEGAL_FUNCTION
+# define STATUS_ILLEGAL_FUNCTION ((NTSTATUS) 0xC00000AFL)
+#endif
+
+#ifndef STATUS_PIPE_DISCONNECTED
+# define STATUS_PIPE_DISCONNECTED ((NTSTATUS) 0xC00000B0L)
+#endif
+
+#ifndef STATUS_PIPE_CLOSING
+# define STATUS_PIPE_CLOSING ((NTSTATUS) 0xC00000B1L)
+#endif
+
+#ifndef STATUS_PIPE_CONNECTED
+# define STATUS_PIPE_CONNECTED ((NTSTATUS) 0xC00000B2L)
+#endif
+
+#ifndef STATUS_PIPE_LISTENING
+# define STATUS_PIPE_LISTENING ((NTSTATUS) 0xC00000B3L)
+#endif
+
+#ifndef STATUS_INVALID_READ_MODE
+# define STATUS_INVALID_READ_MODE ((NTSTATUS) 0xC00000B4L)
+#endif
+
+#ifndef STATUS_IO_TIMEOUT
+# define STATUS_IO_TIMEOUT ((NTSTATUS) 0xC00000B5L)
+#endif
+
+#ifndef STATUS_FILE_FORCED_CLOSED
+# define STATUS_FILE_FORCED_CLOSED ((NTSTATUS) 0xC00000B6L)
+#endif
+
+#ifndef STATUS_PROFILING_NOT_STARTED
+# define STATUS_PROFILING_NOT_STARTED ((NTSTATUS) 0xC00000B7L)
+#endif
+
+#ifndef STATUS_PROFILING_NOT_STOPPED
+# define STATUS_PROFILING_NOT_STOPPED ((NTSTATUS) 0xC00000B8L)
+#endif
+
+#ifndef STATUS_COULD_NOT_INTERPRET
+# define STATUS_COULD_NOT_INTERPRET ((NTSTATUS) 0xC00000B9L)
+#endif
+
+#ifndef STATUS_FILE_IS_A_DIRECTORY
+# define STATUS_FILE_IS_A_DIRECTORY ((NTSTATUS) 0xC00000BAL)
+#endif
+
+#ifndef STATUS_NOT_SUPPORTED
+# define STATUS_NOT_SUPPORTED ((NTSTATUS) 0xC00000BBL)
+#endif
+
+#ifndef STATUS_REMOTE_NOT_LISTENING
+# define STATUS_REMOTE_NOT_LISTENING ((NTSTATUS) 0xC00000BCL)
+#endif
+
+#ifndef STATUS_DUPLICATE_NAME
+# define STATUS_DUPLICATE_NAME ((NTSTATUS) 0xC00000BDL)
+#endif
+
+#ifndef STATUS_BAD_NETWORK_PATH
+# define STATUS_BAD_NETWORK_PATH ((NTSTATUS) 0xC00000BEL)
+#endif
+
+#ifndef STATUS_NETWORK_BUSY
+# define STATUS_NETWORK_BUSY ((NTSTATUS) 0xC00000BFL)
+#endif
+
+#ifndef STATUS_DEVICE_DOES_NOT_EXIST
+# define STATUS_DEVICE_DOES_NOT_EXIST ((NTSTATUS) 0xC00000C0L)
+#endif
+
+#ifndef STATUS_TOO_MANY_COMMANDS
+# define STATUS_TOO_MANY_COMMANDS ((NTSTATUS) 0xC00000C1L)
+#endif
+
+#ifndef STATUS_ADAPTER_HARDWARE_ERROR
+# define STATUS_ADAPTER_HARDWARE_ERROR ((NTSTATUS) 0xC00000C2L)
+#endif
+
+#ifndef STATUS_INVALID_NETWORK_RESPONSE
+# define STATUS_INVALID_NETWORK_RESPONSE ((NTSTATUS) 0xC00000C3L)
+#endif
+
+#ifndef STATUS_UNEXPECTED_NETWORK_ERROR
+# define STATUS_UNEXPECTED_NETWORK_ERROR ((NTSTATUS) 0xC00000C4L)
+#endif
+
+#ifndef STATUS_BAD_REMOTE_ADAPTER
+# define STATUS_BAD_REMOTE_ADAPTER ((NTSTATUS) 0xC00000C5L)
+#endif
+
+#ifndef STATUS_PRINT_QUEUE_FULL
+# define STATUS_PRINT_QUEUE_FULL ((NTSTATUS) 0xC00000C6L)
+#endif
+
+#ifndef STATUS_NO_SPOOL_SPACE
+# define STATUS_NO_SPOOL_SPACE ((NTSTATUS) 0xC00000C7L)
+#endif
+
+#ifndef STATUS_PRINT_CANCELLED
+# define STATUS_PRINT_CANCELLED ((NTSTATUS) 0xC00000C8L)
+#endif
+
+#ifndef STATUS_NETWORK_NAME_DELETED
+# define STATUS_NETWORK_NAME_DELETED ((NTSTATUS) 0xC00000C9L)
+#endif
+
+#ifndef STATUS_NETWORK_ACCESS_DENIED
+# define STATUS_NETWORK_ACCESS_DENIED ((NTSTATUS) 0xC00000CAL)
+#endif
+
+#ifndef STATUS_BAD_DEVICE_TYPE
+# define STATUS_BAD_DEVICE_TYPE ((NTSTATUS) 0xC00000CBL)
+#endif
+
+#ifndef STATUS_BAD_NETWORK_NAME
+# define STATUS_BAD_NETWORK_NAME ((NTSTATUS) 0xC00000CCL)
+#endif
+
+#ifndef STATUS_TOO_MANY_NAMES
+# define STATUS_TOO_MANY_NAMES ((NTSTATUS) 0xC00000CDL)
+#endif
+
+#ifndef STATUS_TOO_MANY_SESSIONS
+# define STATUS_TOO_MANY_SESSIONS ((NTSTATUS) 0xC00000CEL)
+#endif
+
+#ifndef STATUS_SHARING_PAUSED
+# define STATUS_SHARING_PAUSED ((NTSTATUS) 0xC00000CFL)
+#endif
+
+#ifndef STATUS_REQUEST_NOT_ACCEPTED
+# define STATUS_REQUEST_NOT_ACCEPTED ((NTSTATUS) 0xC00000D0L)
+#endif
+
+#ifndef STATUS_REDIRECTOR_PAUSED
+# define STATUS_REDIRECTOR_PAUSED ((NTSTATUS) 0xC00000D1L)
+#endif
+
+#ifndef STATUS_NET_WRITE_FAULT
+# define STATUS_NET_WRITE_FAULT ((NTSTATUS) 0xC00000D2L)
+#endif
+
+#ifndef STATUS_PROFILING_AT_LIMIT
+# define STATUS_PROFILING_AT_LIMIT ((NTSTATUS) 0xC00000D3L)
+#endif
+
+#ifndef STATUS_NOT_SAME_DEVICE
+# define STATUS_NOT_SAME_DEVICE ((NTSTATUS) 0xC00000D4L)
+#endif
+
+#ifndef STATUS_FILE_RENAMED
+# define STATUS_FILE_RENAMED ((NTSTATUS) 0xC00000D5L)
+#endif
+
+#ifndef STATUS_VIRTUAL_CIRCUIT_CLOSED
+# define STATUS_VIRTUAL_CIRCUIT_CLOSED ((NTSTATUS) 0xC00000D6L)
+#endif
+
+#ifndef STATUS_NO_SECURITY_ON_OBJECT
+# define STATUS_NO_SECURITY_ON_OBJECT ((NTSTATUS) 0xC00000D7L)
+#endif
+
+#ifndef STATUS_CANT_WAIT
+# define STATUS_CANT_WAIT ((NTSTATUS) 0xC00000D8L)
+#endif
+
+#ifndef STATUS_PIPE_EMPTY
+# define STATUS_PIPE_EMPTY ((NTSTATUS) 0xC00000D9L)
+#endif
+
+#ifndef STATUS_CANT_ACCESS_DOMAIN_INFO
+# define STATUS_CANT_ACCESS_DOMAIN_INFO ((NTSTATUS) 0xC00000DAL)
+#endif
+
+#ifndef STATUS_CANT_TERMINATE_SELF
+# define STATUS_CANT_TERMINATE_SELF ((NTSTATUS) 0xC00000DBL)
+#endif
+
+#ifndef STATUS_INVALID_SERVER_STATE
+# define STATUS_INVALID_SERVER_STATE ((NTSTATUS) 0xC00000DCL)
+#endif
+
+#ifndef STATUS_INVALID_DOMAIN_STATE
+# define STATUS_INVALID_DOMAIN_STATE ((NTSTATUS) 0xC00000DDL)
+#endif
+
+#ifndef STATUS_INVALID_DOMAIN_ROLE
+# define STATUS_INVALID_DOMAIN_ROLE ((NTSTATUS) 0xC00000DEL)
+#endif
+
+#ifndef STATUS_NO_SUCH_DOMAIN
+# define STATUS_NO_SUCH_DOMAIN ((NTSTATUS) 0xC00000DFL)
+#endif
+
+#ifndef STATUS_DOMAIN_EXISTS
+# define STATUS_DOMAIN_EXISTS ((NTSTATUS) 0xC00000E0L)
+#endif
+
+#ifndef STATUS_DOMAIN_LIMIT_EXCEEDED
+# define STATUS_DOMAIN_LIMIT_EXCEEDED ((NTSTATUS) 0xC00000E1L)
+#endif
+
+#ifndef STATUS_OPLOCK_NOT_GRANTED
+# define STATUS_OPLOCK_NOT_GRANTED ((NTSTATUS) 0xC00000E2L)
+#endif
+
+#ifndef STATUS_INVALID_OPLOCK_PROTOCOL
+# define STATUS_INVALID_OPLOCK_PROTOCOL ((NTSTATUS) 0xC00000E3L)
+#endif
+
+#ifndef STATUS_INTERNAL_DB_CORRUPTION
+# define STATUS_INTERNAL_DB_CORRUPTION ((NTSTATUS) 0xC00000E4L)
+#endif
+
+#ifndef STATUS_INTERNAL_ERROR
+# define STATUS_INTERNAL_ERROR ((NTSTATUS) 0xC00000E5L)
+#endif
+
+#ifndef STATUS_GENERIC_NOT_MAPPED
+# define STATUS_GENERIC_NOT_MAPPED ((NTSTATUS) 0xC00000E6L)
+#endif
+
+#ifndef STATUS_BAD_DESCRIPTOR_FORMAT
+# define STATUS_BAD_DESCRIPTOR_FORMAT ((NTSTATUS) 0xC00000E7L)
+#endif
+
+#ifndef STATUS_INVALID_USER_BUFFER
+# define STATUS_INVALID_USER_BUFFER ((NTSTATUS) 0xC00000E8L)
+#endif
+
+#ifndef STATUS_UNEXPECTED_IO_ERROR
+# define STATUS_UNEXPECTED_IO_ERROR ((NTSTATUS) 0xC00000E9L)
+#endif
+
+#ifndef STATUS_UNEXPECTED_MM_CREATE_ERR
+# define STATUS_UNEXPECTED_MM_CREATE_ERR ((NTSTATUS) 0xC00000EAL)
+#endif
+
+#ifndef STATUS_UNEXPECTED_MM_MAP_ERROR
+# define STATUS_UNEXPECTED_MM_MAP_ERROR ((NTSTATUS) 0xC00000EBL)
+#endif
+
+#ifndef STATUS_UNEXPECTED_MM_EXTEND_ERR
+# define STATUS_UNEXPECTED_MM_EXTEND_ERR ((NTSTATUS) 0xC00000ECL)
+#endif
+
+#ifndef STATUS_NOT_LOGON_PROCESS
+# define STATUS_NOT_LOGON_PROCESS ((NTSTATUS) 0xC00000EDL)
+#endif
+
+#ifndef STATUS_LOGON_SESSION_EXISTS
+# define STATUS_LOGON_SESSION_EXISTS ((NTSTATUS) 0xC00000EEL)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_1
+# define STATUS_INVALID_PARAMETER_1 ((NTSTATUS) 0xC00000EFL)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_2
+# define STATUS_INVALID_PARAMETER_2 ((NTSTATUS) 0xC00000F0L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_3
+# define STATUS_INVALID_PARAMETER_3 ((NTSTATUS) 0xC00000F1L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_4
+# define STATUS_INVALID_PARAMETER_4 ((NTSTATUS) 0xC00000F2L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_5
+# define STATUS_INVALID_PARAMETER_5 ((NTSTATUS) 0xC00000F3L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_6
+# define STATUS_INVALID_PARAMETER_6 ((NTSTATUS) 0xC00000F4L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_7
+# define STATUS_INVALID_PARAMETER_7 ((NTSTATUS) 0xC00000F5L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_8
+# define STATUS_INVALID_PARAMETER_8 ((NTSTATUS) 0xC00000F6L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_9
+# define STATUS_INVALID_PARAMETER_9 ((NTSTATUS) 0xC00000F7L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_10
+# define STATUS_INVALID_PARAMETER_10 ((NTSTATUS) 0xC00000F8L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_11
+# define STATUS_INVALID_PARAMETER_11 ((NTSTATUS) 0xC00000F9L)
+#endif
+
+#ifndef STATUS_INVALID_PARAMETER_12
+# define STATUS_INVALID_PARAMETER_12 ((NTSTATUS) 0xC00000FAL)
+#endif
+
+#ifndef STATUS_REDIRECTOR_NOT_STARTED
+# define STATUS_REDIRECTOR_NOT_STARTED ((NTSTATUS) 0xC00000FBL)
+#endif
+
+#ifndef STATUS_REDIRECTOR_STARTED
+# define STATUS_REDIRECTOR_STARTED ((NTSTATUS) 0xC00000FCL)
+#endif
+
+#ifndef STATUS_STACK_OVERFLOW
+# define STATUS_STACK_OVERFLOW ((NTSTATUS) 0xC00000FDL)
+#endif
+
+#ifndef STATUS_NO_SUCH_PACKAGE
+# define STATUS_NO_SUCH_PACKAGE ((NTSTATUS) 0xC00000FEL)
+#endif
+
+#ifndef STATUS_BAD_FUNCTION_TABLE
+# define STATUS_BAD_FUNCTION_TABLE ((NTSTATUS) 0xC00000FFL)
+#endif
+
+#ifndef STATUS_VARIABLE_NOT_FOUND
+# define STATUS_VARIABLE_NOT_FOUND ((NTSTATUS) 0xC0000100L)
+#endif
+
+#ifndef STATUS_DIRECTORY_NOT_EMPTY
+# define STATUS_DIRECTORY_NOT_EMPTY ((NTSTATUS) 0xC0000101L)
+#endif
+
+#ifndef STATUS_FILE_CORRUPT_ERROR
+# define STATUS_FILE_CORRUPT_ERROR ((NTSTATUS) 0xC0000102L)
+#endif
+
+#ifndef STATUS_NOT_A_DIRECTORY
+# define STATUS_NOT_A_DIRECTORY ((NTSTATUS) 0xC0000103L)
+#endif
+
+#ifndef STATUS_BAD_LOGON_SESSION_STATE
+# define STATUS_BAD_LOGON_SESSION_STATE ((NTSTATUS) 0xC0000104L)
+#endif
+
+#ifndef STATUS_LOGON_SESSION_COLLISION
+# define STATUS_LOGON_SESSION_COLLISION ((NTSTATUS) 0xC0000105L)
+#endif
+
+#ifndef STATUS_NAME_TOO_LONG
+# define STATUS_NAME_TOO_LONG ((NTSTATUS) 0xC0000106L)
+#endif
+
+#ifndef STATUS_FILES_OPEN
+# define STATUS_FILES_OPEN ((NTSTATUS) 0xC0000107L)
+#endif
+
+#ifndef STATUS_CONNECTION_IN_USE
+# define STATUS_CONNECTION_IN_USE ((NTSTATUS) 0xC0000108L)
+#endif
+
+#ifndef STATUS_MESSAGE_NOT_FOUND
+# define STATUS_MESSAGE_NOT_FOUND ((NTSTATUS) 0xC0000109L)
+#endif
+
+#ifndef STATUS_PROCESS_IS_TERMINATING
+# define STATUS_PROCESS_IS_TERMINATING ((NTSTATUS) 0xC000010AL)
+#endif
+
+#ifndef STATUS_INVALID_LOGON_TYPE
+# define STATUS_INVALID_LOGON_TYPE ((NTSTATUS) 0xC000010BL)
+#endif
+
+#ifndef STATUS_NO_GUID_TRANSLATION
+# define STATUS_NO_GUID_TRANSLATION ((NTSTATUS) 0xC000010CL)
+#endif
+
+#ifndef STATUS_CANNOT_IMPERSONATE
+# define STATUS_CANNOT_IMPERSONATE ((NTSTATUS) 0xC000010DL)
+#endif
+
+#ifndef STATUS_IMAGE_ALREADY_LOADED
+# define STATUS_IMAGE_ALREADY_LOADED ((NTSTATUS) 0xC000010EL)
+#endif
+
+#ifndef STATUS_ABIOS_NOT_PRESENT
+# define STATUS_ABIOS_NOT_PRESENT ((NTSTATUS) 0xC000010FL)
+#endif
+
+#ifndef STATUS_ABIOS_LID_NOT_EXIST
+# define STATUS_ABIOS_LID_NOT_EXIST ((NTSTATUS) 0xC0000110L)
+#endif
+
+#ifndef STATUS_ABIOS_LID_ALREADY_OWNED
+# define STATUS_ABIOS_LID_ALREADY_OWNED ((NTSTATUS) 0xC0000111L)
+#endif
+
+#ifndef STATUS_ABIOS_NOT_LID_OWNER
+# define STATUS_ABIOS_NOT_LID_OWNER ((NTSTATUS) 0xC0000112L)
+#endif
+
+#ifndef STATUS_ABIOS_INVALID_COMMAND
+# define STATUS_ABIOS_INVALID_COMMAND ((NTSTATUS) 0xC0000113L)
+#endif
+
+#ifndef STATUS_ABIOS_INVALID_LID
+# define STATUS_ABIOS_INVALID_LID ((NTSTATUS) 0xC0000114L)
+#endif
+
+#ifndef STATUS_ABIOS_SELECTOR_NOT_AVAILABLE
+# define STATUS_ABIOS_SELECTOR_NOT_AVAILABLE ((NTSTATUS) 0xC0000115L)
+#endif
+
+#ifndef STATUS_ABIOS_INVALID_SELECTOR
+# define STATUS_ABIOS_INVALID_SELECTOR ((NTSTATUS) 0xC0000116L)
+#endif
+
+#ifndef STATUS_NO_LDT
+# define STATUS_NO_LDT ((NTSTATUS) 0xC0000117L)
+#endif
+
+#ifndef STATUS_INVALID_LDT_SIZE
+# define STATUS_INVALID_LDT_SIZE ((NTSTATUS) 0xC0000118L)
+#endif
+
+#ifndef STATUS_INVALID_LDT_OFFSET
+# define STATUS_INVALID_LDT_OFFSET ((NTSTATUS) 0xC0000119L)
+#endif
+
+#ifndef STATUS_INVALID_LDT_DESCRIPTOR
+# define STATUS_INVALID_LDT_DESCRIPTOR ((NTSTATUS) 0xC000011AL)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_NE_FORMAT
+# define STATUS_INVALID_IMAGE_NE_FORMAT ((NTSTATUS) 0xC000011BL)
+#endif
+
+#ifndef STATUS_RXACT_INVALID_STATE
+# define STATUS_RXACT_INVALID_STATE ((NTSTATUS) 0xC000011CL)
+#endif
+
+#ifndef STATUS_RXACT_COMMIT_FAILURE
+# define STATUS_RXACT_COMMIT_FAILURE ((NTSTATUS) 0xC000011DL)
+#endif
+
+#ifndef STATUS_MAPPED_FILE_SIZE_ZERO
+# define STATUS_MAPPED_FILE_SIZE_ZERO ((NTSTATUS) 0xC000011EL)
+#endif
+
+#ifndef STATUS_TOO_MANY_OPENED_FILES
+# define STATUS_TOO_MANY_OPENED_FILES ((NTSTATUS) 0xC000011FL)
+#endif
+
+#ifndef STATUS_CANCELLED
+# define STATUS_CANCELLED ((NTSTATUS) 0xC0000120L)
+#endif
+
+#ifndef STATUS_CANNOT_DELETE
+# define STATUS_CANNOT_DELETE ((NTSTATUS) 0xC0000121L)
+#endif
+
+#ifndef STATUS_INVALID_COMPUTER_NAME
+# define STATUS_INVALID_COMPUTER_NAME ((NTSTATUS) 0xC0000122L)
+#endif
+
+#ifndef STATUS_FILE_DELETED
+# define STATUS_FILE_DELETED ((NTSTATUS) 0xC0000123L)
+#endif
+
+#ifndef STATUS_SPECIAL_ACCOUNT
+# define STATUS_SPECIAL_ACCOUNT ((NTSTATUS) 0xC0000124L)
+#endif
+
+#ifndef STATUS_SPECIAL_GROUP
+# define STATUS_SPECIAL_GROUP ((NTSTATUS) 0xC0000125L)
+#endif
+
+#ifndef STATUS_SPECIAL_USER
+# define STATUS_SPECIAL_USER ((NTSTATUS) 0xC0000126L)
+#endif
+
+#ifndef STATUS_MEMBERS_PRIMARY_GROUP
+# define STATUS_MEMBERS_PRIMARY_GROUP ((NTSTATUS) 0xC0000127L)
+#endif
+
+#ifndef STATUS_FILE_CLOSED
+# define STATUS_FILE_CLOSED ((NTSTATUS) 0xC0000128L)
+#endif
+
+#ifndef STATUS_TOO_MANY_THREADS
+# define STATUS_TOO_MANY_THREADS ((NTSTATUS) 0xC0000129L)
+#endif
+
+#ifndef STATUS_THREAD_NOT_IN_PROCESS
+# define STATUS_THREAD_NOT_IN_PROCESS ((NTSTATUS) 0xC000012AL)
+#endif
+
+#ifndef STATUS_TOKEN_ALREADY_IN_USE
+# define STATUS_TOKEN_ALREADY_IN_USE ((NTSTATUS) 0xC000012BL)
+#endif
+
+#ifndef STATUS_PAGEFILE_QUOTA_EXCEEDED
+# define STATUS_PAGEFILE_QUOTA_EXCEEDED ((NTSTATUS) 0xC000012CL)
+#endif
+
+#ifndef STATUS_COMMITMENT_LIMIT
+# define STATUS_COMMITMENT_LIMIT ((NTSTATUS) 0xC000012DL)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_LE_FORMAT
+# define STATUS_INVALID_IMAGE_LE_FORMAT ((NTSTATUS) 0xC000012EL)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_NOT_MZ
+# define STATUS_INVALID_IMAGE_NOT_MZ ((NTSTATUS) 0xC000012FL)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_PROTECT
+# define STATUS_INVALID_IMAGE_PROTECT ((NTSTATUS) 0xC0000130L)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_WIN_16
+# define STATUS_INVALID_IMAGE_WIN_16 ((NTSTATUS) 0xC0000131L)
+#endif
+
+#ifndef STATUS_LOGON_SERVER_CONFLICT
+# define STATUS_LOGON_SERVER_CONFLICT ((NTSTATUS) 0xC0000132L)
+#endif
+
+#ifndef STATUS_TIME_DIFFERENCE_AT_DC
+# define STATUS_TIME_DIFFERENCE_AT_DC ((NTSTATUS) 0xC0000133L)
+#endif
+
+#ifndef STATUS_SYNCHRONIZATION_REQUIRED
+# define STATUS_SYNCHRONIZATION_REQUIRED ((NTSTATUS) 0xC0000134L)
+#endif
+
+#ifndef STATUS_DLL_NOT_FOUND
+# define STATUS_DLL_NOT_FOUND ((NTSTATUS) 0xC0000135L)
+#endif
+
+#ifndef STATUS_OPEN_FAILED
+# define STATUS_OPEN_FAILED ((NTSTATUS) 0xC0000136L)
+#endif
+
+#ifndef STATUS_IO_PRIVILEGE_FAILED
+# define STATUS_IO_PRIVILEGE_FAILED ((NTSTATUS) 0xC0000137L)
+#endif
+
+#ifndef STATUS_ORDINAL_NOT_FOUND
+# define STATUS_ORDINAL_NOT_FOUND ((NTSTATUS) 0xC0000138L)
+#endif
+
+#ifndef STATUS_ENTRYPOINT_NOT_FOUND
+# define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS) 0xC0000139L)
+#endif
+
+#ifndef STATUS_CONTROL_C_EXIT
+# define STATUS_CONTROL_C_EXIT ((NTSTATUS) 0xC000013AL)
+#endif
+
+#ifndef STATUS_LOCAL_DISCONNECT
+# define STATUS_LOCAL_DISCONNECT ((NTSTATUS) 0xC000013BL)
+#endif
+
+#ifndef STATUS_REMOTE_DISCONNECT
+# define STATUS_REMOTE_DISCONNECT ((NTSTATUS) 0xC000013CL)
+#endif
+
+#ifndef STATUS_REMOTE_RESOURCES
+# define STATUS_REMOTE_RESOURCES ((NTSTATUS) 0xC000013DL)
+#endif
+
+#ifndef STATUS_LINK_FAILED
+# define STATUS_LINK_FAILED ((NTSTATUS) 0xC000013EL)
+#endif
+
+#ifndef STATUS_LINK_TIMEOUT
+# define STATUS_LINK_TIMEOUT ((NTSTATUS) 0xC000013FL)
+#endif
+
+#ifndef STATUS_INVALID_CONNECTION
+# define STATUS_INVALID_CONNECTION ((NTSTATUS) 0xC0000140L)
+#endif
+
+#ifndef STATUS_INVALID_ADDRESS
+# define STATUS_INVALID_ADDRESS ((NTSTATUS) 0xC0000141L)
+#endif
+
+#ifndef STATUS_DLL_INIT_FAILED
+# define STATUS_DLL_INIT_FAILED ((NTSTATUS) 0xC0000142L)
+#endif
+
+#ifndef STATUS_MISSING_SYSTEMFILE
+# define STATUS_MISSING_SYSTEMFILE ((NTSTATUS) 0xC0000143L)
+#endif
+
+#ifndef STATUS_UNHANDLED_EXCEPTION
+# define STATUS_UNHANDLED_EXCEPTION ((NTSTATUS) 0xC0000144L)
+#endif
+
+#ifndef STATUS_APP_INIT_FAILURE
+# define STATUS_APP_INIT_FAILURE ((NTSTATUS) 0xC0000145L)
+#endif
+
+#ifndef STATUS_PAGEFILE_CREATE_FAILED
+# define STATUS_PAGEFILE_CREATE_FAILED ((NTSTATUS) 0xC0000146L)
+#endif
+
+#ifndef STATUS_NO_PAGEFILE
+# define STATUS_NO_PAGEFILE ((NTSTATUS) 0xC0000147L)
+#endif
+
+#ifndef STATUS_INVALID_LEVEL
+# define STATUS_INVALID_LEVEL ((NTSTATUS) 0xC0000148L)
+#endif
+
+#ifndef STATUS_WRONG_PASSWORD_CORE
+# define STATUS_WRONG_PASSWORD_CORE ((NTSTATUS) 0xC0000149L)
+#endif
+
+#ifndef STATUS_ILLEGAL_FLOAT_CONTEXT
+# define STATUS_ILLEGAL_FLOAT_CONTEXT ((NTSTATUS) 0xC000014AL)
+#endif
+
+#ifndef STATUS_PIPE_BROKEN
+# define STATUS_PIPE_BROKEN ((NTSTATUS) 0xC000014BL)
+#endif
+
+#ifndef STATUS_REGISTRY_CORRUPT
+# define STATUS_REGISTRY_CORRUPT ((NTSTATUS) 0xC000014CL)
+#endif
+
+#ifndef STATUS_REGISTRY_IO_FAILED
+# define STATUS_REGISTRY_IO_FAILED ((NTSTATUS) 0xC000014DL)
+#endif
+
+#ifndef STATUS_NO_EVENT_PAIR
+# define STATUS_NO_EVENT_PAIR ((NTSTATUS) 0xC000014EL)
+#endif
+
+#ifndef STATUS_UNRECOGNIZED_VOLUME
+# define STATUS_UNRECOGNIZED_VOLUME ((NTSTATUS) 0xC000014FL)
+#endif
+
+#ifndef STATUS_SERIAL_NO_DEVICE_INITED
+# define STATUS_SERIAL_NO_DEVICE_INITED ((NTSTATUS) 0xC0000150L)
+#endif
+
+#ifndef STATUS_NO_SUCH_ALIAS
+# define STATUS_NO_SUCH_ALIAS ((NTSTATUS) 0xC0000151L)
+#endif
+
+#ifndef STATUS_MEMBER_NOT_IN_ALIAS
+# define STATUS_MEMBER_NOT_IN_ALIAS ((NTSTATUS) 0xC0000152L)
+#endif
+
+#ifndef STATUS_MEMBER_IN_ALIAS
+# define STATUS_MEMBER_IN_ALIAS ((NTSTATUS) 0xC0000153L)
+#endif
+
+#ifndef STATUS_ALIAS_EXISTS
+# define STATUS_ALIAS_EXISTS ((NTSTATUS) 0xC0000154L)
+#endif
+
+#ifndef STATUS_LOGON_NOT_GRANTED
+# define STATUS_LOGON_NOT_GRANTED ((NTSTATUS) 0xC0000155L)
+#endif
+
+#ifndef STATUS_TOO_MANY_SECRETS
+# define STATUS_TOO_MANY_SECRETS ((NTSTATUS) 0xC0000156L)
+#endif
+
+#ifndef STATUS_SECRET_TOO_LONG
+# define STATUS_SECRET_TOO_LONG ((NTSTATUS) 0xC0000157L)
+#endif
+
+#ifndef STATUS_INTERNAL_DB_ERROR
+# define STATUS_INTERNAL_DB_ERROR ((NTSTATUS) 0xC0000158L)
+#endif
+
+#ifndef STATUS_FULLSCREEN_MODE
+# define STATUS_FULLSCREEN_MODE ((NTSTATUS) 0xC0000159L)
+#endif
+
+#ifndef STATUS_TOO_MANY_CONTEXT_IDS
+# define STATUS_TOO_MANY_CONTEXT_IDS ((NTSTATUS) 0xC000015AL)
+#endif
+
+#ifndef STATUS_LOGON_TYPE_NOT_GRANTED
+# define STATUS_LOGON_TYPE_NOT_GRANTED ((NTSTATUS) 0xC000015BL)
+#endif
+
+#ifndef STATUS_NOT_REGISTRY_FILE
+# define STATUS_NOT_REGISTRY_FILE ((NTSTATUS) 0xC000015CL)
+#endif
+
+#ifndef STATUS_NT_CROSS_ENCRYPTION_REQUIRED
+# define STATUS_NT_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS) 0xC000015DL)
+#endif
+
+#ifndef STATUS_DOMAIN_CTRLR_CONFIG_ERROR
+# define STATUS_DOMAIN_CTRLR_CONFIG_ERROR ((NTSTATUS) 0xC000015EL)
+#endif
+
+#ifndef STATUS_FT_MISSING_MEMBER
+# define STATUS_FT_MISSING_MEMBER ((NTSTATUS) 0xC000015FL)
+#endif
+
+#ifndef STATUS_ILL_FORMED_SERVICE_ENTRY
+# define STATUS_ILL_FORMED_SERVICE_ENTRY ((NTSTATUS) 0xC0000160L)
+#endif
+
+#ifndef STATUS_ILLEGAL_CHARACTER
+# define STATUS_ILLEGAL_CHARACTER ((NTSTATUS) 0xC0000161L)
+#endif
+
+#ifndef STATUS_UNMAPPABLE_CHARACTER
+# define STATUS_UNMAPPABLE_CHARACTER ((NTSTATUS) 0xC0000162L)
+#endif
+
+#ifndef STATUS_UNDEFINED_CHARACTER
+# define STATUS_UNDEFINED_CHARACTER ((NTSTATUS) 0xC0000163L)
+#endif
+
+#ifndef STATUS_FLOPPY_VOLUME
+# define STATUS_FLOPPY_VOLUME ((NTSTATUS) 0xC0000164L)
+#endif
+
+#ifndef STATUS_FLOPPY_ID_MARK_NOT_FOUND
+# define STATUS_FLOPPY_ID_MARK_NOT_FOUND ((NTSTATUS) 0xC0000165L)
+#endif
+
+#ifndef STATUS_FLOPPY_WRONG_CYLINDER
+# define STATUS_FLOPPY_WRONG_CYLINDER ((NTSTATUS) 0xC0000166L)
+#endif
+
+#ifndef STATUS_FLOPPY_UNKNOWN_ERROR
+# define STATUS_FLOPPY_UNKNOWN_ERROR ((NTSTATUS) 0xC0000167L)
+#endif
+
+#ifndef STATUS_FLOPPY_BAD_REGISTERS
+# define STATUS_FLOPPY_BAD_REGISTERS ((NTSTATUS) 0xC0000168L)
+#endif
+
+#ifndef STATUS_DISK_RECALIBRATE_FAILED
+# define STATUS_DISK_RECALIBRATE_FAILED ((NTSTATUS) 0xC0000169L)
+#endif
+
+#ifndef STATUS_DISK_OPERATION_FAILED
+# define STATUS_DISK_OPERATION_FAILED ((NTSTATUS) 0xC000016AL)
+#endif
+
+#ifndef STATUS_DISK_RESET_FAILED
+# define STATUS_DISK_RESET_FAILED ((NTSTATUS) 0xC000016BL)
+#endif
+
+#ifndef STATUS_SHARED_IRQ_BUSY
+# define STATUS_SHARED_IRQ_BUSY ((NTSTATUS) 0xC000016CL)
+#endif
+
+#ifndef STATUS_FT_ORPHANING
+# define STATUS_FT_ORPHANING ((NTSTATUS) 0xC000016DL)
+#endif
+
+#ifndef STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT
+# define STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT ((NTSTATUS) 0xC000016EL)
+#endif
+
+#ifndef STATUS_PARTITION_FAILURE
+# define STATUS_PARTITION_FAILURE ((NTSTATUS) 0xC0000172L)
+#endif
+
+#ifndef STATUS_INVALID_BLOCK_LENGTH
+# define STATUS_INVALID_BLOCK_LENGTH ((NTSTATUS) 0xC0000173L)
+#endif
+
+#ifndef STATUS_DEVICE_NOT_PARTITIONED
+# define STATUS_DEVICE_NOT_PARTITIONED ((NTSTATUS) 0xC0000174L)
+#endif
+
+#ifndef STATUS_UNABLE_TO_LOCK_MEDIA
+# define STATUS_UNABLE_TO_LOCK_MEDIA ((NTSTATUS) 0xC0000175L)
+#endif
+
+#ifndef STATUS_UNABLE_TO_UNLOAD_MEDIA
+# define STATUS_UNABLE_TO_UNLOAD_MEDIA ((NTSTATUS) 0xC0000176L)
+#endif
+
+#ifndef STATUS_EOM_OVERFLOW
+# define STATUS_EOM_OVERFLOW ((NTSTATUS) 0xC0000177L)
+#endif
+
+#ifndef STATUS_NO_MEDIA
+# define STATUS_NO_MEDIA ((NTSTATUS) 0xC0000178L)
+#endif
+
+#ifndef STATUS_NO_SUCH_MEMBER
+# define STATUS_NO_SUCH_MEMBER ((NTSTATUS) 0xC000017AL)
+#endif
+
+#ifndef STATUS_INVALID_MEMBER
+# define STATUS_INVALID_MEMBER ((NTSTATUS) 0xC000017BL)
+#endif
+
+#ifndef STATUS_KEY_DELETED
+# define STATUS_KEY_DELETED ((NTSTATUS) 0xC000017CL)
+#endif
+
+#ifndef STATUS_NO_LOG_SPACE
+# define STATUS_NO_LOG_SPACE ((NTSTATUS) 0xC000017DL)
+#endif
+
+#ifndef STATUS_TOO_MANY_SIDS
+# define STATUS_TOO_MANY_SIDS ((NTSTATUS) 0xC000017EL)
+#endif
+
+#ifndef STATUS_LM_CROSS_ENCRYPTION_REQUIRED
+# define STATUS_LM_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS) 0xC000017FL)
+#endif
+
+#ifndef STATUS_KEY_HAS_CHILDREN
+# define STATUS_KEY_HAS_CHILDREN ((NTSTATUS) 0xC0000180L)
+#endif
+
+#ifndef STATUS_CHILD_MUST_BE_VOLATILE
+# define STATUS_CHILD_MUST_BE_VOLATILE ((NTSTATUS) 0xC0000181L)
+#endif
+
+#ifndef STATUS_DEVICE_CONFIGURATION_ERROR
+# define STATUS_DEVICE_CONFIGURATION_ERROR ((NTSTATUS) 0xC0000182L)
+#endif
+
+#ifndef STATUS_DRIVER_INTERNAL_ERROR
+# define STATUS_DRIVER_INTERNAL_ERROR ((NTSTATUS) 0xC0000183L)
+#endif
+
+#ifndef STATUS_INVALID_DEVICE_STATE
+# define STATUS_INVALID_DEVICE_STATE ((NTSTATUS) 0xC0000184L)
+#endif
+
+#ifndef STATUS_IO_DEVICE_ERROR
+# define STATUS_IO_DEVICE_ERROR ((NTSTATUS) 0xC0000185L)
+#endif
+
+#ifndef STATUS_DEVICE_PROTOCOL_ERROR
+# define STATUS_DEVICE_PROTOCOL_ERROR ((NTSTATUS) 0xC0000186L)
+#endif
+
+#ifndef STATUS_BACKUP_CONTROLLER
+# define STATUS_BACKUP_CONTROLLER ((NTSTATUS) 0xC0000187L)
+#endif
+
+#ifndef STATUS_LOG_FILE_FULL
+# define STATUS_LOG_FILE_FULL ((NTSTATUS) 0xC0000188L)
+#endif
+
+#ifndef STATUS_TOO_LATE
+# define STATUS_TOO_LATE ((NTSTATUS) 0xC0000189L)
+#endif
+
+#ifndef STATUS_NO_TRUST_LSA_SECRET
+# define STATUS_NO_TRUST_LSA_SECRET ((NTSTATUS) 0xC000018AL)
+#endif
+
+#ifndef STATUS_NO_TRUST_SAM_ACCOUNT
+# define STATUS_NO_TRUST_SAM_ACCOUNT ((NTSTATUS) 0xC000018BL)
+#endif
+
+#ifndef STATUS_TRUSTED_DOMAIN_FAILURE
+# define STATUS_TRUSTED_DOMAIN_FAILURE ((NTSTATUS) 0xC000018CL)
+#endif
+
+#ifndef STATUS_TRUSTED_RELATIONSHIP_FAILURE
+# define STATUS_TRUSTED_RELATIONSHIP_FAILURE ((NTSTATUS) 0xC000018DL)
+#endif
+
+#ifndef STATUS_EVENTLOG_FILE_CORRUPT
+# define STATUS_EVENTLOG_FILE_CORRUPT ((NTSTATUS) 0xC000018EL)
+#endif
+
+#ifndef STATUS_EVENTLOG_CANT_START
+# define STATUS_EVENTLOG_CANT_START ((NTSTATUS) 0xC000018FL)
+#endif
+
+#ifndef STATUS_TRUST_FAILURE
+# define STATUS_TRUST_FAILURE ((NTSTATUS) 0xC0000190L)
+#endif
+
+#ifndef STATUS_MUTANT_LIMIT_EXCEEDED
+# define STATUS_MUTANT_LIMIT_EXCEEDED ((NTSTATUS) 0xC0000191L)
+#endif
+
+#ifndef STATUS_NETLOGON_NOT_STARTED
+# define STATUS_NETLOGON_NOT_STARTED ((NTSTATUS) 0xC0000192L)
+#endif
+
+#ifndef STATUS_ACCOUNT_EXPIRED
+# define STATUS_ACCOUNT_EXPIRED ((NTSTATUS) 0xC0000193L)
+#endif
+
+#ifndef STATUS_POSSIBLE_DEADLOCK
+# define STATUS_POSSIBLE_DEADLOCK ((NTSTATUS) 0xC0000194L)
+#endif
+
+#ifndef STATUS_NETWORK_CREDENTIAL_CONFLICT
+# define STATUS_NETWORK_CREDENTIAL_CONFLICT ((NTSTATUS) 0xC0000195L)
+#endif
+
+#ifndef STATUS_REMOTE_SESSION_LIMIT
+# define STATUS_REMOTE_SESSION_LIMIT ((NTSTATUS) 0xC0000196L)
+#endif
+
+#ifndef STATUS_EVENTLOG_FILE_CHANGED
+# define STATUS_EVENTLOG_FILE_CHANGED ((NTSTATUS) 0xC0000197L)
+#endif
+
+#ifndef STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT
+# define STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT ((NTSTATUS) 0xC0000198L)
+#endif
+
+#ifndef STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
+# define STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT ((NTSTATUS) 0xC0000199L)
+#endif
+
+#ifndef STATUS_NOLOGON_SERVER_TRUST_ACCOUNT
+# define STATUS_NOLOGON_SERVER_TRUST_ACCOUNT ((NTSTATUS) 0xC000019AL)
+#endif
+
+#ifndef STATUS_DOMAIN_TRUST_INCONSISTENT
+# define STATUS_DOMAIN_TRUST_INCONSISTENT ((NTSTATUS) 0xC000019BL)
+#endif
+
+#ifndef STATUS_FS_DRIVER_REQUIRED
+# define STATUS_FS_DRIVER_REQUIRED ((NTSTATUS) 0xC000019CL)
+#endif
+
+#ifndef STATUS_IMAGE_ALREADY_LOADED_AS_DLL
+# define STATUS_IMAGE_ALREADY_LOADED_AS_DLL ((NTSTATUS) 0xC000019DL)
+#endif
+
+#ifndef STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING
+# define STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING ((NTSTATUS) 0xC000019EL)
+#endif
+
+#ifndef STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME
+# define STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME ((NTSTATUS) 0xC000019FL)
+#endif
+
+#ifndef STATUS_SECURITY_STREAM_IS_INCONSISTENT
+# define STATUS_SECURITY_STREAM_IS_INCONSISTENT ((NTSTATUS) 0xC00001A0L)
+#endif
+
+#ifndef STATUS_INVALID_LOCK_RANGE
+# define STATUS_INVALID_LOCK_RANGE ((NTSTATUS) 0xC00001A1L)
+#endif
+
+#ifndef STATUS_INVALID_ACE_CONDITION
+# define STATUS_INVALID_ACE_CONDITION ((NTSTATUS) 0xC00001A2L)
+#endif
+
+#ifndef STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT
+# define STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT ((NTSTATUS) 0xC00001A3L)
+#endif
+
+#ifndef STATUS_NOTIFICATION_GUID_ALREADY_DEFINED
+# define STATUS_NOTIFICATION_GUID_ALREADY_DEFINED ((NTSTATUS) 0xC00001A4L)
+#endif
+
+#ifndef STATUS_NETWORK_OPEN_RESTRICTION
+# define STATUS_NETWORK_OPEN_RESTRICTION ((NTSTATUS) 0xC0000201L)
+#endif
+
+#ifndef STATUS_NO_USER_SESSION_KEY
+# define STATUS_NO_USER_SESSION_KEY ((NTSTATUS) 0xC0000202L)
+#endif
+
+#ifndef STATUS_USER_SESSION_DELETED
+# define STATUS_USER_SESSION_DELETED ((NTSTATUS) 0xC0000203L)
+#endif
+
+#ifndef STATUS_RESOURCE_LANG_NOT_FOUND
+# define STATUS_RESOURCE_LANG_NOT_FOUND ((NTSTATUS) 0xC0000204L)
+#endif
+
+#ifndef STATUS_INSUFF_SERVER_RESOURCES
+# define STATUS_INSUFF_SERVER_RESOURCES ((NTSTATUS) 0xC0000205L)
+#endif
+
+#ifndef STATUS_INVALID_BUFFER_SIZE
+# define STATUS_INVALID_BUFFER_SIZE ((NTSTATUS) 0xC0000206L)
+#endif
+
+#ifndef STATUS_INVALID_ADDRESS_COMPONENT
+# define STATUS_INVALID_ADDRESS_COMPONENT ((NTSTATUS) 0xC0000207L)
+#endif
+
+#ifndef STATUS_INVALID_ADDRESS_WILDCARD
+# define STATUS_INVALID_ADDRESS_WILDCARD ((NTSTATUS) 0xC0000208L)
+#endif
+
+#ifndef STATUS_TOO_MANY_ADDRESSES
+# define STATUS_TOO_MANY_ADDRESSES ((NTSTATUS) 0xC0000209L)
+#endif
+
+#ifndef STATUS_ADDRESS_ALREADY_EXISTS
+# define STATUS_ADDRESS_ALREADY_EXISTS ((NTSTATUS) 0xC000020AL)
+#endif
+
+#ifndef STATUS_ADDRESS_CLOSED
+# define STATUS_ADDRESS_CLOSED ((NTSTATUS) 0xC000020BL)
+#endif
+
+#ifndef STATUS_CONNECTION_DISCONNECTED
+# define STATUS_CONNECTION_DISCONNECTED ((NTSTATUS) 0xC000020CL)
+#endif
+
+#ifndef STATUS_CONNECTION_RESET
+# define STATUS_CONNECTION_RESET ((NTSTATUS) 0xC000020DL)
+#endif
+
+#ifndef STATUS_TOO_MANY_NODES
+# define STATUS_TOO_MANY_NODES ((NTSTATUS) 0xC000020EL)
+#endif
+
+#ifndef STATUS_TRANSACTION_ABORTED
+# define STATUS_TRANSACTION_ABORTED ((NTSTATUS) 0xC000020FL)
+#endif
+
+#ifndef STATUS_TRANSACTION_TIMED_OUT
+# define STATUS_TRANSACTION_TIMED_OUT ((NTSTATUS) 0xC0000210L)
+#endif
+
+#ifndef STATUS_TRANSACTION_NO_RELEASE
+# define STATUS_TRANSACTION_NO_RELEASE ((NTSTATUS) 0xC0000211L)
+#endif
+
+#ifndef STATUS_TRANSACTION_NO_MATCH
+# define STATUS_TRANSACTION_NO_MATCH ((NTSTATUS) 0xC0000212L)
+#endif
+
+#ifndef STATUS_TRANSACTION_RESPONDED
+# define STATUS_TRANSACTION_RESPONDED ((NTSTATUS) 0xC0000213L)
+#endif
+
+#ifndef STATUS_TRANSACTION_INVALID_ID
+# define STATUS_TRANSACTION_INVALID_ID ((NTSTATUS) 0xC0000214L)
+#endif
+
+#ifndef STATUS_TRANSACTION_INVALID_TYPE
+# define STATUS_TRANSACTION_INVALID_TYPE ((NTSTATUS) 0xC0000215L)
+#endif
+
+#ifndef STATUS_NOT_SERVER_SESSION
+# define STATUS_NOT_SERVER_SESSION ((NTSTATUS) 0xC0000216L)
+#endif
+
+#ifndef STATUS_NOT_CLIENT_SESSION
+# define STATUS_NOT_CLIENT_SESSION ((NTSTATUS) 0xC0000217L)
+#endif
+
+#ifndef STATUS_CANNOT_LOAD_REGISTRY_FILE
+# define STATUS_CANNOT_LOAD_REGISTRY_FILE ((NTSTATUS) 0xC0000218L)
+#endif
+
+#ifndef STATUS_DEBUG_ATTACH_FAILED
+# define STATUS_DEBUG_ATTACH_FAILED ((NTSTATUS) 0xC0000219L)
+#endif
+
+#ifndef STATUS_SYSTEM_PROCESS_TERMINATED
+# define STATUS_SYSTEM_PROCESS_TERMINATED ((NTSTATUS) 0xC000021AL)
+#endif
+
+#ifndef STATUS_DATA_NOT_ACCEPTED
+# define STATUS_DATA_NOT_ACCEPTED ((NTSTATUS) 0xC000021BL)
+#endif
+
+#ifndef STATUS_NO_BROWSER_SERVERS_FOUND
+# define STATUS_NO_BROWSER_SERVERS_FOUND ((NTSTATUS) 0xC000021CL)
+#endif
+
+#ifndef STATUS_VDM_HARD_ERROR
+# define STATUS_VDM_HARD_ERROR ((NTSTATUS) 0xC000021DL)
+#endif
+
+#ifndef STATUS_DRIVER_CANCEL_TIMEOUT
+# define STATUS_DRIVER_CANCEL_TIMEOUT ((NTSTATUS) 0xC000021EL)
+#endif
+
+#ifndef STATUS_REPLY_MESSAGE_MISMATCH
+# define STATUS_REPLY_MESSAGE_MISMATCH ((NTSTATUS) 0xC000021FL)
+#endif
+
+#ifndef STATUS_MAPPED_ALIGNMENT
+# define STATUS_MAPPED_ALIGNMENT ((NTSTATUS) 0xC0000220L)
+#endif
+
+#ifndef STATUS_IMAGE_CHECKSUM_MISMATCH
+# define STATUS_IMAGE_CHECKSUM_MISMATCH ((NTSTATUS) 0xC0000221L)
+#endif
+
+#ifndef STATUS_LOST_WRITEBEHIND_DATA
+# define STATUS_LOST_WRITEBEHIND_DATA ((NTSTATUS) 0xC0000222L)
+#endif
+
+#ifndef STATUS_CLIENT_SERVER_PARAMETERS_INVALID
+# define STATUS_CLIENT_SERVER_PARAMETERS_INVALID ((NTSTATUS) 0xC0000223L)
+#endif
+
+#ifndef STATUS_PASSWORD_MUST_CHANGE
+# define STATUS_PASSWORD_MUST_CHANGE ((NTSTATUS) 0xC0000224L)
+#endif
+
+#ifndef STATUS_NOT_FOUND
+# define STATUS_NOT_FOUND ((NTSTATUS) 0xC0000225L)
+#endif
+
+#ifndef STATUS_NOT_TINY_STREAM
+# define STATUS_NOT_TINY_STREAM ((NTSTATUS) 0xC0000226L)
+#endif
+
+#ifndef STATUS_RECOVERY_FAILURE
+# define STATUS_RECOVERY_FAILURE ((NTSTATUS) 0xC0000227L)
+#endif
+
+#ifndef STATUS_STACK_OVERFLOW_READ
+# define STATUS_STACK_OVERFLOW_READ ((NTSTATUS) 0xC0000228L)
+#endif
+
+#ifndef STATUS_FAIL_CHECK
+# define STATUS_FAIL_CHECK ((NTSTATUS) 0xC0000229L)
+#endif
+
+#ifndef STATUS_DUPLICATE_OBJECTID
+# define STATUS_DUPLICATE_OBJECTID ((NTSTATUS) 0xC000022AL)
+#endif
+
+#ifndef STATUS_OBJECTID_EXISTS
+# define STATUS_OBJECTID_EXISTS ((NTSTATUS) 0xC000022BL)
+#endif
+
+#ifndef STATUS_CONVERT_TO_LARGE
+# define STATUS_CONVERT_TO_LARGE ((NTSTATUS) 0xC000022CL)
+#endif
+
+#ifndef STATUS_RETRY
+# define STATUS_RETRY ((NTSTATUS) 0xC000022DL)
+#endif
+
+#ifndef STATUS_FOUND_OUT_OF_SCOPE
+# define STATUS_FOUND_OUT_OF_SCOPE ((NTSTATUS) 0xC000022EL)
+#endif
+
+#ifndef STATUS_ALLOCATE_BUCKET
+# define STATUS_ALLOCATE_BUCKET ((NTSTATUS) 0xC000022FL)
+#endif
+
+#ifndef STATUS_PROPSET_NOT_FOUND
+# define STATUS_PROPSET_NOT_FOUND ((NTSTATUS) 0xC0000230L)
+#endif
+
+#ifndef STATUS_MARSHALL_OVERFLOW
+# define STATUS_MARSHALL_OVERFLOW ((NTSTATUS) 0xC0000231L)
+#endif
+
+#ifndef STATUS_INVALID_VARIANT
+# define STATUS_INVALID_VARIANT ((NTSTATUS) 0xC0000232L)
+#endif
+
+#ifndef STATUS_DOMAIN_CONTROLLER_NOT_FOUND
+# define STATUS_DOMAIN_CONTROLLER_NOT_FOUND ((NTSTATUS) 0xC0000233L)
+#endif
+
+#ifndef STATUS_ACCOUNT_LOCKED_OUT
+# define STATUS_ACCOUNT_LOCKED_OUT ((NTSTATUS) 0xC0000234L)
+#endif
+
+#ifndef STATUS_HANDLE_NOT_CLOSABLE
+# define STATUS_HANDLE_NOT_CLOSABLE ((NTSTATUS) 0xC0000235L)
+#endif
+
+#ifndef STATUS_CONNECTION_REFUSED
+# define STATUS_CONNECTION_REFUSED ((NTSTATUS) 0xC0000236L)
+#endif
+
+#ifndef STATUS_GRACEFUL_DISCONNECT
+# define STATUS_GRACEFUL_DISCONNECT ((NTSTATUS) 0xC0000237L)
+#endif
+
+#ifndef STATUS_ADDRESS_ALREADY_ASSOCIATED
+# define STATUS_ADDRESS_ALREADY_ASSOCIATED ((NTSTATUS) 0xC0000238L)
+#endif
+
+#ifndef STATUS_ADDRESS_NOT_ASSOCIATED
+# define STATUS_ADDRESS_NOT_ASSOCIATED ((NTSTATUS) 0xC0000239L)
+#endif
+
+#ifndef STATUS_CONNECTION_INVALID
+# define STATUS_CONNECTION_INVALID ((NTSTATUS) 0xC000023AL)
+#endif
+
+#ifndef STATUS_CONNECTION_ACTIVE
+# define STATUS_CONNECTION_ACTIVE ((NTSTATUS) 0xC000023BL)
+#endif
+
+#ifndef STATUS_NETWORK_UNREACHABLE
+# define STATUS_NETWORK_UNREACHABLE ((NTSTATUS) 0xC000023CL)
+#endif
+
+#ifndef STATUS_HOST_UNREACHABLE
+# define STATUS_HOST_UNREACHABLE ((NTSTATUS) 0xC000023DL)
+#endif
+
+#ifndef STATUS_PROTOCOL_UNREACHABLE
+# define STATUS_PROTOCOL_UNREACHABLE ((NTSTATUS) 0xC000023EL)
+#endif
+
+#ifndef STATUS_PORT_UNREACHABLE
+# define STATUS_PORT_UNREACHABLE ((NTSTATUS) 0xC000023FL)
+#endif
+
+#ifndef STATUS_REQUEST_ABORTED
+# define STATUS_REQUEST_ABORTED ((NTSTATUS) 0xC0000240L)
+#endif
+
+#ifndef STATUS_CONNECTION_ABORTED
+# define STATUS_CONNECTION_ABORTED ((NTSTATUS) 0xC0000241L)
+#endif
+
+#ifndef STATUS_BAD_COMPRESSION_BUFFER
+# define STATUS_BAD_COMPRESSION_BUFFER ((NTSTATUS) 0xC0000242L)
+#endif
+
+#ifndef STATUS_USER_MAPPED_FILE
+# define STATUS_USER_MAPPED_FILE ((NTSTATUS) 0xC0000243L)
+#endif
+
+#ifndef STATUS_AUDIT_FAILED
+# define STATUS_AUDIT_FAILED ((NTSTATUS) 0xC0000244L)
+#endif
+
+#ifndef STATUS_TIMER_RESOLUTION_NOT_SET
+# define STATUS_TIMER_RESOLUTION_NOT_SET ((NTSTATUS) 0xC0000245L)
+#endif
+
+#ifndef STATUS_CONNECTION_COUNT_LIMIT
+# define STATUS_CONNECTION_COUNT_LIMIT ((NTSTATUS) 0xC0000246L)
+#endif
+
+#ifndef STATUS_LOGIN_TIME_RESTRICTION
+# define STATUS_LOGIN_TIME_RESTRICTION ((NTSTATUS) 0xC0000247L)
+#endif
+
+#ifndef STATUS_LOGIN_WKSTA_RESTRICTION
+# define STATUS_LOGIN_WKSTA_RESTRICTION ((NTSTATUS) 0xC0000248L)
+#endif
+
+#ifndef STATUS_IMAGE_MP_UP_MISMATCH
+# define STATUS_IMAGE_MP_UP_MISMATCH ((NTSTATUS) 0xC0000249L)
+#endif
+
+#ifndef STATUS_INSUFFICIENT_LOGON_INFO
+# define STATUS_INSUFFICIENT_LOGON_INFO ((NTSTATUS) 0xC0000250L)
+#endif
+
+#ifndef STATUS_BAD_DLL_ENTRYPOINT
+# define STATUS_BAD_DLL_ENTRYPOINT ((NTSTATUS) 0xC0000251L)
+#endif
+
+#ifndef STATUS_BAD_SERVICE_ENTRYPOINT
+# define STATUS_BAD_SERVICE_ENTRYPOINT ((NTSTATUS) 0xC0000252L)
+#endif
+
+#ifndef STATUS_LPC_REPLY_LOST
+# define STATUS_LPC_REPLY_LOST ((NTSTATUS) 0xC0000253L)
+#endif
+
+#ifndef STATUS_IP_ADDRESS_CONFLICT1
+# define STATUS_IP_ADDRESS_CONFLICT1 ((NTSTATUS) 0xC0000254L)
+#endif
+
+#ifndef STATUS_IP_ADDRESS_CONFLICT2
+# define STATUS_IP_ADDRESS_CONFLICT2 ((NTSTATUS) 0xC0000255L)
+#endif
+
+#ifndef STATUS_REGISTRY_QUOTA_LIMIT
+# define STATUS_REGISTRY_QUOTA_LIMIT ((NTSTATUS) 0xC0000256L)
+#endif
+
+#ifndef STATUS_PATH_NOT_COVERED
+# define STATUS_PATH_NOT_COVERED ((NTSTATUS) 0xC0000257L)
+#endif
+
+#ifndef STATUS_NO_CALLBACK_ACTIVE
+# define STATUS_NO_CALLBACK_ACTIVE ((NTSTATUS) 0xC0000258L)
+#endif
+
+#ifndef STATUS_LICENSE_QUOTA_EXCEEDED
+# define STATUS_LICENSE_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000259L)
+#endif
+
+#ifndef STATUS_PWD_TOO_SHORT
+# define STATUS_PWD_TOO_SHORT ((NTSTATUS) 0xC000025AL)
+#endif
+
+#ifndef STATUS_PWD_TOO_RECENT
+# define STATUS_PWD_TOO_RECENT ((NTSTATUS) 0xC000025BL)
+#endif
+
+#ifndef STATUS_PWD_HISTORY_CONFLICT
+# define STATUS_PWD_HISTORY_CONFLICT ((NTSTATUS) 0xC000025CL)
+#endif
+
+#ifndef STATUS_PLUGPLAY_NO_DEVICE
+# define STATUS_PLUGPLAY_NO_DEVICE ((NTSTATUS) 0xC000025EL)
+#endif
+
+#ifndef STATUS_UNSUPPORTED_COMPRESSION
+# define STATUS_UNSUPPORTED_COMPRESSION ((NTSTATUS) 0xC000025FL)
+#endif
+
+#ifndef STATUS_INVALID_HW_PROFILE
+# define STATUS_INVALID_HW_PROFILE ((NTSTATUS) 0xC0000260L)
+#endif
+
+#ifndef STATUS_INVALID_PLUGPLAY_DEVICE_PATH
+# define STATUS_INVALID_PLUGPLAY_DEVICE_PATH ((NTSTATUS) 0xC0000261L)
+#endif
+
+#ifndef STATUS_DRIVER_ORDINAL_NOT_FOUND
+# define STATUS_DRIVER_ORDINAL_NOT_FOUND ((NTSTATUS) 0xC0000262L)
+#endif
+
+#ifndef STATUS_DRIVER_ENTRYPOINT_NOT_FOUND
+# define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND ((NTSTATUS) 0xC0000263L)
+#endif
+
+#ifndef STATUS_RESOURCE_NOT_OWNED
+# define STATUS_RESOURCE_NOT_OWNED ((NTSTATUS) 0xC0000264L)
+#endif
+
+#ifndef STATUS_TOO_MANY_LINKS
+# define STATUS_TOO_MANY_LINKS ((NTSTATUS) 0xC0000265L)
+#endif
+
+#ifndef STATUS_QUOTA_LIST_INCONSISTENT
+# define STATUS_QUOTA_LIST_INCONSISTENT ((NTSTATUS) 0xC0000266L)
+#endif
+
+#ifndef STATUS_FILE_IS_OFFLINE
+# define STATUS_FILE_IS_OFFLINE ((NTSTATUS) 0xC0000267L)
+#endif
+
+#ifndef STATUS_EVALUATION_EXPIRATION
+# define STATUS_EVALUATION_EXPIRATION ((NTSTATUS) 0xC0000268L)
+#endif
+
+#ifndef STATUS_ILLEGAL_DLL_RELOCATION
+# define STATUS_ILLEGAL_DLL_RELOCATION ((NTSTATUS) 0xC0000269L)
+#endif
+
+#ifndef STATUS_LICENSE_VIOLATION
+# define STATUS_LICENSE_VIOLATION ((NTSTATUS) 0xC000026AL)
+#endif
+
+#ifndef STATUS_DLL_INIT_FAILED_LOGOFF
+# define STATUS_DLL_INIT_FAILED_LOGOFF ((NTSTATUS) 0xC000026BL)
+#endif
+
+#ifndef STATUS_DRIVER_UNABLE_TO_LOAD
+# define STATUS_DRIVER_UNABLE_TO_LOAD ((NTSTATUS) 0xC000026CL)
+#endif
+
+#ifndef STATUS_DFS_UNAVAILABLE
+# define STATUS_DFS_UNAVAILABLE ((NTSTATUS) 0xC000026DL)
+#endif
+
+#ifndef STATUS_VOLUME_DISMOUNTED
+# define STATUS_VOLUME_DISMOUNTED ((NTSTATUS) 0xC000026EL)
+#endif
+
+#ifndef STATUS_WX86_INTERNAL_ERROR
+# define STATUS_WX86_INTERNAL_ERROR ((NTSTATUS) 0xC000026FL)
+#endif
+
+#ifndef STATUS_WX86_FLOAT_STACK_CHECK
+# define STATUS_WX86_FLOAT_STACK_CHECK ((NTSTATUS) 0xC0000270L)
+#endif
+
+#ifndef STATUS_VALIDATE_CONTINUE
+# define STATUS_VALIDATE_CONTINUE ((NTSTATUS) 0xC0000271L)
+#endif
+
+#ifndef STATUS_NO_MATCH
+# define STATUS_NO_MATCH ((NTSTATUS) 0xC0000272L)
+#endif
+
+#ifndef STATUS_NO_MORE_MATCHES
+# define STATUS_NO_MORE_MATCHES ((NTSTATUS) 0xC0000273L)
+#endif
+
+#ifndef STATUS_NOT_A_REPARSE_POINT
+# define STATUS_NOT_A_REPARSE_POINT ((NTSTATUS) 0xC0000275L)
+#endif
+
+#ifndef STATUS_IO_REPARSE_TAG_INVALID
+# define STATUS_IO_REPARSE_TAG_INVALID ((NTSTATUS) 0xC0000276L)
+#endif
+
+#ifndef STATUS_IO_REPARSE_TAG_MISMATCH
+# define STATUS_IO_REPARSE_TAG_MISMATCH ((NTSTATUS) 0xC0000277L)
+#endif
+
+#ifndef STATUS_IO_REPARSE_DATA_INVALID
+# define STATUS_IO_REPARSE_DATA_INVALID ((NTSTATUS) 0xC0000278L)
+#endif
+
+#ifndef STATUS_IO_REPARSE_TAG_NOT_HANDLED
+# define STATUS_IO_REPARSE_TAG_NOT_HANDLED ((NTSTATUS) 0xC0000279L)
+#endif
+
+#ifndef STATUS_REPARSE_POINT_NOT_RESOLVED
+# define STATUS_REPARSE_POINT_NOT_RESOLVED ((NTSTATUS) 0xC0000280L)
+#endif
+
+#ifndef STATUS_DIRECTORY_IS_A_REPARSE_POINT
+# define STATUS_DIRECTORY_IS_A_REPARSE_POINT ((NTSTATUS) 0xC0000281L)
+#endif
+
+#ifndef STATUS_RANGE_LIST_CONFLICT
+# define STATUS_RANGE_LIST_CONFLICT ((NTSTATUS) 0xC0000282L)
+#endif
+
+#ifndef STATUS_SOURCE_ELEMENT_EMPTY
+# define STATUS_SOURCE_ELEMENT_EMPTY ((NTSTATUS) 0xC0000283L)
+#endif
+
+#ifndef STATUS_DESTINATION_ELEMENT_FULL
+# define STATUS_DESTINATION_ELEMENT_FULL ((NTSTATUS) 0xC0000284L)
+#endif
+
+#ifndef STATUS_ILLEGAL_ELEMENT_ADDRESS
+# define STATUS_ILLEGAL_ELEMENT_ADDRESS ((NTSTATUS) 0xC0000285L)
+#endif
+
+#ifndef STATUS_MAGAZINE_NOT_PRESENT
+# define STATUS_MAGAZINE_NOT_PRESENT ((NTSTATUS) 0xC0000286L)
+#endif
+
+#ifndef STATUS_REINITIALIZATION_NEEDED
+# define STATUS_REINITIALIZATION_NEEDED ((NTSTATUS) 0xC0000287L)
+#endif
+
+#ifndef STATUS_DEVICE_REQUIRES_CLEANING
+# define STATUS_DEVICE_REQUIRES_CLEANING ((NTSTATUS) 0x80000288L)
+#endif
+
+#ifndef STATUS_DEVICE_DOOR_OPEN
+# define STATUS_DEVICE_DOOR_OPEN ((NTSTATUS) 0x80000289L)
+#endif
+
+#ifndef STATUS_ENCRYPTION_FAILED
+# define STATUS_ENCRYPTION_FAILED ((NTSTATUS) 0xC000028AL)
+#endif
+
+#ifndef STATUS_DECRYPTION_FAILED
+# define STATUS_DECRYPTION_FAILED ((NTSTATUS) 0xC000028BL)
+#endif
+
+#ifndef STATUS_RANGE_NOT_FOUND
+# define STATUS_RANGE_NOT_FOUND ((NTSTATUS) 0xC000028CL)
+#endif
+
+#ifndef STATUS_NO_RECOVERY_POLICY
+# define STATUS_NO_RECOVERY_POLICY ((NTSTATUS) 0xC000028DL)
+#endif
+
+#ifndef STATUS_NO_EFS
+# define STATUS_NO_EFS ((NTSTATUS) 0xC000028EL)
+#endif
+
+#ifndef STATUS_WRONG_EFS
+# define STATUS_WRONG_EFS ((NTSTATUS) 0xC000028FL)
+#endif
+
+#ifndef STATUS_NO_USER_KEYS
+# define STATUS_NO_USER_KEYS ((NTSTATUS) 0xC0000290L)
+#endif
+
+#ifndef STATUS_FILE_NOT_ENCRYPTED
+# define STATUS_FILE_NOT_ENCRYPTED ((NTSTATUS) 0xC0000291L)
+#endif
+
+#ifndef STATUS_NOT_EXPORT_FORMAT
+# define STATUS_NOT_EXPORT_FORMAT ((NTSTATUS) 0xC0000292L)
+#endif
+
+#ifndef STATUS_FILE_ENCRYPTED
+# define STATUS_FILE_ENCRYPTED ((NTSTATUS) 0xC0000293L)
+#endif
+
+#ifndef STATUS_WAKE_SYSTEM
+# define STATUS_WAKE_SYSTEM ((NTSTATUS) 0x40000294L)
+#endif
+
+#ifndef STATUS_WMI_GUID_NOT_FOUND
+# define STATUS_WMI_GUID_NOT_FOUND ((NTSTATUS) 0xC0000295L)
+#endif
+
+#ifndef STATUS_WMI_INSTANCE_NOT_FOUND
+# define STATUS_WMI_INSTANCE_NOT_FOUND ((NTSTATUS) 0xC0000296L)
+#endif
+
+#ifndef STATUS_WMI_ITEMID_NOT_FOUND
+# define STATUS_WMI_ITEMID_NOT_FOUND ((NTSTATUS) 0xC0000297L)
+#endif
+
+#ifndef STATUS_WMI_TRY_AGAIN
+# define STATUS_WMI_TRY_AGAIN ((NTSTATUS) 0xC0000298L)
+#endif
+
+#ifndef STATUS_SHARED_POLICY
+# define STATUS_SHARED_POLICY ((NTSTATUS) 0xC0000299L)
+#endif
+
+#ifndef STATUS_POLICY_OBJECT_NOT_FOUND
+# define STATUS_POLICY_OBJECT_NOT_FOUND ((NTSTATUS) 0xC000029AL)
+#endif
+
+#ifndef STATUS_POLICY_ONLY_IN_DS
+# define STATUS_POLICY_ONLY_IN_DS ((NTSTATUS) 0xC000029BL)
+#endif
+
+#ifndef STATUS_VOLUME_NOT_UPGRADED
+# define STATUS_VOLUME_NOT_UPGRADED ((NTSTATUS) 0xC000029CL)
+#endif
+
+#ifndef STATUS_REMOTE_STORAGE_NOT_ACTIVE
+# define STATUS_REMOTE_STORAGE_NOT_ACTIVE ((NTSTATUS) 0xC000029DL)
+#endif
+
+#ifndef STATUS_REMOTE_STORAGE_MEDIA_ERROR
+# define STATUS_REMOTE_STORAGE_MEDIA_ERROR ((NTSTATUS) 0xC000029EL)
+#endif
+
+#ifndef STATUS_NO_TRACKING_SERVICE
+# define STATUS_NO_TRACKING_SERVICE ((NTSTATUS) 0xC000029FL)
+#endif
+
+#ifndef STATUS_SERVER_SID_MISMATCH
+# define STATUS_SERVER_SID_MISMATCH ((NTSTATUS) 0xC00002A0L)
+#endif
+
+#ifndef STATUS_DS_NO_ATTRIBUTE_OR_VALUE
+# define STATUS_DS_NO_ATTRIBUTE_OR_VALUE ((NTSTATUS) 0xC00002A1L)
+#endif
+
+#ifndef STATUS_DS_INVALID_ATTRIBUTE_SYNTAX
+# define STATUS_DS_INVALID_ATTRIBUTE_SYNTAX ((NTSTATUS) 0xC00002A2L)
+#endif
+
+#ifndef STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED
+# define STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED ((NTSTATUS) 0xC00002A3L)
+#endif
+
+#ifndef STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS
+# define STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS ((NTSTATUS) 0xC00002A4L)
+#endif
+
+#ifndef STATUS_DS_BUSY
+# define STATUS_DS_BUSY ((NTSTATUS) 0xC00002A5L)
+#endif
+
+#ifndef STATUS_DS_UNAVAILABLE
+# define STATUS_DS_UNAVAILABLE ((NTSTATUS) 0xC00002A6L)
+#endif
+
+#ifndef STATUS_DS_NO_RIDS_ALLOCATED
+# define STATUS_DS_NO_RIDS_ALLOCATED ((NTSTATUS) 0xC00002A7L)
+#endif
+
+#ifndef STATUS_DS_NO_MORE_RIDS
+# define STATUS_DS_NO_MORE_RIDS ((NTSTATUS) 0xC00002A8L)
+#endif
+
+#ifndef STATUS_DS_INCORRECT_ROLE_OWNER
+# define STATUS_DS_INCORRECT_ROLE_OWNER ((NTSTATUS) 0xC00002A9L)
+#endif
+
+#ifndef STATUS_DS_RIDMGR_INIT_ERROR
+# define STATUS_DS_RIDMGR_INIT_ERROR ((NTSTATUS) 0xC00002AAL)
+#endif
+
+#ifndef STATUS_DS_OBJ_CLASS_VIOLATION
+# define STATUS_DS_OBJ_CLASS_VIOLATION ((NTSTATUS) 0xC00002ABL)
+#endif
+
+#ifndef STATUS_DS_CANT_ON_NON_LEAF
+# define STATUS_DS_CANT_ON_NON_LEAF ((NTSTATUS) 0xC00002ACL)
+#endif
+
+#ifndef STATUS_DS_CANT_ON_RDN
+# define STATUS_DS_CANT_ON_RDN ((NTSTATUS) 0xC00002ADL)
+#endif
+
+#ifndef STATUS_DS_CANT_MOD_OBJ_CLASS
+# define STATUS_DS_CANT_MOD_OBJ_CLASS ((NTSTATUS) 0xC00002AEL)
+#endif
+
+#ifndef STATUS_DS_CROSS_DOM_MOVE_FAILED
+# define STATUS_DS_CROSS_DOM_MOVE_FAILED ((NTSTATUS) 0xC00002AFL)
+#endif
+
+#ifndef STATUS_DS_GC_NOT_AVAILABLE
+# define STATUS_DS_GC_NOT_AVAILABLE ((NTSTATUS) 0xC00002B0L)
+#endif
+
+#ifndef STATUS_DIRECTORY_SERVICE_REQUIRED
+# define STATUS_DIRECTORY_SERVICE_REQUIRED ((NTSTATUS) 0xC00002B1L)
+#endif
+
+#ifndef STATUS_REPARSE_ATTRIBUTE_CONFLICT
+# define STATUS_REPARSE_ATTRIBUTE_CONFLICT ((NTSTATUS) 0xC00002B2L)
+#endif
+
+#ifndef STATUS_CANT_ENABLE_DENY_ONLY
+# define STATUS_CANT_ENABLE_DENY_ONLY ((NTSTATUS) 0xC00002B3L)
+#endif
+
+#ifndef STATUS_FLOAT_MULTIPLE_FAULTS
+# define STATUS_FLOAT_MULTIPLE_FAULTS ((NTSTATUS) 0xC00002B4L)
+#endif
+
+#ifndef STATUS_FLOAT_MULTIPLE_TRAPS
+# define STATUS_FLOAT_MULTIPLE_TRAPS ((NTSTATUS) 0xC00002B5L)
+#endif
+
+#ifndef STATUS_DEVICE_REMOVED
+# define STATUS_DEVICE_REMOVED ((NTSTATUS) 0xC00002B6L)
+#endif
+
+#ifndef STATUS_JOURNAL_DELETE_IN_PROGRESS
+# define STATUS_JOURNAL_DELETE_IN_PROGRESS ((NTSTATUS) 0xC00002B7L)
+#endif
+
+#ifndef STATUS_JOURNAL_NOT_ACTIVE
+# define STATUS_JOURNAL_NOT_ACTIVE ((NTSTATUS) 0xC00002B8L)
+#endif
+
+#ifndef STATUS_NOINTERFACE
+# define STATUS_NOINTERFACE ((NTSTATUS) 0xC00002B9L)
+#endif
+
+#ifndef STATUS_DS_ADMIN_LIMIT_EXCEEDED
+# define STATUS_DS_ADMIN_LIMIT_EXCEEDED ((NTSTATUS) 0xC00002C1L)
+#endif
+
+#ifndef STATUS_DRIVER_FAILED_SLEEP
+# define STATUS_DRIVER_FAILED_SLEEP ((NTSTATUS) 0xC00002C2L)
+#endif
+
+#ifndef STATUS_MUTUAL_AUTHENTICATION_FAILED
+# define STATUS_MUTUAL_AUTHENTICATION_FAILED ((NTSTATUS) 0xC00002C3L)
+#endif
+
+#ifndef STATUS_CORRUPT_SYSTEM_FILE
+# define STATUS_CORRUPT_SYSTEM_FILE ((NTSTATUS) 0xC00002C4L)
+#endif
+
+#ifndef STATUS_DATATYPE_MISALIGNMENT_ERROR
+# define STATUS_DATATYPE_MISALIGNMENT_ERROR ((NTSTATUS) 0xC00002C5L)
+#endif
+
+#ifndef STATUS_WMI_READ_ONLY
+# define STATUS_WMI_READ_ONLY ((NTSTATUS) 0xC00002C6L)
+#endif
+
+#ifndef STATUS_WMI_SET_FAILURE
+# define STATUS_WMI_SET_FAILURE ((NTSTATUS) 0xC00002C7L)
+#endif
+
+#ifndef STATUS_COMMITMENT_MINIMUM
+# define STATUS_COMMITMENT_MINIMUM ((NTSTATUS) 0xC00002C8L)
+#endif
+
+#ifndef STATUS_REG_NAT_CONSUMPTION
+# define STATUS_REG_NAT_CONSUMPTION ((NTSTATUS) 0xC00002C9L)
+#endif
+
+#ifndef STATUS_TRANSPORT_FULL
+# define STATUS_TRANSPORT_FULL ((NTSTATUS) 0xC00002CAL)
+#endif
+
+#ifndef STATUS_DS_SAM_INIT_FAILURE
+# define STATUS_DS_SAM_INIT_FAILURE ((NTSTATUS) 0xC00002CBL)
+#endif
+
+#ifndef STATUS_ONLY_IF_CONNECTED
+# define STATUS_ONLY_IF_CONNECTED ((NTSTATUS) 0xC00002CCL)
+#endif
+
+#ifndef STATUS_DS_SENSITIVE_GROUP_VIOLATION
+# define STATUS_DS_SENSITIVE_GROUP_VIOLATION ((NTSTATUS) 0xC00002CDL)
+#endif
+
+#ifndef STATUS_PNP_RESTART_ENUMERATION
+# define STATUS_PNP_RESTART_ENUMERATION ((NTSTATUS) 0xC00002CEL)
+#endif
+
+#ifndef STATUS_JOURNAL_ENTRY_DELETED
+# define STATUS_JOURNAL_ENTRY_DELETED ((NTSTATUS) 0xC00002CFL)
+#endif
+
+#ifndef STATUS_DS_CANT_MOD_PRIMARYGROUPID
+# define STATUS_DS_CANT_MOD_PRIMARYGROUPID ((NTSTATUS) 0xC00002D0L)
+#endif
+
+#ifndef STATUS_SYSTEM_IMAGE_BAD_SIGNATURE
+# define STATUS_SYSTEM_IMAGE_BAD_SIGNATURE ((NTSTATUS) 0xC00002D1L)
+#endif
+
+#ifndef STATUS_PNP_REBOOT_REQUIRED
+# define STATUS_PNP_REBOOT_REQUIRED ((NTSTATUS) 0xC00002D2L)
+#endif
+
+#ifndef STATUS_POWER_STATE_INVALID
+# define STATUS_POWER_STATE_INVALID ((NTSTATUS) 0xC00002D3L)
+#endif
+
+#ifndef STATUS_DS_INVALID_GROUP_TYPE
+# define STATUS_DS_INVALID_GROUP_TYPE ((NTSTATUS) 0xC00002D4L)
+#endif
+
+#ifndef STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN
+# define STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN ((NTSTATUS) 0xC00002D5L)
+#endif
+
+#ifndef STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN
+# define STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN ((NTSTATUS) 0xC00002D6L)
+#endif
+
+#ifndef STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER
+# define STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS) 0xC00002D7L)
+#endif
+
+#ifndef STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER
+# define STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS) 0xC00002D8L)
+#endif
+
+#ifndef STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER
+# define STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS) 0xC00002D9L)
+#endif
+
+#ifndef STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER
+# define STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER ((NTSTATUS) 0xC00002DAL)
+#endif
+
+#ifndef STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER
+# define STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER ((NTSTATUS) 0xC00002DBL)
+#endif
+
+#ifndef STATUS_DS_HAVE_PRIMARY_MEMBERS
+# define STATUS_DS_HAVE_PRIMARY_MEMBERS ((NTSTATUS) 0xC00002DCL)
+#endif
+
+#ifndef STATUS_WMI_NOT_SUPPORTED
+# define STATUS_WMI_NOT_SUPPORTED ((NTSTATUS) 0xC00002DDL)
+#endif
+
+#ifndef STATUS_INSUFFICIENT_POWER
+# define STATUS_INSUFFICIENT_POWER ((NTSTATUS) 0xC00002DEL)
+#endif
+
+#ifndef STATUS_SAM_NEED_BOOTKEY_PASSWORD
+# define STATUS_SAM_NEED_BOOTKEY_PASSWORD ((NTSTATUS) 0xC00002DFL)
+#endif
+
+#ifndef STATUS_SAM_NEED_BOOTKEY_FLOPPY
+# define STATUS_SAM_NEED_BOOTKEY_FLOPPY ((NTSTATUS) 0xC00002E0L)
+#endif
+
+#ifndef STATUS_DS_CANT_START
+# define STATUS_DS_CANT_START ((NTSTATUS) 0xC00002E1L)
+#endif
+
+#ifndef STATUS_DS_INIT_FAILURE
+# define STATUS_DS_INIT_FAILURE ((NTSTATUS) 0xC00002E2L)
+#endif
+
+#ifndef STATUS_SAM_INIT_FAILURE
+# define STATUS_SAM_INIT_FAILURE ((NTSTATUS) 0xC00002E3L)
+#endif
+
+#ifndef STATUS_DS_GC_REQUIRED
+# define STATUS_DS_GC_REQUIRED ((NTSTATUS) 0xC00002E4L)
+#endif
+
+#ifndef STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY
+# define STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY ((NTSTATUS) 0xC00002E5L)
+#endif
+
+#ifndef STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS
+# define STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS ((NTSTATUS) 0xC00002E6L)
+#endif
+
+#ifndef STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED
+# define STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED ((NTSTATUS) 0xC00002E7L)
+#endif
+
+#ifndef STATUS_MULTIPLE_FAULT_VIOLATION
+# define STATUS_MULTIPLE_FAULT_VIOLATION ((NTSTATUS) 0xC00002E8L)
+#endif
+
+#ifndef STATUS_CURRENT_DOMAIN_NOT_ALLOWED
+# define STATUS_CURRENT_DOMAIN_NOT_ALLOWED ((NTSTATUS) 0xC00002E9L)
+#endif
+
+#ifndef STATUS_CANNOT_MAKE
+# define STATUS_CANNOT_MAKE ((NTSTATUS) 0xC00002EAL)
+#endif
+
+#ifndef STATUS_SYSTEM_SHUTDOWN
+# define STATUS_SYSTEM_SHUTDOWN ((NTSTATUS) 0xC00002EBL)
+#endif
+
+#ifndef STATUS_DS_INIT_FAILURE_CONSOLE
+# define STATUS_DS_INIT_FAILURE_CONSOLE ((NTSTATUS) 0xC00002ECL)
+#endif
+
+#ifndef STATUS_DS_SAM_INIT_FAILURE_CONSOLE
+# define STATUS_DS_SAM_INIT_FAILURE_CONSOLE ((NTSTATUS) 0xC00002EDL)
+#endif
+
+#ifndef STATUS_UNFINISHED_CONTEXT_DELETED
+# define STATUS_UNFINISHED_CONTEXT_DELETED ((NTSTATUS) 0xC00002EEL)
+#endif
+
+#ifndef STATUS_NO_TGT_REPLY
+# define STATUS_NO_TGT_REPLY ((NTSTATUS) 0xC00002EFL)
+#endif
+
+#ifndef STATUS_OBJECTID_NOT_FOUND
+# define STATUS_OBJECTID_NOT_FOUND ((NTSTATUS) 0xC00002F0L)
+#endif
+
+#ifndef STATUS_NO_IP_ADDRESSES
+# define STATUS_NO_IP_ADDRESSES ((NTSTATUS) 0xC00002F1L)
+#endif
+
+#ifndef STATUS_WRONG_CREDENTIAL_HANDLE
+# define STATUS_WRONG_CREDENTIAL_HANDLE ((NTSTATUS) 0xC00002F2L)
+#endif
+
+#ifndef STATUS_CRYPTO_SYSTEM_INVALID
+# define STATUS_CRYPTO_SYSTEM_INVALID ((NTSTATUS) 0xC00002F3L)
+#endif
+
+#ifndef STATUS_MAX_REFERRALS_EXCEEDED
+# define STATUS_MAX_REFERRALS_EXCEEDED ((NTSTATUS) 0xC00002F4L)
+#endif
+
+#ifndef STATUS_MUST_BE_KDC
+# define STATUS_MUST_BE_KDC ((NTSTATUS) 0xC00002F5L)
+#endif
+
+#ifndef STATUS_STRONG_CRYPTO_NOT_SUPPORTED
+# define STATUS_STRONG_CRYPTO_NOT_SUPPORTED ((NTSTATUS) 0xC00002F6L)
+#endif
+
+#ifndef STATUS_TOO_MANY_PRINCIPALS
+# define STATUS_TOO_MANY_PRINCIPALS ((NTSTATUS) 0xC00002F7L)
+#endif
+
+#ifndef STATUS_NO_PA_DATA
+# define STATUS_NO_PA_DATA ((NTSTATUS) 0xC00002F8L)
+#endif
+
+#ifndef STATUS_PKINIT_NAME_MISMATCH
+# define STATUS_PKINIT_NAME_MISMATCH ((NTSTATUS) 0xC00002F9L)
+#endif
+
+#ifndef STATUS_SMARTCARD_LOGON_REQUIRED
+# define STATUS_SMARTCARD_LOGON_REQUIRED ((NTSTATUS) 0xC00002FAL)
+#endif
+
+#ifndef STATUS_KDC_INVALID_REQUEST
+# define STATUS_KDC_INVALID_REQUEST ((NTSTATUS) 0xC00002FBL)
+#endif
+
+#ifndef STATUS_KDC_UNABLE_TO_REFER
+# define STATUS_KDC_UNABLE_TO_REFER ((NTSTATUS) 0xC00002FCL)
+#endif
+
+#ifndef STATUS_KDC_UNKNOWN_ETYPE
+# define STATUS_KDC_UNKNOWN_ETYPE ((NTSTATUS) 0xC00002FDL)
+#endif
+
+#ifndef STATUS_SHUTDOWN_IN_PROGRESS
+# define STATUS_SHUTDOWN_IN_PROGRESS ((NTSTATUS) 0xC00002FEL)
+#endif
+
+#ifndef STATUS_SERVER_SHUTDOWN_IN_PROGRESS
+# define STATUS_SERVER_SHUTDOWN_IN_PROGRESS ((NTSTATUS) 0xC00002FFL)
+#endif
+
+#ifndef STATUS_NOT_SUPPORTED_ON_SBS
+# define STATUS_NOT_SUPPORTED_ON_SBS ((NTSTATUS) 0xC0000300L)
+#endif
+
+#ifndef STATUS_WMI_GUID_DISCONNECTED
+# define STATUS_WMI_GUID_DISCONNECTED ((NTSTATUS) 0xC0000301L)
+#endif
+
+#ifndef STATUS_WMI_ALREADY_DISABLED
+# define STATUS_WMI_ALREADY_DISABLED ((NTSTATUS) 0xC0000302L)
+#endif
+
+#ifndef STATUS_WMI_ALREADY_ENABLED
+# define STATUS_WMI_ALREADY_ENABLED ((NTSTATUS) 0xC0000303L)
+#endif
+
+#ifndef STATUS_MFT_TOO_FRAGMENTED
+# define STATUS_MFT_TOO_FRAGMENTED ((NTSTATUS) 0xC0000304L)
+#endif
+
+#ifndef STATUS_COPY_PROTECTION_FAILURE
+# define STATUS_COPY_PROTECTION_FAILURE ((NTSTATUS) 0xC0000305L)
+#endif
+
+#ifndef STATUS_CSS_AUTHENTICATION_FAILURE
+# define STATUS_CSS_AUTHENTICATION_FAILURE ((NTSTATUS) 0xC0000306L)
+#endif
+
+#ifndef STATUS_CSS_KEY_NOT_PRESENT
+# define STATUS_CSS_KEY_NOT_PRESENT ((NTSTATUS) 0xC0000307L)
+#endif
+
+#ifndef STATUS_CSS_KEY_NOT_ESTABLISHED
+# define STATUS_CSS_KEY_NOT_ESTABLISHED ((NTSTATUS) 0xC0000308L)
+#endif
+
+#ifndef STATUS_CSS_SCRAMBLED_SECTOR
+# define STATUS_CSS_SCRAMBLED_SECTOR ((NTSTATUS) 0xC0000309L)
+#endif
+
+#ifndef STATUS_CSS_REGION_MISMATCH
+# define STATUS_CSS_REGION_MISMATCH ((NTSTATUS) 0xC000030AL)
+#endif
+
+#ifndef STATUS_CSS_RESETS_EXHAUSTED
+# define STATUS_CSS_RESETS_EXHAUSTED ((NTSTATUS) 0xC000030BL)
+#endif
+
+#ifndef STATUS_PKINIT_FAILURE
+# define STATUS_PKINIT_FAILURE ((NTSTATUS) 0xC0000320L)
+#endif
+
+#ifndef STATUS_SMARTCARD_SUBSYSTEM_FAILURE
+# define STATUS_SMARTCARD_SUBSYSTEM_FAILURE ((NTSTATUS) 0xC0000321L)
+#endif
+
+#ifndef STATUS_NO_KERB_KEY
+# define STATUS_NO_KERB_KEY ((NTSTATUS) 0xC0000322L)
+#endif
+
+#ifndef STATUS_HOST_DOWN
+# define STATUS_HOST_DOWN ((NTSTATUS) 0xC0000350L)
+#endif
+
+#ifndef STATUS_UNSUPPORTED_PREAUTH
+# define STATUS_UNSUPPORTED_PREAUTH ((NTSTATUS) 0xC0000351L)
+#endif
+
+#ifndef STATUS_EFS_ALG_BLOB_TOO_BIG
+# define STATUS_EFS_ALG_BLOB_TOO_BIG ((NTSTATUS) 0xC0000352L)
+#endif
+
+#ifndef STATUS_PORT_NOT_SET
+# define STATUS_PORT_NOT_SET ((NTSTATUS) 0xC0000353L)
+#endif
+
+#ifndef STATUS_DEBUGGER_INACTIVE
+# define STATUS_DEBUGGER_INACTIVE ((NTSTATUS) 0xC0000354L)
+#endif
+
+#ifndef STATUS_DS_VERSION_CHECK_FAILURE
+# define STATUS_DS_VERSION_CHECK_FAILURE ((NTSTATUS) 0xC0000355L)
+#endif
+
+#ifndef STATUS_AUDITING_DISABLED
+# define STATUS_AUDITING_DISABLED ((NTSTATUS) 0xC0000356L)
+#endif
+
+#ifndef STATUS_PRENT4_MACHINE_ACCOUNT
+# define STATUS_PRENT4_MACHINE_ACCOUNT ((NTSTATUS) 0xC0000357L)
+#endif
+
+#ifndef STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER
+# define STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS) 0xC0000358L)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_WIN_32
+# define STATUS_INVALID_IMAGE_WIN_32 ((NTSTATUS) 0xC0000359L)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_WIN_64
+# define STATUS_INVALID_IMAGE_WIN_64 ((NTSTATUS) 0xC000035AL)
+#endif
+
+#ifndef STATUS_BAD_BINDINGS
+# define STATUS_BAD_BINDINGS ((NTSTATUS) 0xC000035BL)
+#endif
+
+#ifndef STATUS_NETWORK_SESSION_EXPIRED
+# define STATUS_NETWORK_SESSION_EXPIRED ((NTSTATUS) 0xC000035CL)
+#endif
+
+#ifndef STATUS_APPHELP_BLOCK
+# define STATUS_APPHELP_BLOCK ((NTSTATUS) 0xC000035DL)
+#endif
+
+#ifndef STATUS_ALL_SIDS_FILTERED
+# define STATUS_ALL_SIDS_FILTERED ((NTSTATUS) 0xC000035EL)
+#endif
+
+#ifndef STATUS_NOT_SAFE_MODE_DRIVER
+# define STATUS_NOT_SAFE_MODE_DRIVER ((NTSTATUS) 0xC000035FL)
+#endif
+
+#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT
+# define STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT ((NTSTATUS) 0xC0000361L)
+#endif
+
+#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_PATH
+# define STATUS_ACCESS_DISABLED_BY_POLICY_PATH ((NTSTATUS) 0xC0000362L)
+#endif
+
+#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER
+# define STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER ((NTSTATUS) 0xC0000363L)
+#endif
+
+#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_OTHER
+# define STATUS_ACCESS_DISABLED_BY_POLICY_OTHER ((NTSTATUS) 0xC0000364L)
+#endif
+
+#ifndef STATUS_FAILED_DRIVER_ENTRY
+# define STATUS_FAILED_DRIVER_ENTRY ((NTSTATUS) 0xC0000365L)
+#endif
+
+#ifndef STATUS_DEVICE_ENUMERATION_ERROR
+# define STATUS_DEVICE_ENUMERATION_ERROR ((NTSTATUS) 0xC0000366L)
+#endif
+
+#ifndef STATUS_MOUNT_POINT_NOT_RESOLVED
+# define STATUS_MOUNT_POINT_NOT_RESOLVED ((NTSTATUS) 0xC0000368L)
+#endif
+
+#ifndef STATUS_INVALID_DEVICE_OBJECT_PARAMETER
+# define STATUS_INVALID_DEVICE_OBJECT_PARAMETER ((NTSTATUS) 0xC0000369L)
+#endif
+
+#ifndef STATUS_MCA_OCCURED
+# define STATUS_MCA_OCCURED ((NTSTATUS) 0xC000036AL)
+#endif
+
+#ifndef STATUS_DRIVER_BLOCKED_CRITICAL
+# define STATUS_DRIVER_BLOCKED_CRITICAL ((NTSTATUS) 0xC000036BL)
+#endif
+
+#ifndef STATUS_DRIVER_BLOCKED
+# define STATUS_DRIVER_BLOCKED ((NTSTATUS) 0xC000036CL)
+#endif
+
+#ifndef STATUS_DRIVER_DATABASE_ERROR
+# define STATUS_DRIVER_DATABASE_ERROR ((NTSTATUS) 0xC000036DL)
+#endif
+
+#ifndef STATUS_SYSTEM_HIVE_TOO_LARGE
+# define STATUS_SYSTEM_HIVE_TOO_LARGE ((NTSTATUS) 0xC000036EL)
+#endif
+
+#ifndef STATUS_INVALID_IMPORT_OF_NON_DLL
+# define STATUS_INVALID_IMPORT_OF_NON_DLL ((NTSTATUS) 0xC000036FL)
+#endif
+
+#ifndef STATUS_DS_SHUTTING_DOWN
+# define STATUS_DS_SHUTTING_DOWN ((NTSTATUS) 0x40000370L)
+#endif
+
+#ifndef STATUS_NO_SECRETS
+# define STATUS_NO_SECRETS ((NTSTATUS) 0xC0000371L)
+#endif
+
+#ifndef STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY
+# define STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY ((NTSTATUS) 0xC0000372L)
+#endif
+
+#ifndef STATUS_FAILED_STACK_SWITCH
+# define STATUS_FAILED_STACK_SWITCH ((NTSTATUS) 0xC0000373L)
+#endif
+
+#ifndef STATUS_HEAP_CORRUPTION
+# define STATUS_HEAP_CORRUPTION ((NTSTATUS) 0xC0000374L)
+#endif
+
+#ifndef STATUS_SMARTCARD_WRONG_PIN
+# define STATUS_SMARTCARD_WRONG_PIN ((NTSTATUS) 0xC0000380L)
+#endif
+
+#ifndef STATUS_SMARTCARD_CARD_BLOCKED
+# define STATUS_SMARTCARD_CARD_BLOCKED ((NTSTATUS) 0xC0000381L)
+#endif
+
+#ifndef STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED
+# define STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED ((NTSTATUS) 0xC0000382L)
+#endif
+
+#ifndef STATUS_SMARTCARD_NO_CARD
+# define STATUS_SMARTCARD_NO_CARD ((NTSTATUS) 0xC0000383L)
+#endif
+
+#ifndef STATUS_SMARTCARD_NO_KEY_CONTAINER
+# define STATUS_SMARTCARD_NO_KEY_CONTAINER ((NTSTATUS) 0xC0000384L)
+#endif
+
+#ifndef STATUS_SMARTCARD_NO_CERTIFICATE
+# define STATUS_SMARTCARD_NO_CERTIFICATE ((NTSTATUS) 0xC0000385L)
+#endif
+
+#ifndef STATUS_SMARTCARD_NO_KEYSET
+# define STATUS_SMARTCARD_NO_KEYSET ((NTSTATUS) 0xC0000386L)
+#endif
+
+#ifndef STATUS_SMARTCARD_IO_ERROR
+# define STATUS_SMARTCARD_IO_ERROR ((NTSTATUS) 0xC0000387L)
+#endif
+
+#ifndef STATUS_DOWNGRADE_DETECTED
+# define STATUS_DOWNGRADE_DETECTED ((NTSTATUS) 0xC0000388L)
+#endif
+
+#ifndef STATUS_SMARTCARD_CERT_REVOKED
+# define STATUS_SMARTCARD_CERT_REVOKED ((NTSTATUS) 0xC0000389L)
+#endif
+
+#ifndef STATUS_ISSUING_CA_UNTRUSTED
+# define STATUS_ISSUING_CA_UNTRUSTED ((NTSTATUS) 0xC000038AL)
+#endif
+
+#ifndef STATUS_REVOCATION_OFFLINE_C
+# define STATUS_REVOCATION_OFFLINE_C ((NTSTATUS) 0xC000038BL)
+#endif
+
+#ifndef STATUS_PKINIT_CLIENT_FAILURE
+# define STATUS_PKINIT_CLIENT_FAILURE ((NTSTATUS) 0xC000038CL)
+#endif
+
+#ifndef STATUS_SMARTCARD_CERT_EXPIRED
+# define STATUS_SMARTCARD_CERT_EXPIRED ((NTSTATUS) 0xC000038DL)
+#endif
+
+#ifndef STATUS_DRIVER_FAILED_PRIOR_UNLOAD
+# define STATUS_DRIVER_FAILED_PRIOR_UNLOAD ((NTSTATUS) 0xC000038EL)
+#endif
+
+#ifndef STATUS_SMARTCARD_SILENT_CONTEXT
+# define STATUS_SMARTCARD_SILENT_CONTEXT ((NTSTATUS) 0xC000038FL)
+#endif
+
+#ifndef STATUS_PER_USER_TRUST_QUOTA_EXCEEDED
+# define STATUS_PER_USER_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000401L)
+#endif
+
+#ifndef STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED
+# define STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000402L)
+#endif
+
+#ifndef STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED
+# define STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000403L)
+#endif
+
+#ifndef STATUS_DS_NAME_NOT_UNIQUE
+# define STATUS_DS_NAME_NOT_UNIQUE ((NTSTATUS) 0xC0000404L)
+#endif
+
+#ifndef STATUS_DS_DUPLICATE_ID_FOUND
+# define STATUS_DS_DUPLICATE_ID_FOUND ((NTSTATUS) 0xC0000405L)
+#endif
+
+#ifndef STATUS_DS_GROUP_CONVERSION_ERROR
+# define STATUS_DS_GROUP_CONVERSION_ERROR ((NTSTATUS) 0xC0000406L)
+#endif
+
+#ifndef STATUS_VOLSNAP_PREPARE_HIBERNATE
+# define STATUS_VOLSNAP_PREPARE_HIBERNATE ((NTSTATUS) 0xC0000407L)
+#endif
+
+#ifndef STATUS_USER2USER_REQUIRED
+# define STATUS_USER2USER_REQUIRED ((NTSTATUS) 0xC0000408L)
+#endif
+
+#ifndef STATUS_STACK_BUFFER_OVERRUN
+# define STATUS_STACK_BUFFER_OVERRUN ((NTSTATUS) 0xC0000409L)
+#endif
+
+#ifndef STATUS_NO_S4U_PROT_SUPPORT
+# define STATUS_NO_S4U_PROT_SUPPORT ((NTSTATUS) 0xC000040AL)
+#endif
+
+#ifndef STATUS_CROSSREALM_DELEGATION_FAILURE
+# define STATUS_CROSSREALM_DELEGATION_FAILURE ((NTSTATUS) 0xC000040BL)
+#endif
+
+#ifndef STATUS_REVOCATION_OFFLINE_KDC
+# define STATUS_REVOCATION_OFFLINE_KDC ((NTSTATUS) 0xC000040CL)
+#endif
+
+#ifndef STATUS_ISSUING_CA_UNTRUSTED_KDC
+# define STATUS_ISSUING_CA_UNTRUSTED_KDC ((NTSTATUS) 0xC000040DL)
+#endif
+
+#ifndef STATUS_KDC_CERT_EXPIRED
+# define STATUS_KDC_CERT_EXPIRED ((NTSTATUS) 0xC000040EL)
+#endif
+
+#ifndef STATUS_KDC_CERT_REVOKED
+# define STATUS_KDC_CERT_REVOKED ((NTSTATUS) 0xC000040FL)
+#endif
+
+#ifndef STATUS_PARAMETER_QUOTA_EXCEEDED
+# define STATUS_PARAMETER_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000410L)
+#endif
+
+#ifndef STATUS_HIBERNATION_FAILURE
+# define STATUS_HIBERNATION_FAILURE ((NTSTATUS) 0xC0000411L)
+#endif
+
+#ifndef STATUS_DELAY_LOAD_FAILED
+# define STATUS_DELAY_LOAD_FAILED ((NTSTATUS) 0xC0000412L)
+#endif
+
+#ifndef STATUS_AUTHENTICATION_FIREWALL_FAILED
+# define STATUS_AUTHENTICATION_FIREWALL_FAILED ((NTSTATUS) 0xC0000413L)
+#endif
+
+#ifndef STATUS_VDM_DISALLOWED
+# define STATUS_VDM_DISALLOWED ((NTSTATUS) 0xC0000414L)
+#endif
+
+#ifndef STATUS_HUNG_DISPLAY_DRIVER_THREAD
+# define STATUS_HUNG_DISPLAY_DRIVER_THREAD ((NTSTATUS) 0xC0000415L)
+#endif
+
+#ifndef STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE
+# define STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE ((NTSTATUS) 0xC0000416L)
+#endif
+
+#ifndef STATUS_INVALID_CRUNTIME_PARAMETER
+# define STATUS_INVALID_CRUNTIME_PARAMETER ((NTSTATUS) 0xC0000417L)
+#endif
+
+#ifndef STATUS_NTLM_BLOCKED
+# define STATUS_NTLM_BLOCKED ((NTSTATUS) 0xC0000418L)
+#endif
+
+#ifndef STATUS_DS_SRC_SID_EXISTS_IN_FOREST
+# define STATUS_DS_SRC_SID_EXISTS_IN_FOREST ((NTSTATUS) 0xC0000419L)
+#endif
+
+#ifndef STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST
+# define STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST ((NTSTATUS) 0xC000041AL)
+#endif
+
+#ifndef STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST
+# define STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST ((NTSTATUS) 0xC000041BL)
+#endif
+
+#ifndef STATUS_INVALID_USER_PRINCIPAL_NAME
+# define STATUS_INVALID_USER_PRINCIPAL_NAME ((NTSTATUS) 0xC000041CL)
+#endif
+
+#ifndef STATUS_FATAL_USER_CALLBACK_EXCEPTION
+# define STATUS_FATAL_USER_CALLBACK_EXCEPTION ((NTSTATUS) 0xC000041DL)
+#endif
+
+#ifndef STATUS_ASSERTION_FAILURE
+# define STATUS_ASSERTION_FAILURE ((NTSTATUS) 0xC0000420L)
+#endif
+
+#ifndef STATUS_VERIFIER_STOP
+# define STATUS_VERIFIER_STOP ((NTSTATUS) 0xC0000421L)
+#endif
+
+#ifndef STATUS_CALLBACK_POP_STACK
+# define STATUS_CALLBACK_POP_STACK ((NTSTATUS) 0xC0000423L)
+#endif
+
+#ifndef STATUS_INCOMPATIBLE_DRIVER_BLOCKED
+# define STATUS_INCOMPATIBLE_DRIVER_BLOCKED ((NTSTATUS) 0xC0000424L)
+#endif
+
+#ifndef STATUS_HIVE_UNLOADED
+# define STATUS_HIVE_UNLOADED ((NTSTATUS) 0xC0000425L)
+#endif
+
+#ifndef STATUS_COMPRESSION_DISABLED
+# define STATUS_COMPRESSION_DISABLED ((NTSTATUS) 0xC0000426L)
+#endif
+
+#ifndef STATUS_FILE_SYSTEM_LIMITATION
+# define STATUS_FILE_SYSTEM_LIMITATION ((NTSTATUS) 0xC0000427L)
+#endif
+
+#ifndef STATUS_INVALID_IMAGE_HASH
+# define STATUS_INVALID_IMAGE_HASH ((NTSTATUS) 0xC0000428L)
+#endif
+
+#ifndef STATUS_NOT_CAPABLE
+# define STATUS_NOT_CAPABLE ((NTSTATUS) 0xC0000429L)
+#endif
+
+#ifndef STATUS_REQUEST_OUT_OF_SEQUENCE
+# define STATUS_REQUEST_OUT_OF_SEQUENCE ((NTSTATUS) 0xC000042AL)
+#endif
+
+#ifndef STATUS_IMPLEMENTATION_LIMIT
+# define STATUS_IMPLEMENTATION_LIMIT ((NTSTATUS) 0xC000042BL)
+#endif
+
+#ifndef STATUS_ELEVATION_REQUIRED
+# define STATUS_ELEVATION_REQUIRED ((NTSTATUS) 0xC000042CL)
+#endif
+
+#ifndef STATUS_NO_SECURITY_CONTEXT
+# define STATUS_NO_SECURITY_CONTEXT ((NTSTATUS) 0xC000042DL)
+#endif
+
+#ifndef STATUS_PKU2U_CERT_FAILURE
+# define STATUS_PKU2U_CERT_FAILURE ((NTSTATUS) 0xC000042FL)
+#endif
+
+#ifndef STATUS_BEYOND_VDL
+# define STATUS_BEYOND_VDL ((NTSTATUS) 0xC0000432L)
+#endif
+
+#ifndef STATUS_ENCOUNTERED_WRITE_IN_PROGRESS
+# define STATUS_ENCOUNTERED_WRITE_IN_PROGRESS ((NTSTATUS) 0xC0000433L)
+#endif
+
+#ifndef STATUS_PTE_CHANGED
+# define STATUS_PTE_CHANGED ((NTSTATUS) 0xC0000434L)
+#endif
+
+#ifndef STATUS_PURGE_FAILED
+# define STATUS_PURGE_FAILED ((NTSTATUS) 0xC0000435L)
+#endif
+
+#ifndef STATUS_CRED_REQUIRES_CONFIRMATION
+# define STATUS_CRED_REQUIRES_CONFIRMATION ((NTSTATUS) 0xC0000440L)
+#endif
+
+#ifndef STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE
+# define STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE ((NTSTATUS) 0xC0000441L)
+#endif
+
+#ifndef STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER
+# define STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER ((NTSTATUS) 0xC0000442L)
+#endif
+
+#ifndef STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE
+# define STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE ((NTSTATUS) 0xC0000443L)
+#endif
+
+#ifndef STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE
+# define STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE ((NTSTATUS) 0xC0000444L)
+#endif
+
+#ifndef STATUS_CS_ENCRYPTION_FILE_NOT_CSE
+# define STATUS_CS_ENCRYPTION_FILE_NOT_CSE ((NTSTATUS) 0xC0000445L)
+#endif
+
+#ifndef STATUS_INVALID_LABEL
+# define STATUS_INVALID_LABEL ((NTSTATUS) 0xC0000446L)
+#endif
+
+#ifndef STATUS_DRIVER_PROCESS_TERMINATED
+# define STATUS_DRIVER_PROCESS_TERMINATED ((NTSTATUS) 0xC0000450L)
+#endif
+
+#ifndef STATUS_AMBIGUOUS_SYSTEM_DEVICE
+# define STATUS_AMBIGUOUS_SYSTEM_DEVICE ((NTSTATUS) 0xC0000451L)
+#endif
+
+#ifndef STATUS_SYSTEM_DEVICE_NOT_FOUND
+# define STATUS_SYSTEM_DEVICE_NOT_FOUND ((NTSTATUS) 0xC0000452L)
+#endif
+
+#ifndef STATUS_RESTART_BOOT_APPLICATION
+# define STATUS_RESTART_BOOT_APPLICATION ((NTSTATUS) 0xC0000453L)
+#endif
+
+#ifndef STATUS_INSUFFICIENT_NVRAM_RESOURCES
+# define STATUS_INSUFFICIENT_NVRAM_RESOURCES ((NTSTATUS) 0xC0000454L)
+#endif
+
+#ifndef STATUS_INVALID_TASK_NAME
+# define STATUS_INVALID_TASK_NAME ((NTSTATUS) 0xC0000500L)
+#endif
+
+#ifndef STATUS_INVALID_TASK_INDEX
+# define STATUS_INVALID_TASK_INDEX ((NTSTATUS) 0xC0000501L)
+#endif
+
+#ifndef STATUS_THREAD_ALREADY_IN_TASK
+# define STATUS_THREAD_ALREADY_IN_TASK ((NTSTATUS) 0xC0000502L)
+#endif
+
+#ifndef STATUS_CALLBACK_BYPASS
+# define STATUS_CALLBACK_BYPASS ((NTSTATUS) 0xC0000503L)
+#endif
+
+#ifndef STATUS_FAIL_FAST_EXCEPTION
+# define STATUS_FAIL_FAST_EXCEPTION ((NTSTATUS) 0xC0000602L)
+#endif
+
+#ifndef STATUS_IMAGE_CERT_REVOKED
+# define STATUS_IMAGE_CERT_REVOKED ((NTSTATUS) 0xC0000603L)
+#endif
+
+#ifndef STATUS_PORT_CLOSED
+# define STATUS_PORT_CLOSED ((NTSTATUS) 0xC0000700L)
+#endif
+
+#ifndef STATUS_MESSAGE_LOST
+# define STATUS_MESSAGE_LOST ((NTSTATUS) 0xC0000701L)
+#endif
+
+#ifndef STATUS_INVALID_MESSAGE
+# define STATUS_INVALID_MESSAGE ((NTSTATUS) 0xC0000702L)
+#endif
+
+#ifndef STATUS_REQUEST_CANCELED
+# define STATUS_REQUEST_CANCELED ((NTSTATUS) 0xC0000703L)
+#endif
+
+#ifndef STATUS_RECURSIVE_DISPATCH
+# define STATUS_RECURSIVE_DISPATCH ((NTSTATUS) 0xC0000704L)
+#endif
+
+#ifndef STATUS_LPC_RECEIVE_BUFFER_EXPECTED
+# define STATUS_LPC_RECEIVE_BUFFER_EXPECTED ((NTSTATUS) 0xC0000705L)
+#endif
+
+#ifndef STATUS_LPC_INVALID_CONNECTION_USAGE
+# define STATUS_LPC_INVALID_CONNECTION_USAGE ((NTSTATUS) 0xC0000706L)
+#endif
+
+#ifndef STATUS_LPC_REQUESTS_NOT_ALLOWED
+# define STATUS_LPC_REQUESTS_NOT_ALLOWED ((NTSTATUS) 0xC0000707L)
+#endif
+
+#ifndef STATUS_RESOURCE_IN_USE
+# define STATUS_RESOURCE_IN_USE ((NTSTATUS) 0xC0000708L)
+#endif
+
+#ifndef STATUS_HARDWARE_MEMORY_ERROR
+# define STATUS_HARDWARE_MEMORY_ERROR ((NTSTATUS) 0xC0000709L)
+#endif
+
+#ifndef STATUS_THREADPOOL_HANDLE_EXCEPTION
+# define STATUS_THREADPOOL_HANDLE_EXCEPTION ((NTSTATUS) 0xC000070AL)
+#endif
+
+#ifndef STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED
+# define STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070BL)
+#endif
+
+#ifndef STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED
+# define STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070CL)
+#endif
+
+#ifndef STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED
+# define STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070DL)
+#endif
+
+#ifndef STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED
+# define STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070EL)
+#endif
+
+#ifndef STATUS_THREADPOOL_RELEASED_DURING_OPERATION
+# define STATUS_THREADPOOL_RELEASED_DURING_OPERATION ((NTSTATUS) 0xC000070FL)
+#endif
+
+#ifndef STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING
+# define STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING ((NTSTATUS) 0xC0000710L)
+#endif
+
+#ifndef STATUS_APC_RETURNED_WHILE_IMPERSONATING
+# define STATUS_APC_RETURNED_WHILE_IMPERSONATING ((NTSTATUS) 0xC0000711L)
+#endif
+
+#ifndef STATUS_PROCESS_IS_PROTECTED
+# define STATUS_PROCESS_IS_PROTECTED ((NTSTATUS) 0xC0000712L)
+#endif
+
+#ifndef STATUS_MCA_EXCEPTION
+# define STATUS_MCA_EXCEPTION ((NTSTATUS) 0xC0000713L)
+#endif
+
+#ifndef STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE
+# define STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE ((NTSTATUS) 0xC0000714L)
+#endif
+
+#ifndef STATUS_SYMLINK_CLASS_DISABLED
+# define STATUS_SYMLINK_CLASS_DISABLED ((NTSTATUS) 0xC0000715L)
+#endif
+
+#ifndef STATUS_INVALID_IDN_NORMALIZATION
+# define STATUS_INVALID_IDN_NORMALIZATION ((NTSTATUS) 0xC0000716L)
+#endif
+
+#ifndef STATUS_NO_UNICODE_TRANSLATION
+# define STATUS_NO_UNICODE_TRANSLATION ((NTSTATUS) 0xC0000717L)
+#endif
+
+#ifndef STATUS_ALREADY_REGISTERED
+# define STATUS_ALREADY_REGISTERED ((NTSTATUS) 0xC0000718L)
+#endif
+
+#ifndef STATUS_CONTEXT_MISMATCH
+# define STATUS_CONTEXT_MISMATCH ((NTSTATUS) 0xC0000719L)
+#endif
+
+#ifndef STATUS_PORT_ALREADY_HAS_COMPLETION_LIST
+# define STATUS_PORT_ALREADY_HAS_COMPLETION_LIST ((NTSTATUS) 0xC000071AL)
+#endif
+
+#ifndef STATUS_CALLBACK_RETURNED_THREAD_PRIORITY
+# define STATUS_CALLBACK_RETURNED_THREAD_PRIORITY ((NTSTATUS) 0xC000071BL)
+#endif
+
+#ifndef STATUS_INVALID_THREAD
+# define STATUS_INVALID_THREAD ((NTSTATUS) 0xC000071CL)
+#endif
+
+#ifndef STATUS_CALLBACK_RETURNED_TRANSACTION
+# define STATUS_CALLBACK_RETURNED_TRANSACTION ((NTSTATUS) 0xC000071DL)
+#endif
+
+#ifndef STATUS_CALLBACK_RETURNED_LDR_LOCK
+# define STATUS_CALLBACK_RETURNED_LDR_LOCK ((NTSTATUS) 0xC000071EL)
+#endif
+
+#ifndef STATUS_CALLBACK_RETURNED_LANG
+# define STATUS_CALLBACK_RETURNED_LANG ((NTSTATUS) 0xC000071FL)
+#endif
+
+#ifndef STATUS_CALLBACK_RETURNED_PRI_BACK
+# define STATUS_CALLBACK_RETURNED_PRI_BACK ((NTSTATUS) 0xC0000720L)
+#endif
+
+#ifndef STATUS_CALLBACK_RETURNED_THREAD_AFFINITY
+# define STATUS_CALLBACK_RETURNED_THREAD_AFFINITY ((NTSTATUS) 0xC0000721L)
+#endif
+
+#ifndef STATUS_DISK_REPAIR_DISABLED
+# define STATUS_DISK_REPAIR_DISABLED ((NTSTATUS) 0xC0000800L)
+#endif
+
+#ifndef STATUS_DS_DOMAIN_RENAME_IN_PROGRESS
+# define STATUS_DS_DOMAIN_RENAME_IN_PROGRESS ((NTSTATUS) 0xC0000801L)
+#endif
+
+#ifndef STATUS_DISK_QUOTA_EXCEEDED
+# define STATUS_DISK_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000802L)
+#endif
+
+#ifndef STATUS_DATA_LOST_REPAIR
+# define STATUS_DATA_LOST_REPAIR ((NTSTATUS) 0x80000803L)
+#endif
+
+#ifndef STATUS_CONTENT_BLOCKED
+# define STATUS_CONTENT_BLOCKED ((NTSTATUS) 0xC0000804L)
+#endif
+
+#ifndef STATUS_BAD_CLUSTERS
+# define STATUS_BAD_CLUSTERS ((NTSTATUS) 0xC0000805L)
+#endif
+
+#ifndef STATUS_VOLUME_DIRTY
+# define STATUS_VOLUME_DIRTY ((NTSTATUS) 0xC0000806L)
+#endif
+
+#ifndef STATUS_FILE_CHECKED_OUT
+# define STATUS_FILE_CHECKED_OUT ((NTSTATUS) 0xC0000901L)
+#endif
+
+#ifndef STATUS_CHECKOUT_REQUIRED
+# define STATUS_CHECKOUT_REQUIRED ((NTSTATUS) 0xC0000902L)
+#endif
+
+#ifndef STATUS_BAD_FILE_TYPE
+# define STATUS_BAD_FILE_TYPE ((NTSTATUS) 0xC0000903L)
+#endif
+
+#ifndef STATUS_FILE_TOO_LARGE
+# define STATUS_FILE_TOO_LARGE ((NTSTATUS) 0xC0000904L)
+#endif
+
+#ifndef STATUS_FORMS_AUTH_REQUIRED
+# define STATUS_FORMS_AUTH_REQUIRED ((NTSTATUS) 0xC0000905L)
+#endif
+
+#ifndef STATUS_VIRUS_INFECTED
+# define STATUS_VIRUS_INFECTED ((NTSTATUS) 0xC0000906L)
+#endif
+
+#ifndef STATUS_VIRUS_DELETED
+# define STATUS_VIRUS_DELETED ((NTSTATUS) 0xC0000907L)
+#endif
+
+#ifndef STATUS_BAD_MCFG_TABLE
+# define STATUS_BAD_MCFG_TABLE ((NTSTATUS) 0xC0000908L)
+#endif
+
+#ifndef STATUS_CANNOT_BREAK_OPLOCK
+# define STATUS_CANNOT_BREAK_OPLOCK ((NTSTATUS) 0xC0000909L)
+#endif
+
+#ifndef STATUS_WOW_ASSERTION
+# define STATUS_WOW_ASSERTION ((NTSTATUS) 0xC0009898L)
+#endif
+
+#ifndef STATUS_INVALID_SIGNATURE
+# define STATUS_INVALID_SIGNATURE ((NTSTATUS) 0xC000A000L)
+#endif
+
+#ifndef STATUS_HMAC_NOT_SUPPORTED
+# define STATUS_HMAC_NOT_SUPPORTED ((NTSTATUS) 0xC000A001L)
+#endif
+
+#ifndef STATUS_AUTH_TAG_MISMATCH
+# define STATUS_AUTH_TAG_MISMATCH ((NTSTATUS) 0xC000A002L)
+#endif
+
+#ifndef STATUS_IPSEC_QUEUE_OVERFLOW
+# define STATUS_IPSEC_QUEUE_OVERFLOW ((NTSTATUS) 0xC000A010L)
+#endif
+
+#ifndef STATUS_ND_QUEUE_OVERFLOW
+# define STATUS_ND_QUEUE_OVERFLOW ((NTSTATUS) 0xC000A011L)
+#endif
+
+#ifndef STATUS_HOPLIMIT_EXCEEDED
+# define STATUS_HOPLIMIT_EXCEEDED ((NTSTATUS) 0xC000A012L)
+#endif
+
+#ifndef STATUS_PROTOCOL_NOT_SUPPORTED
+# define STATUS_PROTOCOL_NOT_SUPPORTED ((NTSTATUS) 0xC000A013L)
+#endif
+
+#ifndef STATUS_FASTPATH_REJECTED
+# define STATUS_FASTPATH_REJECTED ((NTSTATUS) 0xC000A014L)
+#endif
+
+#ifndef STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED
+# define STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED ((NTSTATUS) 0xC000A080L)
+#endif
+
+#ifndef STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR
+# define STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR ((NTSTATUS) 0xC000A081L)
+#endif
+
+#ifndef STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR
+# define STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR ((NTSTATUS) 0xC000A082L)
+#endif
+
+#ifndef STATUS_XML_PARSE_ERROR
+# define STATUS_XML_PARSE_ERROR ((NTSTATUS) 0xC000A083L)
+#endif
+
+#ifndef STATUS_XMLDSIG_ERROR
+# define STATUS_XMLDSIG_ERROR ((NTSTATUS) 0xC000A084L)
+#endif
+
+#ifndef STATUS_WRONG_COMPARTMENT
+# define STATUS_WRONG_COMPARTMENT ((NTSTATUS) 0xC000A085L)
+#endif
+
+#ifndef STATUS_AUTHIP_FAILURE
+# define STATUS_AUTHIP_FAILURE ((NTSTATUS) 0xC000A086L)
+#endif
+
+#ifndef STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS
+# define STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS ((NTSTATUS) 0xC000A087L)
+#endif
+
+#ifndef STATUS_DS_OID_NOT_FOUND
+# define STATUS_DS_OID_NOT_FOUND ((NTSTATUS) 0xC000A088L)
+#endif
+
+#ifndef STATUS_HASH_NOT_SUPPORTED
+# define STATUS_HASH_NOT_SUPPORTED ((NTSTATUS) 0xC000A100L)
+#endif
+
+#ifndef STATUS_HASH_NOT_PRESENT
+# define STATUS_HASH_NOT_PRESENT ((NTSTATUS) 0xC000A101L)
+#endif
+
+/* This is not the NTSTATUS_FROM_WIN32 that the DDK provides, because the */
+/* DDK got it wrong! */
+#ifdef NTSTATUS_FROM_WIN32
+# undef NTSTATUS_FROM_WIN32
+#endif
+#define NTSTATUS_FROM_WIN32(error) ((NTSTATUS) (error) <= 0 ? \
+        ((NTSTATUS) (error)) : ((NTSTATUS) (((error) & 0x0000FFFF) | \
+        (FACILITY_NTWIN32 << 16) | ERROR_SEVERITY_WARNING)))
+
+#ifndef JOB_OBJECT_LIMIT_PROCESS_MEMORY
+# define JOB_OBJECT_LIMIT_PROCESS_MEMORY             0x00000100
+#endif
+#ifndef JOB_OBJECT_LIMIT_JOB_MEMORY
+# define JOB_OBJECT_LIMIT_JOB_MEMORY                 0x00000200
+#endif
+#ifndef JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION
+# define JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION 0x00000400
+#endif
+#ifndef JOB_OBJECT_LIMIT_BREAKAWAY_OK
+# define JOB_OBJECT_LIMIT_BREAKAWAY_OK               0x00000800
+#endif
+#ifndef JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK
+# define JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK        0x00001000
+#endif
+#ifndef JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
+# define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE          0x00002000
+#endif
+
+/* from winternl.h */
+typedef struct _UNICODE_STRING {
+  USHORT Length;
+  USHORT MaximumLength;
+  PWSTR  Buffer;
+} UNICODE_STRING, *PUNICODE_STRING;
+
+typedef const UNICODE_STRING *PCUNICODE_STRING;
+
+/* from ntifs.h */
+#ifndef DEVICE_TYPE
+# define DEVICE_TYPE DWORD
+#endif
+
+/* MinGW already has a definition for REPARSE_DATA_BUFFER, but mingw-w64 does
+ * not.
+ */
+#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)
+  typedef struct _REPARSE_DATA_BUFFER {
+    ULONG  ReparseTag;
+    USHORT ReparseDataLength;
+    USHORT Reserved;
+    union {
+      struct {
+        USHORT SubstituteNameOffset;
+        USHORT SubstituteNameLength;
+        USHORT PrintNameOffset;
+        USHORT PrintNameLength;
+        ULONG Flags;
+        WCHAR PathBuffer[1];
+      } SymbolicLinkReparseBuffer;
+      struct {
+        USHORT SubstituteNameOffset;
+        USHORT SubstituteNameLength;
+        USHORT PrintNameOffset;
+        USHORT PrintNameLength;
+        WCHAR PathBuffer[1];
+      } MountPointReparseBuffer;
+      struct {
+        UCHAR  DataBuffer[1];
+      } GenericReparseBuffer;
+    };
+  } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
+#endif
+
+typedef struct _IO_STATUS_BLOCK {
+  union {
+    NTSTATUS Status;
+    PVOID Pointer;
+  };
+  ULONG_PTR Information;
+} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
+
+typedef enum _FILE_INFORMATION_CLASS {
+  FileDirectoryInformation = 1,
+  FileFullDirectoryInformation,
+  FileBothDirectoryInformation,
+  FileBasicInformation,
+  FileStandardInformation,
+  FileInternalInformation,
+  FileEaInformation,
+  FileAccessInformation,
+  FileNameInformation,
+  FileRenameInformation,
+  FileLinkInformation,
+  FileNamesInformation,
+  FileDispositionInformation,
+  FilePositionInformation,
+  FileFullEaInformation,
+  FileModeInformation,
+  FileAlignmentInformation,
+  FileAllInformation,
+  FileAllocationInformation,
+  FileEndOfFileInformation,
+  FileAlternateNameInformation,
+  FileStreamInformation,
+  FilePipeInformation,
+  FilePipeLocalInformation,
+  FilePipeRemoteInformation,
+  FileMailslotQueryInformation,
+  FileMailslotSetInformation,
+  FileCompressionInformation,
+  FileObjectIdInformation,
+  FileCompletionInformation,
+  FileMoveClusterInformation,
+  FileQuotaInformation,
+  FileReparsePointInformation,
+  FileNetworkOpenInformation,
+  FileAttributeTagInformation,
+  FileTrackingInformation,
+  FileIdBothDirectoryInformation,
+  FileIdFullDirectoryInformation,
+  FileValidDataLengthInformation,
+  FileShortNameInformation,
+  FileIoCompletionNotificationInformation,
+  FileIoStatusBlockRangeInformation,
+  FileIoPriorityHintInformation,
+  FileSfioReserveInformation,
+  FileSfioVolumeInformation,
+  FileHardLinkInformation,
+  FileProcessIdsUsingFileInformation,
+  FileNormalizedNameInformation,
+  FileNetworkPhysicalNameInformation,
+  FileIdGlobalTxDirectoryInformation,
+  FileIsRemoteDeviceInformation,
+  FileAttributeCacheInformation,
+  FileNumaNodeInformation,
+  FileStandardLinkInformation,
+  FileRemoteProtocolInformation,
+  FileMaximumInformation
+} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
+
+typedef struct _FILE_DIRECTORY_INFORMATION {
+  ULONG NextEntryOffset;
+  ULONG FileIndex;
+  LARGE_INTEGER CreationTime;
+  LARGE_INTEGER LastAccessTime;
+  LARGE_INTEGER LastWriteTime;
+  LARGE_INTEGER ChangeTime;
+  LARGE_INTEGER EndOfFile;
+  LARGE_INTEGER AllocationSize;
+  ULONG FileAttributes;
+  ULONG FileNameLength;
+  WCHAR FileName[1];
+} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;
+
+typedef struct _FILE_BOTH_DIR_INFORMATION {
+  ULONG NextEntryOffset;
+  ULONG FileIndex;
+  LARGE_INTEGER CreationTime;
+  LARGE_INTEGER LastAccessTime;
+  LARGE_INTEGER LastWriteTime;
+  LARGE_INTEGER ChangeTime;
+  LARGE_INTEGER EndOfFile;
+  LARGE_INTEGER AllocationSize;
+  ULONG FileAttributes;
+  ULONG FileNameLength;
+  ULONG EaSize;
+  CCHAR ShortNameLength;
+  WCHAR ShortName[12];
+  WCHAR FileName[1];
+} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
+
+typedef struct _FILE_BASIC_INFORMATION {
+  LARGE_INTEGER CreationTime;
+  LARGE_INTEGER LastAccessTime;
+  LARGE_INTEGER LastWriteTime;
+  LARGE_INTEGER ChangeTime;
+  DWORD FileAttributes;
+} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;
+
+typedef struct _FILE_STANDARD_INFORMATION {
+  LARGE_INTEGER AllocationSize;
+  LARGE_INTEGER EndOfFile;
+  ULONG         NumberOfLinks;
+  BOOLEAN       DeletePending;
+  BOOLEAN       Directory;
+} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
+
+typedef struct _FILE_INTERNAL_INFORMATION {
+  LARGE_INTEGER IndexNumber;
+} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION;
+
+typedef struct _FILE_EA_INFORMATION {
+  ULONG EaSize;
+} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION;
+
+typedef struct _FILE_ACCESS_INFORMATION {
+  ACCESS_MASK AccessFlags;
+} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION;
+
+typedef struct _FILE_POSITION_INFORMATION {
+  LARGE_INTEGER CurrentByteOffset;
+} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
+
+typedef struct _FILE_MODE_INFORMATION {
+  ULONG Mode;
+} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION;
+
+typedef struct _FILE_ALIGNMENT_INFORMATION {
+  ULONG AlignmentRequirement;
+} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION;
+
+typedef struct _FILE_NAME_INFORMATION {
+  ULONG FileNameLength;
+  WCHAR FileName[1];
+} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
+
+typedef struct _FILE_END_OF_FILE_INFORMATION {
+  LARGE_INTEGER  EndOfFile;
+} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION;
+
+typedef struct _FILE_ALL_INFORMATION {
+  FILE_BASIC_INFORMATION     BasicInformation;
+  FILE_STANDARD_INFORMATION  StandardInformation;
+  FILE_INTERNAL_INFORMATION  InternalInformation;
+  FILE_EA_INFORMATION        EaInformation;
+  FILE_ACCESS_INFORMATION    AccessInformation;
+  FILE_POSITION_INFORMATION  PositionInformation;
+  FILE_MODE_INFORMATION      ModeInformation;
+  FILE_ALIGNMENT_INFORMATION AlignmentInformation;
+  FILE_NAME_INFORMATION      NameInformation;
+} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION;
+
+typedef struct _FILE_DISPOSITION_INFORMATION {
+  BOOLEAN DeleteFile;
+} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION;
+
+typedef struct _FILE_PIPE_LOCAL_INFORMATION {
+  ULONG NamedPipeType;
+  ULONG NamedPipeConfiguration;
+  ULONG MaximumInstances;
+  ULONG CurrentInstances;
+  ULONG InboundQuota;
+  ULONG ReadDataAvailable;
+  ULONG OutboundQuota;
+  ULONG WriteQuotaAvailable;
+  ULONG NamedPipeState;
+  ULONG NamedPipeEnd;
+} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;
+
+#define FILE_SYNCHRONOUS_IO_ALERT               0x00000010
+#define FILE_SYNCHRONOUS_IO_NONALERT            0x00000020
+
+typedef enum _FS_INFORMATION_CLASS {
+  FileFsVolumeInformation       = 1,
+  FileFsLabelInformation        = 2,
+  FileFsSizeInformation         = 3,
+  FileFsDeviceInformation       = 4,
+  FileFsAttributeInformation    = 5,
+  FileFsControlInformation      = 6,
+  FileFsFullSizeInformation     = 7,
+  FileFsObjectIdInformation     = 8,
+  FileFsDriverPathInformation   = 9,
+  FileFsVolumeFlagsInformation  = 10,
+  FileFsSectorSizeInformation   = 11
+} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
+
+typedef struct _FILE_FS_VOLUME_INFORMATION {
+  LARGE_INTEGER VolumeCreationTime;
+  ULONG         VolumeSerialNumber;
+  ULONG         VolumeLabelLength;
+  BOOLEAN       SupportsObjects;
+  WCHAR         VolumeLabel[1];
+} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION;
+
+typedef struct _FILE_FS_LABEL_INFORMATION {
+  ULONG VolumeLabelLength;
+  WCHAR VolumeLabel[1];
+} FILE_FS_LABEL_INFORMATION, *PFILE_FS_LABEL_INFORMATION;
+
+typedef struct _FILE_FS_SIZE_INFORMATION {
+  LARGE_INTEGER TotalAllocationUnits;
+  LARGE_INTEGER AvailableAllocationUnits;
+  ULONG         SectorsPerAllocationUnit;
+  ULONG         BytesPerSector;
+} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION;
+
+typedef struct _FILE_FS_DEVICE_INFORMATION {
+  DEVICE_TYPE DeviceType;
+  ULONG       Characteristics;
+} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;
+
+typedef struct _FILE_FS_ATTRIBUTE_INFORMATION {
+  ULONG FileSystemAttributes;
+  LONG  MaximumComponentNameLength;
+  ULONG FileSystemNameLength;
+  WCHAR FileSystemName[1];
+} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;
+
+typedef struct _FILE_FS_CONTROL_INFORMATION {
+  LARGE_INTEGER FreeSpaceStartFiltering;
+  LARGE_INTEGER FreeSpaceThreshold;
+  LARGE_INTEGER FreeSpaceStopFiltering;
+  LARGE_INTEGER DefaultQuotaThreshold;
+  LARGE_INTEGER DefaultQuotaLimit;
+  ULONG         FileSystemControlFlags;
+} FILE_FS_CONTROL_INFORMATION, *PFILE_FS_CONTROL_INFORMATION;
+
+typedef struct _FILE_FS_FULL_SIZE_INFORMATION {
+  LARGE_INTEGER TotalAllocationUnits;
+  LARGE_INTEGER CallerAvailableAllocationUnits;
+  LARGE_INTEGER ActualAvailableAllocationUnits;
+  ULONG         SectorsPerAllocationUnit;
+  ULONG         BytesPerSector;
+} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION;
+
+typedef struct _FILE_FS_OBJECTID_INFORMATION {
+  UCHAR ObjectId[16];
+  UCHAR ExtendedInfo[48];
+} FILE_FS_OBJECTID_INFORMATION, *PFILE_FS_OBJECTID_INFORMATION;
+
+typedef struct _FILE_FS_DRIVER_PATH_INFORMATION {
+  BOOLEAN DriverInPath;
+  ULONG   DriverNameLength;
+  WCHAR   DriverName[1];
+} FILE_FS_DRIVER_PATH_INFORMATION, *PFILE_FS_DRIVER_PATH_INFORMATION;
+
+typedef struct _FILE_FS_VOLUME_FLAGS_INFORMATION {
+  ULONG Flags;
+} FILE_FS_VOLUME_FLAGS_INFORMATION, *PFILE_FS_VOLUME_FLAGS_INFORMATION;
+
+typedef struct _FILE_FS_SECTOR_SIZE_INFORMATION {
+  ULONG LogicalBytesPerSector;
+  ULONG PhysicalBytesPerSectorForAtomicity;
+  ULONG PhysicalBytesPerSectorForPerformance;
+  ULONG FileSystemEffectivePhysicalBytesPerSectorForAtomicity;
+  ULONG Flags;
+  ULONG ByteOffsetForSectorAlignment;
+  ULONG ByteOffsetForPartitionAlignment;
+} FILE_FS_SECTOR_SIZE_INFORMATION, *PFILE_FS_SECTOR_SIZE_INFORMATION;
+
+typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
+    LARGE_INTEGER IdleTime;
+    LARGE_INTEGER KernelTime;
+    LARGE_INTEGER UserTime;
+    LARGE_INTEGER DpcTime;
+    LARGE_INTEGER InterruptTime;
+    ULONG InterruptCount;
+} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
+
+#ifndef SystemProcessorPerformanceInformation
+# define SystemProcessorPerformanceInformation 8
+#endif
+
+#ifndef FILE_DEVICE_FILE_SYSTEM
+# define FILE_DEVICE_FILE_SYSTEM 0x00000009
+#endif
+
+#ifndef FILE_DEVICE_NETWORK
+# define FILE_DEVICE_NETWORK 0x00000012
+#endif
+
+#ifndef METHOD_BUFFERED
+# define METHOD_BUFFERED 0
+#endif
+
+#ifndef METHOD_IN_DIRECT
+# define METHOD_IN_DIRECT 1
+#endif
+
+#ifndef METHOD_OUT_DIRECT
+# define METHOD_OUT_DIRECT 2
+#endif
+
+#ifndef METHOD_NEITHER
+#define METHOD_NEITHER 3
+#endif
+
+#ifndef METHOD_DIRECT_TO_HARDWARE
+# define METHOD_DIRECT_TO_HARDWARE METHOD_IN_DIRECT
+#endif
+
+#ifndef METHOD_DIRECT_FROM_HARDWARE
+# define METHOD_DIRECT_FROM_HARDWARE METHOD_OUT_DIRECT
+#endif
+
+#ifndef FILE_ANY_ACCESS
+# define FILE_ANY_ACCESS 0
+#endif
+
+#ifndef FILE_SPECIAL_ACCESS
+# define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS)
+#endif
+
+#ifndef FILE_READ_ACCESS
+# define FILE_READ_ACCESS 0x0001
+#endif
+
+#ifndef FILE_WRITE_ACCESS
+# define FILE_WRITE_ACCESS 0x0002
+#endif
+
+#ifndef CTL_CODE
+# define CTL_CODE(device_type, function, method, access)                      \
+    (((device_type) << 16) | ((access) << 14) | ((function) << 2) | (method))
+#endif
+
+#ifndef FSCTL_SET_REPARSE_POINT
+# define FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM,            \
+                                          41,                                 \
+                                          METHOD_BUFFERED,                    \
+                                          FILE_SPECIAL_ACCESS)
+#endif
+
+#ifndef FSCTL_GET_REPARSE_POINT
+# define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM,            \
+                                          42,                                 \
+                                          METHOD_BUFFERED,                    \
+                                          FILE_ANY_ACCESS)
+#endif
+
+#ifndef FSCTL_DELETE_REPARSE_POINT
+# define FSCTL_DELETE_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM,         \
+                                             43,                              \
+                                             METHOD_BUFFERED,                 \
+                                             FILE_SPECIAL_ACCESS)
+#endif
+
+#ifndef IO_REPARSE_TAG_SYMLINK
+# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
+#endif
+
+typedef VOID (NTAPI *PIO_APC_ROUTINE)
+             (PVOID ApcContext,
+              PIO_STATUS_BLOCK IoStatusBlock,
+              ULONG Reserved);
+
+typedef ULONG (NTAPI *sRtlNtStatusToDosError)
+              (NTSTATUS Status);
+
+typedef NTSTATUS (NTAPI *sNtDeviceIoControlFile)
+                 (HANDLE FileHandle,
+                  HANDLE Event,
+                  PIO_APC_ROUTINE ApcRoutine,
+                  PVOID ApcContext,
+                  PIO_STATUS_BLOCK IoStatusBlock,
+                  ULONG IoControlCode,
+                  PVOID InputBuffer,
+                  ULONG InputBufferLength,
+                  PVOID OutputBuffer,
+                  ULONG OutputBufferLength);
+
+typedef NTSTATUS (NTAPI *sNtQueryInformationFile)
+                 (HANDLE FileHandle,
+                  PIO_STATUS_BLOCK IoStatusBlock,
+                  PVOID FileInformation,
+                  ULONG Length,
+                  FILE_INFORMATION_CLASS FileInformationClass);
+
+typedef NTSTATUS (NTAPI *sNtSetInformationFile)
+                 (HANDLE FileHandle,
+                  PIO_STATUS_BLOCK IoStatusBlock,
+                  PVOID FileInformation,
+                  ULONG Length,
+                  FILE_INFORMATION_CLASS FileInformationClass);
+
+typedef NTSTATUS (NTAPI *sNtQueryVolumeInformationFile)
+                 (HANDLE FileHandle,
+                  PIO_STATUS_BLOCK IoStatusBlock,
+                  PVOID FsInformation,
+                  ULONG Length,
+                  FS_INFORMATION_CLASS FsInformationClass);
+
+typedef NTSTATUS (NTAPI *sNtQuerySystemInformation)
+                 (UINT SystemInformationClass,
+                  PVOID SystemInformation,
+                  ULONG SystemInformationLength,
+                  PULONG ReturnLength);
+
+typedef NTSTATUS (NTAPI *sNtQueryDirectoryFile)
+                 (HANDLE FileHandle,
+                  HANDLE Event,
+                  PIO_APC_ROUTINE ApcRoutine,
+                  PVOID ApcContext,
+                  PIO_STATUS_BLOCK IoStatusBlock,
+                  PVOID FileInformation,
+                  ULONG Length,
+                  FILE_INFORMATION_CLASS FileInformationClass,
+                  BOOLEAN ReturnSingleEntry,
+                  PUNICODE_STRING FileName,
+                  BOOLEAN RestartScan
+                );
+
+/*
+ * Kernel32 headers
+ */
+#ifndef FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
+# define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 0x1
+#endif
+
+#ifndef FILE_SKIP_SET_EVENT_ON_HANDLE
+# define FILE_SKIP_SET_EVENT_ON_HANDLE 0x2
+#endif
+
+#ifndef SYMBOLIC_LINK_FLAG_DIRECTORY
+# define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1
+#endif
+
+#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
+  typedef struct _OVERLAPPED_ENTRY {
+      ULONG_PTR lpCompletionKey;
+      LPOVERLAPPED lpOverlapped;
+      ULONG_PTR Internal;
+      DWORD dwNumberOfBytesTransferred;
+  } OVERLAPPED_ENTRY, *LPOVERLAPPED_ENTRY;
+#endif
+
+/* from wincon.h */
+#ifndef ENABLE_INSERT_MODE
+# define ENABLE_INSERT_MODE 0x20
+#endif
+
+#ifndef ENABLE_QUICK_EDIT_MODE
+# define ENABLE_QUICK_EDIT_MODE 0x40
+#endif
+
+#ifndef ENABLE_EXTENDED_FLAGS
+# define ENABLE_EXTENDED_FLAGS 0x80
+#endif
+
+/* from winerror.h */
+#ifndef ERROR_SYMLINK_NOT_SUPPORTED
+# define ERROR_SYMLINK_NOT_SUPPORTED 1464
+#endif
+
+#ifndef ERROR_MUI_FILE_NOT_FOUND
+# define ERROR_MUI_FILE_NOT_FOUND 15100
+#endif
+
+#ifndef ERROR_MUI_INVALID_FILE
+# define ERROR_MUI_INVALID_FILE 15101
+#endif
+
+#ifndef ERROR_MUI_INVALID_RC_CONFIG
+# define ERROR_MUI_INVALID_RC_CONFIG 15102
+#endif
+
+#ifndef ERROR_MUI_INVALID_LOCALE_NAME
+# define ERROR_MUI_INVALID_LOCALE_NAME 15103
+#endif
+
+#ifndef ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME
+# define ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME 15104
+#endif
+
+#ifndef ERROR_MUI_FILE_NOT_LOADED
+# define ERROR_MUI_FILE_NOT_LOADED 15105
+#endif
+
+typedef BOOL (WINAPI *sGetQueuedCompletionStatusEx)
+             (HANDLE CompletionPort,
+              LPOVERLAPPED_ENTRY lpCompletionPortEntries,
+              ULONG ulCount,
+              PULONG ulNumEntriesRemoved,
+              DWORD dwMilliseconds,
+              BOOL fAlertable);
+
+typedef BOOL (WINAPI* sSetFileCompletionNotificationModes)
+             (HANDLE FileHandle,
+              UCHAR Flags);
+
+typedef BOOLEAN (WINAPI* sCreateSymbolicLinkW)
+                (LPCWSTR lpSymlinkFileName,
+                 LPCWSTR lpTargetFileName,
+                 DWORD dwFlags);
+
+typedef BOOL (WINAPI* sCancelIoEx)
+             (HANDLE hFile,
+              LPOVERLAPPED lpOverlapped);
+
+typedef VOID (WINAPI* sInitializeConditionVariable)
+             (PCONDITION_VARIABLE ConditionVariable);
+
+typedef BOOL (WINAPI* sSleepConditionVariableCS)
+             (PCONDITION_VARIABLE ConditionVariable,
+              PCRITICAL_SECTION CriticalSection,
+              DWORD dwMilliseconds);
+
+typedef BOOL (WINAPI* sSleepConditionVariableSRW)
+             (PCONDITION_VARIABLE ConditionVariable,
+              PSRWLOCK SRWLock,
+              DWORD dwMilliseconds,
+              ULONG Flags);
+
+typedef VOID (WINAPI* sWakeAllConditionVariable)
+             (PCONDITION_VARIABLE ConditionVariable);
+
+typedef VOID (WINAPI* sWakeConditionVariable)
+             (PCONDITION_VARIABLE ConditionVariable);
+
+typedef BOOL (WINAPI* sCancelSynchronousIo)
+             (HANDLE hThread);
+
+typedef DWORD (WINAPI* sGetFinalPathNameByHandleW)
+             (HANDLE hFile,
+              LPWSTR lpszFilePath,
+              DWORD cchFilePath,
+              DWORD dwFlags);
+
+/* from powerbase.h */
+#ifndef DEVICE_NOTIFY_CALLBACK
+# define DEVICE_NOTIFY_CALLBACK 2
+#endif
+
+#ifndef PBT_APMRESUMEAUTOMATIC
+# define PBT_APMRESUMEAUTOMATIC 18
+#endif
+
+#ifndef PBT_APMRESUMESUSPEND
+# define PBT_APMRESUMESUSPEND 7
+#endif
+
+typedef ULONG CALLBACK _DEVICE_NOTIFY_CALLBACK_ROUTINE(
+  PVOID Context,
+  ULONG Type,
+  PVOID Setting
+);
+typedef _DEVICE_NOTIFY_CALLBACK_ROUTINE* _PDEVICE_NOTIFY_CALLBACK_ROUTINE;
+
+typedef struct _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS {
+  _PDEVICE_NOTIFY_CALLBACK_ROUTINE Callback;
+  PVOID Context;
+} _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS, *_PDEVICE_NOTIFY_SUBSCRIBE_PARAMETERS;
+
+typedef PVOID _HPOWERNOTIFY;
+typedef _HPOWERNOTIFY *_PHPOWERNOTIFY;
+
+typedef DWORD (WINAPI *sPowerRegisterSuspendResumeNotification)
+              (DWORD         Flags,
+               HANDLE        Recipient,
+               _PHPOWERNOTIFY RegistrationHandle);
+
+
+/* Ntdll function pointers */
+extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
+extern sNtDeviceIoControlFile pNtDeviceIoControlFile;
+extern sNtQueryInformationFile pNtQueryInformationFile;
+extern sNtSetInformationFile pNtSetInformationFile;
+extern sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
+extern sNtQueryDirectoryFile pNtQueryDirectoryFile;
+extern sNtQuerySystemInformation pNtQuerySystemInformation;
+
+
+/* Kernel32 function pointers */
+extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
+extern sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
+extern sCreateSymbolicLinkW pCreateSymbolicLinkW;
+extern sCancelIoEx pCancelIoEx;
+extern sInitializeConditionVariable pInitializeConditionVariable;
+extern sSleepConditionVariableCS pSleepConditionVariableCS;
+extern sSleepConditionVariableSRW pSleepConditionVariableSRW;
+extern sWakeAllConditionVariable pWakeAllConditionVariable;
+extern sWakeConditionVariable pWakeConditionVariable;
+extern sCancelSynchronousIo pCancelSynchronousIo;
+extern sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW;
+
+
+/* Powrprof.dll function pointer */
+extern sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
+
+#endif /* UV_WIN_WINAPI_H_ */
diff --git a/deps/libtuv/src/win/winsock.c b/deps/libtuv/src/win/winsock.c
new file mode 100644 (file)
index 0000000..32c2b0d
--- /dev/null
@@ -0,0 +1,563 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "internal.h"
+
+
+/* Whether there are any non-IFS LSPs stacked on TCP */
+int uv_tcp_non_ifs_lsp_ipv4;
+int uv_tcp_non_ifs_lsp_ipv6;
+
+/* Ip address used to bind to any port at any interface */
+struct sockaddr_in uv_addr_ip4_any_;
+struct sockaddr_in6 uv_addr_ip6_any_;
+
+
+/*
+ * Retrieves the pointer to a winsock extension function.
+ */
+static BOOL uv_get_extension_function(SOCKET socket, GUID guid,
+    void **target) {
+  int result;
+  DWORD bytes;
+
+  result = WSAIoctl(socket,
+                    SIO_GET_EXTENSION_FUNCTION_POINTER,
+                    &guid,
+                    sizeof(guid),
+                    (void*)target,
+                    sizeof(*target),
+                    &bytes,
+                    NULL,
+                    NULL);
+
+  if (result == SOCKET_ERROR) {
+    *target = NULL;
+    return FALSE;
+  } else {
+    return TRUE;
+  }
+}
+
+
+BOOL uv_get_acceptex_function(SOCKET socket, LPFN_ACCEPTEX* target) {
+  const GUID wsaid_acceptex = WSAID_ACCEPTEX;
+  return uv_get_extension_function(socket, wsaid_acceptex, (void**)target);
+}
+
+
+BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target) {
+  const GUID wsaid_connectex = WSAID_CONNECTEX;
+  return uv_get_extension_function(socket, wsaid_connectex, (void**)target);
+}
+
+
+static int error_means_no_support(DWORD error) {
+  return error == WSAEPROTONOSUPPORT || error == WSAESOCKTNOSUPPORT ||
+         error == WSAEPFNOSUPPORT || error == WSAEAFNOSUPPORT;
+}
+
+
+void uv_winsock_init() {
+  WSADATA wsa_data;
+  int errorno;
+  SOCKET dummy;
+  WSAPROTOCOL_INFOW protocol_info;
+  int opt_len;
+
+  /* Initialize winsock */
+  errorno = WSAStartup(MAKEWORD(2, 2), &wsa_data);
+  if (errorno != 0) {
+    uv_fatal_error(errorno, "WSAStartup");
+  }
+
+  /* Set implicit binding address used by connectEx */
+  if (uv_ip4_addr("0.0.0.0", 0, &uv_addr_ip4_any_)) {
+    abort();
+  }
+
+  /* TODO: IPv6 support in libtuv is incomplete, disable this for now.
+   if (uv_ip6_addr("::", 0, &uv_addr_ip6_any_)) {
+    abort();
+  }
+  */
+
+  /* Detect non-IFS LSPs */
+  dummy = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+
+  if (dummy != INVALID_SOCKET) {
+    opt_len = (int) sizeof protocol_info;
+    if (getsockopt(dummy,
+                   SOL_SOCKET,
+                   SO_PROTOCOL_INFOW,
+                   (char*) &protocol_info,
+                   &opt_len) == SOCKET_ERROR)
+      uv_fatal_error(WSAGetLastError(), "getsockopt");
+
+    if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES))
+      uv_tcp_non_ifs_lsp_ipv4 = 1;
+
+    if (closesocket(dummy) == SOCKET_ERROR)
+      uv_fatal_error(WSAGetLastError(), "closesocket");
+
+  } else if (!error_means_no_support(WSAGetLastError())) {
+    /* Any error other than "socket type not supported" is fatal. */
+    uv_fatal_error(WSAGetLastError(), "socket");
+  }
+
+  /* Detect IPV6 support and non-IFS LSPs */
+  dummy = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP);
+
+  if (dummy != INVALID_SOCKET) {
+    opt_len = (int) sizeof protocol_info;
+    if (getsockopt(dummy,
+                   SOL_SOCKET,
+                   SO_PROTOCOL_INFOW,
+                   (char*) &protocol_info,
+                   &opt_len) == SOCKET_ERROR)
+      uv_fatal_error(WSAGetLastError(), "getsockopt");
+
+    if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES))
+      uv_tcp_non_ifs_lsp_ipv6 = 1;
+
+    if (closesocket(dummy) == SOCKET_ERROR)
+      uv_fatal_error(WSAGetLastError(), "closesocket");
+
+  } else if (!error_means_no_support(WSAGetLastError())) {
+    /* Any error other than "socket type not supported" is fatal. */
+    uv_fatal_error(WSAGetLastError(), "socket");
+  }
+}
+
+
+int uv_ntstatus_to_winsock_error(NTSTATUS status) {
+  switch (status) {
+    case STATUS_SUCCESS:
+      return ERROR_SUCCESS;
+
+    case STATUS_PENDING:
+      return ERROR_IO_PENDING;
+
+    case STATUS_INVALID_HANDLE:
+    case STATUS_OBJECT_TYPE_MISMATCH:
+      return WSAENOTSOCK;
+
+    case STATUS_INSUFFICIENT_RESOURCES:
+    case STATUS_PAGEFILE_QUOTA:
+    case STATUS_COMMITMENT_LIMIT:
+    case STATUS_WORKING_SET_QUOTA:
+    case STATUS_NO_MEMORY:
+    case STATUS_QUOTA_EXCEEDED:
+    case STATUS_TOO_MANY_PAGING_FILES:
+    case STATUS_REMOTE_RESOURCES:
+      return WSAENOBUFS;
+
+    case STATUS_TOO_MANY_ADDRESSES:
+    case STATUS_SHARING_VIOLATION:
+    case STATUS_ADDRESS_ALREADY_EXISTS:
+      return WSAEADDRINUSE;
+
+    case STATUS_LINK_TIMEOUT:
+    case STATUS_IO_TIMEOUT:
+    case STATUS_TIMEOUT:
+      return WSAETIMEDOUT;
+
+    case STATUS_GRACEFUL_DISCONNECT:
+      return WSAEDISCON;
+
+    case STATUS_REMOTE_DISCONNECT:
+    case STATUS_CONNECTION_RESET:
+    case STATUS_LINK_FAILED:
+    case STATUS_CONNECTION_DISCONNECTED:
+    case STATUS_PORT_UNREACHABLE:
+    case STATUS_HOPLIMIT_EXCEEDED:
+      return WSAECONNRESET;
+
+    case STATUS_LOCAL_DISCONNECT:
+    case STATUS_TRANSACTION_ABORTED:
+    case STATUS_CONNECTION_ABORTED:
+      return WSAECONNABORTED;
+
+    case STATUS_BAD_NETWORK_PATH:
+    case STATUS_NETWORK_UNREACHABLE:
+    case STATUS_PROTOCOL_UNREACHABLE:
+      return WSAENETUNREACH;
+
+    case STATUS_HOST_UNREACHABLE:
+      return WSAEHOSTUNREACH;
+
+    case STATUS_CANCELLED:
+    case STATUS_REQUEST_ABORTED:
+      return WSAEINTR;
+
+    case STATUS_BUFFER_OVERFLOW:
+    case STATUS_INVALID_BUFFER_SIZE:
+      return WSAEMSGSIZE;
+
+    case STATUS_BUFFER_TOO_SMALL:
+    case STATUS_ACCESS_VIOLATION:
+      return WSAEFAULT;
+
+    case STATUS_DEVICE_NOT_READY:
+    case STATUS_REQUEST_NOT_ACCEPTED:
+      return WSAEWOULDBLOCK;
+
+    case STATUS_INVALID_NETWORK_RESPONSE:
+    case STATUS_NETWORK_BUSY:
+    case STATUS_NO_SUCH_DEVICE:
+    case STATUS_NO_SUCH_FILE:
+    case STATUS_OBJECT_PATH_NOT_FOUND:
+    case STATUS_OBJECT_NAME_NOT_FOUND:
+    case STATUS_UNEXPECTED_NETWORK_ERROR:
+      return WSAENETDOWN;
+
+    case STATUS_INVALID_CONNECTION:
+      return WSAENOTCONN;
+
+    case STATUS_REMOTE_NOT_LISTENING:
+    case STATUS_CONNECTION_REFUSED:
+      return WSAECONNREFUSED;
+
+    case STATUS_PIPE_DISCONNECTED:
+      return WSAESHUTDOWN;
+
+    case STATUS_CONFLICTING_ADDRESSES:
+    case STATUS_INVALID_ADDRESS:
+    case STATUS_INVALID_ADDRESS_COMPONENT:
+      return WSAEADDRNOTAVAIL;
+
+    case STATUS_NOT_SUPPORTED:
+    case STATUS_NOT_IMPLEMENTED:
+      return WSAEOPNOTSUPP;
+
+    case STATUS_ACCESS_DENIED:
+      return WSAEACCES;
+
+    default:
+      if ((status & (FACILITY_NTWIN32 << 16)) == (FACILITY_NTWIN32 << 16) &&
+          (status & (ERROR_SEVERITY_ERROR | ERROR_SEVERITY_WARNING))) {
+        /* It's a windows error that has been previously mapped to an */
+        /* ntstatus code. */
+        return (DWORD) (status & 0xffff);
+      } else {
+        /* The default fallback for unmappable ntstatus codes. */
+        return WSAEINVAL;
+      }
+  }
+}
+
+
+/*
+ * This function provides a workaround for a bug in the winsock implementation
+ * of WSARecv. The problem is that when SetFileCompletionNotificationModes is
+ * used to avoid IOCP notifications of completed reads, WSARecv does not
+ * reliably indicate whether we can expect a completion package to be posted
+ * when the receive buffer is smaller than the received datagram.
+ *
+ * However it is desirable to use SetFileCompletionNotificationModes because
+ * it yields a massive performance increase.
+ *
+ * This function provides a workaround for that bug, but it only works for the
+ * specific case that we need it for. E.g. it assumes that the "avoid iocp"
+ * bit has been set, and supports only overlapped operation. It also requires
+ * the user to use the default msafd driver, doesn't work when other LSPs are
+ * stacked on top of it.
+ */
+int WSAAPI uv_wsarecv_workaround(SOCKET socket, WSABUF* buffers,
+    DWORD buffer_count, DWORD* bytes, DWORD* flags, WSAOVERLAPPED *overlapped,
+    LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine) {
+  NTSTATUS status;
+  void* apc_context;
+  IO_STATUS_BLOCK* iosb = (IO_STATUS_BLOCK*) &overlapped->Internal;
+  AFD_RECV_INFO info;
+  DWORD error;
+
+  if (overlapped == NULL || completion_routine != NULL) {
+    WSASetLastError(WSAEINVAL);
+    return SOCKET_ERROR;
+  }
+
+  info.BufferArray = buffers;
+  info.BufferCount = buffer_count;
+  info.AfdFlags = AFD_OVERLAPPED;
+  info.TdiFlags = TDI_RECEIVE_NORMAL;
+
+  if (*flags & MSG_PEEK) {
+    info.TdiFlags |= TDI_RECEIVE_PEEK;
+  }
+
+  if (*flags & MSG_PARTIAL) {
+    info.TdiFlags |= TDI_RECEIVE_PARTIAL;
+  }
+
+  if (!((intptr_t) overlapped->hEvent & 1)) {
+    apc_context = (void*) overlapped;
+  } else {
+    apc_context = NULL;
+  }
+
+  iosb->Status = STATUS_PENDING;
+  iosb->Pointer = 0;
+
+  status = pNtDeviceIoControlFile((HANDLE) socket,
+                                  overlapped->hEvent,
+                                  NULL,
+                                  apc_context,
+                                  iosb,
+                                  IOCTL_AFD_RECEIVE,
+                                  &info,
+                                  sizeof(info),
+                                  NULL,
+                                  0);
+
+  *flags = 0;
+  *bytes = (DWORD) iosb->Information;
+
+  switch (status) {
+    case STATUS_SUCCESS:
+      error = ERROR_SUCCESS;
+      break;
+
+    case STATUS_PENDING:
+      error = WSA_IO_PENDING;
+      break;
+
+    case STATUS_BUFFER_OVERFLOW:
+      error = WSAEMSGSIZE;
+      break;
+
+    case STATUS_RECEIVE_EXPEDITED:
+      error = ERROR_SUCCESS;
+      *flags = MSG_OOB;
+      break;
+
+    case STATUS_RECEIVE_PARTIAL_EXPEDITED:
+      error = ERROR_SUCCESS;
+      *flags = MSG_PARTIAL | MSG_OOB;
+      break;
+
+    case STATUS_RECEIVE_PARTIAL:
+      error = ERROR_SUCCESS;
+      *flags = MSG_PARTIAL;
+      break;
+
+    default:
+      error = uv_ntstatus_to_winsock_error(status);
+      break;
+  }
+
+  WSASetLastError(error);
+
+  if (error == ERROR_SUCCESS) {
+    return 0;
+  } else {
+    return SOCKET_ERROR;
+  }
+}
+
+
+/* See description of uv_wsarecv_workaround. */
+int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers,
+    DWORD buffer_count, DWORD* bytes, DWORD* flags, struct sockaddr* addr,
+    int* addr_len, WSAOVERLAPPED *overlapped,
+    LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine) {
+  NTSTATUS status;
+  void* apc_context;
+  IO_STATUS_BLOCK* iosb = (IO_STATUS_BLOCK*) &overlapped->Internal;
+  AFD_RECV_DATAGRAM_INFO info;
+  DWORD error;
+
+  if (overlapped == NULL || addr == NULL || addr_len == NULL ||
+      completion_routine != NULL) {
+    WSASetLastError(WSAEINVAL);
+    return SOCKET_ERROR;
+  }
+
+  info.BufferArray = buffers;
+  info.BufferCount = buffer_count;
+  info.AfdFlags = AFD_OVERLAPPED;
+  info.TdiFlags = TDI_RECEIVE_NORMAL;
+  info.Address = addr;
+  info.AddressLength = addr_len;
+
+  if (*flags & MSG_PEEK) {
+    info.TdiFlags |= TDI_RECEIVE_PEEK;
+  }
+
+  if (*flags & MSG_PARTIAL) {
+    info.TdiFlags |= TDI_RECEIVE_PARTIAL;
+  }
+
+  if (!((intptr_t) overlapped->hEvent & 1)) {
+    apc_context = (void*) overlapped;
+  } else {
+    apc_context = NULL;
+  }
+
+  iosb->Status = STATUS_PENDING;
+  iosb->Pointer = 0;
+
+  status = pNtDeviceIoControlFile((HANDLE) socket,
+                                  overlapped->hEvent,
+                                  NULL,
+                                  apc_context,
+                                  iosb,
+                                  IOCTL_AFD_RECEIVE_DATAGRAM,
+                                  &info,
+                                  sizeof(info),
+                                  NULL,
+                                  0);
+
+  *flags = 0;
+  *bytes = (DWORD) iosb->Information;
+
+  switch (status) {
+    case STATUS_SUCCESS:
+      error = ERROR_SUCCESS;
+      break;
+
+    case STATUS_PENDING:
+      error = WSA_IO_PENDING;
+      break;
+
+    case STATUS_BUFFER_OVERFLOW:
+      error = WSAEMSGSIZE;
+      break;
+
+    case STATUS_RECEIVE_EXPEDITED:
+      error = ERROR_SUCCESS;
+      *flags = MSG_OOB;
+      break;
+
+    case STATUS_RECEIVE_PARTIAL_EXPEDITED:
+      error = ERROR_SUCCESS;
+      *flags = MSG_PARTIAL | MSG_OOB;
+      break;
+
+    case STATUS_RECEIVE_PARTIAL:
+      error = ERROR_SUCCESS;
+      *flags = MSG_PARTIAL;
+      break;
+
+    default:
+      error = uv_ntstatus_to_winsock_error(status);
+      break;
+  }
+
+  WSASetLastError(error);
+
+  if (error == ERROR_SUCCESS) {
+    return 0;
+  } else {
+    return SOCKET_ERROR;
+  }
+}
+
+
+int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in,
+    AFD_POLL_INFO* info_out, OVERLAPPED* overlapped) {
+  IO_STATUS_BLOCK iosb;
+  IO_STATUS_BLOCK* iosb_ptr;
+  HANDLE event = NULL;
+  void* apc_context;
+  NTSTATUS status;
+  DWORD error;
+
+  if (overlapped != NULL) {
+    /* Overlapped operation. */
+    iosb_ptr = (IO_STATUS_BLOCK*) &overlapped->Internal;
+    event = overlapped->hEvent;
+
+    /* Do not report iocp completion if hEvent is tagged. */
+    if ((uintptr_t) event & 1) {
+      event = (HANDLE)((uintptr_t) event & ~(uintptr_t) 1);
+      apc_context = NULL;
+    } else {
+      apc_context = overlapped;
+    }
+
+  } else {
+    /* Blocking operation. */
+    iosb_ptr = &iosb;
+    event = CreateEvent(NULL, FALSE, FALSE, NULL);
+    if (event == NULL) {
+      return SOCKET_ERROR;
+    }
+    apc_context = NULL;
+  }
+
+  iosb_ptr->Status = STATUS_PENDING;
+  status = pNtDeviceIoControlFile((HANDLE) socket,
+                                  event,
+                                  NULL,
+                                  apc_context,
+                                  iosb_ptr,
+                                  IOCTL_AFD_POLL,
+                                  info_in,
+                                  sizeof *info_in,
+                                  info_out,
+                                  sizeof *info_out);
+
+  if (overlapped == NULL) {
+    /* If this is a blocking operation, wait for the event to become */
+    /* signaled, and then grab the real status from the io status block. */
+    if (status == STATUS_PENDING) {
+      DWORD r = WaitForSingleObject(event, INFINITE);
+
+      if (r == WAIT_FAILED) {
+        DWORD saved_error = GetLastError();
+        CloseHandle(event);
+        WSASetLastError(saved_error);
+        return SOCKET_ERROR;
+      }
+
+      status = iosb.Status;
+    }
+
+    CloseHandle(event);
+  }
+
+  switch (status) {
+    case STATUS_SUCCESS:
+      error = ERROR_SUCCESS;
+      break;
+
+    case STATUS_PENDING:
+      error = WSA_IO_PENDING;
+      break;
+
+    default:
+      error = uv_ntstatus_to_winsock_error(status);
+      break;
+  }
+
+  WSASetLastError(error);
+
+  if (error == ERROR_SUCCESS) {
+    return 0;
+  } else {
+    return SOCKET_ERROR;
+  }
+}
diff --git a/deps/libtuv/src/win/winsock.h b/deps/libtuv/src/win/winsock.h
new file mode 100644 (file)
index 0000000..7c007ab
--- /dev/null
@@ -0,0 +1,190 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef UV_WIN_WINSOCK_H_
+#define UV_WIN_WINSOCK_H_
+
+#include <winsock2.h>
+#include <iptypes.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+
+#include "winapi.h"
+
+
+/*
+ * MinGW is missing these too
+ */
+#ifndef SO_UPDATE_CONNECT_CONTEXT
+# define SO_UPDATE_CONNECT_CONTEXT 0x7010
+#endif
+
+#ifndef TCP_KEEPALIVE
+# define TCP_KEEPALIVE 3
+#endif
+
+#ifndef IPV6_V6ONLY
+# define IPV6_V6ONLY 27
+#endif
+
+#ifndef IPV6_HOPLIMIT
+# define IPV6_HOPLIMIT 21
+#endif
+
+#ifndef SIO_BASE_HANDLE
+# define SIO_BASE_HANDLE 0x48000022
+#endif
+
+/*
+ * TDI defines that are only in the DDK.
+ * We only need receive flags so far.
+ */
+#ifndef TDI_RECEIVE_NORMAL
+  #define TDI_RECEIVE_BROADCAST           0x00000004
+  #define TDI_RECEIVE_MULTICAST           0x00000008
+  #define TDI_RECEIVE_PARTIAL             0x00000010
+  #define TDI_RECEIVE_NORMAL              0x00000020
+  #define TDI_RECEIVE_EXPEDITED           0x00000040
+  #define TDI_RECEIVE_PEEK                0x00000080
+  #define TDI_RECEIVE_NO_RESPONSE_EXP     0x00000100
+  #define TDI_RECEIVE_COPY_LOOKAHEAD      0x00000200
+  #define TDI_RECEIVE_ENTIRE_MESSAGE      0x00000400
+  #define TDI_RECEIVE_AT_DISPATCH_LEVEL   0x00000800
+  #define TDI_RECEIVE_CONTROL_INFO        0x00001000
+  #define TDI_RECEIVE_FORCE_INDICATION    0x00002000
+  #define TDI_RECEIVE_NO_PUSH             0x00004000
+#endif
+
+/*
+ * The "Auxiliary Function Driver" is the windows kernel-mode driver that does
+ * TCP, UDP etc. Winsock is just a layer that dispatches requests to it.
+ * Having these definitions allows us to bypass winsock and make an AFD kernel
+ * call directly, avoiding a bug in winsock's recvfrom implementation.
+ */
+
+#define AFD_NO_FAST_IO   0x00000001
+#define AFD_OVERLAPPED   0x00000002
+#define AFD_IMMEDIATE    0x00000004
+
+#define AFD_POLL_RECEIVE_BIT            0
+#define AFD_POLL_RECEIVE                (1 << AFD_POLL_RECEIVE_BIT)
+#define AFD_POLL_RECEIVE_EXPEDITED_BIT  1
+#define AFD_POLL_RECEIVE_EXPEDITED      (1 << AFD_POLL_RECEIVE_EXPEDITED_BIT)
+#define AFD_POLL_SEND_BIT               2
+#define AFD_POLL_SEND                   (1 << AFD_POLL_SEND_BIT)
+#define AFD_POLL_DISCONNECT_BIT         3
+#define AFD_POLL_DISCONNECT             (1 << AFD_POLL_DISCONNECT_BIT)
+#define AFD_POLL_ABORT_BIT              4
+#define AFD_POLL_ABORT                  (1 << AFD_POLL_ABORT_BIT)
+#define AFD_POLL_LOCAL_CLOSE_BIT        5
+#define AFD_POLL_LOCAL_CLOSE            (1 << AFD_POLL_LOCAL_CLOSE_BIT)
+#define AFD_POLL_CONNECT_BIT            6
+#define AFD_POLL_CONNECT                (1 << AFD_POLL_CONNECT_BIT)
+#define AFD_POLL_ACCEPT_BIT             7
+#define AFD_POLL_ACCEPT                 (1 << AFD_POLL_ACCEPT_BIT)
+#define AFD_POLL_CONNECT_FAIL_BIT       8
+#define AFD_POLL_CONNECT_FAIL           (1 << AFD_POLL_CONNECT_FAIL_BIT)
+#define AFD_POLL_QOS_BIT                9
+#define AFD_POLL_QOS                    (1 << AFD_POLL_QOS_BIT)
+#define AFD_POLL_GROUP_QOS_BIT          10
+#define AFD_POLL_GROUP_QOS              (1 << AFD_POLL_GROUP_QOS_BIT)
+
+#define AFD_NUM_POLL_EVENTS             11
+#define AFD_POLL_ALL                    ((1 << AFD_NUM_POLL_EVENTS) - 1)
+
+typedef struct _AFD_RECV_DATAGRAM_INFO {
+    LPWSABUF BufferArray;
+    ULONG BufferCount;
+    ULONG AfdFlags;
+    ULONG TdiFlags;
+    struct sockaddr* Address;
+    int* AddressLength;
+} AFD_RECV_DATAGRAM_INFO, *PAFD_RECV_DATAGRAM_INFO;
+
+typedef struct _AFD_RECV_INFO {
+    LPWSABUF BufferArray;
+    ULONG BufferCount;
+    ULONG AfdFlags;
+    ULONG TdiFlags;
+} AFD_RECV_INFO, *PAFD_RECV_INFO;
+
+
+#define _AFD_CONTROL_CODE(operation, method) \
+    ((FSCTL_AFD_BASE) << 12 | (operation << 2) | method)
+
+#define FSCTL_AFD_BASE FILE_DEVICE_NETWORK
+
+#define AFD_RECEIVE            5
+#define AFD_RECEIVE_DATAGRAM   6
+#define AFD_POLL               9
+
+#define IOCTL_AFD_RECEIVE \
+    _AFD_CONTROL_CODE(AFD_RECEIVE, METHOD_NEITHER)
+
+#define IOCTL_AFD_RECEIVE_DATAGRAM \
+    _AFD_CONTROL_CODE(AFD_RECEIVE_DATAGRAM, METHOD_NEITHER)
+
+#define IOCTL_AFD_POLL \
+    _AFD_CONTROL_CODE(AFD_POLL, METHOD_BUFFERED)
+
+#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
+typedef struct _IP_ADAPTER_UNICAST_ADDRESS_XP {
+  /* FIXME: __C89_NAMELESS was removed */
+  /* __C89_NAMELESS */ union {
+    ULONGLONG Alignment;
+    /* __C89_NAMELESS */ struct {
+      ULONG Length;
+      DWORD Flags;
+    };
+  };
+  struct _IP_ADAPTER_UNICAST_ADDRESS_XP *Next;
+  SOCKET_ADDRESS Address;
+  IP_PREFIX_ORIGIN PrefixOrigin;
+  IP_SUFFIX_ORIGIN SuffixOrigin;
+  IP_DAD_STATE DadState;
+  ULONG ValidLifetime;
+  ULONG PreferredLifetime;
+  ULONG LeaseLifetime;
+} IP_ADAPTER_UNICAST_ADDRESS_XP,*PIP_ADAPTER_UNICAST_ADDRESS_XP;
+
+typedef struct _IP_ADAPTER_UNICAST_ADDRESS_LH {
+  union {
+    ULONGLONG Alignment;
+    struct {
+      ULONG Length;
+      DWORD Flags;
+    };
+  };
+  struct _IP_ADAPTER_UNICAST_ADDRESS_LH *Next;
+  SOCKET_ADDRESS Address;
+  IP_PREFIX_ORIGIN PrefixOrigin;
+  IP_SUFFIX_ORIGIN SuffixOrigin;
+  IP_DAD_STATE DadState;
+  ULONG ValidLifetime;
+  ULONG PreferredLifetime;
+  ULONG LeaseLifetime;
+  UINT8 OnLinkPrefixLength;
+} IP_ADAPTER_UNICAST_ADDRESS_LH,*PIP_ADAPTER_UNICAST_ADDRESS_LH;
+
+#endif
+
+#endif /* UV_WIN_WINSOCK_H_ */
index 0db62e82f06a480ef2b0eb04ab247152a2fce78c..f0ce6d178dc17dc8947453a89cbc98a160fb9a52 100644 (file)
@@ -167,14 +167,14 @@ static void on_connection(uv_stream_t* server, int status) {
     TUV_ASSERT(r == 0);
     break;
 
-/*
-  case PIPE:
+#ifdef TUV_FEATURE_PIPE
+  case TEST_PIPE:
     stream = (uv_stream_t*)malloc(sizeof(uv_pipe_t));
     TUV_ASSERT(stream != NULL);
-    r = uv_pipe_init(loop, (uv_pipe_t*)stream, 0);
+    r = uv_pipe_init(&loop, (uv_pipe_t*)stream, 0);
     TUV_ASSERT(r == 0);
     break;
-*/
+#endif
 
   default:
     TUV_ASSERT(0 && "Bad serverType");
index 6b41f71cc5192bcd844397630db829f715d15bc3..b779a25ff2a8c58c8e4decaefbfb054a07dfa473 100644 (file)
@@ -46,6 +46,7 @@
 extern "C" {
 #endif
 
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 
 #if defined(__NUTTX__) || defined(__TUV_RAW__)
 #define EMBED_LOW_MEMORY
@@ -79,6 +80,15 @@ typedef struct {
   int run_helper_##name(void);                                                \
   int run_helper_##name(void)
 
+#ifdef _WIN32
+# define TEST_PIPENAME "\\\\?\\pipe\\uv-test"
+# define TEST_PIPENAME_2 "\\\\?\\pipe\\uv-test2"
+# define TEST_PIPENAME_3 "\\\\?\\pipe\\uv-test3"
+#else
+# define TEST_PIPENAME "/tmp/uv-test-sock"
+# define TEST_PIPENAME_2 "/tmp/uv-test-sock2"
+# define TEST_PIPENAME_3 "/tmp/uv-test-sock3"
+#endif
 
 /* Have our own assert, so we are sure it does not get optimized away in
  * a release build.
index 9229440649462fe97cb311fa020e242bae91e89d..1b4a42eadd277148255c59e31c2e2b97c01d12bb 100644 (file)
@@ -347,6 +347,14 @@ int main(int argc, char *argv[]) {
 
 #else
 
+int ipc_helper(int listen_after_write);
+int ipc_helper_tcp_connection(void);
+// int ipc_send_recv_helper(void);
+int ipc_helper_bind_twice(void);
+// int stdio_over_pipes_helper(void);
+int spawn_stdin_stdout(void);
+
+static int maybe_run_test(int argc, char **argv);
 static pthread_t tid = 0;
 
 
@@ -387,20 +395,152 @@ int run_test_one(task_entry_t* task) {
   return run_test_part(task->task_name, task->process_name);
 }
 
-int main(int argc, char *argv[]) {
-  int result;
 
-  InitDebugSettings();
+int main(int argc, char **argv) {
+  if (platform_init(argc, argv))
+    return 1;
 
-  platform_init(argc, argv);
+  InitDebugSettings();
 
-  if (argc>2) {
-    return run_test_part(argv[1], argv[2]);
+  switch (argc) {
+  case 1: return run_tests();
+  case 2: return maybe_run_test(argc, argv);
+  case 3: return run_test_part(argv[1], argv[2]);
+  default:
+    ReleaseDebugSettings();
+
+    fprintf(stderr, "Too many arguments.\n");
+    fflush(stderr);
+    return 1;
   }
-  result = run_tests();
+
   ReleaseDebugSettings();
 
-  return result;
+  return 0;
+}
+
+static int maybe_run_test(int argc, char **argv) {
+#if TUV_FEATURE_PROCESS
+  if (strcmp(argv[1], "ipc_helper_listen_before_write") == 0) {
+    return ipc_helper(0);
+  }
+
+  if (strcmp(argv[1], "ipc_helper_listen_after_write") == 0) {
+    return ipc_helper(1);
+  }
+
+  // if (strcmp(argv[1], "ipc_send_recv_helper") == 0) {
+  //   return ipc_send_recv_helper();
+  // }
+
+  if (strcmp(argv[1], "ipc_helper_tcp_connection") == 0) {
+    return ipc_helper_tcp_connection();
+  }
+
+  if (strcmp(argv[1], "ipc_helper_bind_twice") == 0) {
+    return ipc_helper_bind_twice();
+  }
+
+  // if (strcmp(argv[1], "stdio_over_pipes_helper") == 0) {
+  //   return stdio_over_pipes_helper();
+  // }
+
+  if (strcmp(argv[1], "spawn_helper1") == 0) {
+    return 1;
+  }
+
+  if (strcmp(argv[1], "spawn_helper2") == 0) {
+    printf("hello world\n");
+    return 1;
+  }
+
+  if (strcmp(argv[1], "spawn_helper3") == 0) {
+    char buffer[256];
+    TUV_ASSERT(buffer == fgets(buffer, sizeof(buffer) - 1, stdin));
+    buffer[sizeof(buffer) - 1] = '\0';
+    fputs(buffer, stdout);
+    return 1;
+  }
+
+  if (strcmp(argv[1], "spawn_helper4") == 0) {
+    /* Never surrender, never return! */
+    while (1) uv_sleep(10000);
+  }
+
+  if (strcmp(argv[1], "spawn_helper5") == 0) {
+    const char out[] = "fourth stdio!\n";
+#ifdef _WIN32
+    DWORD bytes;
+    WriteFile((HANDLE) _get_osfhandle(3), out, sizeof(out) - 1, &bytes, NULL);
+#else
+    {
+      ssize_t r;
+
+      do
+        r = write(3, out, sizeof(out) - 1);
+      while (r == -1 && errno == EINTR);
+
+      fsync(3);
+    }
+#endif
+    return 1;
+  }
+
+  if (strcmp(argv[1], "spawn_helper6") == 0) {
+    int r;
+
+    r = fprintf(stdout, "hello world\n");
+    TUV_ASSERT(r > 0);
+
+    r = fprintf(stderr, "hello errworld\n");
+    TUV_ASSERT(r > 0);
+
+    return 1;
+  }
+
+  if (strcmp(argv[1], "spawn_helper7") == 0) {
+    int r;
+    char *test;
+    /* Test if the test value from the parent is still set */
+    test = getenv("ENV_TEST");
+    TUV_ASSERT(test != NULL);
+
+    r = fprintf(stdout, "%s", test);
+    TUV_ASSERT(r > 0);
+
+    return 1;
+  }
+
+#ifndef _WIN32
+  if (strcmp(argv[1], "spawn_helper8") == 0) {
+    int fd;
+    TUV_ASSERT(sizeof(fd) == read(0, &fd, sizeof(fd)));
+    TUV_ASSERT(fd > 2);
+    TUV_ASSERT(-1 == write(fd, "x", 1));
+
+    return 1;
+  }
+#endif  /* !_WIN32 */
+
+  if (strcmp(argv[1], "spawn_helper9") == 0) {
+    return spawn_stdin_stdout();
+  }
+
+#ifndef _WIN32
+  if (strcmp(argv[1], "spawn_helper_setuid_setgid") == 0) {
+    uv_uid_t uid = atoi(argv[2]);
+    uv_gid_t gid = atoi(argv[3]);
+
+    TUV_ASSERT(uid == getuid());
+    TUV_ASSERT(gid == getgid());
+
+    return 1;
+  }
+#endif  /* !_WIN32 */
+
+#endif /* TUV_FEATURE_PROCESS */
+  // return run_test(argv[1], 0, 1);
+  return 1;
 }
 
 #endif
index bdfc5bdff04a0ca7088c56804246396b1773e8aa..1b2e06e327077e988b09edaffb1974c3527a88a7 100644 (file)
 
 // shutdown_eof should be last of tcp test, it'll stop "echo_sevrer"
 
+#if defined(__linux__) && defined(TUV_FEATURE_PIPE)
+#define TEST_LIST_EXT_PIPE(TE)                                                \
+  TE(pipe_bind_error_addrinuse, 5000)                                         \
+  TE(pipe_bind_error_addrnotavail, 5000)                                      \
+  TE(pipe_bind_error_inval, 5000)                                             \
+  TE(pipe_listen_without_bind, 5000)                                          \
+/*TE(pipe_close_stdout_read_stdin, 5000)*/                                    \
+  TE(pipe_connect_bad_name, 5000)                                             \
+/*TE(pipe_connect_to_file, 5000)*/                                            \
+/*TE(pipe_connect_multiple, 5000)*/                                           \
+/*TE(pipe_connect_on_prepare, 5000)*/                                         \
+  TE(pipe_getsockname, 5000)                                                  \
+  TE(pipe_getsockname_abstract, 5000)                                         \
+  TE(pipe_getsockname_blocking, 5000)                                         \
+  TE(pipe_pending_instances, 5000)                                            \
+  TE(pipe_sendmsg, 5000)                                                      \
+  TE(pipe_server_close, 5000)                                                 \
+  TE(pipe_set_non_blocking, 5000)
+#else
+#define TEST_LIST_EXT_PIPE(TE)
+#endif
+
+#if defined(__linux__) && defined(TUV_FEATURE_SIGNAL)
+#define TEST_LIST_EXT_SIGNAL(TE)                                              \
+  TE(we_get_signal, 5000)                                                     \
+  TE(we_get_signals, 5000)
+#else
+#define TEST_LIST_EXT_SIGNAL(TE)
+#endif
+
+#if defined(__linux__) && defined(TUV_FEATURE_PROCESS)
+#define TEST_LIST_EXT_PROCESS(TE)                                             \
+/*TE(ipc_listen_before_write, 5000)*/                                         \
+/*TE(ipc_listen_after_write, 5000)*/                                          \
+/*TE(ipc_tcp_connection, 5000)*/                                              \
+/*TE(spawn_fails_check_for_waitpid_cleanup, 5000) */                          \
+/*TE(spawn_exit_code, 5000) */                                                \
+  TE(spawn_stdout, 5000)                                                      \
+/*TE(spawn_stdout_to_file, 5000) */                                           \
+/*TE(spawn_stdout_and_stderr_to_file, 5000) */                                \
+/*TE(spawn_stdout_and_stderr_to_file2, 5000) */                               \
+/*TE(spawn_stdout_and_stderr_to_file_swap, 5000) */                           \
+/*TE(spawn_stdin, 5000) */                                                    \
+/*TE(spawn_stdio_greater_than_3, 5000) */                                     \
+/*TE(spawn_ignored_stdio, 5000) */                                            \
+/*TE(spawn_and_kill, 5000) */                                                 \
+/*TE(spawn_preserve_env, 5000) */                                             \
+/*TE(spawn_detached, 5000) */                                                 \
+/*TE(spawn_and_kill_with_std, 5000) */                                        \
+/*TE(spawn_and_ping, 5000) */                                                 \
+/*TE(spawn_same_stdout_stderr, 5000) */                                       \
+/*TE(spawn_closed_process_io, 5000) */                                        \
+/*TE(spawn_fails, 5000) */                                                    \
+/*TE(kill, 5000) */                                                           \
+/*TE(spawn_setuid_fails, 5000) */                                             \
+/*TE(spawn_setgid_fails, 5000) */                                             \
+/*TE(spawn_setuid_fails, 5000) */                                             \
+/*TE(spawn_setgid_fails, 5000) */                                             \
+/*TE(spawn_auto_unref, 5000) */                                               \
+/*TE(spawn_fs_open, 5000) */                                                  \
+/*TE(closed_fd_events, 5000) */                                               \
+/*TE(spawn_reads_child_path, 5000) */                                         \
+/*TE(spawn_inherit_streams, 5000) */
+#else
+#define TEST_LIST_EXT_PROCESS(TE)
+#endif
+
 #if defined(__linux__)
 #define TEST_LIST_EXT(TE)                                                     \
   TE(condvar_1, 5000)                                                         \
   TE(getaddrinfo_basic, 5000)                                                 \
   TE(getaddrinfo_basic_sync, 5000)                                            \
   TE(getaddrinfo_concurrent, 5000)                                            \
+  \
+  TEST_LIST_EXT_PIPE(TE) \
+  TEST_LIST_EXT_PROCESS(TE) \
+  TEST_LIST_EXT_SIGNAL(TE)
 
 #elif defined(__TUV_RAW__)
 #define TEST_LIST_EXT(TE)                                                     \
diff --git a/deps/libtuv/test/test_ipc.c b/deps/libtuv/test/test_ipc.c
new file mode 100644 (file)
index 0000000..4972f2b
--- /dev/null
@@ -0,0 +1,773 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "runner.h"
+
+#include <stdio.h>
+#include <string.h>
+
+static uv_pipe_t channel;
+static uv_tcp_t tcp_server;
+static uv_tcp_t tcp_server2;
+static uv_tcp_t tcp_connection;
+
+static int exit_cb_called;
+static int read_cb_called;
+static int tcp_write_cb_called;
+static int tcp_read_cb_called;
+static int on_pipe_read_called;
+static int local_conn_accepted;
+static int remote_conn_accepted;
+static int tcp_server_listening;
+static uv_write_t write_req;
+static uv_write_t conn_notify_req;
+static int close_cb_called;
+static int connection_accepted;
+static int tcp_conn_read_cb_called;
+static int tcp_conn_write_cb_called;
+
+typedef struct {
+  uv_connect_t conn_req;
+  uv_write_t tcp_write_req;
+  uv_tcp_t conn;
+} tcp_conn;
+
+#define CONN_COUNT 100
+#define BACKLOG 128
+
+
+static void close_server_conn_cb(uv_handle_t* handle) {
+  free(handle);
+}
+
+
+static void on_connection(uv_stream_t* server, int status) {
+  uv_tcp_t* conn;
+  int r;
+
+  if (!local_conn_accepted) {
+    /* Accept the connection and close it.  Also and close the server. */
+    TUV_ASSERT(status == 0);
+    TUV_ASSERT((uv_stream_t*)&tcp_server == server);
+
+    conn = malloc(sizeof(*conn));
+    TUV_ASSERT(conn);
+    r = uv_tcp_init(server->loop, conn);
+    TUV_ASSERT(r == 0);
+
+    r = uv_accept(server, (uv_stream_t*)conn);
+    TUV_ASSERT(r == 0);
+
+    uv_close((uv_handle_t*)conn, close_server_conn_cb);
+    uv_close((uv_handle_t*)server, NULL);
+    local_conn_accepted = 1;
+  }
+}
+
+
+static void exit_cb(uv_process_t* process,
+                    int64_t exit_status,
+                    int term_signal) {
+  printf("exit_cb\n");
+  exit_cb_called++;
+  TUV_ASSERT(exit_status == 0);
+  uv_close((uv_handle_t*)process, NULL);
+}
+
+
+static void on_alloc(uv_handle_t* handle,
+                     size_t suggested_size,
+                     uv_buf_t* buf) {
+  buf->base = malloc(suggested_size);
+  buf->len = suggested_size;
+}
+
+
+static void close_client_conn_cb(uv_handle_t* handle) {
+  tcp_conn* p = (tcp_conn*)handle->data;
+  free(p);
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+  uv_close((uv_handle_t*)req->handle, close_client_conn_cb);
+}
+
+
+static void make_many_connections(void) {
+  tcp_conn* conn;
+  struct sockaddr_in addr;
+  int r, i;
+
+  for (i = 0; i < CONN_COUNT; i++) {
+    conn = malloc(sizeof(*conn));
+    TUV_ASSERT(conn);
+
+    r = uv_tcp_init(uv_default_loop(), &conn->conn);
+    TUV_ASSERT(r == 0);
+
+    TUV_ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+    r = uv_tcp_connect(&conn->conn_req,
+                       (uv_tcp_t*) &conn->conn,
+                       (const struct sockaddr*) &addr,
+                       connect_cb);
+    TUV_ASSERT(r == 0);
+
+    conn->conn.data = conn;
+  }
+}
+
+
+static void on_read(uv_stream_t* handle,
+                    ssize_t nread,
+                    const uv_buf_t* buf) {
+  int r;
+  uv_pipe_t* pipe;
+  uv_handle_type pending;
+  uv_buf_t outbuf;
+
+  pipe = (uv_pipe_t*) handle;
+
+  if (nread == 0) {
+    /* Everything OK, but nothing read. */
+    free(buf->base);
+    return;
+  }
+
+  if (nread < 0) {
+    if (nread == UV_EOF) {
+      free(buf->base);
+      return;
+    }
+
+    printf("error recving on channel: %s\n", uv_strerror(nread));
+    abort();
+  }
+
+  fprintf(stderr, "got %d bytes\n", (int)nread);
+
+  pending = uv_pipe_pending_type(pipe);
+  if (!tcp_server_listening) {
+    TUV_ASSERT(1 == uv_pipe_pending_count(pipe));
+    TUV_ASSERT(nread > 0 && buf->base && pending != UV_UNKNOWN_HANDLE);
+    read_cb_called++;
+
+    /* Accept the pending TCP server, and start listening on it. */
+    TUV_ASSERT(pending == UV_TCP);
+    r = uv_tcp_init(uv_default_loop(), &tcp_server);
+    TUV_ASSERT(r == 0);
+
+    r = uv_accept((uv_stream_t*)pipe, (uv_stream_t*)&tcp_server);
+    TUV_ASSERT(r == 0);
+
+    r = uv_listen((uv_stream_t*)&tcp_server, BACKLOG, on_connection);
+    TUV_ASSERT(r == 0);
+
+    tcp_server_listening = 1;
+
+    /* Make sure that the expected data is correctly multiplexed. */
+    TUV_ASSERT(memcmp("hello\n", buf->base, nread) == 0);
+
+    outbuf = uv_buf_init("world\n", 6);
+    r = uv_write(&write_req, (uv_stream_t*)pipe, &outbuf, 1, NULL);
+    TUV_ASSERT(r == 0);
+
+    /* Create a bunch of connections to get both servers to accept. */
+    make_many_connections();
+  } else if (memcmp("accepted_connection\n", buf->base, nread) == 0) {
+    /* Remote server has accepted a connection.  Close the channel. */
+    TUV_ASSERT(0 == uv_pipe_pending_count(pipe));
+    TUV_ASSERT(pending == UV_UNKNOWN_HANDLE);
+    remote_conn_accepted = 1;
+    uv_close((uv_handle_t*)&channel, NULL);
+  }
+
+  free(buf->base);
+}
+
+#ifdef _WIN32
+static void on_read_listen_after_bound_twice(uv_stream_t* handle,
+                                             ssize_t nread,
+                                             const uv_buf_t* buf) {
+  int r;
+  uv_pipe_t* pipe;
+  uv_handle_type pending;
+
+  pipe = (uv_pipe_t*) handle;
+
+  if (nread == 0) {
+    /* Everything OK, but nothing read. */
+    free(buf->base);
+    return;
+  }
+
+  if (nread < 0) {
+    if (nread == UV_EOF) {
+      free(buf->base);
+      return;
+    }
+
+    printf("error recving on channel: %s\n", uv_strerror(nread));
+    abort();
+  }
+
+  fprintf(stderr, "got %d bytes\n", (int)nread);
+
+  TUV_ASSERT(uv_pipe_pending_count(pipe) > 0);
+  pending = uv_pipe_pending_type(pipe);
+  TUV_ASSERT(nread > 0 && buf->base && pending != UV_UNKNOWN_HANDLE);
+  read_cb_called++;
+
+  if (read_cb_called == 1) {
+    /* Accept the first TCP server, and start listening on it. */
+    TUV_ASSERT(pending == UV_TCP);
+    r = uv_tcp_init(uv_default_loop(), &tcp_server);
+    TUV_ASSERT(r == 0);
+
+    r = uv_accept((uv_stream_t*)pipe, (uv_stream_t*)&tcp_server);
+    TUV_ASSERT(r == 0);
+
+    r = uv_listen((uv_stream_t*)&tcp_server, BACKLOG, on_connection);
+    TUV_ASSERT(r == 0);
+  } else if (read_cb_called == 2) {
+    /* Accept the second TCP server, and start listening on it. */
+    TUV_ASSERT(pending == UV_TCP);
+    r = uv_tcp_init(uv_default_loop(), &tcp_server2);
+    TUV_ASSERT(r == 0);
+
+    r = uv_accept((uv_stream_t*)pipe, (uv_stream_t*)&tcp_server2);
+    TUV_ASSERT(r == 0);
+
+    r = uv_listen((uv_stream_t*)&tcp_server2, BACKLOG, on_connection);
+    TUV_ASSERT(r == UV_EADDRINUSE);
+
+    uv_close((uv_handle_t*)&tcp_server, NULL);
+    uv_close((uv_handle_t*)&tcp_server2, NULL);
+    TUV_ASSERT(0 == uv_pipe_pending_count(pipe));
+    uv_close((uv_handle_t*)&channel, NULL);
+  }
+
+  free(buf->base);
+}
+#endif
+
+void spawn_helper(uv_pipe_t* channel,
+                  uv_process_t* process,
+                  const char* helper) {
+  uv_process_options_t options;
+  size_t exepath_size;
+  char exepath[1024];
+  char* args[3];
+  int r;
+  uv_stdio_container_t stdio[1];
+
+  r = uv_pipe_init(uv_default_loop(), channel, 1);
+  TUV_ASSERT(r == 0);
+  TUV_ASSERT(channel->ipc);
+
+  exepath_size = sizeof(exepath);
+  r = uv_exepath(exepath, &exepath_size);
+  TUV_ASSERT(r == 0);
+
+  exepath[exepath_size] = '\0';
+  args[0] = exepath;
+  args[1] = (char*)helper;
+  args[2] = NULL;
+
+  memset(&options, 0, sizeof(options));
+  options.file = exepath;
+  options.args = args;
+  options.exit_cb = exit_cb;
+
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_CREATE_PIPE |
+    UV_READABLE_PIPE | UV_WRITABLE_PIPE;
+  options.stdio[0].data.stream = (uv_stream_t*)channel;
+  options.stdio_count = 1;
+
+  r = uv_spawn(uv_default_loop(), process, &options);
+  TUV_ASSERT(r == 0);
+}
+
+
+static void on_tcp_write(uv_write_t* req, int status) {
+  TUV_ASSERT(status == 0);
+  TUV_ASSERT(req->handle == (uv_stream_t*)&tcp_connection);
+  tcp_write_cb_called++;
+}
+
+
+static void on_read_alloc(uv_handle_t* handle,
+                          size_t suggested_size,
+                          uv_buf_t* buf) {
+  buf->base = malloc(suggested_size);
+  buf->len = suggested_size;
+}
+
+
+static void on_tcp_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
+  TUV_ASSERT(nread > 0);
+  TUV_ASSERT(memcmp("hello again\n", buf->base, nread) == 0);
+  TUV_ASSERT(tcp == (uv_stream_t*)&tcp_connection);
+  free(buf->base);
+
+  tcp_read_cb_called++;
+
+  uv_close((uv_handle_t*)tcp, NULL);
+  uv_close((uv_handle_t*)&channel, NULL);
+}
+
+
+static void on_read_connection(uv_stream_t* handle,
+                               ssize_t nread,
+                               const uv_buf_t* buf) {
+  int r;
+  uv_buf_t outbuf;
+  uv_pipe_t* pipe;
+  uv_handle_type pending;
+
+  pipe = (uv_pipe_t*) handle;
+  if (nread == 0) {
+    /* Everything OK, but nothing read. */
+    free(buf->base);
+    return;
+  }
+
+  if (nread < 0) {
+    if (nread == UV_EOF) {
+      free(buf->base);
+      return;
+    }
+
+    printf("error recving on channel: %s\n", uv_strerror(nread));
+    abort();
+  }
+
+  fprintf(stderr, "got %d bytes\n", (int)nread);
+
+  TUV_ASSERT(1 == uv_pipe_pending_count(pipe));
+  pending = uv_pipe_pending_type(pipe);
+
+  TUV_ASSERT(nread > 0 && buf->base && pending != UV_UNKNOWN_HANDLE);
+  read_cb_called++;
+
+  /* Accept the pending TCP connection */
+  TUV_ASSERT(pending == UV_TCP);
+  r = uv_tcp_init(uv_default_loop(), &tcp_connection);
+  TUV_ASSERT(r == 0);
+
+  r = uv_accept(handle, (uv_stream_t*)&tcp_connection);
+  TUV_ASSERT(r == 0);
+
+  /* Make sure that the expected data is correctly multiplexed. */
+  TUV_ASSERT(memcmp("hello\n", buf->base, nread) == 0);
+
+  /* Write/read to/from the connection */
+  outbuf = uv_buf_init("world\n", 6);
+  r = uv_write(&write_req, (uv_stream_t*)&tcp_connection, &outbuf, 1,
+    on_tcp_write);
+  TUV_ASSERT(r == 0);
+
+  r = uv_read_start((uv_stream_t*)&tcp_connection, on_read_alloc, on_tcp_read);
+  TUV_ASSERT(r == 0);
+
+  free(buf->base);
+}
+
+
+static int run_ipc_test(const char* helper, uv_read_cb read_cb) {
+  uv_process_t process;
+  int r;
+
+  spawn_helper(&channel, &process, helper);
+  uv_read_start((uv_stream_t*)&channel, on_alloc, read_cb);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  return 0;
+}
+
+
+TEST_IMPL(ipc_listen_before_write) {
+  int r = run_ipc_test("ipc_helper_listen_before_write", on_read);
+  TUV_ASSERT(local_conn_accepted == 1);
+  TUV_ASSERT(remote_conn_accepted == 1);
+  TUV_ASSERT(read_cb_called == 1);
+  TUV_ASSERT(exit_cb_called == 1);
+  return r;
+}
+
+
+TEST_IMPL(ipc_listen_after_write) {
+  int r = run_ipc_test("ipc_helper_listen_after_write", on_read);
+  TUV_ASSERT(local_conn_accepted == 1);
+  TUV_ASSERT(remote_conn_accepted == 1);
+  TUV_ASSERT(read_cb_called == 1);
+  TUV_ASSERT(exit_cb_called == 1);
+  return r;
+}
+
+
+TEST_IMPL(ipc_tcp_connection) {
+  int r = run_ipc_test("ipc_helper_tcp_connection", on_read_connection);
+  TUV_ASSERT(read_cb_called == 1);
+  TUV_ASSERT(tcp_write_cb_called == 1);
+  TUV_ASSERT(tcp_read_cb_called == 1);
+  TUV_ASSERT(exit_cb_called == 1);
+  return r;
+}
+
+
+#ifdef _WIN32
+TEST_IMPL(listen_with_simultaneous_accepts) {
+  uv_tcp_t server;
+  int r;
+  struct sockaddr_in addr;
+
+  TUV_ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+  r = uv_tcp_init(uv_default_loop(), &server);
+  TUV_ASSERT(r == 0);
+
+  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_tcp_simultaneous_accepts(&server, 1);
+  TUV_ASSERT(r == 0);
+
+  r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL);
+  TUV_ASSERT(r == 0);
+  TUV_ASSERT(server.reqs_pending == 32);
+
+  return 0;
+}
+
+
+TEST_IMPL(listen_no_simultaneous_accepts) {
+  uv_tcp_t server;
+  int r;
+  struct sockaddr_in addr;
+
+  TUV_ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+  r = uv_tcp_init(uv_default_loop(), &server);
+  TUV_ASSERT(r == 0);
+
+  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_tcp_simultaneous_accepts(&server, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL);
+  TUV_ASSERT(r == 0);
+  TUV_ASSERT(server.reqs_pending == 1);
+
+  return 0;
+}
+
+TEST_IMPL(ipc_listen_after_bind_twice) {
+  int r = run_ipc_test("ipc_helper_bind_twice", on_read_listen_after_bound_twice);
+  TUV_ASSERT(read_cb_called == 2);
+  TUV_ASSERT(exit_cb_called == 1);
+  return r;
+}
+#endif
+
+
+/* Everything here runs in a child process. */
+
+static tcp_conn conn;
+
+
+static void close_cb(uv_handle_t* handle) {
+  close_cb_called++;
+}
+
+
+static void conn_notify_write_cb(uv_write_t* req, int status) {
+  uv_close((uv_handle_t*)&tcp_server, close_cb);
+  uv_close((uv_handle_t*)&channel, close_cb);
+}
+
+
+static void tcp_connection_write_cb(uv_write_t* req, int status) {
+  TUV_ASSERT((uv_handle_t*)&conn.conn == (uv_handle_t*)req->handle);
+  uv_close((uv_handle_t*)req->handle, close_cb);
+  uv_close((uv_handle_t*)&channel, close_cb);
+  uv_close((uv_handle_t*)&tcp_server, close_cb);
+  tcp_conn_write_cb_called++;
+}
+
+
+static void on_tcp_child_process_read(uv_stream_t* tcp,
+                                      ssize_t nread,
+                                      const uv_buf_t* buf) {
+  uv_buf_t outbuf;
+  int r;
+
+  if (nread < 0) {
+    if (nread == UV_EOF) {
+      free(buf->base);
+      return;
+    }
+
+    printf("error recving on tcp connection: %s\n", uv_strerror(nread));
+    abort();
+  }
+
+  TUV_ASSERT(nread > 0);
+  TUV_ASSERT(memcmp("world\n", buf->base, nread) == 0);
+  on_pipe_read_called++;
+  free(buf->base);
+
+  /* Write to the socket */
+  outbuf = uv_buf_init("hello again\n", 12);
+  r = uv_write(&conn.tcp_write_req, tcp, &outbuf, 1, tcp_connection_write_cb);
+  TUV_ASSERT(r == 0);
+
+  tcp_conn_read_cb_called++;
+}
+
+
+static void connect_child_process_cb(uv_connect_t* req, int status) {
+  int r;
+
+  TUV_ASSERT(status == 0);
+  r = uv_read_start(req->handle, on_read_alloc, on_tcp_child_process_read);
+  TUV_ASSERT(r == 0);
+}
+
+
+static void ipc_on_connection(uv_stream_t* server, int status) {
+  int r;
+  uv_buf_t buf;
+
+  if (!connection_accepted) {
+    /*
+     * Accept the connection and close it.  Also let the other
+     * side know.
+     */
+    TUV_ASSERT(status == 0);
+    TUV_ASSERT((uv_stream_t*)&tcp_server == server);
+
+    r = uv_tcp_init(server->loop, &conn.conn);
+    TUV_ASSERT(r == 0);
+
+    r = uv_accept(server, (uv_stream_t*)&conn.conn);
+    TUV_ASSERT(r == 0);
+
+    uv_close((uv_handle_t*)&conn.conn, close_cb);
+
+    buf = uv_buf_init("accepted_connection\n", 20);
+    r = uv_write2(&conn_notify_req, (uv_stream_t*)&channel, &buf, 1,
+      NULL, conn_notify_write_cb);
+    TUV_ASSERT(r == 0);
+
+    connection_accepted = 1;
+  }
+}
+
+
+static void ipc_on_connection_tcp_conn(uv_stream_t* server, int status) {
+  int r;
+  uv_buf_t buf;
+  uv_tcp_t* conn;
+
+  TUV_ASSERT(status == 0);
+  TUV_ASSERT((uv_stream_t*)&tcp_server == server);
+
+  conn = malloc(sizeof(*conn));
+  TUV_ASSERT(conn);
+
+  r = uv_tcp_init(server->loop, conn);
+  TUV_ASSERT(r == 0);
+
+  r = uv_accept(server, (uv_stream_t*)conn);
+  TUV_ASSERT(r == 0);
+
+  /* Send the accepted connection to the other process */
+  buf = uv_buf_init("hello\n", 6);
+  r = uv_write2(&conn_notify_req, (uv_stream_t*)&channel, &buf, 1,
+    (uv_stream_t*)conn, NULL);
+  TUV_ASSERT(r == 0);
+
+  r = uv_read_start((uv_stream_t*) conn,
+                    on_read_alloc,
+                    on_tcp_child_process_read);
+  TUV_ASSERT(r == 0);
+
+  uv_close((uv_handle_t*)conn, close_cb);
+}
+
+
+int ipc_helper(int listen_after_write) {
+  /*
+   * This is launched from test-ipc.c. stdin is a duplex channel that we
+   * over which a handle will be transmitted.
+   */
+  struct sockaddr_in addr;
+  uv_write_t write_req;
+  int r;
+  uv_buf_t buf;
+
+  TUV_ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+  r = uv_pipe_init(uv_default_loop(), &channel, 1);
+  TUV_ASSERT(r == 0);
+
+  uv_pipe_open(&channel, 0);
+
+  TUV_ASSERT(1 == uv_is_readable((uv_stream_t*) &channel));
+  TUV_ASSERT(1 == uv_is_writable((uv_stream_t*) &channel));
+  TUV_ASSERT(0 == uv_is_closing((uv_handle_t*) &channel));
+
+  r = uv_tcp_init(uv_default_loop(), &tcp_server);
+  TUV_ASSERT(r == 0);
+
+  r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
+  TUV_ASSERT(r == 0);
+
+  if (!listen_after_write) {
+    r = uv_listen((uv_stream_t*)&tcp_server, BACKLOG, ipc_on_connection);
+    TUV_ASSERT(r == 0);
+  }
+
+  buf = uv_buf_init("hello\n", 6);
+  r = uv_write2(&write_req, (uv_stream_t*)&channel, &buf, 1,
+      (uv_stream_t*)&tcp_server, NULL);
+  TUV_ASSERT(r == 0);
+
+  if (listen_after_write) {
+    r = uv_listen((uv_stream_t*)&tcp_server, BACKLOG, ipc_on_connection);
+    TUV_ASSERT(r == 0);
+  }
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(connection_accepted == 1);
+  TUV_ASSERT(close_cb_called == 3);
+
+  return 0;
+}
+
+
+int ipc_helper_tcp_connection(void) {
+  /*
+   * This is launched from test-ipc.c. stdin is a duplex channel
+   * over which a handle will be transmitted.
+   */
+
+  int r;
+  struct sockaddr_in addr;
+
+  r = uv_pipe_init(uv_default_loop(), &channel, 1);
+  TUV_ASSERT(r == 0);
+
+  uv_pipe_open(&channel, 0);
+
+  TUV_ASSERT(1 == uv_is_readable((uv_stream_t*) &channel));
+  TUV_ASSERT(1 == uv_is_writable((uv_stream_t*) &channel));
+  TUV_ASSERT(0 == uv_is_closing((uv_handle_t*) &channel));
+
+  r = uv_tcp_init(uv_default_loop(), &tcp_server);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+  r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_listen((uv_stream_t*)&tcp_server, BACKLOG, ipc_on_connection_tcp_conn);
+  TUV_ASSERT(r == 0);
+
+  /* Make a connection to the server */
+  r = uv_tcp_init(uv_default_loop(), &conn.conn);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+  r = uv_tcp_connect(&conn.conn_req,
+                     (uv_tcp_t*) &conn.conn,
+                     (const struct sockaddr*) &addr,
+                     connect_child_process_cb);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(tcp_conn_read_cb_called == 1);
+  TUV_ASSERT(tcp_conn_write_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 4);
+
+  return 0;
+}
+
+int ipc_helper_bind_twice(void) {
+  /*
+   * This is launched from test-ipc.c. stdin is a duplex channel
+   * over which two handles will be transmitted.
+   */
+  struct sockaddr_in addr;
+  uv_write_t write_req;
+  uv_write_t write_req2;
+  int r;
+  uv_buf_t buf;
+
+  TUV_ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+  r = uv_pipe_init(uv_default_loop(), &channel, 1);
+  TUV_ASSERT(r == 0);
+
+  uv_pipe_open(&channel, 0);
+
+  TUV_ASSERT(1 == uv_is_readable((uv_stream_t*) &channel));
+  TUV_ASSERT(1 == uv_is_writable((uv_stream_t*) &channel));
+  TUV_ASSERT(0 == uv_is_closing((uv_handle_t*) &channel));
+
+  buf = uv_buf_init("hello\n", 6);
+
+  r = uv_tcp_init(uv_default_loop(), &tcp_server);
+  TUV_ASSERT(r == 0);
+  r = uv_tcp_init(uv_default_loop(), &tcp_server2);
+  TUV_ASSERT(r == 0);
+
+  r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
+  TUV_ASSERT(r == 0);
+  r = uv_tcp_bind(&tcp_server2, (const struct sockaddr*) &addr, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_write2(&write_req, (uv_stream_t*)&channel, &buf, 1,
+                (uv_stream_t*)&tcp_server, NULL);
+  TUV_ASSERT(r == 0);
+  r = uv_write2(&write_req2, (uv_stream_t*)&channel, &buf, 1,
+                (uv_stream_t*)&tcp_server2, NULL);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  return 0;
+}
diff --git a/deps/libtuv/test/test_pipe_bind_error.c b/deps/libtuv/test/test_pipe_bind_error.c
new file mode 100644 (file)
index 0000000..ddc31aa
--- /dev/null
@@ -0,0 +1,137 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "runner.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#ifdef _WIN32
+# define BAD_PIPENAME "bad-pipe"
+#else
+# define BAD_PIPENAME "/path/to/unix/socket/that/really/should/not/be/there"
+#endif
+
+
+static int close_cb_called = 0;
+
+
+static void close_cb(uv_handle_t* handle) {
+  TUV_ASSERT(handle != NULL);
+  close_cb_called++;
+}
+
+
+TEST_IMPL(pipe_bind_error_addrinuse) {
+  uv_pipe_t server1, server2;
+  int r;
+  close_cb_called = 0;
+
+  r = uv_pipe_init(uv_default_loop(), &server1, 0);
+  TUV_ASSERT(r == 0);
+  r = uv_pipe_bind(&server1, TEST_PIPENAME);
+  TUV_ASSERT(r == 0);
+
+  r = uv_pipe_init(uv_default_loop(), &server2, 0);
+  TUV_ASSERT(r == 0);
+  r = uv_pipe_bind(&server2, TEST_PIPENAME);
+  TUV_ASSERT(r == UV_EADDRINUSE);
+
+  r = uv_listen((uv_stream_t*)&server1, SOMAXCONN, NULL);
+  TUV_ASSERT(r == 0);
+  r = uv_listen((uv_stream_t*)&server2, SOMAXCONN, NULL);
+  TUV_ASSERT(r == UV_EINVAL);
+
+  uv_close((uv_handle_t*)&server1, close_cb);
+  uv_close((uv_handle_t*)&server2, close_cb);
+
+  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+  TUV_ASSERT(close_cb_called == 2);
+
+  return 0;
+}
+
+
+TEST_IMPL(pipe_bind_error_addrnotavail) {
+  uv_pipe_t server;
+  int r;
+  close_cb_called = 0;
+
+  r = uv_pipe_init(uv_default_loop(), &server, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_pipe_bind(&server, BAD_PIPENAME);
+  TUV_ASSERT(r == UV_EACCES);
+
+  uv_close((uv_handle_t*)&server, close_cb);
+
+  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+  TUV_ASSERT(close_cb_called == 1);
+
+  return 0;
+}
+
+
+TEST_IMPL(pipe_bind_error_inval) {
+  uv_pipe_t server;
+  int r;
+  close_cb_called = 0;
+
+  r = uv_pipe_init(uv_default_loop(), &server, 0);
+  TUV_ASSERT(r == 0);
+  r = uv_pipe_bind(&server, TEST_PIPENAME);
+  TUV_ASSERT(r == 0);
+  r = uv_pipe_bind(&server, TEST_PIPENAME_2);
+  TUV_ASSERT(r == UV_EINVAL);
+
+  uv_close((uv_handle_t*)&server, close_cb);
+
+  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+  TUV_ASSERT(close_cb_called == 1);
+
+  return 0;
+}
+
+
+TEST_IMPL(pipe_listen_without_bind) {
+  uv_pipe_t server;
+  int r;
+  close_cb_called = 0;
+
+  r = uv_pipe_init(uv_default_loop(), &server, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL);
+  TUV_ASSERT(r == UV_EINVAL);
+
+  uv_close((uv_handle_t*)&server, close_cb);
+
+  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+  TUV_ASSERT(close_cb_called == 1);
+
+  return 0;
+}
diff --git a/deps/libtuv/test/test_pipe_close_stdout_read_stdin.c b/deps/libtuv/test/test_pipe_close_stdout_read_stdin.c
new file mode 100644 (file)
index 0000000..ae92dfa
--- /dev/null
@@ -0,0 +1,106 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef _WIN32
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+
+#include "uv.h"
+#include "runner.h"
+
+void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t* buf)
+{
+  static char buffer[1024];
+
+  buf->base = buffer;
+  buf->len = sizeof(buffer);
+}
+
+void read_stdin(uv_stream_t *stream, ssize_t nread, const uv_buf_t* buf)
+{
+  if (nread < 0) {
+    uv_close((uv_handle_t*)stream, NULL);
+    return;
+  }
+}
+
+/*
+ * This test is a reproduction of joyent/libuv#1419 .
+ */
+TEST_IMPL(pipe_close_stdout_read_stdin) {
+  int r = -1;
+  int pid;
+  int fd[2];
+  int status;
+  char buf;
+  uv_pipe_t stdin_pipe;
+
+  r = pipe(fd);
+  TUV_ASSERT(r == 0);
+
+  if ((pid = fork()) == 0) {
+    /*
+     * Make the read side of the pipe our stdin.
+     * The write side will be closed by the parent process.
+    */
+    close(fd[1]);
+    /* block until write end of pipe is closed */
+    read(fd[0], &buf, 1);
+    close(0);
+    r = dup(fd[0]);
+    TUV_ASSERT(r != -1);
+
+    /* Create a stream that reads from the pipe. */
+    r = uv_pipe_init(uv_default_loop(), (uv_pipe_t *)&stdin_pipe, 0);
+    TUV_ASSERT(r == 0);
+
+    r = uv_pipe_open((uv_pipe_t *)&stdin_pipe, 0);
+    TUV_ASSERT(r == 0);
+
+    r = uv_read_start((uv_stream_t *)&stdin_pipe, alloc_buffer, read_stdin);
+    TUV_ASSERT(r == 0);
+
+    /*
+     * Because the other end of the pipe was closed, there should
+     * be no event left to process after one run of the event loop.
+     * Otherwise, it means that events were not processed correctly.
+     */
+    TUV_ASSERT(uv_run(uv_default_loop(), UV_RUN_NOWAIT) == 0);
+  } else {
+    /*
+     * Close both ends of the pipe so that the child
+     * get a POLLHUP event when it tries to read from
+     * the other end.
+     */
+     close(fd[1]);
+     close(fd[0]);
+
+    waitpid(pid, &status, 0);
+    TUV_ASSERT(WIFEXITED(status) && WEXITSTATUS(status) == 0);
+  }
+
+  return 0;
+}
+
+#endif /* ifndef _WIN32 */
diff --git a/deps/libtuv/test/test_pipe_connect_error.c b/deps/libtuv/test/test_pipe_connect_error.c
new file mode 100644 (file)
index 0000000..563902f
--- /dev/null
@@ -0,0 +1,94 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "runner.h"
+
+
+#ifdef _WIN32
+# define BAD_PIPENAME "bad-pipe"
+#else
+# define BAD_PIPENAME "/path/to/unix/socket/that/really/should/not/be/there"
+#endif
+
+
+static int close_cb_called = 0;
+static int connect_cb_called = 0;
+
+
+static void close_cb(uv_handle_t* handle) {
+  TUV_ASSERT(handle != NULL);
+  close_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* connect_req, int status) {
+  TUV_ASSERT(status == UV_ENOENT);
+  uv_close((uv_handle_t*)connect_req->handle, close_cb);
+  connect_cb_called++;
+}
+
+
+static void connect_cb_file(uv_connect_t* connect_req, int status) {
+  TUV_ASSERT(status == UV_ENOTSOCK || status == UV_ECONNREFUSED);
+  uv_close((uv_handle_t*)connect_req->handle, close_cb);
+  connect_cb_called++;
+}
+
+
+TEST_IMPL(pipe_connect_bad_name) {
+  uv_pipe_t client;
+  uv_connect_t req;
+  int r;
+
+  r = uv_pipe_init(uv_default_loop(), &client, 0);
+  TUV_ASSERT(r == 0);
+  uv_pipe_connect(&req, &client, BAD_PIPENAME, connect_cb);
+
+  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+  TUV_ASSERT(close_cb_called == 1);
+  TUV_ASSERT(connect_cb_called == 1);
+
+  return 0;
+}
+
+
+TEST_IMPL(pipe_connect_to_file) {
+  const char* path = "test/fixtures/empty_file";
+  uv_pipe_t client;
+  uv_connect_t req;
+  int r;
+
+  r = uv_pipe_init(uv_default_loop(), &client, 0);
+  TUV_ASSERT(r == 0);
+  uv_pipe_connect(&req, &client, path, connect_cb_file);
+
+  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+  TUV_ASSERT(close_cb_called == 1);
+  TUV_ASSERT(connect_cb_called == 1);
+
+  return 0;
+}
diff --git a/deps/libtuv/test/test_pipe_connect_multiple.c b/deps/libtuv/test/test_pipe_connect_multiple.c
new file mode 100644 (file)
index 0000000..5a3599a
--- /dev/null
@@ -0,0 +1,104 @@
+/* Copyright (c) 2015 Saúl Ibarra Corretgé <saghul@gmail.com>.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "runner.h"
+
+
+static int connection_cb_called = 0;
+static int connect_cb_called = 0;
+
+#define NUM_CLIENTS 4
+
+typedef struct {
+  uv_pipe_t pipe_handle;
+  uv_connect_t conn_req;
+} client_t;
+
+static uv_pipe_t server_handle;
+static client_t clients[NUM_CLIENTS];
+static uv_pipe_t connections[NUM_CLIENTS];
+
+
+static void connection_cb(uv_stream_t* server, int status) {
+  int r;
+  uv_pipe_t* conn;
+  TUV_ASSERT(status == 0);
+
+  conn = &connections[connection_cb_called];
+  r = uv_pipe_init(server->loop, conn, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_accept(server, (uv_stream_t*)conn);
+  TUV_ASSERT(r == 0);
+
+  if (++connection_cb_called == NUM_CLIENTS &&
+      connect_cb_called == NUM_CLIENTS) {
+    uv_stop(server->loop);
+  }
+}
+
+
+static void connect_cb(uv_connect_t* connect_req, int status) {
+  TUV_ASSERT(status == 0);
+  if (++connect_cb_called == NUM_CLIENTS &&
+      connection_cb_called == NUM_CLIENTS) {
+    uv_stop(connect_req->handle->loop);
+  }
+}
+
+
+TEST_IMPL(pipe_connect_multiple) {
+  int i;
+  int r;
+  uv_loop_t* loop;
+
+  loop = uv_default_loop();
+
+  r = uv_pipe_init(loop, &server_handle, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_pipe_bind(&server_handle, TEST_PIPENAME);
+  TUV_ASSERT(r == 0);
+
+  r = uv_listen((uv_stream_t*)&server_handle, 128, connection_cb);
+  TUV_ASSERT(r == 0);
+
+  for (i = 0; i < NUM_CLIENTS; i++) {
+    r = uv_pipe_init(loop, &clients[i].pipe_handle, 0);
+    TUV_ASSERT(r == 0);
+    uv_pipe_connect(&clients[i].conn_req,
+                    &clients[i].pipe_handle,
+                    TEST_PIPENAME,
+                    connect_cb);
+  }
+
+  uv_run(loop, UV_RUN_DEFAULT);
+
+  TUV_ASSERT(connection_cb_called == NUM_CLIENTS);
+  TUV_ASSERT(connect_cb_called == NUM_CLIENTS);
+
+  return 0;
+}
diff --git a/deps/libtuv/test/test_pipe_connect_prepare.c b/deps/libtuv/test/test_pipe_connect_prepare.c
new file mode 100644 (file)
index 0000000..efdcf21
--- /dev/null
@@ -0,0 +1,84 @@
+/* Copyright (c) 2015 Saúl Ibarra Corretgé <saghul@gmail.com>.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "uv.h"
+#include "runner.h"
+
+
+#ifdef _WIN32
+# define BAD_PIPENAME "bad-pipe"
+#else
+# define BAD_PIPENAME "/path/to/unix/socket/that/really/should/not/be/there"
+#endif
+
+
+static int close_cb_called = 0;
+static int connect_cb_called = 0;
+
+static uv_pipe_t pipe_handle;
+static uv_prepare_t prepare_handle;
+static uv_connect_t conn_req;
+
+
+static void close_cb(uv_handle_t* handle) {
+  TUV_ASSERT(handle != NULL);
+  close_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* connect_req, int status) {
+  TUV_ASSERT(status == UV_ENOENT);
+  connect_cb_called++;
+  uv_close((uv_handle_t*)&prepare_handle, close_cb);
+  uv_close((uv_handle_t*)&pipe_handle, close_cb);
+}
+
+
+static void prepare_cb(uv_prepare_t* handle) {
+  TUV_ASSERT(handle == &prepare_handle);
+  uv_pipe_connect(&conn_req, &pipe_handle, BAD_PIPENAME, connect_cb);
+}
+
+/*
+TEST_IMPL(pipe_connect_on_prepare) {
+  int r;
+
+  r = uv_pipe_init(uv_default_loop(), &pipe_handle, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_prepare_init(uv_default_loop(), &prepare_handle);
+  TUV_ASSERT(r == 0);
+  r = uv_prepare_start(&prepare_handle, prepare_cb);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(close_cb_called == 2);
+  TUV_ASSERT(connect_cb_called == 1);
+
+  return 0;
+}
+*/
diff --git a/deps/libtuv/test/test_pipe_getsockname.c b/deps/libtuv/test/test_pipe_getsockname.c
new file mode 100644 (file)
index 0000000..808922a
--- /dev/null
@@ -0,0 +1,262 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "runner.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if defined(__linux__)
+  #include <sys/socket.h>
+  #include <sys/un.h>
+#endif
+
+#ifndef _WIN32
+# include <unistd.h>  /* close */
+#else
+# include <fcntl.h>
+#endif
+
+static uv_pipe_t pipe_client;
+static uv_pipe_t pipe_server;
+static uv_connect_t connect_req;
+
+static int pipe_close_cb_called = 0;
+static int pipe_client_connect_cb_called = 0;
+
+
+static void pipe_close_cb(uv_handle_t* handle) {
+  TUV_ASSERT(handle == (uv_handle_t*) &pipe_client ||
+         handle == (uv_handle_t*) &pipe_server);
+  pipe_close_cb_called++;
+}
+
+
+static void pipe_client_connect_cb(uv_connect_t* req, int status) {
+  char buf[1024];
+  size_t len;
+  int r;
+
+  TUV_ASSERT(req == &connect_req);
+  TUV_ASSERT(status == 0);
+
+  len = sizeof buf;
+  r = uv_pipe_getpeername(&pipe_client, buf, &len);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(buf[len - 1] != 0);
+  TUV_ASSERT(memcmp(buf, TEST_PIPENAME, len) == 0);
+
+  len = sizeof buf;
+  r = uv_pipe_getsockname(&pipe_client, buf, &len);
+  TUV_ASSERT(r == 0 && len == 0);
+
+  pipe_client_connect_cb_called++;
+
+
+  uv_close((uv_handle_t*) &pipe_client, pipe_close_cb);
+  uv_close((uv_handle_t*) &pipe_server, pipe_close_cb);
+}
+
+
+static void pipe_server_connection_cb(uv_stream_t* handle, int status) {
+  /* This function *may* be called, depending on whether accept or the
+   * connection callback is called first.
+   */
+  TUV_ASSERT(status == 0);
+}
+
+
+TEST_IMPL(pipe_getsockname) {
+  uv_loop_t* loop;
+  char buf[1024];
+  size_t len;
+  int r;
+  pipe_close_cb_called = 0;
+
+  loop = uv_default_loop();
+  TUV_ASSERT(loop != NULL);
+
+  r = uv_pipe_init(loop, &pipe_server, 0);
+  TUV_ASSERT(r == 0);
+
+  len = sizeof buf;
+  r = uv_pipe_getsockname(&pipe_server, buf, &len);
+  TUV_ASSERT(r == UV_EBADF);
+
+  len = sizeof buf;
+  r = uv_pipe_getpeername(&pipe_server, buf, &len);
+  TUV_ASSERT(r == UV_EBADF);
+
+  r = uv_pipe_bind(&pipe_server, TEST_PIPENAME);
+  TUV_ASSERT(r == 0);
+
+  len = sizeof buf;
+  r = uv_pipe_getsockname(&pipe_server, buf, &len);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(buf[len - 1] != 0);
+  TUV_ASSERT(buf[len] == '\0');
+  TUV_ASSERT(memcmp(buf, TEST_PIPENAME, len) == 0);
+
+  len = sizeof buf;
+  r = uv_pipe_getpeername(&pipe_server, buf, &len);
+  TUV_ASSERT(r == UV_ENOTCONN);
+
+  r = uv_listen((uv_stream_t*) &pipe_server, 0, pipe_server_connection_cb);
+  TUV_ASSERT(r == 0);
+
+  r = uv_pipe_init(loop, &pipe_client, 0);
+  TUV_ASSERT(r == 0);
+
+  len = sizeof buf;
+  r = uv_pipe_getsockname(&pipe_client, buf, &len);
+  TUV_ASSERT(r == UV_EBADF);
+
+  len = sizeof buf;
+  r = uv_pipe_getpeername(&pipe_client, buf, &len);
+  TUV_ASSERT(r == UV_EBADF);
+
+  uv_pipe_connect(&connect_req, &pipe_client, TEST_PIPENAME, pipe_client_connect_cb);
+
+  len = sizeof buf;
+  r = uv_pipe_getsockname(&pipe_client, buf, &len);
+  TUV_ASSERT(r == 0 && len == 0);
+
+  len = sizeof buf;
+  r = uv_pipe_getpeername(&pipe_client, buf, &len);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(buf[len - 1] != 0);
+  TUV_ASSERT(memcmp(buf, TEST_PIPENAME, len) == 0);
+
+  r = uv_run(loop, UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+  TUV_ASSERT(pipe_client_connect_cb_called == 1);
+  TUV_ASSERT(pipe_close_cb_called == 2);
+
+  return 0;
+}
+
+
+TEST_IMPL(pipe_getsockname_abstract) {
+#if defined(__linux__)
+  char buf[1024];
+  size_t len;
+  int r;
+  int sock;
+  struct sockaddr_un sun;
+  socklen_t sun_len;
+  char abstract_pipe[] = "\0test-pipe";
+  pipe_close_cb_called = 0;
+
+  sock = socket(AF_LOCAL, SOCK_STREAM, 0);
+  TUV_ASSERT(sock != -1);
+
+  sun_len = sizeof sun;
+  memset(&sun, 0, sun_len);
+  sun.sun_family = AF_UNIX;
+  memcpy(sun.sun_path, abstract_pipe, sizeof abstract_pipe);
+
+  r = bind(sock, (struct sockaddr*)&sun, sun_len);
+  TUV_ASSERT(r == 0);
+
+  r = uv_pipe_init(uv_default_loop(), &pipe_server, 0);
+  TUV_ASSERT(r == 0);
+  r = uv_pipe_open(&pipe_server, sock);
+  TUV_ASSERT(r == 0);
+
+  len = sizeof buf;
+  r = uv_pipe_getsockname(&pipe_server, buf, &len);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(memcmp(buf, abstract_pipe, sizeof abstract_pipe) == 0);
+
+  uv_close((uv_handle_t*)&pipe_server, pipe_close_cb);
+
+  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+  close(sock);
+
+  TUV_ASSERT(pipe_close_cb_called == 1);
+  return 0;
+#else
+  return 0;
+#endif
+}
+
+TEST_IMPL(pipe_getsockname_blocking) {
+#ifdef _WIN32
+  HANDLE readh, writeh;
+  int readfd;
+  char buf1[1024], buf2[1024];
+  size_t len1, len2;
+  int r;
+
+  r = CreatePipe(&readh, &writeh, NULL, 65536);
+  TUV_ASSERT(r != 0);
+
+  r = uv_pipe_init(uv_default_loop(), &pipe_client, 0);
+  TUV_ASSERT(r == 0);
+  readfd = _open_osfhandle((intptr_t)readh, _O_RDONLY);
+  TUV_ASSERT(r != -1);
+  r = uv_pipe_open(&pipe_client, readfd);
+  TUV_ASSERT(r == 0);
+  r = uv_read_start((uv_stream_t*)&pipe_client, NULL, NULL);
+  TUV_ASSERT(r == 0);
+  Sleep(100);
+  r = uv_read_stop((uv_stream_t*)&pipe_client);
+  TUV_ASSERT(r == 0);
+
+  len1 = sizeof buf1;
+  r = uv_pipe_getsockname(&pipe_client, buf1, &len1);
+  TUV_ASSERT(r == 0);
+  TUV_ASSERT(len1 == 0);  /* It's an annonymous pipe. */
+
+  r = uv_read_start((uv_stream_t*)&pipe_client, NULL, NULL);
+  TUV_ASSERT(r == 0);
+  Sleep(100);
+
+  len2 = sizeof buf2;
+  r = uv_pipe_getsockname(&pipe_client, buf2, &len2);
+  TUV_ASSERT(r == 0);
+  TUV_ASSERT(len2 == 0);  /* It's an annonymous pipe. */
+
+  r = uv_read_stop((uv_stream_t*)&pipe_client);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(len1 == len2);
+  TUV_ASSERT(memcmp(buf1, buf2, len1) == 0);
+
+  pipe_close_cb_called = 0;
+  uv_close((uv_handle_t*)&pipe_client, pipe_close_cb);
+
+  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+  TUV_ASSERT(pipe_close_cb_called == 1);
+
+  CloseHandle(writeh);
+#endif
+
+  return 0;
+}
diff --git a/deps/libtuv/test/test_pipe_pending_instances.c b/deps/libtuv/test/test_pipe_pending_instances.c
new file mode 100644 (file)
index 0000000..600e1fe
--- /dev/null
@@ -0,0 +1,58 @@
+/* Copyright (c) 2015 Saúl Ibarra Corretgé <saghul@gmail.com>.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "runner.h"
+
+
+static void connection_cb(uv_stream_t* server, int status) {
+  TUV_ASSERT(0 && "this will never be called");
+}
+
+
+TEST_IMPL(pipe_pending_instances) {
+  int r;
+  uv_pipe_t pipe_handle;
+  uv_loop_t* loop;
+
+  loop = uv_default_loop();
+
+  r = uv_pipe_init(loop, &pipe_handle, 0);
+  TUV_ASSERT(r == 0);
+
+  uv_pipe_pending_instances(&pipe_handle, 8);
+
+  r = uv_pipe_bind(&pipe_handle, TEST_PIPENAME);
+  TUV_ASSERT(r == 0);
+
+  uv_pipe_pending_instances(&pipe_handle, 16);
+
+  r = uv_listen((uv_stream_t*)&pipe_handle, 128, connection_cb);
+  TUV_ASSERT(r == 0);
+
+  uv_close((uv_handle_t*)&pipe_handle, NULL);
+
+  r = uv_run(loop, UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  return 0;
+}
diff --git a/deps/libtuv/test/test_pipe_sendmsg.c b/deps/libtuv/test/test_pipe_sendmsg.c
new file mode 100644 (file)
index 0000000..e63e767
--- /dev/null
@@ -0,0 +1,167 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "runner.h"
+
+
+#ifndef _WIN32
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+
+/* NOTE: size should be divisible by 2 */
+static uv_pipe_t incoming[4];
+static unsigned int incoming_count;
+static unsigned int close_called;
+
+
+static void set_nonblocking(uv_os_sock_t sock) {
+  int r;
+#ifdef _WIN32
+  unsigned long on = 1;
+  r = ioctlsocket(sock, FIONBIO, &on);
+  TUV_ASSERT(r == 0);
+#else
+  int flags = fcntl(sock, F_GETFL, 0);
+  TUV_ASSERT(flags >= 0);
+  r = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
+  TUV_ASSERT(r >= 0);
+#endif
+}
+
+
+
+
+static void close_cb(uv_handle_t* handle) {
+  close_called++;
+}
+
+
+static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+  static char base[1];
+
+  buf->base = base;
+  buf->len = sizeof(base);
+}
+
+
+static void read_cb(uv_stream_t* handle,
+                    ssize_t nread,
+                    const uv_buf_t* buf) {
+  uv_pipe_t* p;
+  uv_pipe_t* inc;
+  uv_handle_type pending;
+  unsigned int i;
+
+  p = (uv_pipe_t*) handle;
+  TUV_ASSERT(nread >= 0);
+
+  while (uv_pipe_pending_count(p) != 0) {
+    pending = uv_pipe_pending_type(p);
+    TUV_ASSERT(pending == UV_NAMED_PIPE);
+
+    TUV_ASSERT(incoming_count < ARRAY_SIZE(incoming));
+    inc = &incoming[incoming_count++];
+    TUV_ASSERT(0 == uv_pipe_init(p->loop, inc, 0));
+    TUV_ASSERT(0 == uv_accept(handle, (uv_stream_t*) inc));
+  }
+
+  if (incoming_count != ARRAY_SIZE(incoming))
+    return;
+
+  TUV_ASSERT(0 == uv_read_stop((uv_stream_t*) p));
+  uv_close((uv_handle_t*) p, close_cb);
+  for (i = 0; i < ARRAY_SIZE(incoming); i++)
+    uv_close((uv_handle_t*) &incoming[i], close_cb);
+}
+
+
+TEST_IMPL(pipe_sendmsg) {
+  uv_pipe_t p;
+  int r;
+  int fds[2];
+  int send_fds[ARRAY_SIZE(incoming)];
+  struct msghdr msg;
+  char scratch[64];
+  struct cmsghdr *cmsg;
+  unsigned int i;
+  uv_buf_t buf;
+
+  TUV_ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, fds));
+  for (i = 0; i < ARRAY_SIZE(send_fds); i += 2)
+    TUV_ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, send_fds + i));
+  TUV_ASSERT(i == ARRAY_SIZE(send_fds));
+  TUV_ASSERT(0 == uv_pipe_init(uv_default_loop(), &p, 1));
+  TUV_ASSERT(0 == uv_pipe_open(&p, fds[1]));
+
+  buf = uv_buf_init("X", 1);
+  memset(&msg, 0, sizeof(msg));
+  msg.msg_iov = (struct iovec*) &buf;
+  msg.msg_iovlen = 1;
+  msg.msg_flags = 0;
+
+  msg.msg_control = (void*) scratch;
+  msg.msg_controllen = CMSG_LEN(sizeof(send_fds));
+  TUV_ASSERT(sizeof(scratch) >= msg.msg_controllen);
+
+  cmsg = CMSG_FIRSTHDR(&msg);
+  cmsg->cmsg_level = SOL_SOCKET;
+  cmsg->cmsg_type = SCM_RIGHTS;
+  cmsg->cmsg_len = msg.msg_controllen;
+
+  /* silence aliasing warning */
+  {
+    void* pv = CMSG_DATA(cmsg);
+    int* pi = pv;
+    for (i = 0; i < ARRAY_SIZE(send_fds); i++)
+      pi[i] = send_fds[i];
+  }
+
+  set_nonblocking(fds[1]);
+  TUV_ASSERT(0 == uv_read_start((uv_stream_t*) &p, alloc_cb, read_cb));
+
+  do
+    r = sendmsg(fds[0], &msg, 0);
+  while (r == -1 && errno == EINTR);
+  TUV_ASSERT(r == 1);
+
+  uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(ARRAY_SIZE(incoming) == incoming_count);
+  TUV_ASSERT(ARRAY_SIZE(incoming) + 1 == close_called);
+  close(fds[0]);
+
+  return 0;
+}
+
+#else  /* !_WIN32 */
+
+TEST_IMPL(pipe_sendmsg) {
+  return 0;
+}
+
+#endif  /* _WIN32 */
diff --git a/deps/libtuv/test/test_pipe_server_close.c b/deps/libtuv/test/test_pipe_server_close.c
new file mode 100644 (file)
index 0000000..7b7c42b
--- /dev/null
@@ -0,0 +1,90 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <errno.h>
+
+#include "uv.h"
+#include "runner.h"
+
+
+static uv_pipe_t pipe_client;
+static uv_pipe_t pipe_server;
+static uv_connect_t connect_req;
+
+static int pipe_close_cb_called = 0;
+static int pipe_client_connect_cb_called = 0;
+
+
+static void pipe_close_cb(uv_handle_t* handle) {
+  TUV_ASSERT(handle == (uv_handle_t*) &pipe_client ||
+         handle == (uv_handle_t*) &pipe_server);
+  pipe_close_cb_called++;
+}
+
+
+static void pipe_client_connect_cb(uv_connect_t* req, int status) {
+  TUV_ASSERT(req == &connect_req);
+  TUV_ASSERT(status == 0);
+
+  pipe_client_connect_cb_called++;
+
+  uv_close((uv_handle_t*) &pipe_client, pipe_close_cb);
+  uv_close((uv_handle_t*) &pipe_server, pipe_close_cb);
+}
+
+
+static void pipe_server_connection_cb(uv_stream_t* handle, int status) {
+  /* This function *may* be called, depending on whether accept or the
+   * connection callback is called first.
+   */
+  TUV_ASSERT(status == 0);
+}
+
+
+TEST_IMPL(pipe_server_close) {
+  uv_loop_t* loop;
+  int r;
+
+  loop = uv_default_loop();
+  TUV_ASSERT(loop != NULL);
+
+  r = uv_pipe_init(loop, &pipe_server, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_pipe_bind(&pipe_server, TEST_PIPENAME);
+  TUV_ASSERT(r == 0);
+
+  r = uv_listen((uv_stream_t*) &pipe_server, 0, pipe_server_connection_cb);
+  TUV_ASSERT(r == 0);
+
+  r = uv_pipe_init(loop, &pipe_client, 0);
+  TUV_ASSERT(r == 0);
+
+  uv_pipe_connect(&connect_req, &pipe_client, TEST_PIPENAME, pipe_client_connect_cb);
+
+  r = uv_run(loop, UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+  TUV_ASSERT(pipe_client_connect_cb_called == 1);
+  TUV_ASSERT(pipe_close_cb_called == 2);
+
+  return 0;
+}
diff --git a/deps/libtuv/test/test_pipe_set_non_blocking.c b/deps/libtuv/test/test_pipe_set_non_blocking.c
new file mode 100644 (file)
index 0000000..f767796
--- /dev/null
@@ -0,0 +1,98 @@
+/* Copyright (c) 2015, Ben Noordhuis <info@bnoordhuis.nl>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "uv.h"
+#include "runner.h"
+
+#ifdef _WIN32
+
+TEST_IMPL(pipe_set_non_blocking) {
+  RETURN_SKIP("Test not implemented on Windows.");
+}
+
+#else  /* !_WIN32 */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+struct thread_ctx {
+  uv_barrier_t barrier;
+  int fd;
+};
+
+static void thread_main(void* arg) {
+  struct thread_ctx* ctx;
+  char buf[4096];
+  ssize_t n;
+
+  ctx = arg;
+  uv_barrier_wait(&ctx->barrier);
+
+  do
+    n = read(ctx->fd, buf, sizeof(buf));
+  while (n > 0 || (n == -1 && errno == EINTR));
+
+  TUV_ASSERT(n == 0);
+}
+
+TEST_IMPL(pipe_set_non_blocking) {
+  struct thread_ctx ctx;
+  uv_pipe_t pipe_handle;
+  uv_thread_t thread;
+  size_t nwritten;
+  char data[4096];
+  uv_buf_t buf;
+  int fd[2];
+  int n;
+
+  TUV_ASSERT(0 == uv_pipe_init(uv_default_loop(), &pipe_handle, 0));
+  TUV_ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, fd));
+  TUV_ASSERT(0 == uv_pipe_open(&pipe_handle, fd[0]));
+  TUV_ASSERT(0 == uv_stream_set_blocking((uv_stream_t*) &pipe_handle, 1));
+
+  ctx.fd = fd[1];
+  TUV_ASSERT(0 == uv_barrier_init(&ctx.barrier, 2));
+  TUV_ASSERT(0 == uv_thread_create(&thread, thread_main, &ctx));
+  uv_barrier_wait(&ctx.barrier);
+
+  buf.len = sizeof(data);
+  buf.base = data;
+  memset(data, '.', sizeof(data));
+
+  nwritten = 0;
+  while (nwritten < 10 << 20) {
+    /* The stream is in blocking mode so uv_try_write() should always succeed
+     * with the exact number of bytes that we wanted written.
+     */
+    n = uv_try_write((uv_stream_t*) &pipe_handle, &buf, 1);
+    TUV_ASSERT(n == sizeof(data));
+    nwritten += n;
+  }
+
+  uv_close((uv_handle_t*) &pipe_handle, NULL);
+  TUV_ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+  TUV_ASSERT(0 == uv_thread_join(&thread));
+  TUV_ASSERT(0 == close(fd[1]));  /* fd[0] is closed by uv_close(). */
+  uv_barrier_destroy(&ctx.barrier);
+
+  return 0;
+}
+
+#endif  /* !_WIN32 */
diff --git a/deps/libtuv/test/test_signal.c b/deps/libtuv/test/test_signal.c
new file mode 100644 (file)
index 0000000..843e20d
--- /dev/null
@@ -0,0 +1,153 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+
+/* This test does not pretend to be cross-platform. */
+#ifndef _WIN32
+
+#include "uv.h"
+#include "runner.h"
+
+#include <errno.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define NSIGNALS  10
+
+#define container_of(ptr, type, member) \
+  ((type *) ((char *) (ptr) - offsetof(type, member)))
+
+struct timer_ctx {
+  unsigned int ncalls;
+  uv_timer_t handle;
+  int signum;
+};
+
+struct signal_ctx {
+  enum { CLOSE, STOP } stop_or_close;
+  unsigned int ncalls;
+  uv_signal_t handle;
+  int signum;
+};
+
+
+static void signal_cb(uv_signal_t* handle, int signum) {
+  struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle);
+  TUV_ASSERT(signum == ctx->signum);
+
+  if (++ctx->ncalls == NSIGNALS) {
+    if (ctx->stop_or_close == STOP)
+      uv_signal_stop(handle);
+    else if (ctx->stop_or_close == CLOSE)
+      uv_close((uv_handle_t*)handle, NULL);
+    else
+      TUV_ASSERT(0);
+  }
+}
+
+
+static void timer_cb(uv_timer_t* handle) {
+  struct timer_ctx* ctx = container_of(handle, struct timer_ctx, handle);
+
+  raise(ctx->signum);
+
+  if (++ctx->ncalls == NSIGNALS)
+    uv_close((uv_handle_t*)handle, NULL);
+}
+
+
+static void start_watcher(uv_loop_t* loop, int signum, struct signal_ctx* ctx) {
+  ctx->ncalls = 0;
+  ctx->signum = signum;
+  ctx->stop_or_close = CLOSE;
+  TUV_ASSERT(0 == uv_signal_init(loop, &ctx->handle));
+  TUV_ASSERT(0 == uv_signal_start(&ctx->handle, signal_cb, signum));
+}
+
+
+static void start_timer(uv_loop_t* loop, int signum, struct timer_ctx* ctx) {
+  ctx->ncalls = 0;
+  ctx->signum = signum;
+  TUV_ASSERT(0 == uv_timer_init(loop, &ctx->handle));
+  TUV_ASSERT(0 == uv_timer_start(&ctx->handle, timer_cb, 5, 5));
+}
+
+
+TEST_IMPL(we_get_signal) {
+  struct signal_ctx sc;
+  struct timer_ctx tc;
+  uv_loop_t* loop;
+
+  loop = uv_default_loop();
+  start_timer(loop, SIGCHLD, &tc);
+  start_watcher(loop, SIGCHLD, &sc);
+  sc.stop_or_close = STOP; /* stop, don't close the signal handle */
+  TUV_ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+  TUV_ASSERT(tc.ncalls == NSIGNALS);
+  TUV_ASSERT(sc.ncalls == NSIGNALS);
+
+  start_timer(loop, SIGCHLD, &tc);
+  TUV_ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+  TUV_ASSERT(tc.ncalls == NSIGNALS);
+  TUV_ASSERT(sc.ncalls == NSIGNALS);
+
+  sc.ncalls = 0;
+  sc.stop_or_close = CLOSE; /* now close it when it's done */
+  uv_signal_start(&sc.handle, signal_cb, SIGCHLD);
+
+  start_timer(loop, SIGCHLD, &tc);
+  TUV_ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+  TUV_ASSERT(tc.ncalls == NSIGNALS);
+  TUV_ASSERT(sc.ncalls == NSIGNALS);
+
+  return 0;
+}
+
+
+TEST_IMPL(we_get_signals) {
+  struct signal_ctx sc[4];
+  struct timer_ctx tc[2];
+  uv_loop_t* loop;
+  unsigned int i;
+
+  loop = uv_default_loop();
+  start_watcher(loop, SIGUSR1, sc + 0);
+  start_watcher(loop, SIGUSR1, sc + 1);
+  start_watcher(loop, SIGUSR2, sc + 2);
+  start_watcher(loop, SIGUSR2, sc + 3);
+  start_timer(loop, SIGUSR1, tc + 0);
+  start_timer(loop, SIGUSR2, tc + 1);
+  TUV_ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+
+  for (i = 0; i < ARRAY_SIZE(sc); i++)
+    TUV_ASSERT(sc[i].ncalls == NSIGNALS);
+
+  for (i = 0; i < ARRAY_SIZE(tc); i++)
+    TUV_ASSERT(tc[i].ncalls == NSIGNALS);
+
+  return 0;
+}
+
+#endif /* _WIN32 */
diff --git a/deps/libtuv/test/test_spawn.c b/deps/libtuv/test/test_spawn.c
new file mode 100644 (file)
index 0000000..1c48122
--- /dev/null
@@ -0,0 +1,1638 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "runner.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _WIN32
+# if defined(__MINGW32__)
+#  include <basetyps.h>
+# endif
+# include <shellapi.h>
+# include <wchar.h>
+#else
+# include <unistd.h>
+# include <sys/wait.h>
+#endif
+
+
+static int close_cb_called;
+static int exit_cb_called;
+static uv_process_t process;
+static uv_timer_t timer;
+static uv_process_options_t options;
+static char exepath[1024];
+static size_t exepath_size = 1024;
+static char* args[5];
+static int no_term_signal;
+static int timer_counter;
+
+#define OUTPUT_SIZE 1024
+static char output[OUTPUT_SIZE];
+static int output_used;
+
+
+static void close_cb(uv_handle_t* handle) {
+  printf("close_cb\n");
+  close_cb_called++;
+}
+
+static void exit_cb(uv_process_t* process,
+                    int64_t exit_status,
+                    int term_signal) {
+  printf("exit_cb\n");
+  exit_cb_called++;
+  TUV_ASSERT(exit_status == 1);
+  TUV_ASSERT(term_signal == 0);
+  uv_close((uv_handle_t*)process, close_cb);
+}
+
+
+static void fail_cb(uv_process_t* process,
+                    int64_t exit_status,
+                    int term_signal) {
+  TUV_ASSERT(0 && "fail_cb called");
+}
+
+
+static void kill_cb(uv_process_t* process,
+                    int64_t exit_status,
+                    int term_signal) {
+  int err;
+
+  printf("exit_cb\n");
+  exit_cb_called++;
+#ifdef _WIN32
+  TUV_ASSERT(exit_status == 1);
+#else
+  TUV_ASSERT(exit_status == 0);
+#endif
+  TUV_ASSERT(no_term_signal || term_signal == 15);
+  uv_close((uv_handle_t*)process, close_cb);
+
+  /*
+   * Sending signum == 0 should check if the
+   * child process is still alive, not kill it.
+   * This process should be dead.
+   */
+  err = uv_kill(process->pid, 0);
+  TUV_ASSERT(err == UV_ESRCH);
+}
+
+static void detach_failure_cb(uv_process_t* process,
+                              int64_t exit_status,
+                              int term_signal) {
+  printf("detach_cb\n");
+  exit_cb_called++;
+}
+
+static void on_alloc(uv_handle_t* handle,
+                     size_t suggested_size,
+                     uv_buf_t* buf) {
+  buf->base = output + output_used;
+  buf->len = OUTPUT_SIZE - output_used;
+}
+
+
+static void on_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
+  if (nread > 0) {
+    output_used += nread;
+  } else if (nread < 0) {
+    TUV_ASSERT(nread == UV_EOF);
+    uv_close((uv_handle_t*)tcp, close_cb);
+  }
+}
+
+
+static void on_read_once(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
+  uv_read_stop(tcp);
+  on_read(tcp, nread, buf);
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+  TUV_ASSERT(status == 0);
+  uv_close((uv_handle_t*)req->handle, close_cb);
+}
+
+
+static void init_process_options(char* test, uv_exit_cb exit_cb) {
+  /* Note spawn_helper1 defined in test/run-tests.c */
+  int r = uv_exepath(exepath, &exepath_size);
+  TUV_ASSERT(r == 0);
+  exepath[exepath_size] = '\0';
+  args[0] = exepath;
+  args[1] = test;
+  args[2] = NULL;
+  args[3] = NULL;
+  args[4] = NULL;
+  options.file = exepath;
+  options.args = args;
+  options.exit_cb = exit_cb;
+  options.flags = 0;
+}
+
+
+static void timer_cb(uv_timer_t* handle) {
+  uv_process_kill(&process, /* SIGTERM */ 15);
+  uv_close((uv_handle_t*)handle, close_cb);
+}
+
+
+static void timer_counter_cb(uv_timer_t* handle) {
+  ++timer_counter;
+}
+
+
+TEST_IMPL(spawn_fails) {
+  int r;
+
+  init_process_options("", fail_cb);
+  options.file = options.args[0] = "program-that-had-better-not-exist";
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == UV_ENOENT || r == UV_EACCES);
+  TUV_ASSERT(0 == uv_is_active((uv_handle_t*) &process));
+  uv_close((uv_handle_t*) &process, NULL);
+  TUV_ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+  return 0;
+}
+
+
+#ifndef _WIN32
+TEST_IMPL(spawn_fails_check_for_waitpid_cleanup) {
+  int r;
+  int status;
+  int err;
+
+  init_process_options("", fail_cb);
+  options.file = options.args[0] = "program-that-had-better-not-exist";
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == UV_ENOENT || r == UV_EACCES);
+  TUV_ASSERT(0 == uv_is_active((uv_handle_t*) &process));
+  TUV_ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+  /* verify the child is successfully cleaned up within libuv */
+  do
+    err = waitpid(process.pid, &status, 0);
+  while (err == -1 && errno == EINTR);
+
+  TUV_ASSERT(err == -1);
+  TUV_ASSERT(errno == ECHILD);
+
+  uv_close((uv_handle_t*) &process, NULL);
+  TUV_ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+  return 0;
+}
+#endif
+
+
+TEST_IMPL(spawn_exit_code) {
+  int r;
+
+  init_process_options("spawn_helper1", exit_cb);
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 1);
+
+  return 0;
+}
+
+
+TEST_IMPL(spawn_stdout) {
+  int r;
+  uv_pipe_t out;
+  uv_stdio_container_t stdio[2];
+
+  init_process_options("spawn_helper2", exit_cb);
+
+  uv_pipe_init(uv_default_loop(), &out, 0);
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_IGNORE;
+  options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+  options.stdio[1].data.stream = (uv_stream_t*)&out;
+  options.stdio_count = 2;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 2); /* Once for process once for the pipe. */
+  printf("output is: %s", output);
+  TUV_ASSERT(strcmp("hello world\n", output) == 0);
+
+  return 0;
+}
+
+
+TEST_IMPL(spawn_stdout_to_file) {
+  int r;
+  uv_file file;
+  uv_fs_t fs_req;
+  uv_stdio_container_t stdio[2];
+  uv_buf_t buf;
+
+  /* Setup. */
+  unlink("stdout_file");
+
+  init_process_options("spawn_helper2", exit_cb);
+
+  r = uv_fs_open(NULL, &fs_req, "stdout_file", O_CREAT | O_RDWR,
+      S_IRUSR | S_IWUSR, NULL);
+  TUV_ASSERT(r != -1);
+  uv_fs_req_cleanup(&fs_req);
+
+  file = r;
+
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_IGNORE;
+  options.stdio[1].flags = UV_INHERIT_FD;
+  options.stdio[1].data.fd = file;
+  options.stdio_count = 2;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 1);
+
+  buf = uv_buf_init(output, sizeof(output));
+  r = uv_fs_read(NULL, &fs_req, file, &buf, 1, 0, NULL);
+  TUV_ASSERT(r == 12);
+  uv_fs_req_cleanup(&fs_req);
+
+  r = uv_fs_close(NULL, &fs_req, file, NULL);
+  TUV_ASSERT(r == 0);
+  uv_fs_req_cleanup(&fs_req);
+
+  printf("output is: %s", output);
+  TUV_ASSERT(strcmp("hello world\n", output) == 0);
+
+  /* Cleanup. */
+  unlink("stdout_file");
+
+  return 0;
+}
+
+
+TEST_IMPL(spawn_stdout_and_stderr_to_file) {
+  int r;
+  uv_file file;
+  uv_fs_t fs_req;
+  uv_stdio_container_t stdio[3];
+  uv_buf_t buf;
+
+  /* Setup. */
+  unlink("stdout_file");
+
+  init_process_options("spawn_helper6", exit_cb);
+
+  r = uv_fs_open(NULL, &fs_req, "stdout_file", O_CREAT | O_RDWR,
+      S_IRUSR | S_IWUSR, NULL);
+  TUV_ASSERT(r != -1);
+  uv_fs_req_cleanup(&fs_req);
+
+  file = r;
+
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_IGNORE;
+  options.stdio[1].flags = UV_INHERIT_FD;
+  options.stdio[1].data.fd = file;
+  options.stdio[2].flags = UV_INHERIT_FD;
+  options.stdio[2].data.fd = file;
+  options.stdio_count = 3;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 1);
+
+  buf = uv_buf_init(output, sizeof(output));
+  r = uv_fs_read(NULL, &fs_req, file, &buf, 1, 0, NULL);
+  TUV_ASSERT(r == 27);
+  uv_fs_req_cleanup(&fs_req);
+
+  r = uv_fs_close(NULL, &fs_req, file, NULL);
+  TUV_ASSERT(r == 0);
+  uv_fs_req_cleanup(&fs_req);
+
+  printf("output is: %s", output);
+  TUV_ASSERT(strcmp("hello world\nhello errworld\n", output) == 0);
+
+  /* Cleanup. */
+  unlink("stdout_file");
+
+  return 0;
+}
+
+
+#ifndef _WIN32
+TEST_IMPL(spawn_stdout_and_stderr_to_file2) {
+  int r;
+  uv_file file;
+  uv_fs_t fs_req;
+  uv_stdio_container_t stdio[3];
+  uv_buf_t buf;
+
+  /* Setup. */
+  unlink("stdout_file");
+
+  init_process_options("spawn_helper6", exit_cb);
+
+  /* Replace stderr with our file */
+  r = uv_fs_open(NULL,
+                 &fs_req,
+                 "stdout_file",
+                 O_CREAT | O_RDWR,
+                 S_IRUSR | S_IWUSR,
+                 NULL);
+  TUV_ASSERT(r != -1);
+  uv_fs_req_cleanup(&fs_req);
+  file = dup2(r, STDERR_FILENO);
+  TUV_ASSERT(file != -1);
+
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_IGNORE;
+  options.stdio[1].flags = UV_INHERIT_FD;
+  options.stdio[1].data.fd = file;
+  options.stdio[2].flags = UV_INHERIT_FD;
+  options.stdio[2].data.fd = file;
+  options.stdio_count = 3;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 1);
+
+  buf = uv_buf_init(output, sizeof(output));
+  r = uv_fs_read(NULL, &fs_req, file, &buf, 1, 0, NULL);
+  TUV_ASSERT(r == 27);
+  uv_fs_req_cleanup(&fs_req);
+
+  r = uv_fs_close(NULL, &fs_req, file, NULL);
+  TUV_ASSERT(r == 0);
+  uv_fs_req_cleanup(&fs_req);
+
+  printf("output is: %s", output);
+  TUV_ASSERT(strcmp("hello world\nhello errworld\n", output) == 0);
+
+  /* Cleanup. */
+  unlink("stdout_file");
+
+  return 0;
+}
+#endif
+
+
+#ifndef _WIN32
+TEST_IMPL(spawn_stdout_and_stderr_to_file_swap) {
+  int r;
+  uv_file stdout_file;
+  uv_file stderr_file;
+  uv_fs_t fs_req;
+  uv_stdio_container_t stdio[3];
+  uv_buf_t buf;
+
+  /* Setup. */
+  unlink("stdout_file");
+  unlink("stderr_file");
+
+  init_process_options("spawn_helper6", exit_cb);
+
+  /* open 'stdout_file' and replace STDOUT_FILENO with it */
+  r = uv_fs_open(NULL,
+                 &fs_req,
+                 "stdout_file",
+                 O_CREAT | O_RDWR,
+                 S_IRUSR | S_IWUSR,
+                 NULL);
+  TUV_ASSERT(r != -1);
+  uv_fs_req_cleanup(&fs_req);
+  stdout_file = dup2(r, STDOUT_FILENO);
+  TUV_ASSERT(stdout_file != -1);
+
+  /* open 'stderr_file' and replace STDERR_FILENO with it */
+  r = uv_fs_open(NULL, &fs_req, "stderr_file", O_CREAT | O_RDWR,
+      S_IRUSR | S_IWUSR, NULL);
+  TUV_ASSERT(r != -1);
+  uv_fs_req_cleanup(&fs_req);
+  stderr_file = dup2(r, STDERR_FILENO);
+  TUV_ASSERT(stderr_file != -1);
+
+  /* now we're going to swap them: the child process' stdout will be our
+   * stderr_file and vice versa */
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_IGNORE;
+  options.stdio[1].flags = UV_INHERIT_FD;
+  options.stdio[1].data.fd = stderr_file;
+  options.stdio[2].flags = UV_INHERIT_FD;
+  options.stdio[2].data.fd = stdout_file;
+  options.stdio_count = 3;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 1);
+
+  buf = uv_buf_init(output, sizeof(output));
+
+  /* check the content of stdout_file */
+  r = uv_fs_read(NULL, &fs_req, stdout_file, &buf, 1, 0, NULL);
+  TUV_ASSERT(r >= 15);
+  uv_fs_req_cleanup(&fs_req);
+
+  r = uv_fs_close(NULL, &fs_req, stdout_file, NULL);
+  TUV_ASSERT(r == 0);
+  uv_fs_req_cleanup(&fs_req);
+
+  printf("output is: %s", output);
+  TUV_ASSERT(strncmp("hello errworld\n", output, 15) == 0);
+
+  /* check the content of stderr_file */
+  r = uv_fs_read(NULL, &fs_req, stderr_file, &buf, 1, 0, NULL);
+  TUV_ASSERT(r >= 12);
+  uv_fs_req_cleanup(&fs_req);
+
+  r = uv_fs_close(NULL, &fs_req, stderr_file, NULL);
+  TUV_ASSERT(r == 0);
+  uv_fs_req_cleanup(&fs_req);
+
+  printf("output is: %s", output);
+  TUV_ASSERT(strncmp("hello world\n", output, 12) == 0);
+
+  /* Cleanup. */
+  unlink("stdout_file");
+  unlink("stderr_file");
+
+  return 0;
+}
+#endif
+
+
+TEST_IMPL(spawn_stdin) {
+  int r;
+  uv_pipe_t out;
+  uv_pipe_t in;
+  uv_write_t write_req;
+  uv_buf_t buf;
+  uv_stdio_container_t stdio[2];
+  char buffer[] = "hello-from-spawn_stdin";
+
+  init_process_options("spawn_helper3", exit_cb);
+
+  uv_pipe_init(uv_default_loop(), &out, 0);
+  uv_pipe_init(uv_default_loop(), &in, 0);
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
+  options.stdio[0].data.stream = (uv_stream_t*)&in;
+  options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+  options.stdio[1].data.stream = (uv_stream_t*)&out;
+  options.stdio_count = 2;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  buf.base = buffer;
+  buf.len = sizeof(buffer);
+  r = uv_write(&write_req, (uv_stream_t*)&in, &buf, 1, write_cb);
+  TUV_ASSERT(r == 0);
+
+  r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 3); /* Once for process twice for the pipe. */
+  TUV_ASSERT(strcmp(buffer, output) == 0);
+
+  return 0;
+}
+
+
+TEST_IMPL(spawn_stdio_greater_than_3) {
+  int r;
+  uv_pipe_t pipe;
+  uv_stdio_container_t stdio[4];
+
+  init_process_options("spawn_helper5", exit_cb);
+
+  uv_pipe_init(uv_default_loop(), &pipe, 0);
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_IGNORE;
+  options.stdio[1].flags = UV_IGNORE;
+  options.stdio[2].flags = UV_IGNORE;
+  options.stdio[3].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+  options.stdio[3].data.stream = (uv_stream_t*)&pipe;
+  options.stdio_count = 4;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  r = uv_read_start((uv_stream_t*) &pipe, on_alloc, on_read);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 2); /* Once for process once for the pipe. */
+  printf("output from stdio[3] is: %s", output);
+  TUV_ASSERT(strcmp("fourth stdio!\n", output) == 0);
+
+  return 0;
+}
+
+
+TEST_IMPL(spawn_ignored_stdio) {
+  int r;
+
+  init_process_options("spawn_helper6", exit_cb);
+
+  options.stdio = NULL;
+  options.stdio_count = 0;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 1);
+
+  return 0;
+}
+
+
+TEST_IMPL(spawn_and_kill) {
+  int r;
+
+  init_process_options("spawn_helper4", kill_cb);
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  r = uv_timer_init(uv_default_loop(), &timer);
+  TUV_ASSERT(r == 0);
+
+  r = uv_timer_start(&timer, timer_cb, 500, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 2); /* Once for process and once for timer. */
+
+  return 0;
+}
+
+
+TEST_IMPL(spawn_preserve_env) {
+  int r;
+  uv_pipe_t out;
+  uv_stdio_container_t stdio[2];
+
+  init_process_options("spawn_helper7", exit_cb);
+
+  uv_pipe_init(uv_default_loop(), &out, 0);
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_IGNORE;
+  options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+  options.stdio[1].data.stream = (uv_stream_t*) &out;
+  options.stdio_count = 2;
+
+  r = putenv("ENV_TEST=testval");
+  TUV_ASSERT(r == 0);
+
+  /* Explicitly set options.env to NULL to test for env clobbering. */
+  options.env = NULL;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 2);
+
+  printf("output is: %s", output);
+  TUV_ASSERT(strcmp("testval", output) == 0);
+
+  return 0;
+}
+
+
+TEST_IMPL(spawn_detached) {
+  int r;
+
+  init_process_options("spawn_helper4", detach_failure_cb);
+
+  options.flags |= UV_PROCESS_DETACHED;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  uv_unref((uv_handle_t*)&process);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 0);
+
+  r = uv_kill(process.pid, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_kill(process.pid, 15);
+  TUV_ASSERT(r == 0);
+
+  return 0;
+}
+
+TEST_IMPL(spawn_and_kill_with_std) {
+  int r;
+  uv_pipe_t in, out, err;
+  uv_write_t write;
+  char message[] = "Nancy's joining me because the message this evening is "
+                   "not my message but ours.";
+  uv_buf_t buf;
+  uv_stdio_container_t stdio[3];
+
+  init_process_options("spawn_helper4", kill_cb);
+
+  r = uv_pipe_init(uv_default_loop(), &in, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_pipe_init(uv_default_loop(), &out, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_pipe_init(uv_default_loop(), &err, 0);
+  TUV_ASSERT(r == 0);
+
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
+  options.stdio[0].data.stream = (uv_stream_t*)&in;
+  options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+  options.stdio[1].data.stream = (uv_stream_t*)&out;
+  options.stdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+  options.stdio[2].data.stream = (uv_stream_t*)&err;
+  options.stdio_count = 3;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  buf = uv_buf_init(message, sizeof message);
+  r = uv_write(&write, (uv_stream_t*) &in, &buf, 1, write_cb);
+  TUV_ASSERT(r == 0);
+
+  r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
+  TUV_ASSERT(r == 0);
+
+  r = uv_read_start((uv_stream_t*) &err, on_alloc, on_read);
+  TUV_ASSERT(r == 0);
+
+  r = uv_timer_init(uv_default_loop(), &timer);
+  TUV_ASSERT(r == 0);
+
+  r = uv_timer_start(&timer, timer_cb, 500, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 5); /* process x 1, timer x 1, stdio x 3. */
+
+  return 0;
+}
+
+
+TEST_IMPL(spawn_and_ping) {
+  uv_write_t write_req;
+  uv_pipe_t in, out;
+  uv_buf_t buf;
+  uv_stdio_container_t stdio[2];
+  int r;
+
+  init_process_options("spawn_helper3", exit_cb);
+  buf = uv_buf_init("TEST", 4);
+
+  uv_pipe_init(uv_default_loop(), &out, 0);
+  uv_pipe_init(uv_default_loop(), &in, 0);
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
+  options.stdio[0].data.stream = (uv_stream_t*)&in;
+  options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+  options.stdio[1].data.stream = (uv_stream_t*)&out;
+  options.stdio_count = 2;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  /* Sending signum == 0 should check if the
+   * child process is still alive, not kill it.
+   */
+  r = uv_process_kill(&process, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_write(&write_req, (uv_stream_t*)&in, &buf, 1, write_cb);
+  TUV_ASSERT(r == 0);
+
+  r = uv_read_start((uv_stream_t*)&out, on_alloc, on_read);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(strcmp(output, "TEST") == 0);
+
+  return 0;
+}
+
+
+TEST_IMPL(spawn_same_stdout_stderr) {
+  uv_write_t write_req;
+  uv_pipe_t in, out;
+  uv_buf_t buf;
+  uv_stdio_container_t stdio[3];
+  int r;
+
+  init_process_options("spawn_helper3", exit_cb);
+  buf = uv_buf_init("TEST", 4);
+
+  uv_pipe_init(uv_default_loop(), &out, 0);
+  uv_pipe_init(uv_default_loop(), &in, 0);
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
+  options.stdio[0].data.stream = (uv_stream_t*)&in;
+  options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+  options.stdio[1].data.stream = (uv_stream_t*)&out;
+  options.stdio_count = 2;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  /* Sending signum == 0 should check if the
+   * child process is still alive, not kill it.
+   */
+  r = uv_process_kill(&process, 0);
+  TUV_ASSERT(r == 0);
+
+  r = uv_write(&write_req, (uv_stream_t*)&in, &buf, 1, write_cb);
+  TUV_ASSERT(r == 0);
+
+  r = uv_read_start((uv_stream_t*)&out, on_alloc, on_read);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(strcmp(output, "TEST") == 0);
+
+  return 0;
+}
+
+
+TEST_IMPL(spawn_closed_process_io) {
+  uv_pipe_t in;
+  uv_write_t write_req;
+  uv_buf_t buf;
+  uv_stdio_container_t stdio[2];
+  static char buffer[] = "hello-from-spawn_stdin\n";
+
+  init_process_options("spawn_helper3", exit_cb);
+
+  uv_pipe_init(uv_default_loop(), &in, 0);
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
+  options.stdio[0].data.stream = (uv_stream_t*) &in;
+  options.stdio_count = 1;
+
+  close(0); /* Close process stdin. */
+
+  TUV_ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options));
+
+  buf = uv_buf_init(buffer, sizeof(buffer));
+  TUV_ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb));
+
+  TUV_ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 2); /* process, child stdin */
+
+  return 0;
+}
+
+
+TEST_IMPL(kill) {
+  int r;
+
+#ifdef _WIN32
+  no_term_signal = 1;
+#endif
+
+  init_process_options("spawn_helper4", kill_cb);
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  /* Sending signum == 0 should check if the
+   * child process is still alive, not kill it.
+   */
+  r = uv_kill(process.pid, 0);
+  TUV_ASSERT(r == 0);
+
+  /* Kill the process. */
+  r = uv_kill(process.pid, /* SIGTERM */ 15);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 1);
+
+  return 0;
+}
+
+
+#ifdef _WIN32
+TEST_IMPL(spawn_detect_pipe_name_collisions_on_windows) {
+  int r;
+  uv_pipe_t out;
+  char name[64];
+  HANDLE pipe_handle;
+  uv_stdio_container_t stdio[2];
+
+  init_process_options("spawn_helper2", exit_cb);
+
+  uv_pipe_init(uv_default_loop(), &out, 0);
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_IGNORE;
+  options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+  options.stdio[1].data.stream = (uv_stream_t*)&out;
+  options.stdio_count = 2;
+
+  /* Create a pipe that'll cause a collision. */
+  snprintf(name,
+           sizeof(name),
+           "\\\\.\\pipe\\uv\\%p-%d",
+           &out,
+           GetCurrentProcessId());
+  pipe_handle = CreateNamedPipeA(name,
+                                PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
+                                PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
+                                10,
+                                65536,
+                                65536,
+                                0,
+                                NULL);
+  TUV_ASSERT(pipe_handle != INVALID_HANDLE_VALUE);
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 2); /* Once for process once for the pipe. */
+  printf("output is: %s", output);
+  TUV_ASSERT(strcmp("hello world\n", output) == 0);
+
+  return 0;
+}
+
+
+#if !defined(USING_UV_SHARED)
+int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr);
+WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target);
+
+TEST_IMPL(argument_escaping) {
+  const WCHAR* test_str[] = {
+    L"",
+    L"HelloWorld",
+    L"Hello World",
+    L"Hello\"World",
+    L"Hello World\\",
+    L"Hello\\\"World",
+    L"Hello\\World",
+    L"Hello\\\\World",
+    L"Hello World\\",
+    L"c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\""
+  };
+  const int count = sizeof(test_str) / sizeof(*test_str);
+  WCHAR** test_output;
+  WCHAR* command_line;
+  WCHAR** cracked;
+  size_t total_size = 0;
+  int i;
+  int num_args;
+  int result;
+
+  char* verbatim[] = {
+    "cmd.exe",
+    "/c",
+    "c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\"",
+    NULL
+  };
+  WCHAR* verbatim_output;
+  WCHAR* non_verbatim_output;
+
+  test_output = calloc(count, sizeof(WCHAR*));
+  TUV_ASSERT(test_output != NULL);
+  for (i = 0; i < count; ++i) {
+    test_output[i] = calloc(2 * (wcslen(test_str[i]) + 2), sizeof(WCHAR));
+    quote_cmd_arg(test_str[i], test_output[i]);
+    wprintf(L"input : %s\n", test_str[i]);
+    wprintf(L"output: %s\n", test_output[i]);
+    total_size += wcslen(test_output[i]) + 1;
+  }
+  command_line = calloc(total_size + 1, sizeof(WCHAR));
+  TUV_ASSERT(command_line != NULL);
+  for (i = 0; i < count; ++i) {
+    wcscat(command_line, test_output[i]);
+    wcscat(command_line, L" ");
+  }
+  command_line[total_size - 1] = L'\0';
+
+  wprintf(L"command_line: %s\n", command_line);
+
+  cracked = CommandLineToArgvW(command_line, &num_args);
+  for (i = 0; i < num_args; ++i) {
+    wprintf(L"%d: %s\t%s\n", i, test_str[i], cracked[i]);
+    TUV_ASSERT(wcscmp(test_str[i], cracked[i]) == 0);
+  }
+
+  LocalFree(cracked);
+  for (i = 0; i < count; ++i) {
+    free(test_output[i]);
+  }
+
+  result = make_program_args(verbatim, 1, &verbatim_output);
+  TUV_ASSERT(result == 0);
+  result = make_program_args(verbatim, 0, &non_verbatim_output);
+  TUV_ASSERT(result == 0);
+
+  wprintf(L"    verbatim_output: %s\n", verbatim_output);
+  wprintf(L"non_verbatim_output: %s\n", non_verbatim_output);
+
+  TUV_ASSERT(wcscmp(verbatim_output,
+                L"cmd.exe /c c:\\path\\to\\node.exe --eval "
+                L"\"require('c:\\\\path\\\\to\\\\test.js')\"") == 0);
+  TUV_ASSERT(wcscmp(non_verbatim_output,
+                L"cmd.exe /c \"c:\\path\\to\\node.exe --eval "
+                L"\\\"require('c:\\\\path\\\\to\\\\test.js')\\\"\"") == 0);
+
+  free(verbatim_output);
+  free(non_verbatim_output);
+
+  return 0;
+}
+
+int make_program_env(char** env_block, WCHAR** dst_ptr);
+
+TEST_IMPL(environment_creation) {
+  int i;
+  char* environment[] = {
+    "FOO=BAR",
+    "SYSTEM=ROOT", /* substring of a supplied var name */
+    "SYSTEMROOTED=OMG", /* supplied var name is a substring */
+    "TEMP=C:\\Temp",
+    "INVALID",
+    "BAZ=QUX",
+    "B_Z=QUX",
+    "B\xe2\x82\xacZ=QUX",
+    "B\xf0\x90\x80\x82Z=QUX",
+    "B\xef\xbd\xa1Z=QUX",
+    "B\xf0\xa3\x91\x96Z=QUX",
+    "BAZ", /* repeat, invalid variable */
+    NULL
+  };
+  WCHAR* wenvironment[] = {
+    L"BAZ=QUX",
+    L"B_Z=QUX",
+    L"B\x20acZ=QUX",
+    L"B\xd800\xdc02Z=QUX",
+    L"B\xd84d\xdc56Z=QUX",
+    L"B\xff61Z=QUX",
+    L"FOO=BAR",
+    L"SYSTEM=ROOT", /* substring of a supplied var name */
+    L"SYSTEMROOTED=OMG", /* supplied var name is a substring */
+    L"TEMP=C:\\Temp",
+  };
+  WCHAR* from_env[] = {
+    /* list should be kept in sync with list
+     * in process.c, minus variables in wenvironment */
+    L"HOMEDRIVE",
+    L"HOMEPATH",
+    L"LOGONSERVER",
+    L"PATH",
+    L"USERDOMAIN",
+    L"USERNAME",
+    L"USERPROFILE",
+    L"SYSTEMDRIVE",
+    L"SYSTEMROOT",
+    L"WINDIR",
+    /* test for behavior in the absence of a
+     * required-environment variable: */
+    L"ZTHIS_ENV_VARIABLE_DOES_NOT_EXIST",
+  };
+  int found_in_loc_env[ARRAY_SIZE(wenvironment)] = {0};
+  int found_in_usr_env[ARRAY_SIZE(from_env)] = {0};
+  WCHAR *expected[ARRAY_SIZE(from_env)];
+  int result;
+  WCHAR* str;
+  WCHAR* prev;
+  WCHAR* env;
+
+  for (i = 0; i < ARRAY_SIZE(from_env); i++) {
+      /* copy expected additions to environment locally */
+      size_t len = GetEnvironmentVariableW(from_env[i], NULL, 0);
+      if (len == 0) {
+        found_in_usr_env[i] = 1;
+        str = malloc(1 * sizeof(WCHAR));
+        *str = 0;
+        expected[i] = str;
+      } else {
+        size_t name_len = wcslen(from_env[i]);
+        str = malloc((name_len+1+len) * sizeof(WCHAR));
+        wmemcpy(str, from_env[i], name_len);
+        expected[i] = str;
+        str += name_len;
+        *str++ = L'=';
+        GetEnvironmentVariableW(from_env[i], str, len);
+     }
+  }
+
+  result = make_program_env(environment, &env);
+  TUV_ASSERT(result == 0);
+
+  for (str = env, prev = NULL; *str; prev = str, str += wcslen(str) + 1) {
+    int found = 0;
+#if 0
+    _cputws(str);
+    putchar('\n');
+#endif
+    for (i = 0; i < ARRAY_SIZE(wenvironment) && !found; i++) {
+      if (!wcscmp(str, wenvironment[i])) {
+        TUV_ASSERT(!found_in_loc_env[i]);
+        found_in_loc_env[i] = 1;
+        found = 1;
+      }
+    }
+    for (i = 0; i < ARRAY_SIZE(expected) && !found; i++) {
+      if (!wcscmp(str, expected[i])) {
+        TUV_ASSERT(!found_in_usr_env[i]);
+        found_in_usr_env[i] = 1;
+        found = 1;
+      }
+    }
+    if (prev) { /* verify sort order -- requires Vista */
+#if _WIN32_WINNT >= 0x0600 && \
+    (!defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR))
+      TUV_ASSERT(CompareStringOrdinal(prev, -1, str, -1, TRUE) == 1);
+#endif
+    }
+    TUV_ASSERT(found); /* verify that we expected this variable */
+  }
+
+  /* verify that we found all expected variables */
+  for (i = 0; i < ARRAY_SIZE(wenvironment); i++) {
+    TUV_ASSERT(found_in_loc_env[i]);
+  }
+  for (i = 0; i < ARRAY_SIZE(expected); i++) {
+    TUV_ASSERT(found_in_usr_env[i]);
+  }
+
+  return 0;
+}
+#endif
+
+/* Regression test for issue #909 */
+TEST_IMPL(spawn_with_an_odd_path) {
+  int r;
+
+  char newpath[2048];
+  char *path = getenv("PATH");
+  TUV_ASSERT(path != NULL);
+  snprintf(newpath, 2048, ";.;%s", path);
+  SetEnvironmentVariable("PATH", newpath);
+
+  init_process_options("", exit_cb);
+  options.file = options.args[0] = "program-that-had-better-not-exist";
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == UV_ENOENT || r == UV_EACCES);
+  TUV_ASSERT(0 == uv_is_active((uv_handle_t*) &process));
+  uv_close((uv_handle_t*) &process, NULL);
+  TUV_ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+  return 0;
+}
+#endif
+
+#ifndef _WIN32
+TEST_IMPL(spawn_setuid_fails) {
+  int r;
+
+  /* if root, become nobody. */
+  uv_uid_t uid = getuid();
+  if (uid == 0) {
+    struct passwd* pw;
+    pw = getpwnam("nobody");
+    TUV_ASSERT(pw != NULL);
+    TUV_ASSERT(0 == setgid(pw->pw_gid));
+    TUV_ASSERT(0 == setuid(pw->pw_uid));
+  }
+
+  init_process_options("spawn_helper1", fail_cb);
+
+  options.flags |= UV_PROCESS_SETUID;
+  options.uid = 0;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == UV_EPERM);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(close_cb_called == 0);
+
+  return 0;
+}
+
+
+TEST_IMPL(spawn_setgid_fails) {
+  int r;
+
+  /* if root, become nobody. */
+  uv_uid_t uid = getuid();
+  if (uid == 0) {
+    struct passwd* pw;
+    pw = getpwnam("nobody");
+    TUV_ASSERT(pw != NULL);
+    TUV_ASSERT(0 == setgid(pw->pw_gid));
+    TUV_ASSERT(0 == setuid(pw->pw_uid));
+  }
+
+  init_process_options("spawn_helper1", fail_cb);
+
+  options.flags |= UV_PROCESS_SETGID;
+  options.gid = 0;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == UV_EPERM);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(close_cb_called == 0);
+
+  return 0;
+}
+#endif
+
+
+#ifdef _WIN32
+
+static void exit_cb_unexpected(uv_process_t* process,
+                               int64_t exit_status,
+                               int term_signal) {
+  TUV_ASSERT(0 && "should not have been called");
+}
+
+
+TEST_IMPL(spawn_setuid_fails) {
+  int r;
+
+  init_process_options("spawn_helper1", exit_cb_unexpected);
+
+  options.flags |= UV_PROCESS_SETUID;
+  options.uid = (uv_uid_t) -42424242;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == UV_ENOTSUP);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(close_cb_called == 0);
+
+  return 0;
+}
+
+
+TEST_IMPL(spawn_setgid_fails) {
+  int r;
+
+  init_process_options("spawn_helper1", exit_cb_unexpected);
+
+  options.flags |= UV_PROCESS_SETGID;
+  options.gid = (uv_gid_t) -42424242;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == UV_ENOTSUP);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(close_cb_called == 0);
+
+  return 0;
+}
+#endif
+
+
+TEST_IMPL(spawn_auto_unref) {
+  init_process_options("spawn_helper1", NULL);
+  TUV_ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options));
+  TUV_ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+  TUV_ASSERT(0 == uv_is_closing((uv_handle_t*) &process));
+  uv_close((uv_handle_t*) &process, NULL);
+  TUV_ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+  TUV_ASSERT(1 == uv_is_closing((uv_handle_t*) &process));
+  return 0;
+}
+
+
+#ifndef _WIN32
+TEST_IMPL(spawn_fs_open) {
+  int fd;
+  uv_fs_t fs_req;
+  uv_pipe_t in;
+  uv_write_t write_req;
+  uv_buf_t buf;
+  uv_stdio_container_t stdio[1];
+
+  fd = uv_fs_open(NULL, &fs_req, "/dev/null", O_RDWR, 0, NULL);
+  TUV_ASSERT(fd >= 0);
+  uv_fs_req_cleanup(&fs_req);
+
+  init_process_options("spawn_helper8", exit_cb);
+
+  TUV_ASSERT(0 == uv_pipe_init(uv_default_loop(), &in, 0));
+
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
+  options.stdio[0].data.stream = (uv_stream_t*) &in;
+  options.stdio_count = 1;
+
+  TUV_ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options));
+
+  buf = uv_buf_init((char*) &fd, sizeof(fd));
+  TUV_ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb));
+
+  TUV_ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+  TUV_ASSERT(0 == uv_fs_close(NULL, &fs_req, fd, NULL));
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 2);  /* One for `in`, one for process */
+
+  return 0;
+}
+#endif  /* !_WIN32 */
+
+
+#ifndef _WIN32
+TEST_IMPL(closed_fd_events) {
+  uv_stdio_container_t stdio[3];
+  uv_pipe_t pipe_handle;
+  int fd[2];
+
+  /* create a pipe and share it with a child process */
+  TUV_ASSERT(0 == pipe(fd));
+
+  /* spawn_helper4 blocks indefinitely. */
+  init_process_options("spawn_helper4", exit_cb);
+  options.stdio_count = 3;
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_INHERIT_FD;
+  options.stdio[0].data.fd = fd[0];
+  options.stdio[1].flags = UV_IGNORE;
+  options.stdio[2].flags = UV_IGNORE;
+
+  TUV_ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options));
+  uv_unref((uv_handle_t*) &process);
+
+  /* read from the pipe with uv */
+  TUV_ASSERT(0 == uv_pipe_init(uv_default_loop(), &pipe_handle, 0));
+  TUV_ASSERT(0 == uv_pipe_open(&pipe_handle, fd[0]));
+  fd[0] = -1;
+
+  TUV_ASSERT(0 == uv_read_start((uv_stream_t*) &pipe_handle, on_alloc, on_read_once));
+
+  TUV_ASSERT(1 == write(fd[1], "", 1));
+
+  TUV_ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
+
+  /* should have received just one byte */
+  TUV_ASSERT(output_used == 1);
+
+  /* close the pipe and see if we still get events */
+  uv_close((uv_handle_t*) &pipe_handle, close_cb);
+
+  TUV_ASSERT(1 == write(fd[1], "", 1));
+
+  TUV_ASSERT(0 == uv_timer_init(uv_default_loop(), &timer));
+  TUV_ASSERT(0 == uv_timer_start(&timer, timer_counter_cb, 10, 0));
+
+  /* see if any spurious events interrupt the timer */
+  if (1 == uv_run(uv_default_loop(), UV_RUN_ONCE))
+    /* have to run again to really trigger the timer */
+    TUV_ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
+
+  TUV_ASSERT(timer_counter == 1);
+
+  /* cleanup */
+  TUV_ASSERT(0 == uv_process_kill(&process, /* SIGTERM */ 15));
+  TUV_ASSERT(0 == close(fd[1]));
+
+  return 0;
+}
+#endif  /* !_WIN32 */
+
+TEST_IMPL(spawn_reads_child_path) {
+  int r;
+  int len;
+  char file[64];
+  char path[1024];
+  char* env[3];
+
+  /* Need to carry over the dynamic linker path when the test runner is
+   * linked against libuv.so, see https://github.com/libuv/libuv/issues/85.
+   */
+#if defined(__APPLE__)
+  static const char dyld_path_var[] = "DYLD_LIBRARY_PATH";
+#elif defined __MVS__
+  static const char dyld_path_var[] = "LIBPATH";
+#else
+  static const char dyld_path_var[] = "LD_LIBRARY_PATH";
+#endif
+
+  /* Set up the process, but make sure that the file to run is relative and */
+  /* requires a lookup into PATH */
+  init_process_options("spawn_helper1", exit_cb);
+
+  /* Set up the PATH env variable */
+  for (len = strlen(exepath);
+       exepath[len - 1] != '/' && exepath[len - 1] != '\\';
+       len--);
+  strcpy(file, exepath + len);
+  exepath[len] = 0;
+  strcpy(path, "PATH=");
+  strcpy(path + 5, exepath);
+
+  env[0] = path;
+  env[1] = getenv(dyld_path_var);
+  env[2] = NULL;
+
+  if (env[1] != NULL) {
+    static char buf[1024 + sizeof(dyld_path_var)];
+    snprintf(buf, sizeof(buf), "%s=%s", dyld_path_var, env[1]);
+    env[1] = buf;
+  }
+
+  options.file = file;
+  options.args[0] = file;
+  options.env = env;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 1);
+
+  return 0;
+}
+
+#ifndef _WIN32
+static int mpipe(int *fds) {
+  if (pipe(fds) == -1)
+    return -1;
+  if (fcntl(fds[0], F_SETFD, FD_CLOEXEC) == -1 ||
+      fcntl(fds[1], F_SETFD, FD_CLOEXEC) == -1) {
+    close(fds[0]);
+    close(fds[1]);
+    return -1;
+  }
+  return 0;
+}
+#else
+static int mpipe(int *fds) {
+  SECURITY_ATTRIBUTES attr;
+  HANDLE readh, writeh;
+  attr.nLength = sizeof(attr);
+  attr.lpSecurityDescriptor = NULL;
+  attr.bInheritHandle = FALSE;
+  if (!CreatePipe(&readh, &writeh, &attr, 0))
+    return -1;
+  fds[0] = _open_osfhandle((intptr_t)readh, 0);
+  fds[1] = _open_osfhandle((intptr_t)writeh, 0);
+  if (fds[0] == -1 || fds[1] == -1) {
+    CloseHandle(readh);
+    CloseHandle(writeh);
+    return -1;
+  }
+  return 0;
+}
+#endif /* !_WIN32 */
+
+TEST_IMPL(spawn_inherit_streams) {
+  uv_process_t child_req;
+  uv_stdio_container_t child_stdio[2];
+  int fds_stdin[2];
+  int fds_stdout[2];
+  uv_pipe_t pipe_stdin_child;
+  uv_pipe_t pipe_stdout_child;
+  uv_pipe_t pipe_stdin_parent;
+  uv_pipe_t pipe_stdout_parent;
+  unsigned char ubuf[OUTPUT_SIZE - 1];
+  uv_buf_t buf;
+  unsigned int i;
+  int r;
+  uv_write_t write_req;
+  uv_loop_t* loop;
+
+  init_process_options("spawn_helper9", exit_cb);
+
+  loop = uv_default_loop();
+  TUV_ASSERT(uv_pipe_init(loop, &pipe_stdin_child, 0) == 0);
+  TUV_ASSERT(uv_pipe_init(loop, &pipe_stdout_child, 0) == 0);
+  TUV_ASSERT(uv_pipe_init(loop, &pipe_stdin_parent, 0) == 0);
+  TUV_ASSERT(uv_pipe_init(loop, &pipe_stdout_parent, 0) == 0);
+
+  TUV_ASSERT(mpipe(fds_stdin) != -1);
+  TUV_ASSERT(mpipe(fds_stdout) != -1);
+
+  TUV_ASSERT(uv_pipe_open(&pipe_stdin_child, fds_stdin[0]) == 0);
+  TUV_ASSERT(uv_pipe_open(&pipe_stdout_child, fds_stdout[1]) == 0);
+  TUV_ASSERT(uv_pipe_open(&pipe_stdin_parent, fds_stdin[1]) == 0);
+  TUV_ASSERT(uv_pipe_open(&pipe_stdout_parent, fds_stdout[0]) == 0);
+
+  child_stdio[0].flags = UV_INHERIT_STREAM;
+  child_stdio[0].data.stream = (uv_stream_t *)&pipe_stdin_child;
+
+  child_stdio[1].flags = UV_INHERIT_STREAM;
+  child_stdio[1].data.stream = (uv_stream_t *)&pipe_stdout_child;
+
+  options.stdio = child_stdio;
+  options.stdio_count = 2;
+
+  TUV_ASSERT(uv_spawn(loop, &child_req, &options) == 0);
+
+  uv_close((uv_handle_t*)&pipe_stdin_child, NULL);
+  uv_close((uv_handle_t*)&pipe_stdout_child, NULL);
+
+  buf = uv_buf_init((char*)ubuf, sizeof ubuf);
+  for (i = 0; i < sizeof ubuf; ++i)
+    ubuf[i] = i & 255u;
+  memset(output, 0, sizeof ubuf);
+
+  r = uv_write(&write_req,
+               (uv_stream_t*)&pipe_stdin_parent,
+               &buf,
+               1,
+               write_cb);
+  TUV_ASSERT(r == 0);
+
+  r = uv_read_start((uv_stream_t*)&pipe_stdout_parent, on_alloc, on_read);
+  TUV_ASSERT(r == 0);
+
+  r = uv_run(loop, UV_RUN_DEFAULT);
+  TUV_ASSERT(r == 0);
+
+  TUV_ASSERT(exit_cb_called == 1);
+  TUV_ASSERT(close_cb_called == 3);
+
+  r = memcmp(ubuf, output, sizeof ubuf);
+  TUV_ASSERT(r == 0);
+
+  return 0;
+}
+
+/* Helper for child process of spawn_inherit_streams */
+#ifndef _WIN32
+int spawn_stdin_stdout(void) {
+  char buf[1024];
+  char* pbuf;
+  for (;;) {
+    ssize_t r, w, c;
+    do {
+      r = read(0, buf, sizeof buf);
+    } while (r == -1 && errno == EINTR);
+    if (r == 0) {
+      return 1;
+    }
+    TUV_ASSERT(r > 0);
+    c = r;
+    pbuf = buf;
+    while (c) {
+      do {
+        w = write(1, pbuf, (size_t)c);
+      } while (w == -1 && errno == EINTR);
+      TUV_ASSERT(w >= 0);
+      pbuf = pbuf + w;
+      c = c - w;
+    }
+  }
+  return 2;
+}
+#else
+int spawn_stdin_stdout(void) {
+  char buf[1024];
+  char* pbuf;
+  HANDLE h_stdin = GetStdHandle(STD_INPUT_HANDLE);
+  HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
+  TUV_ASSERT(h_stdin != INVALID_HANDLE_VALUE);
+  TUV_ASSERT(h_stdout != INVALID_HANDLE_VALUE);
+  for (;;) {
+    DWORD n_read;
+    DWORD n_written;
+    DWORD to_write;
+    if (!ReadFile(h_stdin, buf, sizeof buf, &n_read, NULL)) {
+      TUV_ASSERT(GetLastError() == ERROR_BROKEN_PIPE);
+      return 1;
+    }
+    to_write = n_read;
+    pbuf = buf;
+    while (to_write) {
+      TUV_ASSERT(WriteFile(h_stdout, pbuf, to_write, &n_written, NULL));
+      to_write -= n_written;
+      pbuf += n_written;
+    }
+  }
+  return 2;
+}
+#endif /* !_WIN32 */
index a132942775de0034391cf3e2e4800230ad4bac92..def476c21c3b8005a8ae379df66df9ffab4d4ae8 100644 (file)
@@ -1,13 +1,16 @@
 ### Supported platforms
-Current supported platforms are **Linux and NuttX**
+Current supported platforms are **Linux, [NuttX][nuttx-site], [Tizen][tizen-site] and [TizenRT][tizenrt-site]**
 
 OSX 10.10 as development host
 
 * [Build for x86 / Linux](build/Build-for-x86-Linux.md): Ubuntu 14.04 is used as a base platform.
+* [Build for Raspberry Pi 2 / Linux](build/Build-for-RPi2-Linux.md)
 * [Build for Raspberry Pi 3 / Tizen](build/Build-for-RPi3-Tizen.md)
 * [Build for Stm32f4 / NuttX](build/Build-for-STM32F4-NuttX.md)
-* [Build for Raspberry Pi 2 / Linux](build/Build-for-RPi2-Linux.md)
 * [Build for ARTIK053 / TizenRT](build/Build-for-ARTIK053-TizenRT.md)
+* [Build for ARTIK530 / Tizen](build/Build-for-RPi3-Tizen.md)
+* [Build for OpenWrt (non-tested)](build/Build-for-OpenWrt.md)
+* [Build for Windows (experimental)](build/Build-for-Windows.md)
 
 #### H/W boards
 * Current supporting
@@ -15,10 +18,34 @@ OSX 10.10 as development host
     * Raspberry Pi 2
     * Raspberry Pi 3
     * Samsung ARTIK 053
+    * Samsung ARTIK 530
 
 We will support the correct behavior of APIs for above environments. However, since IoT.js is targeting various kind IoT devices and platforms, single implementation cannot be the best practice for every environments. Therefore embedders should be in charge of optimization for their own environments. For more details on optimization, see the [Optimization Tips](devs/Optimization-Tips.md) page.
 
 
 ### Build script
-There is a script to help you build IoT.js called "[build.py](https://github.com/Samsung/iotjs/blob/master/tools/build.py)" in source repository.
+There is a [script](build/Build-Script.md) to help you build IoT.js called "[build.py](https://github.com/Samsung/iotjs/blob/master/tools/build.py)" in source repository. Run `tools/build.py --help` command to check all of the build options.
+
+#### How to Build
+
+```bash
+  tools/build.py --clean
+```
+
+#### Frequently used build options
+
+`--clean` Clean build directory before build (default: False).
+
+`--no-snapshot` Disable snapshot generation for IoT.js. It is useful for debugging sessions.
+
+`--profile PROFILE` Specify the module profile file for IoT.js. It is used for enable and disable modules. See also ["How to write a new module"](devs/Writing-New-Module.md#profile)
+
+`--run-test [{full,quiet}]` Execute tests after build, optional argument specifies the level of output for the test runner.
+
+`--jerry-debugger` Enable JerryScript debugger, so JavaScript could can be investigated with an available debugger client (eg.: [Python Debugger Console](https://github.com/jerryscript-project/jerryscript/blob/master/jerry-debugger/jerry-client-ws.py) or [IoT.js Code](https://github.com/Samsung/iotjscode/)). See also ["Use JerryScript Debugger"](devs/Use-JerryScript-Debugger.md).
+
+`--js-backtrace {ON,OFF}` Enable/disable backtrace information of JavaScript code (default: ON in debug and OFF in release build).
 
+[nuttx-site]: http://nuttx.org/
+[tizen-site]: https://www.tizen.org/
+[tizenrt-site]: https://wiki.tizen.org/Tizen_RT
\ No newline at end of file
index 49b3a750ce8e334753383b94d2360e0bf9e283b1..deca9eeed7f67184e74c5638ba57c03dda08d7e6 100644 (file)
@@ -8,6 +8,7 @@ The following shows Buffer module APIs available for each platform.
 | buf.copy | O | O | O | O | O |
 | buf.equals | O | O | O | O | O |
 | buf.fill | O | O | O | O | O |
+| buf.from | O | O | O | O | O |
 | buf.slice | O | O | O | O | O |
 | buf.toString | O | O | O | O | O |
 | buf.write | O | O | O | O | O |
@@ -182,6 +183,84 @@ console.log(buffer);
 ```
 
 
+### Buffer.from(array)
+* `array` {Array} Array of numbers.
+* Returns: {Buffer} containing the elements from `array`
+
+Creates a new Buffer from an array of numbers. The numbers are converted to integers first and their modulo 256 remainder is used for constructing the buffer.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+var source = new Buffer[65, 66, 67];
+var buffer = Buffer.from(source);
+
+//prints: ABC
+console.log(buffer.toString());
+```
+
+
+### Buffer.from(string[,encoding])
+* `str` {String} Source string.
+* `encoding` {String} Encoding format.
+* Returns: {Buffer} containing the elements from `str`
+
+Creates a new buffer which contains the CESU-8 representation of the str string argument. If encoding optional argument is present its value must be hex. When this encoding is specified the str argument must be a sequence of hexadecimal digit pairs, and these pairs are converted to bytes.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+var buffer = Buffer.from('4142','hex');
+
+//prints: AB
+console.log(buffer.toString());
+```
+
+
+### Buffer.from(buffer)
+* `buffer` {Buffer} Source buffer.
+* Returns: {Buffer} which is the copy of `buffer`
+Creates a copy of an existing buffer. The buffer data is not shared between the two buffers.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+var source = new Buffer(12);
+var buffer = Buffer.from(source);
+```
+
+
+### Buffer.from(arrayBuffer[, byteOffset[, length]])
+* `arrayBuffer` {ArrayBuffer} Arraybuffer, or a buffer of a TypedArray
+* `byteOffset` {Number} Index of first byte to expose. Default: 0.
+* `length` {Number} Number of bytes to expose. Default: arrayBuffer.length - byteOffset.
+* Returns: {Buffer} containing the data of `arraybuffer` from read `offset` with `length`
+
+**Example**
+
+```js
+var source = new ArrayBuffer(12);
+var buffer = Buffer.from(source, 0, 2);
+
+//prints: 2
+console.log(buffer.length);
+```
+
+```js
+var typed_source = new Uint8Array([65,66]);
+var arr_buff = Buffer.from(typed_source1.buffer, 0, 2);
+
+//prints: AB
+console.log(buff.toString('utf-8'));
+```
+
+
 ### Buffer.isBuffer(obj)
 * `obj` {Object}
 * Returns: {boolean}
diff --git a/docs/api/IoT.js-API-Crypto.md b/docs/api/IoT.js-API-Crypto.md
new file mode 100644 (file)
index 0000000..bdaea8c
--- /dev/null
@@ -0,0 +1,93 @@
+### Platform Support
+
+The following chart shows the availability of each Crypto module API function on each platform.
+
+|  | Linux<br/>(Ubuntu) | Tizen<br/>(Raspberry Pi) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) | TizenRT<br/>(Artik053) |
+| :---: | :---: | :---: | :---: | :---: | :---: |
+| crypto.createHash  | O | O | O | O | O |
+| crypto.createVerify  | O | O | O | O | O |
+| crypto.getHashes  | O | O | O | O | O |
+
+# Crypto
+
+The module provides limited cryptographic functionality, namely hashing and signature verification.
+To access this module use `require('crypto')`.
+
+### crypto.createVerify(hashType)
+Creates and returns a `Verify` object. This object can not be created with the `new` keyword.
+  - `hashType` {string} Hash type of the signature. {`sha1 | sha256`}
+
+Note: We currently only support `rsa-sha1` and `rsa-sha256` signatures.
+
+### crypto.createHash(hashType)
+Creates and returns a `Hash` object. This object can not be created with the `new` keyword.
+  - `hashType` {string} Type of the hash. {`sha1 | sha256`}
+
+Note: We currently only support `sha1` and `sha256` hashes.
+
+### crypto.getHashes()
+Returns the available hashing methods.
+
+## Class: Verify
+The `Verify` class allows the user to verify a signature against a public key.
+
+### verify.update(data)
+Updates the `Verify` object with the given `data`.
+  - `data` {Buffer | string} Updates the object with the `data`. If there is already `data` in the object, concatenates them.
+
+**Example**
+```js
+var crypto = require('crypto');
+var myVerifyObject = crypto.createVerify('sha256');
+
+myVerifyObject.update('This data should be verified');
+myVerifyObject.update('\nAnd this belongs there too.');
+```
+
+### verify.verify(publicKey, signature)
+Verifies the `signature` against the `publicKey` using the `data` added with `verify.update()`.
+  - `publicKey` {string | Buffer} A valid RSA Public key.
+  - `signature` {string | Buffer} A base64 encoded `rsa-sha1` or `rsa-sha256` signature.
+
+Returns `true` if the verification succeeds, `false` otherwise.
+
+**Example**
+```js
+var crypto = require('crypto');
+
+var myVerifyObject = crypto.createVerify('sha256');
+var myKey = getPublicKeySomehow();
+var myData = getSomeStringToVerify();
+var mySignature = getSignatureSomehow();
+
+
+myVerifyObject.update(myData);
+var success = myVerifyObject.verify(myKey, mySignature);
+
+if (!success) {
+  throw new Error('Invalid signature !');
+}
+```
+
+## Class: Hash
+The `Hash` class creates hashes from the data given.
+
+### hash.update(data)
+Updates the `Hash` object with the given `data`.
+  - `data` {Buffer | String} Updates the object with the `data`. If there is already `data` in the object, concatenates them.
+
+### hash.digest(encoding)
+Returns an `encoded` hash of the input `data` as a `string` or `Buffer`.
+  - `encoding` {string} Encodes the result of the hashing to the given format. Can be {`hex | base64`}. If no `encoding` is given, or the given `encoding` doesn't match the known formats, returns the raw `hash` in a `Buffer`.
+
+Digest can only be called once on a given `Hash` object.
+
+**Example**
+```js
+var crypto = require('crypto');
+
+var myData = 'Some data to hash';
+var myHashObj = crypto.createHash('sha1');
+myHashObj.update(myData);
+var myHash = myHashObj.digest('hex');
+```
index 9450c116544c00cb6668b2fa003bfc38b4852cca..7bd59cff68315d773f5281c2bbc8aeab288f8a50 100644 (file)
@@ -6,6 +6,8 @@ The following shows fs module APIs available for each platform.
 | :---: | :---: | :---: | :---: | :---: | :---: |
 | fs.close | O | O | O | O | O |
 | fs.closeSync | O | O | O | O | O |
+| fs.createReadStream | O | O | O | O | O |
+| fs.createWriteStream | O | O | O | O | O |
 | fs.exists | O | O | O | O | O |
 | fs.existsSync | O | O | O | O | O |
 | fs.fstat | O | O | O | X | X |
@@ -112,6 +114,168 @@ fs.closeSync(fd);
 ```
 
 
+## Class: fs.ReadStream
+
+A successful call to `fs.createReadStream()` will return a new `fs.ReadStream`
+object.
+
+`fs.ReadStream` inherits from `stream.Readable`.
+
+
+### Event: 'open'
+* `fd` {integer} File descriptor used by the `fs.ReadStream`.
+
+Emitted when the `fs.ReadStream`'s file descriptor has been opened.
+
+
+### Event: 'ready'
+
+Emitted when the `fs.ReadStream` is ready to be used. Emitted immediately
+after `open`.
+
+
+### Event: 'data'
+* `chunk` {Buffer|string}
+
+Inherited from `stream.Readable`. Emitted when the stream passes the ownership
+of the data to a consumer. Only streams in flowing mode emit this event.
+
+A stream can be switched to flowing mode by calling the readable.resume()
+function or by adding a 'data' event handler.
+
+
+### Event: 'close'
+
+Emitted when the `fs.ReadStream`'s file descriptor has been closed.
+
+
+### ReadStream.bytesRead
+* {integer}
+
+Number of bytes that have been read so far.
+
+
+### ReadStream.path
+* {string}
+
+The path to the file of the `fs.ReadStream`.
+
+
+### fs.createReadStream(path[, options])
+* `path` {string} File path to open for reading.
+* `options` {Object}
+  * `flags` {string} Flags to open file with. **Default:** `'r'`
+  * `encoding` {string} **Default:** `null`
+  * `fd` {integer} File descriptor to be used. **Default:** `null`
+  * `mode` {integer} Permission mode. **Default:** `0666`
+  * `autoClose` {boolean} Should the file be closed automatically. **Default:** `true`
+  * `bufferSize` {integer} Size of buffer in bytes. **Default:** `4096`
+* Returns: `fs.ReadStream`
+
+If `fd` is specified, `path` will be ignored and the specified file
+descriptor will be used instead.
+
+If `autoClose` is `false`, the file will not be closed automatically,
+even if there is an error, it will be the application's responsibility.
+If it is `true` (as by default), the file will be closed automatically
+when end of file is reached or the stream ends.
+
+**Example**
+
+```js
+var fs = require('fs');
+
+var rStream = fs.createReadStream('example.txt');
+rStream.on('data', function(data) {
+  console.log(data.toString());
+});
+```
+
+`fs.ReadStream` inherits from `stream.Readable`, so it is possible to pipe
+it into any `stream.Writable`.
+
+**Example**
+
+```js
+var fs = require('fs');
+
+var readableFileStream = fs.createReadStream('in.txt');
+var writableFileStream = fs.createWriteStream('out.txt');
+
+// The content of in.txt will be copied to out.txt
+readableFileStream.pipe(writableFileStream);
+```
+
+
+## Class: fs.WriteStream
+
+A successful call to `fs.createWriteStream()` will return a new `fs.WriteStream`
+object.
+
+`fs.WriteStream` inherits from `stream.Writable`.
+
+
+### Event: 'open'
+* `fd` {integer} File descriptor used by the `fs.WriteStream`.
+
+Emitted when the `fs.WriteStream`'s file descriptor has been opened.
+
+
+### Event: 'ready'
+
+Emitted when the `fs.WriteStream` is ready to be used. Emitted immediately
+after `open`.
+
+
+### Event: 'close'
+
+Emitted when the `fs.WriteStream`'s file descriptor has been closed.
+
+
+### WriteStream.bytesWritten
+
+The number of bytes written so far. Does not include data that is still queued
+for writing.
+
+
+### WriteStream.path
+
+The path to the file of the `fs.WriteStream`.
+
+
+### fs.createWriteStream
+* `path` {string} File path to be opened for writing.
+* `options` {Object}
+  * `flags` {string} Flags to open the file with. **Default:** `'w'`
+  * `fd` {integer} File descriptor to be used. **Default:** `null`
+  * `mode` {integer} Permission mode. **Default:** `0666`
+  * `autoClose` {boolean} Should the file be closed automatically. **Default:** `true`
+* Returns `fs.WriteStream`
+
+Works similarly to `fs.createReadStream()`, but returns an `fs.WriteStream`.
+
+If `fd` is specified, `path` will be ignored and the specified file
+descriptor will be used instead.
+
+If `autoClose` is `false`, the file will not be closed automatically,
+even if there is an error, it will be the application's responsibility.
+If it is `true` (as by default), the file will be closed automatically
+when end of file is reached or the stream ends.
+
+**Example**
+
+```js
+var fs = require('fs');
+
+var wStream = fs.createWriteStream('example.txt');
+
+wStream.on('ready', function() {
+  wStream.write('test data');
+  // 'test data' will be written into example.txt
+});
+```
+
+
 ### fs.exists(path, callback)
 * `path` {string} File path to be checked.
 * `callback` {Function}
index 06b38608db1644a18396ea1a53b29ee5dfd0e930..3db7598a2c09df892ee6095ba17f6e528942ac40 100644 (file)
@@ -6,9 +6,10 @@ The following shows GPIO module APIs available for each platform.
 | :---: | :---: | :---: | :---: | :---: | :---: |
 | gpio.open | X | O | O | O | O |
 | gpio.openSync | X | O | O | O | O |
+| gpiopin.setDirectionSync | X | O | O | O | O |
 | gpiopin.write | X | O | O | O | O |
 | gpiopin.writeSync | X | O | O | O | O |
-| gpiopin.read | X | O |  | O | O |
+| gpiopin.read | X | O | O | O | O |
 | gpiopin.readSync | X | O | O | O | O |
 | gpiopin.close | X | O | O | O | O |
 | gpiopin.closeSync | X | O | O | O | O |
@@ -122,6 +123,21 @@ var gpio10 = gpio.openSync({
 This class represents an opened and configured GPIO pin.
 It allows getting and setting the status of the pin.
 
+### gpiopin.setDirectionSync(direction)
+  * `direction` {[gpio.DIRECTION](#direction)} Pin direction.
+
+Set the direction of a GPIO pin.
+
+**Example**
+
+```js
+gpio10.setDirectionSync(gpio.DIRECTION.OUT);
+gpio10.writeSync(1);
+
+gpio10.setDirectionSync(gpio.DIRECTION.IN);
+var value = gpio10.readSync();
+```
+
 ### gpiopin.write(value[, callback])
 * `value` {number|boolean}
 * `callback` {Function}
diff --git a/docs/api/IoT.js-API-HTTP-Signature.md b/docs/api/IoT.js-API-HTTP-Signature.md
new file mode 100644 (file)
index 0000000..eab7fbf
--- /dev/null
@@ -0,0 +1,40 @@
+### Platform Support
+
+The following chart shows the availability of each HTTP Signature module API function on each platform.
+
+|  | Linux<br/>(Ubuntu) | Tizen<br/>(Raspberry Pi) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) | TizenRT<br/>(Artik053) |
+| :---: | :---: | :---: | :---: | :---: | :---: |
+| httpSignature.parseRequest  | O | O | O | O | O |
+| httpSignature.verify  | O | O | O | O | O |
+
+# HTTP Signature
+The module makes it possible to verify the signature on HTTP Requests as stated in the RFC Standard (https://tools.ietf.org/html/draft-cavage-http-signatures-10).
+
+### httpSignature.parseRequest(request)
+Parses an `HTTP request` and returns with the parsed object.
+  - `request` {Object} A valid `HTTP Request`
+
+The returned object can be used to later to `verify` the `signature` of the `request`.
+
+### httpSignature.verify(parsedRequest, publicKey)
+Verifies the `parsedRequest`'s `signature` against the given `publicKey`. Returns `true` if the verification succeeds, `false` otherwise.
+  - `parsedRequest` {Object} An `HTTP Request` parsed by `httpSignature.parseRequest()` function.
+  - `publicKey` {Buffer | string} The RSA Public key.
+
+**Example**
+```js
+var httpSign = require('http_signature');
+
+...
+
+function myHTTPListener(req, res) {
+  var parsedRequest = httpSign.parseRequest(req);
+  if (!httpSign.verify(parsedRequest))
+    // Verification failed
+    return res.send(401);
+  }
+
+  // Signature is OK, handle the request normally
+  requestHandler(req, res);
+}
+```
index 4ff859a190666382a5fddf5ffebc64f561d43dd9..e8b246cc82aa9bf894aca5721801bbb91810335b 100644 (file)
@@ -3,10 +3,36 @@
  The following shows Http module APIs available for each platform.
 
  |  | Linux<br/>(Ubuntu) | Tizen<br/>(Raspberry Pi) | Raspbian<br/>(Raspberry Pi) | NuttX<br/>(STM32F4-Discovery) | TizenRT<br/>(Artik053) |
- | :---: | :---: | :---: | :---: | :---: | :---: |
- | http.createServer | O | O | O | △ ¹ | △ ¹ |
- | http.request | O | O | O | △ ¹ | △ ¹ |
- | http.get | O | O | O | △ ¹ | △ ¹ |
+ | :--- | :---: | :---: | :---: | :---: | :---: |
+ | http.createServer                    | O | O | O | △ ¹ | △ ¹ |
+ | http.request                         | O | O | O | △ ¹ | △ ¹ |
+ | http.get                             | O | O | O | △ ¹ | △ ¹ |
+ | http.METHODS                         | O | O | O | O   | O   |
+ | http.Server                          | O | O | O | △ ¹ | △ ¹ |
+ | http.Server.close                    | O | O | O | △ ¹ | △ ¹ |
+ | http.Server.listen                   | O | O | O | △ ¹ | △ ¹ |
+ | http.Server.setTimeout               | O | O | O | △ ¹ | △ ¹ |
+ | http.ClientRequest                   | O | O | O | △ ¹ | △ ¹ |
+ | http.ClientRequest.abort             | O | O | O | △ ¹ | △ ¹ |
+ | http.ClientRequest.end               | O | O | O | △ ¹ | △ ¹ |
+ | http.ClientRequest.setTimeout        | O | O | O | △ ¹ | △ ¹ |
+ | http.ClientRequest.write             | O | O | O | △ ¹ | △ ¹ |
+ | http.IncomingMessage                 | O | O | O | △ ¹ | △ ¹ |
+ | http.IncomingMessage.headers         | O | O | O | △ ¹ | △ ¹ |
+ | http.IncomingMessage.method          | O | O | O | △ ¹ | △ ¹ |
+ | http.IncomingMessage.httpVersion     | O | O | O | △ ¹ | △ ¹ |
+ | http.IncomingMessage.socket          | O | O | O | △ ¹ | △ ¹ |
+ | http.IncomingMessage.statusCode      | O | O | O | △ ¹ | △ ¹ |
+ | http.IncomingMessage.url             | O | O | O | △ ¹ | △ ¹ |
+ | http.IncomingMessage.statusMessage   | O | O | O | △ ¹ | △ ¹ |
+ | http.IncomingMessage.setTimeout      | O | O | O | △ ¹ | △ ¹ |
+ | http.ServerResponse                  | O | O | O | △ ¹ | △ ¹ |
+ | http.ServerResponse.end              | O | O | O | △ ¹ | △ ¹ |
+ | http.ServerResponse.getHeader        | O | O | O | △ ¹ | △ ¹ |
+ | http.ServerResponse.setHeader        | O | O | O | △ ¹ | △ ¹ |
+ | http.ServerResponse.setTimeout       | O | O | O | △ ¹ | △ ¹ |
+ | http.ServerResponse.write            | O | O | O | △ ¹ | △ ¹ |
+ | http.ServerResponse.writeHead        | O | O | O | △ ¹ | △ ¹ |
 
 1. On NuttX/STM32F4-Discovery and TizenRT/Artik053, even a couple of sockets/server/requests might not work properly.
 
 
 IoT.js provides HTTP to support HTTP server and client enabling users to receive/send HTTP request easily.
 
-### http.createServer([requestListener])
+### http.createServer([options][, requestListener])
+* `options` {Object}
+  * `IncomingMessage` {Function} Specifies the `IncomingMessage` constructor to be used when creating an http incoming message object.
+    Useful when extending the original {http.IncommingMessge}.
+    Default: `http.IncommingMessage`.
+  * `ServerResponse` {Function} Specifies the `ServerResponse` constructor to be used when creating the server response object.
+    Useful when extending the original {http.ServerResponse}.
+    Default: 'http.ServerResponse`.
 * `requestListener` {Function}
-  * request {http.IncomingMessage}
-  * response {http.ServerResponse}
+  * `request` {http.IncomingMessage}
+  * `response` {http.ServerResponse}
 * Returns: {http.Server}
 
-The `requestListener` is a function which is automatically added to the `'request'` event.
+This call only creates the HTTP server instance and does not start the server.
+To start the server and listen for connections use the `server.listen` method.
+
+If a server is no longer needed, all request and response streams should be closed and the `server.close` method
+should be used to stop the server listening for connections.
+
+The `requestListener` is a function which is automatically added to the `'request'` event of the http server.
 
 **Example**
 
 ```js
+var console = require('console');
+var http = require('http');
+
 var server = http.createServer(function(request, response) {
-  ...
+  console.log('Request for path: ' + request.url);
+
+  var message = '<h1>Hello</h1>';
+
+  response.setHeader('Content-Type', 'text/html');
+  response.setHeader('Content-Length', message.length);
+  response.writeHead(200);
+  response.write(message);
+  response.end();
+});
+
+var port = 8081
+server.listen(port, function() {
+  console.log('HTTP server listening on port: ' + port);
 });
 ```
 
+
 ### http.request(options[, callback])
 * `options` {Object}
   * `host` {string} A domain name or IP address of the server to issue the request to. Defaults to 'localhost'.
@@ -42,23 +98,32 @@ var server = http.createServer(function(request, response) {
   * `response` {http.IncomingMessage}
 * Returns: {http.ClientRequest}
 
+The function creates a `http.ClientRequest` instance with the `options` defined.
+This can be used to get data form a server or to send data for a server.
+
+In case of data send the `'Content-Length'` header should be specifed so the server can properly handle the request.
+
 **Example**
 
 ```js
 var http = require('http');
 
+var data_A = 'Data to upload..';
+var data_B = 'more data';
 var request = http.request({
   method: 'POST',
-  port: 80,
-  headers: {'Content-Length': 3}
+  port: 8081,
+  headers: { 'Content-Length': data_A.length + data_B.length }
 });
 
-...
+request.write(data_A);
+request.write(data_B);
 
 request.end();
 ```
 
-Note that in the example `req.end()` was called. With `http.request()` one must always call `req.end()` to signify that you're done with the request - even if there is no data being written to the request body.
+Note that in the example `request.end()` was called. With `http.request()` one must always call
+`request.end()` to signify that you're done with the request - even if there is no data being written to the request body.
 
 ### http.get(options[, callback])
 * `options` {Object}
@@ -66,7 +131,10 @@ Note that in the example `req.end()` was called. With `http.request()` one must
   * `response` {http.IncomingMessage}
 * Returns: {http.ClientRequest}
 
-Same as `http.request` except that `http.get` automatically call `req.end()` at the end.
+Same as `http.request` except that `http.get` automatically calls `request.end()` before returning the `http.ClientRequest`
+instance thus calling the `write` method on the return value is invalid.
+
+This method is usefuly when there is no HTTP body to send.
 
 **Example**
 
@@ -75,22 +143,29 @@ var http = require('http');
 
 http.get({
   port: 80,
-}, function(res) {
-...
+}, function(response) {
+  console.log('Got response');
+  response.on('data', function(chunk) {
+    console.log('Chunk: ');
+    console.log(chunk.toString());
+  });
 });
 ```
 
 
 ### http.METHODS
-A list of HTTP methods supported by the parser as `string` properties of an `Object`.
+* {string[]}
+
+A list of HTTP methods supported by the parser as a `string` array.
 
 ## Class: http.Server
 
-This class inherits from `net.Server`.
+This class inherits from `net.Server` and represents a HTTP server.
 
 ### Event: 'clientError'
-* `exception` {Error}
-* `socket` {net.Socket}
+Event callback arguments:
+* `exception` {Error} Describes what kind of error occured.
+* `socket` {net.Socket} The socket which triggered the error.
 
 If a client connection emits an 'error' event, it will be forwarded here. Listener of this event is responsible for closing/destroying the underlying socket.
 
@@ -113,62 +188,122 @@ server.listen(8000);
 ```
 
 ### Event: 'close'
-This event is emitted when server is closed.
+This event is emitted when the HTTP server is closed.
+
+**Example**
+
+```js
+var console = require('console');
+var http = require('http');
+
+var server = http.createServer();
+
+server.on('close', function() {
+  console.log('Server closed');
+});
+
+server.listen(8081, function() {
+  console.log('HTTP server listening');
+
+  server.close();
+});
+```
+
+When the example is executed the following will text will be printed:
+
+```
+HTTP server listening
+Server closed
+```
 
 ### Event: 'connection'
+Event callback argument:
 * `socket` {net.Socket}
 
-This event is emitted when new TCP connection is established.
+This event is emitted when new TCP connection is established. This event is triggered before
+the `request` event. At this stage no HTTP header or data is processed.
 
-### Event: 'connect'
+Usually there is no need to listen for this event.
 
-Emitted each time a client requests an `HTTP CONNECT` method.
 
 ### Event: 'request'
-* `request` {http.IncomingMessage}
-* `response` {http.ServerResponse}
+* `request` {http.IncomingMessage} Represents the HTTP request sent by the client.
+* `response` {http.ServerResponse} Represents the HTTP response which will be sent by the server.
+
+After HTTP request headers are parsed, the `'request'` event will be fired.
+
+**Example**
+
+```js
+var console = require('console');
+var http = require('http');
 
-After request header is parsed, this event will be fired.
+var server = http.createServer();
+
+server.on('request', function(request, response) {
+  console.log('Request for path: ' + request.url);
+
+  var message = '<h1>Hello</h1>';
+
+  response.setHeader('Content-Type', 'text/html');
+  response.setHeader('Content-Length', message.length);
+  response.writeHead(200);
+  response.write(message);
+  response.end();
+});
 
+var port = 8081
+server.listen(port, function() {
+  console.log('HTTP server listening on port: ' + port);
+});
+```
 
 ### server.timeout
+* {number}
+
 The number of milliseconds of inactivity before a socket is presumed to have timed out. Default value is 120000 (2 minutes).
 
 ### server.listen(port[, hostname][, backlog][, callback])
-* `port` {number}
-* `host` {string}
-* `backlog` {number}
-* `callback` {Function}
+* `port` {number} Port number to listen on.
+* `host` {string} Host IP or name where the server should listen. Default: `'0.0.0.0'`.
+* `backlog` {number} The number of maximum pending connections. Default backlog length is 511 (not 512).
+* `callback` {Function} Callback called when the `'listening'` event is emitted by the underlying `net.Server`.
+* Returns {http.Server} The same server instance which was used to call the `listen` method.
 
-Wait for new TCP connection with specified port and hostname. If no hostname is provided, server accepts any IP address.
-`backlog` is maximum pending connections. Default backlog length is 511 (not 512).
-`callback` will be called when server has been bound.
+Wait for new TCP connections with specified port and hostname. If no hostname is provided, server listens on all available IP address.
 
 **Example**
 
 ```js
+var console = require('console');
 var http = require('http');
 
 var server = http.createServer(function(req, res) {
   res.end();
 });
-server.listen(8080, function() {});
+server.listen(8080, function() {
+  console.log('Started listening');
+});
 ```
 
 ### server.close([callback])
-* `callback` {Function}
+* `callback` {Function} Function which to be registered for the `'close'` event.
+* Returns {http.Server} The same server instance which was used to call the `close` method.
+
+Stop accepting new connections to this server. However, the existing connections are preserved.
+When the server is finally closed after all connections was closed, the `'close'` event is triggered.
 
-Stop accepting new connection to this server. However, the existing connections are preserved. When server is finally closed after all connections are closed, a callback is called.
+See the `'close`' event.
 
-### server.setTimeout(ms, cb)
+### server.setTimeout(ms[, callback])
 
 * `ms` {number}
-* `cb` {Function}
+* `callback` {Function} The callback function registered for the `'timeout'` event.
 
-Registers cb for `'timeout'` event and sets socket's timeout value to ms. This event will be triggered by the underlying socket's 'timeout' event.
+Registers cb for `'timeout'` event and sets socket's timeout value to ms. This event will be triggered by the underlying socket's `'timeout'` event.
 
-If cb is not provided, the socket will be destroyed automatically after timeout.
-If you provide cb, you should handle the socket's timeout.
+If `callback` is not provided, the socket will be destroyed automatically after timeout.
+If the `callback` function is provided, that function should should handle the socket's timeout.
 
 Default timeout for server is 2 minutes.
 
@@ -184,73 +319,16 @@ server.setTimeout(100, function(socket) {
 });
 ```
 
-## Class: http.ServerResponse
-
-### Event: 'close'
-When underlying connection is closed, 'close' event is emitted.
-
-### Event: 'end'
-This event is fired when no more data to be sent.
-
-### Event: 'finish'
-This event is emitted when the response has been sent. It does not guarantee that client has received data yet.
-
-
-### response.end([data][, callback])
-* `data` {Buffer | string}
-* `callback` {Function}
-
-Finishes sending the response.
-
-If `data` is provided, it sends `data` first, and finishes.
-If `callback` is specified, it is called when the response stream is finished.
-
-### response.getHeader(name)
-* `name` {string}
-
-Returns `name` field of response's header
-
-### response.removeHeader(name)
-* `name` {string}
-
-Removes `name` field from response's header
-
-### response.setHeader(name, value)
-* `name` {string}
-* `value` {string}
-
-Sets response's header field(`name`) to `value`. If the field exists, it overwrites the existing value.
-
-### response.setTimeout(ms, cb)
-
-* `ms` {number}
-* `cb` {Function}
-
-Registers cb for 'timeout' event and set socket's timeout value to ms. This event will be triggered by the underlying socket's 'timeout' event.
-
-### response.write(data[, callback])
-* `data` {Buffer | string}
-* `callback` {Function}
-
-Sends `data` as a response body. `callback` will be called when data is flushed.
-
-### response.writeHead(statusCode[, statusMessage][, headers])
-* `statusCode` {number}
-* `statusMessage` {string}
-* `headers` {Object}
-
-Sets response's header. `headers` is a map between field and value in header.
-
 
 ## Class: http.ClientRequest
 
-This object is created internally and returned from http.request(). It represents an in-progress request whose header has already been queued.
+This object is created internally and returned from `http.request()`. It represents an in-progress request whose headers have already been queued.
 
 ### Event: 'close'
 This event is fired when the underlying socket is closed.
 
 ### Event: 'error'
-* `callback` {Function}
+Event callback arguments:
 * `err` {Error}
 
 Emitted if something went wrong with making or parsing the request.
@@ -259,14 +337,41 @@ Emitted if something went wrong with making or parsing the request.
 This event is emitted after all the data was sent, meaning header and body all finished sending.
 
 ### Event: 'response'
-* `response` {http.IncomingMessage}
+Event callback arguments:
+* `response` {http.IncomingMessage} The incoming HTTP response from the server.
+
+This event is emitted when server's HTTP response header is parsed.
+The event is called only once. The developer should attach at least one event handler for this event
+to correctly process any data sent back by the target server.
 
-This event is emitted when server's response header is parsed. ` http.IncomingMessage` object is passed as argument to handler.
+**Example**
+
+```js
+var http = require('http');
+
+var options = {
+  host: 'localhost',
+  port: 8081,
+  method: 'GET',
+};
+var client_request = http.request(options);
+client_request.on('response', function(response) {
+  console.log('HTTP status: ' + response.statusCode);
+  console.log('Headers:');
+  console.log(response.headers);
+
+  response.on('data', function(chunk) {
+    console.log(chunk.toString());
+  });
+});
+client_request.end();
+```
 
 ### Event: 'socket'
+Event callback arguments:
 * `socket` {net.Socket}
 
-This event is emitted when a socket is assigned to this request. `net.Socket` object is passed as argument to handler.
+This event is emitted when a socket is assigned to this request.
 
 After response header is parsed, this event will be fired.
 
@@ -275,62 +380,163 @@ After response header is parsed, this event will be fired.
 Will abort the outgoing request, dropping any data to be sent/received and destroying the underlying socket.
 
 ### request.end([data][, callback])
-* `data` {Buffer | string}
-* `callback` {Function}
+* `data` {Buffer | string} Data to be sent.
+* `callback` {Function} Callback function invoked when all data is processed.
 
 Finishes sending the request.
 
 If `data` is provided, it sends `data` first, and finishes.
 If `callback` is specified, it is called when the request stream is finished.
 
-### request.setTimeout(ms, cb)
+This method must be called to close the request and to make sure all data is sent.
+
+**Example**
+
+```js
+var http = require('http');
+
+var message = 'HTTP Body POST Data';
+var options = {
+  host: 'localhost',
+  port: 8081,
+  method: 'POST',
+  headers: {'Content-Length': message.length},
+};
+var client_request = http.request(options, function(response) {
+  console.log('HTTP status: ' + response.statusCode);
+});
+client_request.end(message);
+```
+
+
+### request.setTimeout(ms[, callback])
 
 * `ms` {number}
-* `cb` {Function}
+* `callback` {Function} The callback function registered for the `'timeout'` event.
 
-Registers cb for 'timeout' event and set socket's timeout value to ms. This event will be triggered by the underlying socket's 'timeout' event.
+Registers `callback` for 'timeout' event and set socket's timeout value to ms. This event will be triggered by the underlying socket's `'timeout'` event.
 
-If cb is not provided, the socket will be destroyed automatically after timeout.
-If you provides cb, you should handle the socket's timeout.
+If `callback` is not provided, the socket will be destroyed automatically after timeout.
+If `callback` is provied, the method should handle the socket's timeout.
 
 ### request.write(data[, callback])
-* `data` {Buffer | string}
+* `data` {Buffer | string} Data to be sent.
 * `callback` {Function}
 
 Sends `data` as a request body. `callback` will be called when data is flushed.
 
 
+**Example**
+
+```js
+var http = require('http');
+
+var message = "This is the data";
+var options = {
+  method: 'POST',
+  port: 8383,
+  path: '/',
+  headers: {'Content-Length': message.length},
+};
+
+var client_request = http.request(options);
+client_request.write(message);
+client_request.end();
+```
+
 ## Class: http.IncomingMessage
 
-This object is created internally and returned to the callback in http.request(). It represents the response sent by a server to a request.
+This object is created internally and returned to the callback for the http.ClientRequest `'response'` event and
+for the `'request'` event in the http.Server class.
+In case of the `http.ClientRequest` class this `IncomingMessage` will represent the response sent by a server for the given request.
+In case of the `http.Server` class this will represent the request sent by a client for the server.
 
-http.IncomingMessage inherits [`Stream.readable`](IoT.js-API-Stream.md). See it's documentation to read incoming data from an HTTP request. Notable events are `'data'` (fired when there is data to read), `'close'`, `'end'` (Request has ended) and the method `readable.read()`.
+http.IncomingMessage inherits [`Stream.readable`](IoT.js-API-Stream.md).
+See it's documentation to read incoming data from an HTTP request.
+Notable events are `'data'` (fired when there is data to read), `'close'`, `'end'` (Request has ended) and the method `readable.read()`.
 
 
 ### Event: 'close'
 When underlying connection is closed, 'close' event is emitted.
 
+### Event: 'data'
+Event callback arguments:
+* `chunk` {Buffer} the buffer containing the data.
+
+Raised when there is data to be processed from the underlying socket.
+It is highly possible that this chunk of data is not the whole data,
+thus if the developer needs the whole data in one, each chunk must be
+stored. (See the example for a naive approach.)
+
+The HTTP headers are already parsed before this event is triggered.
+
+Please note that the total size of the data could be bigger
+than the memory available on the device where the code is running.
+
+
+**Example**
+
+```js
+var console = require('console');
+var http = require('http');
+
+var options = {
+  host: 'localhost',
+  port: 8081,
+  method: 'GET',
+  path: '/'
+};
+var client_request = http.request(options, function(response) {
+  var parts = [];
+  response.on('data', function(chunk) {
+    parts.push(chunk);
+  });
+  response.on('end', function() {
+    var body = Buffer.concat(parts);
+    console.log(body.toString());
+  });
+});
+client_request.end();
+```
+
 ### Event: 'end'
 This event is fired when no more data to be received.
-
+At this point it is safe to assume all data was received from the other end.
 
 ### message.headers
-HTTP header object.
+A JavaScript object containing all HTTP headers sent by the other end.
 
 ### message.method
 Requests method as `string`
 
+### message.httpVersion
+The HTTP version sent by the client. One of the following value: `'1.1'` or `'1.0'`.
+
 ### message.socket
-Underlying socket
+Underlying network socket (`net.Socket`).
 
 ### message.statusCode
 HTTP response status code as `number` of 3-digit.
 
-### message.statusMessage
-HTTP response status message as `string`
-
 ### message.url
-Requests URL as `string`
+Request URL as `string`. Only contains the URL present in the HTTP request.
+
+Note: only valid if the `IncomingMessage` was constructed by a `http.Server`.
+
+**Example**
+
+If the HTTP request is the following:
+
+```
+GET /page/1?data=a HTTP/1.1 \r\n
+Accept: text/html\r\n
+\r\n
+```
+
+the `message.url` will be: `/page/1?data=a`.
+
+### message.statusMessage
+HTTP response status message as `string`.
 
 ### message.setTimeout(ms, cb)
 
@@ -338,3 +544,147 @@ Requests URL as `string`
 * `cb` {Function}
 
 Registers cb for 'timeout' event set socket's timeout value to ms. This event will be triggered by the underlying socket's 'timeout' event.
+
+
+## Class: http.ServerResponse
+
+Created internally when the `'request'` event is triggered by the `http.Server` class and
+represents the response sent by the server to a client.
+
+### Event: 'close'
+When underlying connection is closed, 'close' event is emitted.
+
+### Event: 'end'
+This event is fired when no more data to be sent.
+
+### Event: 'finish'
+This event is emitted when the response has been sent. It does not guarantee that client has received data yet.
+
+
+### response.end([data][, callback])
+* `data` {Buffer | string} Data which should be sent.
+* `callback` {Function}
+
+Finishes sending the response.
+
+If `data` is provided, it sends `data` first, and finishes.
+If `callback` is specified, it is called when the response stream is finished.
+
+The method should be called to correctly finish up a response.
+Any method which sets headers must be called before this method and before any `write` calls.
+
+**Example**
+
+```js
+var console = require('console');
+var http = require('http');
+
+var server = http.createServer(function(request, response) {
+  console.log('Request for path: ' + request.url);
+
+  var message = '<h1>Hello</h1>';
+
+  response.setHeader('Content-Type', 'text/html');
+  response.setHeader('Content-Length', message.length);
+  response.writeHead(200);
+  response.end(message);
+});
+
+var port = 8081
+server.listen(port, function() {
+  console.log('HTTP server listening on port: ' + port);
+});
+```
+
+### response.getHeader(name)
+* `name` {string} Case-sensitive HTTP header field name.
+
+Returns the value of the `name` HTTP header field.
+
+### response.removeHeader(name)
+* `name` {string} Case-sensitive HTTP header field name.
+
+Remove the HTTP header which has the `name` field name.
+HTTP headers can not be modified after the first `write`, `writeHead` or `end` method call.
+
+### response.setHeader(name, value)
+* `name` {string} The name of the HTTP header field to set.
+* `value` {string} The value of the field.
+
+Sets response's header field(`name`) to `value`. If the field exists, it overwrites the existing value.
+HTTP headers can not be modified after the first `write`, `writeHead` or `end` method call.
+
+### response.setTimeout(ms, cb)
+
+* `ms` {number}
+* `cb` {Function}
+
+Registers cb for 'timeout' event and set socket's timeout value to ms. This event will be triggered by the underlying socket's 'timeout' event.
+
+### response.write(data[, callback])
+* `data` {Buffer | string}
+* `callback` {Function}
+
+Sends `data` as a response body. `callback` will be called when data is flushed.
+
+It is advised to set at least the `Content-Length` HTTP header field correctly before
+any `write` calls. This is so the client could properly handle the server response.
+
+After a `write` method was called there is no possibility to change any headers.
+
+**Example**
+
+```js
+var console = require('console');
+var http = require('http');
+
+var server = http.createServer(function(request, response) {
+  console.log('Request for path: ' + request.url);
+
+  var message = '<h1>Hello</h1>';
+
+  response.setHeader('Content-Type', 'text/html');
+  response.setHeader('Content-Length', message.length);
+  response.writeHead(200);
+  response.write(message);
+  response.end();
+});
+
+var port = 8081
+server.listen(port, function() {
+  console.log('HTTP server listening on port: ' + port);
+});
+```
+
+### response.writeHead(statusCode[, statusMessage][, headers])
+* `statusCode` {number}
+* `statusMessage` {string} Optional. If not set the HTTP status message will be inferred from the status code.
+* `headers` {Object} Optional. An object containing HTTP header field names and values.
+
+Sets response status code, the status message and configures a set of HTTP
+header values.
+
+**Example**
+
+```js
+var console = require('console');
+var http = require('http');
+
+var server = http.createServer(function(request, response) {
+  console.log('Request for path: ' + request.url);
+
+  var message = '<h1>Hello</h1>';
+
+  response.writeHead(200, 'OK', {
+    'Content-Type': 'text/html',
+    'Content-Length': message.length,
+  });
+  response.write(message);
+  response.end();
+});
+
+var port = 8081
+server.listen(port, function() {
+  console.log('HTTP server listening on port: ' + port);
+});
+```
index 941cca702553168d8fd4d4158b35f7c37a448a50..6a77795121d2ac44be20d2eec6acc39ed405c5a6 100644 (file)
 
 IoT.js provides HTTPS to support HTTPS clients enabling users to send HTTPS requests easily.
 
+### https.createServer([options][, requestListener])
+* `options` {Object} Accepts the same `options` as [tls.createServer](IoT.js-API-TLS.md#tlscreateserveroptions-secureconnectionlistener) and [http.createServer](IoT.js-API-HTTP.md#httpcreateserverrequestlistener) methods.
+* `requestListener` {Function}
+  * request {http.IncomingMessage}
+  * response {http.ServerResponse}
+* Returns: {https.Server}
+
+To create a server the certificates should be specified via the `options` object.
+
+The `requestListener` is a function which is automatically added to the `'request'` event.
+
+**Example**
+
+```js
+var options = {
+  key: fs.readFileSync('server.key'),
+  cert: fs.readFileSync('server.cert')
+};
+var server = https.createServer(options, function(request, response) {
+  ...
+});
+```
+
+
 ### https.request(options[, callback])
 * `options` {Object}
   * `host` {string} A domain name or IP address of the server to issue the request to. **Default:** 'localhost'.
   * `hostname` {string} Alias for host.
-  * `port` {number} Port of remote server. **Default:** 80.
+  * `port` {number} Port of remote server. **Default:** 443.
   * `method` {string} A string specifying the HTTPS request method. **Default:** 'GET'.
   * `path` {string} Request path. **Default:** '/'. Should include query string if any. E.G. '/index.html?page=12'. An exception is thrown when the request path contains illegal characters. Currently, only spaces are rejected but that may change in the future.
   * `headers` {Object} An object containing request headers.
@@ -29,8 +53,8 @@ IoT.js provides HTTPS to support HTTPS clients enabling users to send HTTPS requ
   * `key` {string} Optional file path to private keys for client cert in PEM format.
   * `rejectUnauthorized` {boolean} Optional Specify whether to verify the Server's certificate against CA certificates. WARNING - Making this `false` may be a security risk. **Default:** `true`
 * `callback` {Function}
-  * `response` {https.IncomingMessage}
-* Returns: {https.ClientRequest}
+  * `response` {http.IncomingMessage}
+* Returns: {http.ClientRequest}
 
 Example:
 ```javascript
@@ -53,7 +77,7 @@ Note that in the example `req.end()` was called. With `https.request()` one must
 * `options` {Object}
   * `host` {string} A domain name or IP address of the server to issue the request to. **Default:** 'localhost'.
   * `hostname` {string} Alias for host.
-  * `port` {number} Port of remote server. **Default:** 80.
+  * `port` {number} Port of remote server. **Default:** 443.
   * `method` {string} A string specifying the HTTPS request method. **Default:** 'GET'.
   * `path` {string} Request path. **Default:** '/'. Should include query string if any. E.G. '/index.html?page=12'. An exception is thrown when the request path contains illegal characters. Currently, only spaces are rejected but that may change in the future.
   * `headers` {Object} An object containing request headers.
@@ -63,8 +87,8 @@ Note that in the example `req.end()` was called. With `https.request()` one must
   * `key` {string} Optional file path to private keys for client cert in PEM format.
   * `rejectUnauthorized` {boolean} Optional Specify whether to verify the Server's certificate against CA certificates. WARNING - Making this `false` may be a security risk. **Default:** `true`
 * `callback` {Function}
-  * `response` {https.IncomingMessage}
-* Returns: {https.ClientRequest}
+  * `response` {http.IncomingMessage}
+* Returns: {http.ClientRequest}
 
 Same as `https.request` except that `https.get` automatically call `req.end()` at the end.
 
@@ -78,20 +102,3 @@ https.get({
 ...
 });
 ```
-
-
-### https.METHODS
-A list of HTTPS methods supported by the parser as `string` properties of an `Object`.
-
-
-## Class: https.ClientRequest
-
-This object is created internally and returned from https.request(). It represents an in-progress request whose header has already been queued.
-
-See also: [http.ClientRequest](IoT.js-API-HTTP.md#class-httpclientrequest)
-
-## Class: https.IncomingMessage
-
-This object is created internally and returned to the callback in https.request(). It represents the response sent by a server to a request.
-
-See also: [http.IncomingMessage](IoT.js-API-HTTP.md#class-httpincomingmessage)
index 22270971899bf3a1f5ab0a05dd55c876ff1ec36e..a2a4908b83d258d3ca0855cc7ce0db302ddb10f4 100644 (file)
@@ -1,15 +1,14 @@
 ### Platform Support
 
-The following chart shows the availability of each TLS module API function on each platform.
+The following chart shows the availability of each MQTT module API function on each platform.
 
 |  | Linux<br/>(Ubuntu) | Tizen<br/>(Raspberry Pi) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) | TizenRT<br/>(Artik053) |
 | :---: | :---: | :---: | :---: | :---: | :---: |
-| mqtt.getClient  | O | X | X | X | X | X |
-| mqtt.publish  | O | X | X | X | X | X |
-| mqtt.subscribe | O | X | X | X | X | X |
-| mqtt.unsubscribe | X | X | X | X | X | X |
-| mqtt.ping | O | X | X | X | X | X |
-| mqtt.connect | O | X | X | X | X | X |
+| mqtt.connect | O | O | O | X | O |
+| mqtt.end | O | O | O | X | O |
+| mqtt.publish  | O | O | O | X | O |
+| mqtt.subscribe | O | O | O | X | O |
+| mqtt.unsubscribe | O | O | O | X | O |
 
 # MQTT
 
@@ -30,11 +29,13 @@ Topics can be wildcarded and they also can be structured into multiple levels. T
 ## Class: MQTTClient
 The `MQTTClient` can subscribe or publish data to a broker. It sends data over a `net.socket`.
 
-### mqtt.getClient(options)
+### mqtt.connect([url], [options], [callback])
+- `url` {string} host name optionally prefixed by `mqtt://` or `mqtts://`.
 - `options` {Object}
-    -  `clientId` {Buffer | string} Optional. The broker identifies each client by its `clientId`. If not specified, a randomly generated `clientId` is created.
-    -  `host` {Buffer | string} The address of the broker.
-    -  `port` {number} The port of the broker.
+    - `clientId` {Buffer | string} Optional. The broker identifies each client by its `clientId`. If not specified, a randomly generated `clientId` is created.
+    - `host` {Buffer | string} The address of the broker.
+    - `port` {number} The port of the broker.
+    - `socket` {net.Socket | TLSSocket} If a `TLSSocket` is given for secure communication it is the user's responsibility to connect it to establish the TLS connection first. Otherwise the client automatically connects the socket to the server.
     - `username` {Buffer | string} Optional. Use username when onnecting to a broker.
     - `password` {Buffer | string} Optional. Use password authentication when connecting to a broker.
     - `keepalive` {number} Keepalive time in seconds. If no data is sent on the connection in the given time window the broker disconnects the client.
@@ -42,63 +43,38 @@ The `MQTTClient` can subscribe or publish data to a broker. It sends data over a
     - `qos` {number} If `will` is set to `true`, the message will be sent with the given QoS.
     - `topic` {Buffer | string} Only processed when `will` is set to `true`. The topic the `message` should be sent to.
     - `message` {Buffer | string} Only processed when `will` is set to `true`. The message to be sent to the broker when connecting.
+- `callback` {function} the function which will be executed when the client successfuly connected to the broker.
 
-Returns an MQTTClient.
+Returns with an MQTTClient object and starts connecting to a broker. Emits a `connect` event after the connection is completed.
 
-### mqtt.connect(callback)
-- `callback` {function} The function will be executed when the client successfuly connected to the broker.
-
-Connects the client to a broker. Emits a `connect` event.
 
 **Example**
 ```js
 var mqtt = require('mqtt');
 
 var opts = {
-    host: '127.0.0.1',
-    port: 443,
-    keepalive: 10,
-    clientId: 'IoT.js Client',
+  port: 443,
+  keepalive: 10,
+  clientId: 'IoT.js Client',
 }
 
-var client = mqtt.getClient(opts);
-client.connect(function () {
-    client.disconnect();
+var client = mqtt.connect('mqtt://127.0.0.1', opts, function () {
+  client.end();
 });
 ```
 
-### mqtt.disconnect()
-Disconnects the client from the broker.
-
-### mqtt.ping()
-Sends a ping request to the server. If the server doesn't respond within 3 seconds, the client closes the connection. Emits a `pingresp` event if the server responded.
-
-**Example**
-```js
-var mqtt = require('mqtt');
-
-var opts = {
-    host: '127.0.0.1',
-    port: 443,
-    keepalive: 10,
-    clientId: 'IoT.js Client',
-}
-
-var client = mqtt.getClient(opts);
-client.connect(function () {
-    client.ping();
-});
+### mqtt.end([force])
+- `force` {boolean} force network connection abort
 
-client.on('pingresp', function() {
-  client.disconnect();
-});
-```
+Disconnects the client from the broker.
 
-### mqtt.subscribe(options)
+### mqtt.subscribe(topic, [options], [callback])
+- `topic` {Buffer | string} topic to subscribe to
 - `options` {Object}
-    - `topic` {Buffer | string} The topic the client subscribes to.
     - `qos` {number} Optional. Defaults to 0.
     - `retain` {boolean} Optional. If retain is `true` the client receives the messages that were sent to the desired `topic` before it connected. Defaults to `false`.
+- `callback` {function} the function which will be executed when the subscribe is completed.
+
 
 The client subscribes to a given `topic`. If there are messages available on the `topic` the client emits a `data` event with the message received from the broker.
 
@@ -107,40 +83,47 @@ The client subscribes to a given `topic`. If there are messages available on the
 var mqtt = require('mqtt');
 
 var opts = {
-    host: '127.0.0.1',
-    port: 443,
-    keepalive: 10,
-    clientId: 'IoT.js Client',
+  host: '127.0.0.1',
+  port: 443,
+  keepalive: 10,
+  clientId: 'IoT.js Client',
 }
 
 var subscribe_opts {
-  topic: 'hello/#/iotjs',
   retain: false,
   qos: 2
 }
 
-var client = mqtt.getClient(opts);
-client.connect(function () {
-    client.subscribe(subscribe_opts);
+var client = mqtt.connect(opts, function () {
+  client.subscribe('hello/#/iotjs', subscribe_opts, function(error) {
+    if (error) {
+      console.log('Subscribe is failed');
+    } else {
+      console.log('Subscribe is successfully completed');
+    }
+  });
 });
 
-client.on('data', function(data) {
-  console.log('I received something: ' + data.toString());
+client.on('message', function(data) {
+  console.log('I received something: ' + data.message.toString());
 });
 ```
 
-### mqtt.unsubscribe(topic)
-- `options` {Buffer | string} The topic to unsubscribe from.
+### mqtt.unsubscribe(topic, [callback])
+- `topic` {Buffer | string} topic to unsubscribe from
+- `callback` {function} the function which will be executed when the unsubscribe is completed.
 
 Unsubscribes the client from a given topic. If QoS was turned on on the subscription the remaining packets will be sent by the server.
 
 
-### mqtt.publish(options)
+### mqtt.publish(topic, message, [options], [callback])
+- `topic` {Buffer | string} topic to publish to
+- `message` {Buffer | string} message to send
 - `options` {Object}
-    - `topic` {Buffer | string} The topic to send the `message` to.
-    - `message` {Buffer | string} The message to be sent.
     - `qos` {number} Optional. Defaults to 0.
     - `retain` {boolean} Optional. If retain is `true` the broker stores the message for clients subscribing with retain `true` flag, therefore they can receive it later.
+- `callback` {function} the function which will be executed when the publish is completed
+
 
 Publishes a `message` to the broker under the given `topic`.
 
@@ -149,22 +132,16 @@ Publishes a `message` to the broker under the given `topic`.
 var mqtt = require('mqtt');
 
 var opts = {
-    host: '127.0.0.1',
-    port: 443,
-    keepalive: 10,
-    clientId: 'IoT.js Client',
-}
-
-var publish_opts {
-  topic: 'hello/#/iotjs',
-  message: 'MQTT now works!',
-  retain: false,
-  qos: 1
+  host: '127.0.0.1',
+  port: 443,
+  keepalive: 10,
+  clientId: 'IoT.js Client',
 }
 
-var client = mqtt.getClient(opts);
-client.connect(function () {
-    client.publish(publish_opts);
+var client = mqtt.connect(opts, function () {
+  client.publish('hello/#/iotjs', 'Hello MQTT clients!', { qos:1 }, function() {
+    console.log('Message has been published');
+  });
 });
 ```
 
@@ -184,15 +161,3 @@ When data is received from the server a `message` event is emitted with a `data`
    - `topic`: The topic the message was sent from.
    - `qos`: The QoS level the message was sent with.
    - `packet_id`: The id of the packet if QoS was enabled.
-
-### `pingresp`
-Emitted when we receive a ping response from the server.
-
-### `puback`
-`puback` is emitted if the server has successfully received the QoS 1 packet sent with `publish`.
-
-### `pubcomp`
-If a QoS level 2 package has successfully arrived a `pubcomp` is emitted.
-
-### `suback`
-If a subscription was accepted by the broker to a topic, a `suback` event is emitted.
index da3362520033bb6e0b8e51522a9365ffb54f4428..2d6a892e39810240937198f34e974c85a37c2a91 100644 (file)
@@ -270,6 +270,116 @@ console.log(readable.read());
 ```
 
 
+### readable.pipe(destination[, options])
+* `destination` {Writable|Duplex}
+* `options`
+  * `end` {bool} **Default: `true`**
+* returns: {Writable|Duplex}
+
+Attaches a Writable or Duplex stream to the Readable. Automatically
+switches the Readable stream into flowing mode and pushes all of its
+data into the attached Writable.
+
+**Example**
+```js
+var stream = require('stream');
+var Readable = stream.Readable;
+var Writable = stream.Writable;
+
+var source = new Readable();
+var dest = new Writable();
+
+dest._write = function(chunk, callback, onwrite) {
+  console.log('dest received: ', chunk.toString());
+};
+dest._readyToWrite();
+
+source.pipe(dest);
+source.push('hello'); // the dest._write function will print the data
+```
+
+It is also possible to attach multiple Writable streams to a single
+Readable stream.
+The `readable.pipe()` method returns a reference to the `destination` stream,
+making it possible to set up a chain of piped streams
+(only if `destination` is Duplex).
+
+**Example**
+```js
+var stream = require('stream');
+var Readable = stream.Readable;
+var Writable = stream.Writable;
+
+var source = new Readable();
+var dest = new Duplex();
+var dest2 = new Duplex();
+
+dest._write = function(chunk, callback, onwrite) {
+  console.log('dest received: ', chunk.toString());
+};
+dest._readyToWrite();
+
+dest2._write = function(chunk, callback, onwrite) {
+  console.log('dest2 received: ', chunk.toString());
+};
+dest2._readyToWrite();
+
+source.pipe(dest).pipe(dest2);
+source.push('hello'); // dest and dest2 will receive and print the data
+```
+
+By default, the `end()` method of the `destination` stream is called when the
+Readable emits `end`. This behavior can be disabled by passing the `end`
+option as `false` to the `Readable.pipe()` method.
+
+Note: in case of a stream error, the attached streams will NOT be closed
+automatically. If a stream error occurs, each of the attached streams must
+be closed manually.
+
+
+### readable.unpipe([destination])
+* `destination` {Writable|Duplex}
+* returns: `this`
+
+Detaches a previously attached stream from the Readable.
+If the optional `destination` argument is not specified, all attached streams
+will be detached.
+If `destination` is specified but there is no pipe set up for it, then the
+method simply returns and does nothing.
+
+**Example**
+```js
+var stream = require('stream');
+var Readable = stream.Readable;
+var Writable = stream.Writable;
+
+var source = new Readable();
+var dest = new Writable();
+
+dest._write = function(chunk, callback, onwrite) {
+  console.log('dest received: ', chunk.toString());
+};
+dest._readyToWrite();
+
+source.pipe(dest);
+source.push('hello'); // the dest._write function will print the data
+source.unpipe(dest); // source.unpipe() has the same effect in this case
+source.push(world); // dest will not receive the data anymore
+```
+
+Note: if multiple streams are piped together in a chain, unpiping the first one
+from the readable will not unpipe the rest of them.
+
+**Example**
+```js
+source.pipe(dest).pipe(dest2).pipe(dest3).pipe(dest4);
+// ... some code ...
+source.unpipe(dest);
+// dest will no longer be piped to source, but dest2 will still be
+// piped to dest, etc
+```
+
+
 # Class: Stream.Writable
 
 Writable stream is an abstraction for a *destination*
index a1e800389dd1277ca541271f5fd10f527992b82c..d0b5534ab762a368a3de6398e9fb970182d5091f 100644 (file)
@@ -4,44 +4,40 @@ The following chart shows the availability of each TLS module API function on ea
 
 |  | Linux<br/>(Ubuntu) | Tizen<br/>(Raspberry Pi) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) | TizenRT<br/>(Artik053) |
 | :---: | :---: | :---: | :---: | :---: | :---: |
-| tls.connect  | X | O | O | O | O | O |
-| tls.write  | X | O | O | O | O | O |
-| tls.pause | X | O | O | O | O | O |
-| tls.end | X | O | O | O | O | O |
-| tls.resume | X | O | O | O | O | O |
-| tls.pause | X | O | O | O | O | O |
+| tls.connect             | O | O | O | O | O | O |
+| tls.createServer        | O | O | O | O | O | O |
+| tls.createSecureContext | O | O | O | O | O | O |
+| tls.Server              | O | O | O | O | O | O |
+| tls.TLSSocket           | O | O | O | O | O | O |
+| tls.TLSSocket.write     | O | O | O | O | O | O |
+| tls.TLSSocket.pause     | O | O | O | O | O | O |
+| tls.TLSSocket.end       | O | O | O | O | O | O |
+| tls.TLSSocket.resume    | O | O | O | O | O | O |
+| tls.TLSSocket.pause     | O | O | O | O | O | O |
+
+As even a couple of sockets/servers/requests require a considerable size of memory, on NuttX/STM32F4-Discovery and TizenRT/Artik053
+the number of such sockets are limited.
 
 # TLS
 
 Transport Layer Security makes secure communication over sockets possible.
 
-## Class: tls.TLSSocket
-The `TLSSocket` is responsible for all TLS negotiations and data encryption on a `net.Socket`.
-
-Just like `net.Socket` it uses a `Stream.duplex` interface.
-
-### new tls.TLSSocket(socket[,options])
-- `socket` {net.Socket | stream.Duplex}
-- `options` {Object}
-    - `session` {Buffer} Optional, `Buffer` instance containing a TLS session.
-
-Note: `tls.connect()` must be used to create the socket.
-
 ### tls.connect(options[,callback])
-- `options` {Object}
-    - `host` {string} Host the client should connect to, defaults to 'localhost'.
-    - `port` {number} Port the client should connect to.
-    - `socket` {stream.Duplex} Optional, typically an instance of `net.Socket`. If this options is specified, host and port are ignored. The user passing the options is responsible for it connecting to the server. `tls.connect` won't call `net.connect` on it.
-    - `rejectUnauthorized` {boolean} Whether the server certificate should be verified against the list of supplied CAs. An `error` event is emitted if verifications fails; `err.code` contains the MbedTLS error code. Defaults to `false`. NOT READY
-    - `servername` {string} Server name for the SNI (Server name Indication) TLS extension. NOT READY
-    - `session` {Buffer} A `Buffer` containing a TLS session. NOT READY
-    - `minDHSize` {number} The minimum size of the DH parameter in bits to accept a TLS connection. If a server offers a DH parameter with a size less than specified, the TLS connection is destroyed and an error is thrown. Defaults to `1024`.
-    - `lookup` {Function} Custom lookup. Defaults to `dns.lookup()`.
-- `callback` {Function} The callback function will be added as a listener for the `secureConnect` event.
+* `options` {Object}
+    * `host` {string} Host the client should connect to, defaults to 'localhost'.
+    * `port` {number} Port the client should connect to.
+    * `socket` {stream.Duplex} Optional, typically an instance of `net.Socket`. If this options is specified, host and port are ignored. The user passing the options is responsible for it connecting to the server. `tls.connect` won't call `net.connect` on it.
+    * `rejectUnauthorized` {boolean} Whether the server certificate should be verified against the list of supplied CAs. An `error` event is emitted if verifications fails; `err.code` contains the MbedTLS error code. Defaults to `false`. NOT READY
+    * `servername` {string} Server name for the SNI (Server name Indication) TLS extension. NOT READY
+    * `session` {Buffer} A `Buffer` containing a TLS session. NOT READY
+    * `minDHSize` {number} The minimum size of the DH parameter in bits to accept a TLS connection. If a server offers a DH parameter with a size less than specified, the TLS connection is destroyed and an error is thrown. Defaults to `1024`.
+    * `lookup` {Function} Custom lookup. Defaults to `dns.lookup()`.
+* `callback` {Function} The callback function will be added as a listener for the `secureConnect` event.
 
 Returns a `tls.TLSSocket` object.
 
 **Example**
+
 ```js
 var tls = require('tls');
 
@@ -58,15 +54,16 @@ var socket = tls.connect(opts, function() {
 ```
 
 ### tls.connect(port[,host][,options][,callback])
-- `port` {number} Port the client should connect to.
-- `host` {string} Host the client should connect to, defaults to 'localhost'.
-- `options` {Object} See `tls.connect()`.
-- `callback` {Function} See `tls.connect()`.
+* `port` {number} Port the client should connect to.
+* `host` {string} Host the client should connect to, defaults to 'localhost'.
+* `options` {Object} See `tls.connect()`.
+* `callback` {Function} See `tls.connect()`.
 
 Same as tls.connect() except that port and host can be provided as arguments instead of options.
 A port or host option, if specified, will take precedence over any port or host argument.
 
 **Example**
+
 ```js
 var tls = require('tls');
 
@@ -76,6 +73,97 @@ var socket = tls.connect(443, 'localhost', function() {
 });
 ```
 
+### tls.createServer([options][, secureConnectionListener])
+* `options` {object} Accepts the same options as the `tls.Server()` and `tls.createSecureContext()`.
+* `secureConnectionListener` {Function}
+  * `socket` {tls.TLSSocket} The connected TLSSocket.
+* Returns {tls.Server}
+
+Create a TLS Server. Behaves the same way as the `new tls.Server(options, secureConnectionListener)`
+call.
+
+**Example**
+
+```js
+
+var fs = require('fs');
+var tls = require('tls');
+var options = {
+  key: fs.readFileSync('server.key'),
+  cert: fs.readFileSync('server.crt')
+};
+var server = tls.createServer(options, function(socket) {
+  console.log('got connection');
+  ...
+});
+
+server.listen(8081);
+```
+
+
+### tls.createSecureContext([options])
+* `options` {object}
+  * `ca` {string | Buffer} Optional trusted CA certificates. No default is provided.
+  * `cert` {string | Buffer} Cert chains in PEM format.
+  * `key` {string | Buffer} Private keys in PEM format.
+* Returns {Object}
+
+The method returns a special object containing the tls context and credential information.
+
+## Class: tls.Server
+
+A server object repesenting a TLS server. Based on the `net.Server`.
+All events, methods and properties are inherited from the `net.Server`.
+
+### new tls.Server([options][, secureConnectionListener])
+
+* `options` {object} Options for the TLS connection.
+  * `secureContext` {object} An special object containing the tls credential information.
+    This should be only created via a `tls.createSecureContext()` call if needed. If not provided
+    a secureContext will be created automatically, using the `options` object. No default value is provided.
+  * Additonal options are from `tls.createSecureContext()`.
+* `secureConnectionListener` {Function}
+  * `socket` {tls.TLSSocket}
+* Returns {tls.Server}
+
+Creates new `tls.Server` object. The `secureConnectionListener` method is automatically set
+as a listener for the `'secureConnection'` event.
+
+To correctly create a TLS Server the server certificates should be provided in the `options`
+object.
+
+**Example**
+
+```js
+var fs = require('fs');
+var tls = require('tls');
+var options = {
+  key: fs.readFileSync('server.key'),
+  cert: fs.readFileSync('server.crt')
+};
+var server = new tls.Server(options, function(socket) {
+  console.log('got connection');
+  ...
+});
+
+server.listen(8081);
+```
+
+## Class: tls.TLSSocket
+The `TLSSocket` is responsible for all TLS negotiations and data encryption on a `net.Socket`.
+
+Just like `net.Socket` it uses a `Stream.duplex` interface.
+
+### new tls.TLSSocket(socket[,options])
+* `socket` {net.Socket | stream.Duplex}
+* `options` {Object}
+  * `isServer` {boolean} The TLSSocket must know if it represents the server or client side of the connection. Default: `false`.
+  * `secureContext` {Object} The TLS context object. If none provided one will be created with the `tls.createSecureContext` method
+    using the given `options` object.
+* Returns {tls.TLSSocket}
+
+Creates a new TLSSocket object for an existing TCP socket.
+
 ### tlsSocket.address()
 Returns an object containing the bound address, family name, and port of the socket.`{port: 443, family: 'IPv4', address: '127.0.0.1'}`
 
index ab572105c00432eac2a270c0220e7b4337f44b8f..34b033cbb0568ee01000fef2fb68a944129dd4ce 100644 (file)
@@ -133,7 +133,7 @@ Closes the UART device synchronously.
 
 ### Event: 'data'
 * `callback` {Function}
-  * `data` {string} A string from the sender.
+  * `data` {Buffer} A data from the sender.
 
 **Example**
 
diff --git a/docs/api/IoT.js-API-WebSocket.md b/docs/api/IoT.js-API-WebSocket.md
new file mode 100644 (file)
index 0000000..5cf9296
--- /dev/null
@@ -0,0 +1,263 @@
+### Platform Support
+
+The following chart shows the availability of each WebSocket module API function on each platform.
+
+|  | Linux<br/>(Ubuntu) | Tizen<br/>(Raspberry Pi) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) | TizenRT<br/>(Artik053) |
+| :---: | :---: | :---: | :---: | :---: | :---: |
+| websocket.connect | O | O | O | X | O |
+| websocket.close | O | O | O | X | O |
+| websocket.ping | O | O | O | X | O |
+| websocket.send  | O | O | O | X | O |
+
+# WebSocket
+
+WebSocket provides full-duplex communication over a TCP connection. It is designed to work over HTTP ports 80 and 443.
+
+### Requirements
+WebSocket requires you to enable both the `TLS` and the `WebSocket` module. This can be done by compiling IoT.js with `--cmake-param=-DENABLE_MODULE_WEBSOCKET=ON`. Currently WebSocket only works if TLS is enabled as well.
+
+## Class: Websocket.Server
+Create a new Websocket server instance.
+
+### Websocket.Server(options[, callback])
+Create a new server instance. One of `port` or `server` must be provided or an error is thrown. An HTTP server is automatically created, started, and used if `port` is set. If `secure` is set TLS server is automatically created, started and used. The `tls` module is required or an error is thrown. To use an external HTTP/S server instead, specify only `server`. In this case the HTTP/S server must be started manually.
+
+- `options` {Object}
+  - `port` {Number}
+  - `host` {String} Optional. Defaults to `localhost`.
+  - `server` {Object} Optional.
+  - `path` {String} Optional. Defaults to `/`.
+  - `secure` {Boolean} Optional.
+  - `key` {String} Optional. (Required on `secure` server)
+  - `cert` {String} Optional. (Required on `secure` server)
+- `callback` {Function} Optional. The function which will be executed when the client successfully connected to the server.
+
+Emits a `connection` event when the connection is established.
+
+**Example**
+```js
+var websocket = require('websocket');
+
+var options = {
+  port: 9999
+}
+
+var server = new websocket.Server(options, Listener);
+
+function Listener(ws) {
+  console.log('Client connected: handshake done!');
+  ws.on('message', function (msg) {
+    console.log('Message received: %s', msg.toString());
+    ws.send(msg.toString(), {mask: true, binary: false}); //echo
+    server.close();
+  });
+  ws.on('ping', function (msg) {
+    console.log('Ping received: %s', msg.toString());
+  });
+  ws.on('close', function (msg) {
+    console.log('Client close :\n'
+      'Reason: ' + msg.reason + ' Code: ' + msg.code);
+  });
+  ws.on('error', function (msg) {
+    console.log('Error: %s', msg.toString());
+  });
+
+server.broadcast('Message to all clients', {mask: false, binary: false});
+};
+
+server.on('error', function (msg) {
+  console.log('Error: %s', msg.toString());
+});
+
+server.on('close', function (msg) {
+  console.log('Server close: \nReason: ' +
+              msg.reason + ' Code: ' + msg.code);
+});
+```
+
+**Example using http server**
+```js
+var websocket = require('websocket');
+var http = require('http');
+
+var httpserver = http.createServer().listen(9999);
+
+options = {
+  server: httpserver
+};
+
+var wss3 = new websocket.Server(options, Listener);
+
+function Listener(ws) {
+  console.log('Client connected: handshake done!');
+};
+```
+
+### server.address()
+
+Returns an object with `port`, `family`, and `address` properties specifying
+the bound address, the family name, and port of the server.
+
+**Example**
+```js
+var websocket = require('websocket');
+
+var options = {
+  port: 9999
+}
+
+var server = new websocket.Server(options, function(ws) {
+});
+
+console.log(server.address());
+```
+
+### server.close([reason], [code])
+You can specify a close message and a close code as well. More info on them can be read here: [https://tools.ietf.org/html/rfc6455#section-7.4.1](https://tools.ietf.org/html/rfc6455#section-7.4.1 "The WebSocket Protocol Status Codes")
+
+- `reason` {String} Optional. Defaults to `Connection successfully closed`.
+- `code` {Number} Optional. Defaults to `1000`.
+
+Close the Websocket server, terminate all clients and emit the `close` event.
+
+**Example**
+```js
+var websocket = require('websocket');
+
+var options = {
+  port: 9999
+}
+
+var server = new websocket.Server(options, Listener);
+
+function Listener(ws) {
+  console.log('Client connected: handshake done!');
+  server.close('Connection successfully closed', 1000);
+};
+```
+
+### server.broadcast(message [, options])
+You can specify a message that will be sent to every clients.
+The `mask` will specify whether the data frame should be masked or not.
+The `binary` will specify that if the data frame mode should be text or binary, default to text.
+More info on them can be read here: [https://tools.ietf.org/html/rfc6455#section-5.6](https://tools.ietf.org/html/rfc6455#section-5.6 "The WebSocket Protocol Data Frames")
+
+- `message` {String}
+- `options` {Object} Optional.
+  - `mask` {Boolean} Optional. Defaults to `true`.
+  - `binary` {Boolean} Optional. Defaults to `false`.
+
+Send message to all clients.
+
+**Example**
+```js
+var websocket = require('websocket');
+
+var options = {
+  port: 9999
+}
+
+var server = new websocket.Server(options, Listener);
+
+function Listener(ws) {
+  console.log('Client connected: handshake done!');
+};
+
+server.broadcast('Message to receive all client',
+                 {mask: true, binary: false});
+```
+
+### Event: 'connection'
+
+- `socket` {Websocket}
+
+Emitted when the handshake is complete.
+
+### Event: 'close'
+
+- `message` {Object}
+  - `reason` {String}
+  - `code` {Number}
+
+Emitted when the server close.
+
+### Event: 'error'
+
+- `error` {Error}
+
+Emmitted when an error occurs on the server.
+
+## Class: Websocket
+The `Websocket` client can simultaneously receive and send data. Both `net` and `TLS` sockets are supported, however the latter is recommended, since `websocket` itself doesn't provide a secure enough context to communicate sensitive data.
+
+### websocket.connect([host], [port], [path], [callback])
+Connects to a `websocket` server, host names can be prefixed with `ws://` or `wss://`.
+- `host` {string} Optional. Defaults to `localhost`.
+- `port` {number} Optional. Defaults to `80` if the `host` begins with `ws://` or `443` with `wss://`.
+- `path` {Buffer | string} Optional. Defaults to `/`. If given, the client connects to that `endpoint`.
+- `callback` {function} Optional. The function which will be executed when the client successfully connected to the server.
+
+Emits an `open` event when the connection is established.
+
+**Example**
+```js
+var ws = require('websocket');
+
+var my_websocket = new ws.Websocket();
+
+my_websocket.connect('wss://127.0.0.1', 443, '/my_endpoint', function() {
+  my_websocket.close('Successful connection', 1000);
+});
+
+```
+
+### websocket.close([message], [code], [callback])
+Closes the `websocket` connection with the server. You can specify a close `message` and a close `code` as well. More info on them can be read here: https://tools.ietf.org/html/rfc6455#section-7.4.1
+- `message` {Buffer | string} Optional. This `message` is sent to the server as a close message, mostly for explaining the status `code`.
+- `code` {number} Optional. The `code` indicates the reason why the `websocket` connection was closed. Defaults to 1000.
+- `callback` {function} Optional. The function will be executed when the `websocket` connection is closed.
+
+Emits a `close` event when the connection is closed.
+
+### websocket.ping([message], [mask], [callback])
+Sends a `ping` to the server. If there is no response in the next 30 seconds, the connection is closed.
+- `message` {Buffer | string} Optional. The `message` is used to identify the `ping` frame.
+- `mask` {boolean} Optional. Defaults to `false`. Sets to mask the `message` or not.
+- `callback` {function} Optional. The function to be executed when the server sends a response to the `ping`.
+
+**Example**
+```js
+my_websocket.ping('Ping frame 1', true, function(msg) {
+  console.log('Pong frame successfully received for frame ' + msg);
+});
+
+```
+
+### websocket.send([message], [options], [callback])
+Sends data to the server. It can be either `binary` or `utf8` data.
+- `message` {Buffer | string} The `message` to be sent to the server.
+- `options` {Object}
+  - `mask` {boolean} Optional. Defaults to `false`. If set, the `message` is masked.
+  - `binary` {boolean} Optional. Defaults to `false`. If set, the `message` is expected to be binary data.
+- `callback` {function} Optional. The function to be executed when the `frame` is successfully sent.
+
+**Example**
+```js
+my_websocket.send('My first WebSocket message!', {mask: true, binary: false}, function() {
+  console.log('The data was successfully written to the socket!');
+});
+```
+
+## Events
+
+### `close`
+Having closed the `websocket` connection, with the server, a `close` is emitted.
+
+### `error`
+If an `error` occurs, the `error` event is emitted, with the corresponding error message.
+
+### `message`
+The `message` event is emitted when the client receives data from the server.
+
+### `open`
+Emitted when the client established a `websocket` connection with the server.
index 9491b64a8696c2ca92ffbe1aa8bfc3d2158d965b..725fb78db6773d6573ff32a116d9d39155ebcca8 100644 (file)
@@ -23,10 +23,10 @@ You can also build release binary with;
 ./tools/build.py --buildtype=release
 ```
 
-## Parameters Candidates
-**NOTE: some parameters are not supported by current version of build.py**
+### Arguments of IoT.js
+The following arguments are related to the IoT.js framework.
 
---
+---
 #### `--buildtype`
 * `release` | `debug`
 
@@ -36,7 +36,7 @@ Specify whether build output will be for 'debug' or 'release'.
 ./tools/build.py --buildtype=release
 ```
 
---
+---
 #### `--builddir`
 
 Specify a directory where build outputs will be generated.
@@ -47,15 +47,7 @@ If given path is not exist, build.py will create it.
 ./tools/build.py --builddir=./build
 ```
 
---
-#### `--clean`
-With given this option, build.py will clear all the build directory before start new build.
-
-```
-./tools/build.py --clean
-```
-
---
+---
 #### `--buildlib`
 With given this option, build.py will generate IoT.js output as a library.
 
@@ -63,64 +55,87 @@ With given this option, build.py will generate IoT.js output as a library.
 ./tools/build.py ---buildlib
 ```
 
---
-#### `--profile`
-With given this option, build.py will use the specified profile for the build.
+---
+#### `--cmake-param`
+Specify CMake parameters for IoT.js.
+
+"cmake" command for IoT.js will be executed with the given parameter applied.
+
+If you have multiple parameters, supply it with multiple use of this option;
 
 ```
-./tools/build.py --profile=./profiles/minimal.profile
+./tools/build.py --cmake-param="..." --cmake-param="..."
 ```
 
---
-#### `--target-arch`
-* `arm` | `x86` | `i686` | `x86_64` | `x64`
+---
+#### `--compile-flag`
+Specify C compiler flags for IoT.js.
 
-Specify target architecture.
+If you have multiple compile flags, supply it with multiple use of this option;
+```
+./tools/build.py --compile-flag="..." --compile-flag="..."
+```
+
+---
+#### `--clean`
+With given this option, build.py will clear all the build directory before start new build.
 
 ```
-./tools/build.py --target-arch=arm
+./tools/build.py --clean
 ```
---
-#### `--target-os`
-* `linux` | `darwin` | `osx` | `nuttx`
 
-Specify target OS.
+---
+#### `--config`
+Specify build configuration file path.
 
 ```
-./tools/build.py --target-os=nuttx --target-arch=arm
+./tools/build.py --config=build.arm.nuttx.stm32f4dis.config
 ```
 
---
-#### `--target-board`
-* `stm32f4dis` | empty
+`build.default.config` file is in the source tree for default setting.
 
-Specify target board.
+If this option is not specified, `build.config` file will be applied. If the file does not exist, it will be copied from `build.default.config`.
+
+Parameters specified by the config file is applied, and then the parameters given by command line overwrite over the settings.
+
+If you need to apply the same set of parameters for each build, making your own config file and trigger build.py with the config file would be more convenient.
+
+---
+#### `-e, --experimental`
+Enable to build experimental features
 
 ```
-./tools/build.py --target-os=nuttx --target-arch=arm --target-board=stm32f4dis
+./tools/build.py --experimental
 ```
---
-#### `--cmake-param`
-Specify CMake parameters for IoT.js.
 
-"cmake" command for IoT.js will be executed with the given parameter applied.
+---
+#### `--external-include-dir`
+Specify external include directory for IoT.js.
 
-If you have multiple parameters, supply it with multiple use of this option;
+If you have multiple external include directoies, supply it with multiple use of this option;
+```
+./tools/build.py --external-include-dir="..." --external-include-dir="..."
+```
 
+---
+#### `--external-lib`
+Specify external library that will be linked with IoT.js.
+
+If you have multiple such libraries, supply it with multiple use of this option;
 ```
-./tools/build.py --cmake-param="..." --cmake-param="..."
+./tools/build.py --external-lib="libxxx"
 ```
 
---
-#### `--compile-flag`
-Specify C compiler flags for IoT.js.
+---
+#### `--external-modules`
+Specify the path of modules.json files which should be processed (format: path1,path2,...).
+See also: ["How to write a new module"](../devs/Writing-New-Module.md)
 
-If you have multiple compile flags, supply it with multiple use of this option;
 ```
-./tools/build.py --compile-flag="..." --compile-flag="..."
+./tools/build.py --external-modules=/home/iotjs/my-modules-directory
 ```
 
---
+---
 #### `--link-flag`
 Specify linker flags for IoT.js.
 
@@ -129,25 +144,100 @@ If you have multiple link flags, supply it with multiple use of this option;
 ./tools/build.py --link-flag="..." --link-flag="..."
 ```
 
---
-#### `--external-include-dir`
-Specify external include directory for IoT.js.
+---
+#### `--no-check-valgrind`
+Disable test execution with valgrind after build.
 
-If you have multiple external include directoies, supply it with multiple use of this option;
 ```
-./tools/build.py --external-include-dir="..." --external-include-dir="..."
+./tools/build.py --no-check-valgrind
 ```
 
---
-#### `--external-lib`
-Specify external library that will be linked with IoT.js.
+---
+#### `--no-init-submodule`
+With given this option, submoduls will not initialized before start build.
 
-If you have multiple such libraries, supply it with multiple use of this option;
 ```
-./tools/build.py --external-lib="libxxx"
+./tools/build.py --no-init-submodule
+```
+
+---
+#### `--no-parallel-build`
+With given this option, compilation process will not run in parallel. In other words, executes `make` without `-j` option.
+
+```
+./tools/build.py --no-parallel-build
 ```
 
---
+---
+#### `--nuttx-home`
+To build for nuttx os, nuttx home directory must be given.
+
+```
+./tools/build.py --target-os=nuttx --target-arch=arm --target-board=stm32f4dis --nuttx-home="..."
+```
+
+---
+#### `--profile`
+With given this option, build.py will use the specified profile for the build.
+See also: ["How to write a new module"](../devs/Writing-New-Module.md#profile)
+
+```
+./tools/build.py --profile=./profiles/minimal.profile
+```
+
+---
+#### `--run-test`
+* `full` | `quiet`
+
+Execute tests after build, optional argument specifies the level of output for the testrunner.
+
+```
+./tools/build.py --run-test=full
+```
+
+---
+#### `--sysroot`
+The location of the development tree root directory (sysroot). Must be compatible with used toolchain.
+
+```
+./tools/build.py --sysroot=/home/iotjs/sysroot-directory
+```
+
+---
+#### `--target-arch`
+* `arm` | `x86` | `i686` | `x86_64` | `x64` | `mips` | `noarch`
+
+Specify target architecture.
+
+```
+./tools/build.py --target-arch=arm
+```
+
+---
+#### `--target-board`
+* `artik10` | `artik05x` | `rpi2` | `rpi3` | `stm32f4dis` | empty
+
+Specify target board.
+
+```
+./tools/build.py --target-os=nuttx --target-arch=arm --target-board=stm32f4dis
+```
+
+---
+#### `--target-os`
+* `linux` | `darwin` | `osx` | `nuttx` | `tizen` | `tizenrt` | `openwrt`
+
+Specify target OS.
+
+```
+./tools/build.py --target-os=nuttx --target-arch=arm
+```
+
+
+### Arguments of JerryScript
+The following arguments are related to the JavaScript engine under the framework. For example they can change the enabled features of the ECMA-262 standard.
+
+---
 #### `--jerry-cmake-param`
 Specify CMake parameters for JerryScript.
 
@@ -155,7 +245,7 @@ Specify CMake parameters for JerryScript.
 
 If you have multiple parameters, supply it with multiple use of this option
 
---
+---
 #### `--jerry-compile-flag`
 Specify C compiler flags for JerryScript.
 
@@ -165,13 +255,15 @@ If you have multiple cflags, supply it with multiple use of this option
 ./tools/build.py --jerry-compile-flag="-DCONFIG_ECMA_LCACHE_DISABLE"
 ```
 
---
-#### `--jerry-link-flag`
-Specify linker flags for JerryScript.
+---
+#### `--jerry-debugger`
+Enable JerryScript debugger. See also ["Use JerryScript Debugger"](../devs/Use-JerryScript-Debugger.md).
 
-If you have multiple ldflags, supply it with multiple use of this option
+```
+./tools/build.py --jerry-debugger
+```
 
---
+---
 #### `--jerry-heaplimit`
 Specify object heap limit for JerryScript engine.
 
@@ -179,15 +271,15 @@ Specify object heap limit for JerryScript engine.
 ./tools/build.py --jerry-heaplimit=80
 ```
 
---
-#### `--jerry-memstat`
-Enable memstat of JerryScript engine.
+---
+#### `--jerry-heap-section`
+Specify the name of the JerryScript heap section.
 
 ```
-./tools/build.py --jerry-memstat
+./tools/build.py --jerry-heap-section=".ARM.__at_0x20000"
 ```
 
---
+---
 #### `--jerry-lto`
 With given this option, JerryScript will be built with LTO.
 
@@ -195,58 +287,38 @@ With given this option, JerryScript will be built with LTO.
 ./tools/build.py --jerry-lto
 ```
 
---
-#### `--no-init-submodule`
-With given this option, submoduls will not initialized before start build.
+---
+#### `--jerry-memstat`
+Enable memstat of JerryScript engine.
 
 ```
-./tools/build.py --no-init-submodule
+./tools/build.py --jerry-memstat
 ```
 
---
-#### `--no-check-tidy`
-With given this option, tidy checking will not performed.
+---
+#### `--jerry-profile`
+* `es5.1` | `es2015-subset | absolute path to a custom profile file`
 
-```
-./tools/build.py --no-check-tidy
-```
-
---
-#### `--no-parallel-build`
-With given this option, compilation process will not run in parallel. In other words, executes `make` without `-j` option.
-
-```
-./tools/build.py --no-parallel-build
-```
-
---
-#### `--nuttx-home`
-To build for nuttx os, nuttx home directory must be given.
+Specify the profile for JerryScript (default: es5.1). In JerryScript all of the features are enabled by default, so an empty profile file turns on all of the available ECMA features. See also the related [README.md](https://github.com/jerryscript-project/jerryscript/blob/master/jerry-core/profiles/README.md).
 
+E.g.:
+**/home/iotjs/my-jerry-profile.profile**
 ```
-./tools/build.py --target-os=nuttx --target-arch=arm --target-board=stm32f4dis --nuttx-home="..."
+# Turn off every ES2015 feature EXCEPT the arrow functions
+CONFIG_DISABLE_ES2015_BUILTIN
+CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
+CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS
+CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
 ```
 
---
-#### `--run-test`
-With given this option, unit test checking will be performed.
-
 ```
-./tools/build.py --run-test
+./tools/build.py --jerry-profile=/home/iotjs/my-jerry-profile.profile
 ```
 
---
-#### `--config`
-Specify build configuration file path.
+---
+#### `--js-backtrace`
+Enable/disable backtrace information of JavaScript code (default: ON in debug and OFF in release build).
 
 ```
-./tools/build.py --config=build.arm.nuttx.stm32f4dis.config
+./tools/build.py --js-backtrace
 ```
-
-`build.default.config` file is in the source tree for default setting.
-
-If this option is not specified, `build.config` file will be applied. If the file is not exist, it will be copied from `build.default.config`.
-
-Parameters specified by the config file is applied, and then the parameters given by command line overwrite over the settings.
-
-If you need to apply the same set of parameters for each build, making your own config file and trigger build.py with the config file would be more convenient.
\ No newline at end of file
index 1540bda91331419f4acd30d397978943b445dc0e..d5fba9df6f1756f707cb6dff1c0cbb50f9a91bdc 100644 (file)
@@ -103,3 +103,37 @@ make download ALL
 >Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
 >Bus 003 Device 005: ID 0403:6010 Future Technology Devices International, Ltd >FT2232C Dual USB-UART/FIFO IC
 >```
+
+
+#### 7. Run IoT.js
+
+You should use `minicom` to login to the device:
+
+```bash
+$ sudo minicom -s
+```
+The following changes are necessaries in the `Serial port setup` menu:
+
+```
+Serial Device         : /dev/<device-id>      # e.g. /dev/ttyUSB0
+Hardware Flow Control : No
+```
+After `Exit`, press an enter and the prompt should be available:
+
+```bash
+TASH>>
+```
+The following commands help to establish Internet connection on the device:
+
+```bash
+TASH>> wifi startsta
+TASH>> wifi join <ssid> <password>
+TASH>> ifconfig wl1 dhcp
+```
+Finally, the `iotjs` built-in command can be executed:
+
+```bash
+TASH>> iotjs
+Usage: iotjs [options] {FILE | FILE.js} [arguments]
+TASH>>
+```
diff --git a/docs/build/Build-for-ARTIK10-Tizen.md b/docs/build/Build-for-ARTIK10-Tizen.md
deleted file mode 100644 (file)
index f1e1efb..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-
-### 1. Tizen on ARTIK10 cross-compile
-
-#### Prerequisites
-
-* ARTIK10 with Tizen (https://wiki.tizen.org/wiki/Tizen_On_ARTIK)  
-* Tizen Studio with Native app development CLI tools.  
-  This is required to get rootstrap for Tizen (set of native libraries).  
-
-* arm-linux-gnueabi-gcc cross compiler (can be found in Tizen Studio / Native toolchain)  
-  Otherwise, you can install it on your PC.  
-```bash
-sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi
-```
-
-#### Building
-1. Make sure arm-linux-gnueabi-gcc is in path.
-2. Locate Tizen SDK. Default location is: ~/tizen-studio.  
-3. In platforms/tizen-3.0/mobile there should be compatible rootstrap (eg. mobile-3.0-device)  
-
-Compile:
-* Compile with rootstrap in case you use tizen 3.0 libraries.  
-``` bash
-tools/build.py \
-  --target-arch=arm --target-os=tizen --target-board=artik10 \
-  --compile-flag="--sysroot=~/tizen-studio/platforms/tizen-3.0/mobile/rootstraps/mobile-3.0-device.core/"
-```
-
-#### Testing
-Transfer iotjs binary and test file to the device:  
-``` bash
- $ sdb push ./build/arm-tizen/debug/bin/iotjs /home/owner/iotjs/
- $ sdb push ./test/run_pass/test_console.js /home/owner/iotjs/
-```
-
-Run the test:
-``` bash
-sdb shell
-$ cd /home/owner/iotjs
-$ ./iotjs test_console.js
-```
index 83491d17fc4d508ccbb7c00ac867da69fee2670d..f85fda65c10091f860e6bf99a06a1f126d0d3e7f 100644 (file)
@@ -111,7 +111,7 @@ You can set up IP using WiFi or Ethernet
 #### Install
 Transfer iotjs binary and test file to the device:
 ``` bash
-(ubuntu)$ sdb push  ~/GBS-ROOT/local/repos/tizen_unified_preview2/armv7l/RPMS/iotjs-1.0.0-0.armv7l.rpm /tmp
+(ubuntu)$ sdb push  ~/GBS-ROOT/local/repos/tizen_unified_m1/armv7l/RPMS/iotjs-1.0.0-0.armv7l.rpm /tmp
 (ubuntu)$ sdb push ./test/run_pass/test_console.js /home/owner/iotjs/
 (ubuntu)$ sdb root on
 (ubuntu)$ sdb shell
index f25ed043b453b6880c29942dc7abcefb749c10a1..7c0aea61f279dde3b0df352d2f1ffe82b2410c10 100644 (file)
@@ -52,8 +52,8 @@ $ brew install gcc-arm-none-eabi libusb minicom
 #### Supported Nuttx version
 |Repository|Tag Name|
 |----------|:------:|
-| nuttx | nuttx-7.19 |
-| app | nuttx-7.19 |
+| nuttx | nuttx-7.25 |
+| app | nuttx-7.25 |
 
 We only guarantee that the specified version will work well. It is recommended to check out with the specified tag from a git repository.
 
@@ -65,8 +65,8 @@ Clone IoT.js and NuttX into iotjs-nuttx directory
 $ mkdir iotjs-nuttx
 $ cd iotjs-nuttx
 $ git clone https://github.com/Samsung/iotjs.git
-$ git clone https://bitbucket.org/nuttx/nuttx.git --branch nuttx-7.19
-$ git clone https://bitbucket.org/nuttx/apps.git --branch nuttx-7.19
+$ git clone https://bitbucket.org/nuttx/nuttx.git --branch nuttx-7.25
+$ git clone https://bitbucket.org/nuttx/apps.git --branch nuttx-7.25
 $ git clone https://github.com/texane/stlink.git
 ```
 
diff --git a/docs/build/Build-for-Windows.md b/docs/build/Build-for-Windows.md
new file mode 100644 (file)
index 0000000..2767133
--- /dev/null
@@ -0,0 +1,69 @@
+# IoT.js for Windows build guide
+
+> :exclamation: This document describes an experimental feature and considerations.
+Please be aware that every experimental feature may change, be broken,
+or be removed in the future without any notice.
+
+
+The document presents the steps required to compile the IoT.js
+for Windows.
+Tested on Windows 10 and with Visual Studio 2017 Community Edition.
+
+## Build IoT.js for Windows
+
+### 0. Check environment
+
+Check if the following tools are installed:
+ * GIT
+ * Visual Studio 2017 with C++ support
+ * Python 3
+
+Additionally clone the IoT.js repository into a convenient directory.
+In the document the `C:\dev\iotjs` path will be used as an example.
+
+### 1. Run the build script
+
+To create the required Visual Studio solution file(s) the build scripts needs to be
+executed. Please start a Command Prompt and navigate to the source directory where
+the IoT.js is cloned.
+
+In the IoT.js directory issue the following command:
+
+```sh
+C:\dev\iotjs> .\tools\build.py --experimental
+```
+
+Currently for Windows the `--experimental` option is a must. Additionally if
+other options are required it can be specified after this option.
+
+This command will create the solution files in the build directory.
+Specifically in the `build\i686-windows\debug` directory in case of debug build.
+In case of release build the solution files will be in the `build\i686-windows\release\`
+directory.
+
+Please note that currently only the `i686` target is supported.
+
+### 2. Open the IoT.js solution file
+
+In the `build\i686-windows\debug` directory the `IOTJS.sln` file should be opened
+with Visual Studion 2017.
+
+### 3. Build
+
+After the IoT.js solution file is opened the Visual Studio can now start the build.
+Press CTRL+SHIFT+B to build the whole solution.
+
+The resulting iotjs.exe will be placed in the build's `bin\Debug` or `bin\Release`
+directory depending on the configuration chosen in the Visual Studio.
+
+### Extra
+
+On Windows the test runner can also be executed. To do this the following steps are required:
+
+1. Have a built iotjs.exe
+2. Start a command prompt
+3. Navigate to the IoT.js source directory
+4. Execute the test runner. Ex.:
+```sh
+C:\dev\iotjs> tools\testrunner.py build\i686-windows\debug\bin\Debug\iotjs.exe
+```
index 9789400fd3ac2f37e62ad63eb7b2542c241a9918..934a1820101a3fb13b13fcf6164e2e27e73acea7 100644 (file)
@@ -7,7 +7,7 @@ Community participants must adhere to these simple rules:
 
 <br>
 
-### Community Consensus, Lazy Consensus and Slient Consent
+### Community Consensus, Lazy Consensus and Silent Consent
 
 Community consensus about a Project issue means that the issue has been submitted to and discussed by Contributors, and that ALL discussing member agree about the issue.<p>
 Lazy consensus means that Contributors may proceed with work when they have reason to believe that other Contributors in the community will agree with the direction of their work, and do not need to stop or initiate unnecessary discussion about the work. Contributors should publish their work (that is, merge proposals to master branch) in a timely manner to allow others to possibly raise issues about the work. When the Contributor is not sure there will be consensus, they should raise a proposal to the community via appropriate public communication channels(**_currently Github issues is possible way to achieve this_**)<p>
index eeeda7aa895fb67d45cb2ebeb16c0f306923aa77..e87239fc7357c6223164f69dbd6600a1e248a820 100644 (file)
 
 The following shows `{Your_module_name}` module APIs available for each platform.
 
-|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | NuttX<br/>(STM32F4-Discovery) |
-| :---: | :---: | :---: | :---: |
-| {class_name}.{functionName1} | O | O | O |
-| {class_name}.{functionName2} | O | O | O |
-| {class_name}.{functionName3} | O | O | O |
+|  | Linux<br/>(Ubuntu) | Tizen<br/>(Raspberry Pi) | Raspbian<br/>(Raspberry Pi) | NuttX<br/>(STM32F4-Discovery) | TizenRT<br/>(Artik053) |
+| :---: | :---: | :---: | :---: | :---: | :---: |
+| {class_name}.{functionName1} | O | O | O | O | O |
+| {class_name}.{functionName2} | O | O | O | O | O |
+| {class_name}.{functionName3} | O | O | O | O | O |
 
 # {Your_module_name}
 
index 815ad19a1efdab79646e0a60c21dd8f12a77194b..3775ee9ef4a3709c378f317922b8c00673f16c82 100644 (file)
@@ -178,7 +178,7 @@ Do not modify prototypes of builtin objects
 ## Javascript Style Rules
 
 ### Naming
-Use lowerCamelCase for varible names and function names.
+Use lowerCamelCase for variable names and function names.
 
     var myFirstVariable;
     function myFirstFunction {
@@ -208,7 +208,7 @@ This tool helps you check your code style. You have to install `clang` and `esli
 
 ```bash
 $ sudo apt-get update
-$ sudo apt-get install clang-format-3.8
+$ sudo apt-get install clang-format-3.9
 $ cd iotjs
 $ npm install
 ```
index c2a0268826bf42d6f4837b0c44daa48597e35587..f032944339be5a356f8b19bb741b8abea8c1924d 100644 (file)
@@ -3,17 +3,16 @@ Inside IoT.js
 
 * [Design](#design)
 * [Javascript Binding](#javascript-binding)
-  * jerry_value_t
-  * iotjs_jobjectwrap_t
-  * Native handler
-  * Embedding API
+  * [jerry_value_t](#jerry_value_t)
+  * [Native handler](#native-handler)
+  * [Embedding API](#embedding-api)
 * [libuv Binding](#libuv-binding)
-  * iotjs_handlewrap_t
-  * iotjs_reqwrap_t
+  * [iotjs_handlewrap_t](#iotjs_handlewrap_t)
+  * [iotjs_reqwrap_t](#iotjs_reqwrap_t)
 * [IoT.js Core](#iotjscoe)
-  * Life cycle of IoT.js
-  * Builtin modules
-  * Event loop
+  * [Life cycle of IoT.js](#life-cycle-of-iot.js)
+  * [Builtin modules](#builtin-modules)
+  * [Event loop](#event-loop)
 
 # Design
 
@@ -54,43 +53,6 @@ This struct provides following functionalities:
 * Evaluating a Javascript script.
 * Set and Get corresponding native data to the Javascript object.
 
-## iotjs_jobjectwrap_t
-
-You can refer Javascript object from C code side using `jerry_value_t` as saw above.
-When a reference for a Javascript object was made using `jerry_value_t`, it will increase the reference count and will decrease the count when it goes out of scope.
-
-```c
-{
-  // Create JavaScript object
-  // It increases reference count in JerryScript side.
-  jerry_value_t jobject = iotjs_jval_create();
-
-  // Use `jobject`
-  ...
-
-  // Before jobject goes out of scope, destroy it.
-  // It decreases reference count in JerryScript side so that it can be GC-ed.
-  iotjs_jval_destroy(&jobject)
-}
-```
-
-But the situation is different if you want to refer a Javascript object through out program execution until the object is live.
-You may write code like this:
-
-```c
-  jerry_value_t* jobject = (jerry_value_t*)malloc(sizeof(jerry_value_t)); // Not allowed
-```
-
-To achieve your wish, we recommend using `iotjs_jobjectwrap_t` for that purpose.
-`iotjs_jobjectwrap_t` is kind of weak pointer to a Javascript Object.
-It refers a Javascript object but never increase reference count so that Javascript engine can collect the object when it turns into garbage.
-The `iotjs_jobjectwrap_t` instance will be released at the time the corresponding Javascript object is being reclaimed.
-
-Do not hold pointer to the wrapper in native code side globally because even if you are holding a wrapper by pointer, Javascript engine probably releases the corresponding Javascript object resulting deallocation of wrapper. Consequentially your pointer will turned into dangling.
-
-The only safe way to get wrapper is to get it from Javascript object. When a wrapper is being created, it links itself with corresponding Javascript object with `iotjs_jval_set_object_native_handle()` method of `jerry_value_t`. And you can get the wrapper from the object with `iotjs_jval_get_object_native_handle()` method of `jerry_value_t` later when you need it.
-
-
 ## Native handler
 
 Some operations - such as file I/O, networking, device control, multitasking, and etc - can not be performed by pure Javascript.
index 9542744abd8805eed40bbb3f4242919039fc916f..85eedddac30886141d66977352a06412cf4f3b02 100644 (file)
@@ -43,3 +43,9 @@ You can make your compiler to place the JerryScript heap in specific section by
 
 jmem_heap_t jerry_global_heap __attribute__ ((aligned (JMEM_ALIGNMENT))) JERRY_GLOBAL_HEAP_SECTION;
 ```
+
+## Modify the default jerry-heap size
+
+By default, JerryScript uses 16 bit long (8 byte aligned) pointers, that is why the maximum addressable area (on the JerryScript heap) is 512 KB. Of course, these compressed pointers can be extended to 32 bit to cover the entire address space of a 32 bit system.
+
+You can modify the default JerryScript heap size by using the `--jerry-heaplimit` argument when building IoT.js. If that value is bigger than `512`, the JerryScript submodule is compiled with 32 bit pointer support.
index 63c9a63f358533d99f5ad0d4d75f2c9e3bc81d09..24b8e7892ea344d50a773447da491077a5ff3a96 100644 (file)
@@ -2,7 +2,7 @@
 
 Depend on the purpose of the test case (whether it's a positive or negative one), place it under `test/run_pass` or `test/run_fail` directory. The required external resources should be placed into `test/resources`.
 
-All test case files must be named in the following form `test_<module name>[_<functionallity].js` where `<module name>`
+All test case files must be named in the following form `test_<module name>[_<functionality].js` where `<module name>`
 should match one of the JS modules name in the IoT.js. If there is a test case which can not tied to a
 module (like some js features) then the `iotjs` name can be used as module name. It is important to
 correctly specify the module name as the test executor relies on that information.
@@ -10,6 +10,33 @@ correctly specify the module name as the test executor relies on that informatio
 1. Write a test case and place it into the proper directory.
 2. List up the test case in [test/testsets.json](https://github.com/Samsung/iotjs/blob/master/test/testsets.json), and set attributes (timeout, skip, ...) on the test case if it needs.
 
+#### Test set descriptor
+* [`test/testsets.json`](https://github.com/Samsung/iotjs/blob/master/test/testsets.json)
+
+```
+{
+  "directory": [
+    { "name": "filename",
+      "skip": ["all"],
+      "reason": "reason of skipping",
+      "timeout": seconds,
+      "expected-failure": true,
+      "required-modules": ["my_module"],
+      "required-features": ["es-262-feature"]
+    },
+    ...
+  ],
+  ...
+}
+```
+
+ - _directory_: group of tests
+ - _name_: filename = testname
+ - _skip_: platform where the test must be skipped. ["all", "darwin", "linux", "nuttx", "tizen", "tizenrt"] **(optional)**
+ - _reason_: it belongs to skip property, reason of skipping. **(optional)**
+ - _timeout_: timeout in seconds **(optional)**
+ - _expected-failure_: identifies the "must fail" testcases. Still catches segfaults, IOTJS_ASSERT and JERRY_ASSERT. Default: false [true, false]  **(optional)**
+
 
 ### How to Test
 
@@ -25,26 +52,11 @@ Some basic options are provided.
 
 Existing test options are listed as follows;
 ```
-start-from
-quiet=yes|no (default is yes)
-output-file
-skip-module
-output-coverage=yes|no (default is no)
-experimental=yes|no (default is no)
+-h, --help           show this help message and exit
+--quiet              show or hide the output of the tests
+--skip-modules list  module list to skip test of specific modules
+--testsets TESTSETS  JSON file to extend or override the default testsets
+--timeout TIMEOUT    default timeout for the tests in seconds
+--valgrind           check tests with Valgrind
+--coverage           measure JavaScript coverage
 ```
-
-To give options, please use two dashes '--' **once** before the option name as described in the following sections.
-
-Options that may need explanations.
-* start-from: a test case file name where the driver starts.
-* quiet: a flag that indicates if the driver suppresses console outputs of test case.
-* output-file: a file name where the driver leaves output.
-* skip-module: a module list to skip test of specific modules.
-* output-coverage: a flag that indicates wether coverage data should be written to disk
-* experimental: a flag that indicates if tests for experimental are needed
-
-#### Options example
-
-```bash
-build/x86_64-linux/debug/bin/iotjs tools/check_test.js -- start-from=test_console.js quiet=no
-```
\ No newline at end of file
index a0a3992eab471db983b2013d064e21aa6a90b88f..db7928b48ec2282e87651d5d7f1a66a3ab6f510b 100644 (file)
@@ -29,8 +29,11 @@ If you want to specify the port number of the debugger-server (default: 5001),
 you can do so with the `--debugger-port <PORT>` option:
 `<iotjs binary> --start-debug-server --debugger-port 8080 test.js`
 
-Two clients are included, a [python](https://github.com/jerryscript-project/jerryscript/blob/master/jerry-debugger/jerry-client-ws.py)
-and an [HTML](https://github.com/jerryscript-project/jerryscript/blob/master/jerry-debugger/jerry-client-ws.html) variant, they can be found under `deps/jerry/jerry-debugger/`.
+#### Available Clients
 
-*Note*: When snapshot support is enabled, you won't be able to examine js-modules
+* [JerryScript console debugger client](https://github.com/jerryscript-project/jerryscript/blob/master/jerry-debugger/jerry-client-ws.py)
+* [Iot.js Code](https://github.com/Samsung/iotjscode)
+* [Jerryscript debugger Chrome webtool](https://github.com/jerryscript-project/jerryscript-debugger-ts)
+
+**Note**: When snapshot support is enabled, you won't be able to examine js-modules
 that are loaded from snapshots.
index 0be3a5580780ca75da8f10f407b6960a1ec9a844..1a535e2b73d87d59e7106196dcb6a521eac35e22 100644 (file)
@@ -10,7 +10,6 @@ Source1:    %{name}.pc.in
 Source1001: %{name}.manifest
 ExclusiveArch: %arm %ix86 x86_64
 
-
 BuildRequires: python
 BuildRequires: cmake
 BuildRequires: glibc-static
@@ -40,6 +39,7 @@ Platform for Internet of Things with JavaScript
 # Initialize the variables
 %{!?build_mode: %define build_mode release}
 %{!?external_build_options: %define external_build_options %{nil}}
+
 %package service
 Summary: Development files for %{name}
 Group: Network & Connectivity/Service
@@ -63,12 +63,13 @@ chmod g-w %_sourcedir/*
 cat LICENSE
 cp %{SOURCE1001} .
 
-
 %build
 V=1 VERBOSE=1 ./tools/build.py \
   --clean \
   --buildtype=%{build_mode} \
   --profile=test/profiles/tizen.profile \
+  --jerry-profile $PWD/test/profiles/tizen-jerry.profile \
+  --js-backtrace ON \
   --target-arch=noarch \
   --target-os=tizen \
 %ifarch %{arm}
@@ -82,13 +83,13 @@ V=1 VERBOSE=1 ./tools/build.py \
   --external-lib=appcore-agent \
   --external-lib=pthread \
   --external-lib=curl \
+  --external-lib=glib-2.0 \
   --external-include-dir=/usr/include/dlog/ \
   --external-include-dir=/usr/include/appcore-agent/ \
   --external-include-dir=/usr/include/appfw/ \
   --compile-flag="%(pkg-config --cflags glib-2.0)" \
   --compile-flag=-D__TIZEN__ \
   --compile-flag=-DENABLE_DEBUG_LOG \
-  --jerry-cmake-param=-DENABLE_STATIC_LINK=OFF \
   --create-shared-lib \
   --no-init-submodule \
   --no-parallel-build \
diff --git a/samples/bridge_sample/README.md b/samples/bridge_sample/README.md
deleted file mode 100644 (file)
index 83d1e50..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# Sample bridge module
-
-See also:
-* [Writing-new-module](Writing-New-Module.md)
-* [Native Module vs. JS module](Native-Module-vs-JS-Module.md)
-* [Inside IoT.js](Inside-IoT.js.md)
-* [Developer Tutorial](Developer-Tutorial.md)
-
-
-## Description
-This sample show you how you can create a 'mixed' module using brige module that has some interfaces to support communicattion between JS and Native code. This sample created using tools/iotjs-create-module.py script.
-You can see how you could reduce your effor to create native module using simple methods provided bridge module.
-
-
-## Build
-
-$ ./tools/build.py --external-modules=./samples/bridge_sample --cmake-param=-DENABLE_MODULE_BRIDGE_SAMPLE=ON
-
-## Testing
-
-$ iotjs samples/bridge_sample/test.js
diff --git a/samples/bridge_sample/js/bridge_sample.js b/samples/bridge_sample/js/bridge_sample.js
deleted file mode 100644 (file)
index f746292..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-var Bridge = require('bridge');
-
-function bridge_sample(){
-    this.bridge = new Bridge(native.MODULE_NAME);
-}
-
-bridge_sample.prototype.getResPath = function(){
-    return this.bridge.sendSync('getResPath', '');
-};
-
-bridge_sample.prototype.getSystemInfo = function(callback){
-    this.bridge.send('getSystemInfo', '', function(err, msg){
-        callback(err, msg);
-    });
-};
-
-bridge_sample.prototype.testThread = function(callback){
-    this.bridge.send('testThread', '', function(err, msg){
-        callback(err, msg);
-    });
-};
-
-module.exports = new bridge_sample();
diff --git a/samples/bridge_sample/module.cmake b/samples/bridge_sample/module.cmake
deleted file mode 100644 (file)
index 2b5ba63..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
-#
-# 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.
-
-# General variables usable from IoT.js cmake:
-# - TARGET_ARCH - the target architecture (as specified during cmake step)
-# - TARGET_BOARD - the target board(/device)
-# - TARGET_OS - the target operating system
-#
-# Module related variables usable from IoT.js cmake:
-# - MODULE_DIR - the modules root directory
-# - MODULE_BINARY_DIR - the build directory for the current module
-# - MODULE_LIBS - list of libraries to use during linking (set this)
-set(MODULE_NAME "bridge_sample")
-
-# DO NOT include the source files which are already in the modules.json file.
-
-# If the module builds its own files into a lib please use the line below.
-# Note: the subdir 'lib' should contain the CMakeLists.txt describing how the
-#  module should be built.
-#add_subdirectory(${MODULE_DIR}/lib/ ${MODULE_BINARY_DIR}/${MODULE_NAME})
-
-# If you wish to link external libraries please add it to
-# the MODULE_LIBS list.
-#
-# IMPORTANT!
-#  if the module builds its own library that should also be specified!
-#
-# Example (to add the 'demo' library for linking):
-#
-#  list(APPEND MODULE_LIBS demo)
diff --git a/samples/bridge_sample/modules.json b/samples/bridge_sample/modules.json
deleted file mode 100644 (file)
index f912106..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "modules": {
-    "bridge_sample": {
-      "js_file": "js/bridge_sample.js",
-      "native_files": ["src/iotjs_bridge_sample.c"],
-      "init": "InitBridgeSample",
-      "cmakefile": "module.cmake",
-      "require": ["bridge"]
-    }
-  }
-}
diff --git a/samples/bridge_sample/src/iotjs_bridge_sample.c b/samples/bridge_sample/src/iotjs_bridge_sample.c
deleted file mode 100644 (file)
index 72708a5..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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 "iotjs_def.h"
-#include "modules/iotjs_module_bridge.h"
-
-
-char* iotjs_bridge_sample_getSystemInfo(const char* message) {
-  return "{'OS':'tizen'}";
-}
-
-void thread1_worker(void* return_handle) {
-  uv_sleep(500);
-  iotjs_bridge_set_msg(return_handle, "{'return':'from thread..'}");
-}
-
-void iotjs_bridge_sample_func(const char* command, const char* message,
-                              void* return_handle) {
-  char* result = 0;
-  if (strncmp(command, "getSystemInfo", strlen("getSystemInfo")) == 0) {
-    result = iotjs_bridge_sample_getSystemInfo(message);
-    if (result == 0) {
-      iotjs_bridge_set_err(return_handle, "Can't get the resource path");
-    } else {
-      iotjs_bridge_set_msg(return_handle, result);
-    }
-  } else if (strncmp(command, "testThread", strlen("testThread")) == 0) {
-    uv_thread_t thread1;
-    uv_thread_create(&thread1, thread1_worker, return_handle);
-  } else if (strncmp(command, "getResPath", strlen("getResPath")) == 0) {
-    iotjs_bridge_set_msg(return_handle, "res/");
-  } else {
-    iotjs_bridge_set_err(return_handle, "Can't find command");
-  }
-}
-
-/**
- * Init method called by IoT.js
- */
-jerry_value_t InitBridgeSample() {
-  char* module_name = "bridge_sample";
-  jerry_value_t mymodule = jerry_create_object();
-  iotjs_jval_set_property_string_raw(mymodule, IOTJS_MAGIC_STRING_MODULE_NAME,
-                                     module_name);
-  iotjs_bridge_register(module_name, iotjs_bridge_sample_func);
-  return mymodule;
-}
diff --git a/samples/bridge_sample/test.js b/samples/bridge_sample/test.js
deleted file mode 100644 (file)
index 1c25d65..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-var bridgeSample = require('bridge_sample');
-
-
-console.log('TestApp: getResPath(): ' + bridgeSample.getResPath());
-
-
-bridgeSample.testThread(function(err, msg) {
-    console.log('TestApp: testThread(): err: ' + err + '  msg: ' + msg);
-});
-
-bridgeSample.getSystemInfo(function(err, msg) {
-    console.log('TestApp: getSystemInfo(): err: ' + err + '  msg: ' + msg);
-});
diff --git a/samples/fur-elise/play.js b/samples/fur-elise/play.js
deleted file mode 100644 (file)
index 1cb8f7e..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-/**
- * Description:
- *
- * Plays Bethovens Fur Elise using PWM
- *
- * Usage:
- *
- * To run this sample please connect a low-power speaker, like a buzzer
- * (piezoelectric speaker), negative feed (-) to GND and positive feed (+) to
- * pin 7 on Artik053 CON703, and run the code by executing
- *
- * $ iotjs play.js
- *
- */
-
-var pwm = require('pwm'),
-  // note indexes definition
-  // please remember that D# is same as Bb here
-  notes = {
-    "C": 0,
-    "C#": 1,
-    "D": 2,
-    "D#": 3,
-    "E": 4,
-    "F": 5,
-    "F#": 6,
-    "G": 7,
-    "G#": 8,
-    "A": 9,
-    "Bb": 10,
-    "B": 11
-  },
-  // note frequencies
-  frequencies = [
-    //C, C#, D, Eb, E, F, F#, G, G#, A, Bb, B in ocatves from 0 to 8
-    [16.35, 17.32, 18.35, 19.45, 20.60, 21.83, 23.12, 24.50, 25.96, 27.50,
-      29.14, 30.87],
-    [32.70, 34.65, 36.71, 38.89, 41.20, 43.65, 46.25, 49.00, 51.91, 55.00,
-      58.27, 61.74],
-    [65.41, 69.30, 73.42, 77.78, 82.41, 87.31, 92.50, 98.00, 103.8, 110.0,
-      116.5, 123.5],
-    [130.8, 138.6, 146.8, 155.6, 164.8, 174.6, 185.0, 196.0, 207.7, 220.0,
-      233.1, 246.9],
-    [261.6, 277.2, 293.7, 311.1, 329.6, 349.2, 370.0, 392.0, 415.3, 440.0,
-      466.2, 493.9],
-    [523.3, 554.4, 587.3, 622.3, 659.3, 698.5, 740.0, 784.0, 830.6, 880.0,
-      932.3, 987.8],
-    [1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976],
-    [2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951],
-    [4186, 4435, 4699, 4978, 5274, 5588, 5920, 6272, 6645, 7040, 7459, 7902]
-  ],
-  // fur elise notes
-  song = [
-    ["E6", 0.2], ["D#6", 0.2], ["E6", 0.2], ["D#6", 0.2], ["E6", 0.2],
-    ["B5", 0.2], ["D6", 0.2], ["C6", 0.2], ["A5", 0.2], ["A3", 0.2],
-    ["E4", 0.2], ["A4", 0.2], ["C5", 0.2], ["E5", 0.2], ["A5", 0.2],
-    ["E3", 0.2], ["B5", 0.2], ["E4", 0.2], ["G#4", 0.2], ["E5", 0.2],
-    ["G#5", 0.2], ["B5", 0.2], ["A3", 0.2], ["C6", 0.2], ["E4", 0.2],
-    ["A4", 0.2], ["E5", 0.2], ["E6", 0.2], ["E6", 0.2], ["D#6", 0.2],
-    ["D#6", 0.2], ["E6", 0.2], ["E6", 0.2], ["D#6", 0.2], ["D#6", 0.2],
-    ["E6", 0.2], ["E6", 0.2], ["B5", 0.2], ["B5", 0.2], ["D6", 0.2],
-    ["D6", 0.2], ["C6", 0.2], ["C6", 0.2], ["A3", 0.2], ["A5", 0.2],
-    ["A5", 0.2], ["E4", 0.2], ["A4", 0.2], ["C5", 0.2], ["E5", 0.2],
-    ["A5", 0.2], ["E3", 0.2], ["B5", 0.2], ["E4", 0.2], ["G#4", 0.2],
-    ["E5", 0.2], ["C6", 0.2], ["B5", 0.2], ["A5", 0.2], ["A3", 0.2],
-    ["E4", 0.2], ["A4", 0.2], ["B5", 0.2], ["C6", 0.2], ["D6", 0.2],
-    ["C4", 0.2], ["E6", 0.2], ["G4", 0.2], ["C5", 0.2], ["G5", 0.2],
-    ["F6", 0.2], ["E6", 0.2], ["G3", 0.2], ["D6", 0.2], ["G4", 0.2],
-    ["B4", 0.2], ["F5", 0.2], ["E6", 0.2], ["D6", 0.2], ["A3", 0.2],
-    ["C6", 0.2], ["E4", 0.2], ["A4", 0.2], ["E5", 0.2], ["D6", 0.2],
-    ["C6", 0.2], ["E3", 0.2], ["B5", 0.2], ["E4", 0.4],
-    ["E5", 0.2], ["E6", 0.2], ["E5", 0.4], ["E6", 0.2],
-    ["E7", 0.2], ["D#6", 0.2], ["E6", 0.2], ["D#6", 0.2], ["E6", 0.2],
-    ["D#6", 0.2], ["E6", 0.2], ["D#6", 0.2], ["E6", 0.2], ["D#6", 0.2],
-    ["E6", 0.2], ["D#6", 0.2], ["E6", 0.2], ["B5", 0.2], ["D6", 0.2],
-    ["C6", 0.2], ["A3", 0.2], ["A5", 0.2], ["E4", 0.2], ["A4", 0.2],
-    ["C5", 0.2], ["E5", 0.2], ["A5", 0.2], ["E3", 0.2], ["B5", 0.2],
-    ["E4", 0.2], ["G#4", 0.2], ["E5", 0.2], ["G#5", 0.2], ["B5", 0.2],
-    ["A3", 0.2], ["C6", 0.2], ["E4", 0.2], ["A4", 0.2], ["E5", 0.2],
-    ["E6", 0.2], ["D#6", 0.2], ["E6", 0.2], ["D#6", 0.2], ["E6", 0.2],
-    ["B5", 0.2], ["D6", 0.2], ["C6", 0.2], ["A3", 0.2], ["A5", 0.2],
-    ["E4", 0.2], ["A4", 0.2], ["C5", 0.2], ["E5", 0.2], ["A5", 0.2],
-    ["E3", 0.2], ["B5", 0.2], ["E4", 0.2], ["G#4", 0.2], ["E5", 0.2],
-    ["C6", 0.2], ["B5", 0.2], ["A3", 0.2], ["A5", 0.2], ["E4", 0.2],
-    ["A4", 0.8]
-  ],
-  log_enable = true,
-  device = null;
-
-// log only when log_enable flag is set to true
-function log(/*...args*/) {
-  if (log_enable) {
-    console.log.apply(console, [].slice.call(arguments));
-  }
-}
-
-// extracts frequency from freq array based on supplied note
-function note2freq(noteStr) {
-  var matches = noteStr.match(/([a-zA-Z\#]+)([0-9]+)/i),
-    freq = 0;
-
-  if (matches && matches.length === 3) {
-    return frequencies[parseInt(matches[2], 10)][notes[matches[1]]];
-  }
-
-  return 0;
-}
-
-// sets pwm period and runs callback after specified length of time
-function setPeriod(period, length, callback) {
-  log('period: ' + period + ', length: ' + length + ' ms');
-  device.setPeriod(period, function (err) {
-    if (err) {
-      callback(err);
-    } else {
-      setTimeout(callback, length);
-    }
-  });
-}
-
-// plays each note of song recursively and runs callback on end
-function playSong(song, callback, currentNote) {
-  var idx = currentNote === undefined ? 0 : currentNote,
-    freq = 0;
-  if (idx < song.length) {
-    freq = note2freq(song[idx][0]);
-    // period = 1 second / frequency
-    setPeriod(freq !== 0 ? 1 / freq : 0.5, 1000 * song[idx][1],
-             playSong.bind(null, song, callback, ++idx));
-  } else {
-    callback();
-  }
-}
-
-device = pwm.open({
-  pin: 0,
-  dutyCycle: 0.5,
-  period: 1 / 10
-}, function (err) {
-  if (err) {
-    log('could not open pwm device: ' + err);
-  } else {
-    device.setEnableSync(true);
-    log('playing song');
-    playSong(song, function () {
-      device.close(function (err) {
-        if (err) {
-          log('error while closing device: ' + err);
-        } else {
-          log('done');
-        }
-      });
-    });
-  }
-});
diff --git a/samples/gpio-blinkedled/gpio_led.js b/samples/gpio-blinkedled/gpio_led.js
deleted file mode 100644 (file)
index 21ee943..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-var gpio = require('gpio');
-var pin = require('systemio_pin').pin;
-
-var gpio_led = gpio.open({
-  pin: pin.led1,
-  direction: gpio.DIRECTION.OUT
-}, function(err) {
-  if (!err) {
-    gpio_led.writeSync(true);
-
-    var interval = setInterval(function() {
-      gpio_led.read(function(err, value) {
-        if (!err) {
-          console.log("read value:%d", value);
-          gpio_led.write(!value);
-        } else {
-          clearInterval(interval);
-        }
-      });
-    }, 1000);
-  }
-});
diff --git a/samples/gpio-blinkedled/systemio_pin.js b/samples/gpio-blinkedled/systemio_pin.js
deleted file mode 100644 (file)
index c4ec6e6..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-var pin = {};
-
-if (process.platform === 'linux') {
-  pin.led1 = 20;
-} else if (process.platform === 'nuttx') {
-  var stm32_pin = require('stm32f4dis').pin;
-  pin.led1 = stm32_pin.PA10;
-} else {
-  throw new Error('Unsupported platform');
-}
-
-exports.pin = pin;
diff --git a/samples/http-gpio-panel/favicon.ico b/samples/http-gpio-panel/favicon.ico
deleted file mode 100644 (file)
index fe90fd4..0000000
Binary files a/samples/http-gpio-panel/favicon.ico and /dev/null differ
diff --git a/samples/http-gpio-panel/index.html b/samples/http-gpio-panel/index.html
deleted file mode 100644 (file)
index 5070f81..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-<!--
-/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-//-->
-<html lang="en">
-  <head>
-    <title>http gpio panel sample</title>
-  </head>
-  <body>
-    <form id="gpioconf">
-      <fieldset>
-        <legend>GPIO Pin configuration</legend>
-        <label>
-          Pin number
-          <input type="number" value="0" name="pin">
-        </label>
-        <label>
-          Direction
-          <select name="direction">
-            <option value="0" selected>IN</option>
-            <option value="1">OUT</option>
-          </select>
-        </label>
-        <label>
-          Mode
-          <select name="mode">
-            <option value="0" selected>NONE</option>
-            <option value="1">PULLUP</option>
-            <option value="2">PULLDOWN</option>
-            <option value="3">FLOAT</option>
-            <option value="4">PUSHPULL</option>
-            <option value="5">OPENDRAIN</option>
-          </select>
-        </label>
-        <label>
-          State
-          <select name="pinValue">
-            <option value="0" selected>LOW</option>
-            <option value="1">HIGH</option>
-          </select>
-        </label>
-        <input type="submit" value="Add">
-      </fieldset>
-    </form>
-    <h3>ACTIVE PINS</h3>
-    <table id="gpioresults">
-      <thead>
-        <tr>
-          <th>Pin</pin>
-          <th>Direction</th>
-          <th>Mode</th>
-          <th>State</th>
-          <th></th>
-        </tr>
-      </thead>
-      <tbody>
-      </tbody>
-    </table>
-    <script type="text/javascript">
-      var form = document.getElementById('gpioconf'),
-        results = document.getElementById('gpioresults'),
-        GPIO_DIRECTION = {
-          '0': 'IN',
-          '1': 'OUT'
-        },
-        GPIO_MODE = {
-          '0': 'NONE',
-          '1': 'PULLUP',
-          '2': 'PULLDOWN',
-          '3': 'FLOAT',
-          '4': 'PUSHPULL',
-          '5': 'OPENDRAIN'
-        },
-        currentPins = {};
-
-      // synchronize pins with response from server
-      function syncPins(pins) {
-        var pin = '',
-          updated = {};
-        // handle updates and add
-        for (pin in pins) {
-          if (pins.hasOwnProperty(pin)) {
-            currentPins[pin] = pins[pin];
-          };
-        }
-        // handle removals
-        for (pin in currentPins) {
-          if (currentPins.hasOwnProperty(pin)) {
-            if (pins[pin] !== undefined) {
-              updated[pin] = currentPins[pin];
-            }
-          }
-        }
-        // update data
-        currentPins = updated;
-      }
-
-      // creates <tr> element with pin data in result table
-      function createRowForPin(pin, data) {
-        var row = document.createElement('tr'),
-          checked = !!parseInt(data.value, 0) ? ' checked' : '',
-          disabled = parseInt(data.direction, 10) === 0 ? ' disabled' : '',
-          attrs = checked + disabled;
-
-        row.setAttribute('id', 'pin_' + pin);
-        row.innerHTML = '<td>' + pin + '</td>'
-                      + '<td>' + GPIO_DIRECTION[data.direction] + '</td>'
-                      + '<td>' + GPIO_MODE[data.mode] + '</td>'
-                      + '<td><input name="value" type="checkbox"' + attrs + '></td>'
-                      + '<td><button value="remove">Remove</button></td>';
-
-        results.tBodies[0].appendChild(row);
-      }
-
-      // removes <tr> element for pin
-      function removeRowForPin(pin) {
-        var pinEl = document.getElementById('pin_' + pin);
-        if (pinEl) {
-          pinEl.parentNode.removeChild(pinEl);
-        }
-      }
-
-      // updates <tr> for pin with specified data
-      function updateRowForPin(row, pin, data) {
-        if (parseInt(data.direction, 10) === 0) {
-          row.children[3].children[0].checked = !!parseInt(data.value);
-        }
-      }
-
-      // updates table with new data
-      function updateResults(data) {
-        var pin = '',
-          pinEl = null;
-        syncPins(data);
-        for (pin in currentPins) {
-          if (currentPins.hasOwnProperty(pin)) {
-            pinEl = document.getElementById('pin_' + pin);
-            if (pinEl) {
-              updateRowForPin(pinEl, pin, data[pin]);
-            } else {
-              pinEl = createRowForPin(pin, data[pin]);
-            }
-          }
-        }
-      }
-
-      // polling for data
-      function updateDataPoll(interval) {
-        var xhr = new XMLHttpRequest();
-        xhr.addEventListener('load', function (e) {
-          var updatedData = [];
-          if (e.target.status === 200) {
-            updateResults(JSON.parse(e.target.responseText));
-          }
-          if (interval) {
-            setTimeout(updateDataPoll.bind(null, interval), interval);
-          }
-        });
-        xhr.open('POST', '/update', true);
-        xhr.send(JSON.stringify(currentPins));
-      }
-
-      // handle clicks on "remove" button
-      document.addEventListener('click', function (e) {
-        var pin = '',
-          id = '',
-          prop = '',
-          updated = {};
-        if (e.target.value && e.target.value === 'remove') {
-          id = e.target.parentNode.parentNode.id;
-          pin = id.replace(/[^0-9]+/gi, '');
-          for (prop in currentPins) {
-            if (currentPins.hasOwnProperty(prop) && prop !== pin) {
-              updated[pin] = currentPins[pin];
-            }
-          }
-          removeRowForPin(pin);
-          currentPins = updated;
-          updateDataPoll(0);
-        }
-      });
-
-      // handles changes on state checkboxes
-      document.addEventListener('change', function (e) {
-        var id = '',
-          pin = '';
-        if (e.target.name && e.target.name === 'value') {
-          id = e.target.parentNode.parentNode.id;
-          pin = id.replace(/[^0-9]+/gi, '');
-          if (currentPins[pin] && currentPins[pin].direction === '1') {
-            currentPins[pin].value = e.target.checked ? '1' : '0';
-            updateDataPoll(0);
-          }
-        }
-      });
-
-      // handles adding of new pins
-      form.addEventListener('submit', function (e) {
-        var formElements = e.target.elements;
-        if (currentPins[formElements.pin.value] === undefined) {
-          currentPins[formElements.pin.value] = {
-            mode: formElements.mode.value,
-            direction: formElements.direction.value,
-            value: formElements.pinValue.value
-          }
-          e.target.reset();
-          updateDataPoll(0);
-        } else {
-          alert('pin already exists');
-        }
-
-        e.preventDefault();
-        return false;
-      });
-
-      updateDataPoll(500);
-    </script>
-  </body>
-</html>
diff --git a/samples/http-gpio-panel/server.js b/samples/http-gpio-panel/server.js
deleted file mode 100644 (file)
index dc0f444..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-/**
- * Description:
- *
- * This sample allows to control GPIO input/output pins through browser
- *
- * Usage:
- *
- * To run this example execute:
- *
- * $ iotjs server.js
- *
- * and navigate your browser to http://[your-ip-address]:8080
- *
- */
-var http = require('http'),
-  fs = require('fs'),
-  Buffer = require('buffer'),
-  gpio = require('gpio'),
-  server = null,
-  port = 8080,
-  logs_enabled = true,
-  pinConfiguration = {},
-  activePins = {},
-  GPIO_DIRECTION = {
-    '0': gpio.DIRECTION.IN,
-    '1': gpio.DIRECTION.OUT
-  },
-  GPIO_MODE = {
-    '0': gpio.MODE.NONE,
-    '1': gpio.MODE.PULLUP,
-    '2': gpio.MODE.PULLDOWN,
-    '3': gpio.MODE.FLOAT,
-    '4': gpio.MODE.PUSHPULL,
-    '5': gpio.MODE.OPENDRAIN
-  };
-
-// splits url by "/" deliminator and removes empty entries
-function extractPath(url) {
-  var urlParts = url.split('/'),
-    i = 0,
-    l = urlParts.length,
-    result = [];
-  for (; i < l; ++i) {
-    if (urlParts[i].length > 0) {
-      result.push(urlParts[i]);
-    }
-  }
-  return result;
-}
-
-// processes request data stream and passes it to callback
-function fetchRequestTextBody(req, callback) {
-  var body = [];
-  req.on('data', function (chunk) {
-    body.push(chunk);
-  });
-  req.on('end', function () {
-    callback(body.join(""));
-  });
-}
-
-// sets 404 header and body as response
-function notFound(res) {
-  res.writeHead(404);
-  res.end('404 not found');
-}
-
-// logs only when log_enabled is set to true
-function log(/*...arg*/) {
-  if (logs_enabled) {
-    console.log.apply(console, [].slice.call(arguments));
-  }
-}
-
-// reads file from specified path
-function fetchFile(path) {
-  var data = null;
-
-  log('trying to open: ' + path);
-  if (fs.existsSync(path)) {
-    data = fs.readFileSync(path);
-  }
-  return data;
-}
-
-// synchronizes pin states with the data that was send with
-// request from panel
-function syncPins(pins) {
-  var pin = '',
-    updatedConf = {},
-    updatedPins = {},
-    value = 0;
-
-  // update and add
-  for (pin in pins) {
-    if (pins.hasOwnProperty(pin)) {
-      if (activePins[pin] === undefined) {
-        // open pin if it does not exist
-        log('opening new pin: ' + pin);
-        activePins[pin] = gpio.open({
-          pin: parseInt(pin, 10),
-          direction: GPIO_DIRECTION[pins[pin].direction],
-          mode: GPIO_MODE[pins[pin].mode]
-        }, function (err) {
-          if (err) {
-            log('error while opening pin: ' + pin);
-          } else {
-            log('pin opened: ' + pin);
-            if(parseInt(pins[pin].direction, 10) === 1) {
-              activePins[pin].writeSync(parseInt(pins[pin].value, 10));
-            }
-          }
-        });
-      } else if(parseInt(pins[pin].direction, 10) === 1 &&
-                pins[pin].value !== pinConfiguration[pin].value) {
-        // update value if pin exists and is writable
-        log('pin: ' + pin + ', new value: ' + parseInt(pins[pin].value, 10));
-        activePins[pin].writeSync(parseInt(pins[pin].value, 10));
-      }
-
-      // save old value if pin exists
-      if (pinConfiguration[pin] !== undefined) {
-        value = pinConfiguration[pin].value;
-      }
-
-      // update
-      pinConfiguration[pin] = pins[pin];
-
-      // if pin is 'readable' then restore the value
-      if(parseInt(pins[pin].direction, 10) === 0) {
-        pinConfiguration[pin].value = value;
-      }
-    }
-  }
-
-  // handle pin removal
-  for (pin in pinConfiguration) {
-    if (pinConfiguration.hasOwnProperty(pin)) {
-      if (pins[pin] !== undefined) {
-        updatedConf[pin] = pinConfiguration[pin];
-        updatedPins[pin] = activePins[pin];
-      } else if (activePins[pin]) {
-        log('closing pin: ' + pin);
-        activePins[pin].closeSync();
-      }
-    }
-  }
-
-  // update internal data
-  activePins = updatedPins;
-  pinConfiguration = updatedConf;
-}
-
-function handleRequest(req, res) {
-  var path = extractPath(req.url);
-  switch (path[0]) {
-    case 'update':
-      fetchRequestTextBody(req, function (data) {
-        syncPins(JSON.parse(data));
-        res.writeHead(200);
-        res.end(JSON.stringify(pinConfiguration));
-      });
-      break;
-    case undefined:
-      // front page
-      path[0] = 'index.html';
-    case 'favicon.ico':
-      // serve favicon as most browsers always fetch this
-      log('serving static: ' + path[0]);
-      var fileData = fetchFile(process.cwd() + '/' + path[0]);
-      if (fileData) {
-        res.writeHead(200);
-        res.end(fileData);
-      } else {
-        notFound(res);
-      }
-      break;
-    default:
-      // return 404 for all other requests
-      notFound(res);
-      break;
-  }
-}
-
-// handles input pin state changes
-setInterval(function () {
-  var pin = '',
-    value = null;
-  for (pin in activePins) {
-    if (activePins.hasOwnProperty(pin) &&
-        parseInt(pinConfiguration[pin].direction, 10) === 0) { // check pin is
-                                                               // if input pin
-      value = activePins[pin].readSync() ? '1' : '0';
-      if (pinConfiguration[pin].value !== value) { // check if value changed
-        log('pin: ' + pin + ' value changed to: ' + value);
-        pinConfiguration[pin].value = value;
-      }
-    }
-  }
-}, 500);
-
-server = http.createServer(handleRequest);
-server.listen(port, function (err) {
-  if (err) {
-    log('error while starting server: ' + err);
-  } else {
-    log('listening for connections on port: ' + port);
-  }
-});
diff --git a/samples/http-hello/client_get.js b/samples/http-hello/client_get.js
deleted file mode 100644 (file)
index 7bcefce..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-var http = require('http');
-var options = {
-  hostname: '127.0.0.1',
-  port: 8080,
-  path: '/'
-};
-
-http.request(options, function (res) {
-  receive(res, function (data) {
-    console.log(data);
-  });
-}).end();
-
-function receive(incoming, callback) {
-  var data = '';
-
-  incoming.on('data', function (chunk) {
-    data += chunk;
-  });
-
-  incoming.on('end', function () {
-    callback ? callback(data) : '';
-  });
-}
diff --git a/samples/http-hello/client_post.js b/samples/http-hello/client_post.js
deleted file mode 100644 (file)
index 277bb0d..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-var http = require('http');
-
-var message = JSON.stringify({
-  greeting: 'Hello, IoT.JS!',
-  answer: '',
-});
-
-var options = {
-  hostname: '127.0.0.1',
-  port: 8080,
-  path: '/',
-  method: 'POST',
-  headers: {
-    'Content-Length': message.length
-  }
-};
-
-http.request(options, function (res) {
-  receive(res, function (data) {
-    var obj = JSON.parse(data);
-    console.log(obj.answer);
-  });
-}).end(message);
-
-function receive(incoming, callback) {
-  var data = '';
-
-  incoming.on('data', function (chunk) {
-    data += chunk;
-  });
-
-  incoming.on('end', function () {
-    callback ? callback(data) : '';
-  });
-}
diff --git a/samples/http-hello/server.js b/samples/http-hello/server.js
deleted file mode 100644 (file)
index 3fcbe48..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-var http = require('http');
-var port = 8080;
-
-http.createServer(function (req, res) {
-  if (req.method == 'GET') {
-    status(res, 'Hello, IoT.JS!');
-
-  } else if (req.method == 'POST') {
-    receive(req, function (data) {
-      var obj = JSON.parse(data);
-      obj.answer = 'Hello, There!'
-      status(res, obj);
-    });
-  }
-}).listen(port);
-
-function receive(incoming, callback) {
-  var data = '';
-
-  incoming.on('data', function (chunk) {
-    data += chunk;
-  });
-
-  incoming.on('end', function () {
-    callback ? callback(data) : '';
-  });
-}
-
-function status(res, data) {
-  var isJson = (typeof data === 'object');
-
-  if (isJson) {
-    data = JSON.stringify(data);
-  }
-
-  var headers = {
-    'Access-Control-Allow-Origin': '*',
-    'Access-Control-Allow-Headers':
-    'Origin, X-Requested-With, Content-Type, Accept',
-    'Content-Type': isJson ? 'application/json' : 'text/plain',
-  };
-
-  res.writeHead(200, headers);
-  res.end(data);
-};
diff --git a/samples/i2c/i2c_ht16k33.js b/samples/i2c/i2c_ht16k33.js
deleted file mode 100644 (file)
index 6b59b5e..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-var i2c = require('i2c');
-
-var CMD_BRIGHTNESS = 0xE0;
-var CMD_OSCILLATOR = 0x21;
-var CMD_DISPLAY_ON = 0x81;
-
-var iotChar = [0x00, 0x00, 0x00, 0x00,
-  0xCE, 0x73, 0x44, 0x22,
-  0x44, 0x22, 0xCE, 0x23,
-  0x00, 0x00, 0x00, 0x00];
-
-var writeLed = function(wire, data) {
-  // 0x00 is a initial signal for writing
-  var buffer = [0x00].concat(data);
-  wire.write(buffer);
-};
-
-var configuration = {};
-configuration.address = 0x70;
-
-if (process.platform === 'linux') {
-  configuration.device = '/dev/i2c-1';
-} else if (process.platform === 'nuttx' || process.platform == 'tizenrt') {
-  configuration.bus = 1;
-} else {
-  throw new Error('Unsupported platform');
-}
-
-i2c.open(configuration, function(err, wire) {
-  if (err) {
-    throw err;
-  }
-
-  wire.writeSync([CMD_OSCILLATOR]); // turn on oscillator
-  wire.writeSync([CMD_DISPLAY_ON]);
-  wire.writeSync([CMD_BRIGHTNESS | 1]); // adjust brightness
-  writeLed(wire, iotChar);
-});
diff --git a/samples/light-fade/light-fade.js b/samples/light-fade/light-fade.js
deleted file mode 100644 (file)
index 86a0eb1..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-/**
- * Description:
- *
- * Turns light on/off with a fade effect
- *
- * Usage:
- *
- * To run this sample please connect a button to GND and pin 8 on CON708
- * header, the LED light cathode (-) to GND and anode (+) to pin 7 on CON703.
- * Next run:
- *
- * $ iotjs light-fade.js
- *
- * Pushing the button will turn on/off (toggle) the light with a fade effect.
- *
- */
-
-var pwm = require('pwm'),
-  gpio = require('gpio'),
-  LOW = 0,
-  HIGH = 1,
-  FADE_TIME = 10000, // 10 seconds
-  log_enabled = true,
-  direction = 0, // 0 off 1 on
-  buttonPin = 50,
-  pwmPin = 0,
-  step = 0.05,
-  value = LOW,
-  buttonDevice = null,
-  pwmDevice = null;
-
-// log only when log_enabled flag is set to true
-function log(/*...args*/) {
-  if (log_enabled) {
-    console.log.apply(console, [].slice.call(arguments));
-  }
-}
-
-// polling for gpio button changes
-function buttonPoll() {
-  buttonDevice.read(function (err, buttonValue) {
-    var timeoutOffset = 0;
-    if (buttonValue) {
-      direction = direction ? 0 : 1; //reverse on button push
-      log('switching to: ' + (direction ? 'ON': 'OFF'));
-      timeoutOffset = 500; // offset the time for next check to prevent errors
-                           // of mechanical buttons
-    }
-    setTimeout(buttonPoll, 100 + timeoutOffset);
-  });
-}
-
-function mainLoop() {
-  // handle fading
-  if (direction === 0 && value > LOW) {
-    value -= step;
-  } else if (direction === 1 && value < HIGH) {
-    value += step;
-  }
-
-  // clamping
-  if (value > HIGH) {
-    value = HIGH;
-  } else if (value < LOW) {
-    value = LOW;
-  }
-
-  pwmDevice.setDutyCycle(value, function (err) {
-    if (err) {
-      log('could not set device duty cycle');
-    }
-    setTimeout(mainLoop, FADE_TIME / (HIGH / step));
-  });
-}
-
-log('setting up gpio');
-buttonDevice = gpio.open({
-  pin: buttonPin,
-  direction: gpio.DIRECTION.IN,
-  mode: gpio.MODE.NONE
-}, function (err) {
-  if (err) {
-    log('error when opening gpio device: ' + err);
-  } else {
-    log('setting up pwm');
-    pwmDevice = pwm.open({
-      pin: pwmPin,
-      period: 0.0001,
-      dutyCycle: value
-    }, function (err) {
-      if (err) {
-        log('error when opening pwm device: ' + err);
-        buttonDevice.closeSync();
-      } else {
-        pwmDevice.setEnable(true, function (err) {
-          if (err) {
-            log('error when enabling pwm: ' + err);
-            buttonDevice.closeSync();
-            pwmDevice.close();
-          } else {
-            log('wating for user input');
-            buttonPoll();
-            mainLoop();
-          }
-        });
-      }
-    });
-  }
-});
diff --git a/samples/net-hello/client.js b/samples/net-hello/client.js
deleted file mode 100644 (file)
index 8c0dc1d..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-var net = require('net');
-
-var port = 7468;
-
-var msg = '';
-var socket = new net.Socket();
-
-var address = process.argv[2] ? process.argv[2] : "127.0.0.1";
-
-socket.connect(port, address);
-
-socket.on('data', function(data) {
-  msg += data;
-});
-
-socket.on('end', function() {
-  console.log(msg);
-  socket.end();
-});
diff --git a/samples/net-hello/server.js b/samples/net-hello/server.js
deleted file mode 100644 (file)
index fc5df42..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-var net = require('net');
-
-var port = 7468;
-var server = net.createServer();
-
-server.listen(port, 5);
-
-server.on('connection', function(socket) {
-  socket.end('Hello IoT.js');
-});
diff --git a/samples/tizen-bridge-native/tizen_bridge_native.c b/samples/tizen-bridge-native/tizen_bridge_native.c
deleted file mode 100644 (file)
index 8ce585c..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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 "iotjs.h"
-#include "iotjs_tizen_service_app.h"
-
-/* thread */
-#include <pthread.h>
-#include <unistd.h>
-/* printf */
-#include <stdio.h>
-
-
-static void user_cb(int err, const char* data) {
-  printf("err: %d, data: %s\n", err, data);
-}
-
-
-void* thread(void* data) {
-  sleep(1);
-
-  char* str = "1234567A1234567B1234567C";
-  IOTJS_TIZEN_CALL_JFUNC("hello", "world", user_cb);
-  IOTJS_TIZEN_CALL_JFUNC("hello", str, user_cb);
-  IOTJS_TIZEN_CALL_JFUNC("hello", "", user_cb);
-  IOTJS_TIZEN_CALL_JFUNC("", "", user_cb);
-  IOTJS_TIZEN_CALL_JFUNC("", "", NULL);
-  IOTJS_TIZEN_CALL_JFUNC("notReturnString", "", user_cb);
-  return 0;
-}
-
-
-int main(int argc, char** argv) {
-  pthread_t tid;
-  if (pthread_create(&(tid), NULL, &thread, NULL)) {
-    return 1;
-  }
-
-  return iotjs_entry(argc, argv);
-}
diff --git a/samples/tizen-bridge-native/tizen_bridge_native.js b/samples/tizen-bridge-native/tizen_bridge_native.js
deleted file mode 100644 (file)
index 0db23fa..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-var tizen = require('tizen');
-
-tizen.hello = function(data) {
-  return 'tizen.hello is called with data, ' + (data ? data : 'null');
-}
-
-tizen.notReturnString = function(data) {
-}
-
-setInterval(function() {
-  console.log('heartbeat');
-}, 10000);
diff --git a/samples/uart-iotjs-console/console.js b/samples/uart-iotjs-console/console.js
deleted file mode 100644 (file)
index 16798e4..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-/**
- * Description:
- *
- * This sample runs a simple REPL mode console on the device UART port
- *
- * Usage:
- *
- * To run this sample, connect a UART device (ex. FTDI USB-UART, RPI UART pins)
- * to RX/TX pin on the artik board (0 and 1 pin on CON709). Please note that
- * the serial device used in this example is different than normal USB port on
- * the Artik053 development board, so you need two connections, one to run
- * the code and second to connect to REPL console. After connecting please run:
- *
- * $ iotjs console.js
- *
- * You can now run simple JS code and the device will evaluate it and return
- * the results
- */
-
-var uart = require('uart'),
-  uartConfig = {
-    device: '/dev/ttyS1',
-    baudRate: 115200,
-    dataBits: 8
-  },
-  buffer = [],
-  serialDevice = null,
-  log_enabled = true,
-  MSG_INFO = 0,
-  MSG_ERROR = 1,
-  EVALUATE_CODE_CHR = 18, // CTRL+R <CR>
-  uartResponseCodes = { // chars to send on specific input char codes
-    8: '\b',
-    13: '\r\n'
-  },
-  fakeConsole = { // fake console to allow sending console messages to user
-    messages: []
-  };
-
-// on linux the device is different
-if (process.platform === 'linux' ||
-    (process.iotjs && process.iotjs.board === 'RP2')) {
-  uartConfig.device = '/dev/serial0';
-}
-
-// tries to 'stringify' objects (and errors)
-function obj2str(obj) {
-  if (obj instanceof Error) {
-    return obj.name + ': ' + obj.message;
-  }
-
-  return JSON.stringify(obj);
-}
-
-// stringify and array of data (ex. arguments of functions)
-function arr2str(arr) {
-  var strArr = [],
-    i = 0,
-    l = arr.length;
-  for (; i < l; ++i) {
-    switch (typeof arr[i]) {
-      case 'object':
-        strArr.push(obj2str(arr[i]));
-        break;
-      case 'function':
-        strArr.push('function');
-        break;
-      default:
-      case 'string':
-      case 'number':
-        strArr.push(arr[i]);
-        break;
-    }
-  }
-  return strArr.join('');
-}
-
-fakeConsole.log = function (/*...args*/) {
-  var body = arr2str([].slice.call(arguments));
-  log('LOG: ' + body);
-  this.messages.push(body);
-};
-
-fakeConsole.error = function (/*...args*/) {
-  var body = arr2str([].slice.call(arguments));
-  log('ERROR: ' + body);
-  this.messages.push(body);
-};
-
-fakeConsole.toString = function () {
-  return this.messages.join('\r\n') + '\r\n';
-};
-
-fakeConsole.clear = function () {
-  this.messages = [];
-};
-
-// logs only if log_enabled flag is set to true
-function log(/*...args*/) {
-  if (log_enabled) {
-    console.log.apply(console, [].slice.call(arguments));
-  }
-}
-
-// faleConsole needs to be available to 'eval'ed scripts
-global.fakeConsole = fakeConsole;
-
-// execude code with 'eval'
-// this is done only for this sample, normally using eval is a no-no,
-// please avoid if possible
-function evalInContext(data) {
-  data = data.replace(/console\.(log|error)/g, 'fakeConsole.$1');
-  eval(data);
-}
-
-// handles code thats to be evaluated and sends response to uart device
-function handleCode(code) {
-  log('evaluating: >>>\r\n ' + code + ' \r\n>>>EOT');
-  try {
-    evalInContext(code);
-  } catch (err) {
-    fakeConsole.error(err);
-  }
-
-  serialDevice.write(fakeConsole.toString(), function (err) {
-    if (err) {
-      log('error while sending console data: ' + err);
-    } else {
-      fakeConsole.clear();
-    }
-  });
-}
-
-// handles data received from uart device
-function handleData(data) {
-  var arr = data.split(''),
-    chrCode = 0,
-    chr = '',
-    i = 0,
-    l = data.length,
-    localBuff = buffer;
-
-  for (;i < l; ++i) {
-    chr = arr[i];
-    chrCode = chr.charCodeAt(0);
-
-    if (chrCode === 8) { // handle backspace
-      localBuff.splice(localBuff.length - 1, 1);
-      serialDevice.writeSync('\b \b'); // move back, erase by space, move back
-    } else if ((chrCode > 31 && chrCode < 127) || chrCode === 13) {
-      // and only visible chars and new lines
-      localBuff.push(chr);
-      serialDevice.writeSync(uartResponseCodes[chrCode] || chr);
-    }
-
-    if (chrCode === EVALUATE_CODE_CHR) { // evaluate code on EVALUATE_CODE_CHR
-      handleCode(localBuff.join(''));
-      localBuff = []; // clear buffer after code evaluation
-    }
-  }
-
-  buffer = localBuff;
-}
-
-process.on('uncaughtException', function (err) {
-  // code errors need to be cached and redirected to uart console
-  log('uncaught exception: ' + err);
-  fakeConsole.error(err);
-});
-
-serialDevice = uart.open(uartConfig, function (err) {
-  if (err) {
-    log('could not opend device: ' + uartConfig.device + ', reason: ' + err);
-  } else {
-    log('waiting for user input');
-    serialDevice.on('data', handleData);
-  }
-});
diff --git a/samples/udp-chat/chat.js b/samples/udp-chat/chat.js
deleted file mode 100644 (file)
index 5a64cde..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-/**
- * Description:
- *
- * Runs chat-bots which talk to each other using UDP protocol. The first
- * instance will create a server node and the other will connect to it
- * automatically
- *
- * Usage:
- *
- * This example requires multiple iotjs instances on different machines in the
- * same LAN/WIFI network. Each machine should run:
- *
- * $ iotjs chat.js
- *
- * This will handle everything and the "chat" activity will be printed on
- * the console
- */
-
-var dgram = require('dgram'),
-  log_enabled = true,
-  socket = null,
-  mode = 'client', // client / server
-  messages = [ // some sentences to send over udp
-    'Hello! How are you?',
-    'The wether was great last weekend, what did you do?',
-    'Last weekend I was trekking in the mountains, it was great.',
-    'How\'s the family?',
-    'My family is great.',
-    'I have watched a great film yesterday.',
-    'I have to go to the dentist.',
-    'What\'s on your mind?',
-    'It\'s getting late.',
-    'You can do anything you want.',
-    'I love camping in the woods',
-    'Do you like rock music?',
-    'I like pop music.',
-    'I would really like to spend some time with you.',
-    'My dad owns a radio store.',
-    'I had great success with building my business'
-  ],
-  names = [ // few available nicknames
-    'phil',
-    'tom',
-    'kate',
-    'john',
-    'george'
-  ],
-  nickname = '',
-  remote = {},
-  clients = [],
-  MSG = {
-    INQUIRE_SERVER: 'is_anyone_here',
-    INQUIRE_SERVER_ADDR: 'i_am_here_dave',
-    JOIN: 'join',
-    CHAT: 'chat'
-  },
-  joined = false,
-  PORT = 9292,
-  bcastTimer = null,
-  converseTimer = null,
-  CONVERSE_INTERVAL = (1 + (Math.random() * 3)) * 1000, // between 1 and 3
-  BCAST_TTL = 1000, // 1s wait for response
-  BCAST_ADDR = '255.255.255.255';
-
-// log only if log_enabled flag is set to true
-function log(/*...args*/) {
-  if (log_enabled) {
-    console.log.apply(console, [].slice.call(arguments));
-  }
-}
-
-// return a random sentence
-function randomMessage() {
-  return messages[(Math.random() * messages.length) | 0];
-}
-
-// return a random nickname with random "year" suffix
-function randomNickname() {
-  var name = names[(Math.random() * names.length) | 0];
-  return name + '_' + (1980 + ((Math.random() * 30) | 0));
-}
-
-// wraps arguments to JSON string format
-function wrapToString(/*...args*/) {
-  return JSON.stringify([].slice.call(arguments));
-}
-
-// closes socket and releases timers
-function cleanup() {
-  if (socket) {
-    socket.close(function (err) {
-      if (err) {
-        log('ERROR: could not close server: ' + err);
-      } else {
-        log('INFO: server closed');
-      }
-    });
-  }
-
-  if (converseTimer) {
-    clearInterval(converseTimer);
-  }
-
-  if (bcastTimer) {
-    clearTimeout(bcastTimer);
-  }
-}
-
-// sends a random message to udp server/clients
-function converse() {
-  var message = randomMessage(),
-    msg = new Buffer(wrapToString(MSG.CHAT, nickname, message));
-
-  if (mode === 'server') {
-    console.log(nickname + ': ' + message); // log my messages
-    forwardMessageToClients(msg);
-  } else {
-    socket.send(
-      msg,
-      0,
-      msg.length,
-      remote.port,
-      remote.address,
-      function (err) {
-        if (err) {
-          log('ERROR: could not send message: ' + err);
-        }
-    });
-  }
-}
-
-// set server mode if no udp inquire was received
-function bcastTimeoutHandle() {
-  mode = 'server';
-  log('INFO: nobody replied, starting server mode');
-}
-
-// send join message to server and generate nickname
-function join() {
-  var message = new Buffer(wrapToString(MSG.JOIN));
-
-  nickname = randomNickname();
-
-  socket.send(
-    message,
-    0,
-    message.length,
-    remote.port,
-    remote.address,
-    function (err) {
-    if (err) {
-      log('ERROR: could not join: ' + err);
-    } else {
-      log('INFO: joined!');
-      joined = true;
-      converseTimer = setInterval(converse, CONVERSE_INTERVAL);
-    }
-  });
-}
-
-// sends supplied message to connected clients
-function forwardMessageToClients(message) {
-  var i = 0,
-    l = clients.length;
-
-  for (; i < l; ++i) {
-    socket.send(
-      message,
-      0,
-      message.length,
-      clients[i].port,
-      clients[i].address,
-      function (err) {
-      if (err) {
-        log('ERROR: could not send data to client: ' + err);
-      }
-    });
-  }
-}
-
-// handles incomming UDP data
-function handleServerMessage(data, rinfo) {
-  var message = JSON.parse(data.toString());
-
-  switch (message[0]) {
-    case MSG.INQUIRE_SERVER: // when somebody asks for the server addres
-      if (mode === 'server') {
-        log('INFO: host inquiry: ' + rinfo.address + ':' + rinfo.port);
-        message = new Buffer(wrapToString(MSG.INQUIRE_SERVER_ADDR));
-        socket.send(
-          message,
-          0,
-          message.length,
-          rinfo.port,
-          rinfo.address,
-          function (err) {
-          if (err) {
-            log('ERROR: could not respond to inquiry: ' + err);
-          } else {
-            log('INFO: responded');
-          }
-        });
-      }
-      break;
-    case MSG.INQUIRE_SERVER_ADDR: // response with server address
-      if (mode === 'client' && !joined) {
-        remote.port = rinfo.port;
-        remote.address = rinfo.address;
-        clearTimeout(bcastTimer);
-        join();
-      }
-      break;
-    case MSG.JOIN: // when a host joins server chat
-      log('INFO: host joining: ' + rinfo.address + ':' + rinfo.port);
-      clients.push(rinfo);
-      if (!converseTimer) {
-        nickname = randomNickname();
-        converseTimer = setInterval(converse, CONVERSE_INTERVAL);
-      }
-      break;
-    case MSG.CHAT: // plain chat messages
-      console.log(message[1] + ': ' + message[2]); // console here
-                                                   // not log wrap
-      if (mode === 'server') {
-        forwardMessageToClients(data);
-      }
-      break;
-    default: // everything other, should never run
-      log('INFO: i do not understand: ' + data.toString());
-      break;
-  }
-}
-
-
-// check if anyone else is server
-log('INFO: looking up server');
-socket = dgram.createSocket({type: 'udp4'});
-socket.on('message', handleServerMessage);
-socket.bind(PORT, function (err) {
-  var message = new Buffer(wrapToString(MSG.INQUIRE_SERVER));
-  if (err) {
-    log('ERROR: could not bind to server port: ' + err);
-  } else {
-    bcastTimer = setTimeout(bcastTimeoutHandle, BCAST_TTL);
-
-    // first try to find out if any server is available in the network
-    socket.setBroadcast(true);
-    socket.send(
-      message,
-      0,
-      message.length,
-      PORT,
-      BCAST_ADDR,
-      function (err) {
-      if (err) {
-        log('ERROR: could not send broadcast message: ' + err);
-      }
-    });
-  }
-});
-
-process.on('exit', cleanup);
index ef2be5340f6a0eeb9370ed2333f1c247a0f85385..b50b9396e7dd2d8739c45cd805c674aa168d9d36 100644 (file)
 #include "iotjs_def.h"
 
 #include "iotjs.h"
-#include "iotjs_handlewrap.h"
 #include "iotjs_js.h"
 #include "iotjs_string_ext.h"
 
-#include "jerryscript-debugger.h"
-#ifndef __NUTTX__
+#include "jerryscript-ext/debugger.h"
+#if !defined(__NUTTX__) && !defined(__TIZENRT__)
 #include "jerryscript-port-default.h"
 #endif
 #include "jerryscript-port.h"
 #include "jerryscript.h"
 
+#include "iotjs_uv_handle.h"
+
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 
@@ -51,16 +53,20 @@ static bool jerry_initialize(iotjs_environment_t* env) {
   // Initialize jerry.
   jerry_init(jerry_flags);
 
+#ifdef JERRY_DEBUGGER
   if (iotjs_environment_config(env)->debugger != NULL) {
-    jerry_debugger_init(iotjs_environment_config(env)->debugger->port);
+    uint16_t port = iotjs_environment_config(env)->debugger->port;
+    jerryx_debugger_after_connect(jerryx_debugger_tcp_create(port) &&
+                                  jerryx_debugger_ws_create());
 
     if (!jerry_debugger_is_connected()) {
-      DLOG("jerry_debugger_init() failed");
+      DLOG("jerry debugger connection failed");
       return false;
     }
 
     jerry_debugger_continue();
   }
+#endif
 
   // Set magic strings.
   iotjs_register_jerry_magic_string();
@@ -71,14 +77,14 @@ static bool jerry_initialize(iotjs_environment_t* env) {
   // Do parse and run to generate initial javascript environment.
   jerry_value_t parsed_code =
       jerry_parse(NULL, 0, (jerry_char_t*)"", 0, JERRY_PARSE_NO_OPTS);
-  if (jerry_value_has_error_flag(parsed_code)) {
+  if (jerry_value_is_error(parsed_code)) {
     DLOG("jerry_parse() failed");
     jerry_release_value(parsed_code);
     return false;
   }
 
   jerry_value_t ret_val = jerry_run(parsed_code);
-  if (jerry_value_has_error_flag(ret_val)) {
+  if (jerry_value_is_error(ret_val)) {
     DLOG("jerry_run() failed");
     jerry_release_value(parsed_code);
     jerry_release_value(ret_val);
@@ -120,6 +126,29 @@ bool iotjs_initialize(iotjs_environment_t* env) {
 }
 
 
+#ifdef JERRY_DEBUGGER
+void iotjs_restart(iotjs_environment_t* env, jerry_value_t jmain) {
+  jerry_value_t abort_value = jerry_get_value_from_error(jmain, false);
+  if (jerry_value_is_string(abort_value)) {
+    /* TODO: When there is an api function to check for reset,
+    this needs an update. */
+    static const char restart_str[] = "r353t";
+
+    jerry_size_t str_size = jerry_get_string_size(abort_value);
+
+    if (str_size == sizeof(restart_str) - 1) {
+      jerry_char_t str_buf[5];
+      jerry_string_to_char_buffer(abort_value, str_buf, str_size);
+      if (memcmp(restart_str, (char*)(str_buf), str_size) == 0) {
+        iotjs_environment_config(env)->debugger->context_reset = true;
+      }
+    }
+  }
+  jerry_release_value(abort_value);
+}
+#endif
+
+
 void iotjs_run(iotjs_environment_t* env) {
 // Evaluating 'iotjs.js' returns a function.
 #ifndef ENABLE_SNAPSHOT
@@ -127,12 +156,18 @@ void iotjs_run(iotjs_environment_t* env) {
                                            iotjs_s, iotjs_l, false);
 #else
   jerry_value_t jmain =
-      jerry_exec_snapshot((const void*)iotjs_js_modules_s, iotjs_js_modules_l,
-                          module_iotjs_idx, 0);
+      jerry_exec_snapshot((const uint32_t*)iotjs_js_modules_s,
+                          iotjs_js_modules_l, module_iotjs_idx,
+                          JERRY_SNAPSHOT_EXEC_ALLOW_STATIC);
 #endif
 
-  if (jerry_value_has_error_flag(jmain) && !iotjs_environment_is_exiting(env)) {
-    jerry_value_t errval = jerry_get_value_without_error_flag(jmain);
+#ifdef JERRY_DEBUGGER
+  if (jerry_value_is_abort(jmain)) {
+    iotjs_restart(env, jmain);
+  } else
+#endif
+      if (jerry_value_is_error(jmain) && !iotjs_environment_is_exiting(env)) {
+    jerry_value_t errval = jerry_get_value_from_error(jmain, false);
     iotjs_uncaught_exception(errval);
     jerry_release_value(errval);
   }
@@ -158,7 +193,7 @@ static int iotjs_start(iotjs_environment_t* env) {
       more |= iotjs_process_next_tick();
 
       jerry_value_t ret_val = jerry_run_all_enqueued_jobs();
-      if (jerry_value_has_error_flag(ret_val)) {
+      if (jerry_value_is_error(ret_val)) {
         DLOG("jerry_run_all_enqueued_jobs() failed");
       }
 
@@ -183,18 +218,10 @@ static int iotjs_start(iotjs_environment_t* env) {
 }
 
 
-static void iotjs_uv_walk_to_close_callback(uv_handle_t* handle, void* arg) {
-  iotjs_handlewrap_t* handle_wrap = iotjs_handlewrap_from_handle(handle);
-  IOTJS_ASSERT(handle_wrap != NULL);
-
-  iotjs_handlewrap_close(handle_wrap, NULL);
-}
-
-
 void iotjs_end(iotjs_environment_t* env) {
   uv_loop_t* loop = iotjs_environment_loop(env);
   // Close uv loop.
-  uv_walk(loop, iotjs_uv_walk_to_close_callback, NULL);
+  uv_walk(loop, (uv_walk_cb)iotjs_uv_handle_close, NULL);
   uv_run(loop, UV_RUN_DEFAULT);
 
   int res = uv_loop_close(loop);
@@ -220,11 +247,11 @@ int iotjs_entry(int argc, char** argv) {
 
   // Initialize debug log and environments
   iotjs_debuglog_init();
+  srand((unsigned)jerry_port_get_current_time());
 
   iotjs_environment_t* env = iotjs_environment_get();
   if (!iotjs_environment_parse_command_line_arguments(env, (uint32_t)argc,
                                                       argv)) {
-    DLOG("iotjs_environment_parse_command_line_arguments failed");
     ret_code = 1;
     goto exit;
   }
@@ -246,6 +273,7 @@ terminate:
   iotjs_terminate(env);
 
 exit:
+#ifdef JERRY_DEBUGGER
   if (iotjs_environment_config(env)->debugger &&
       iotjs_environment_config(env)->debugger->context_reset) {
     iotjs_environment_release();
@@ -253,6 +281,7 @@ exit:
 
     return iotjs_entry(argc, argv);
   }
+#endif
 
   iotjs_environment_release();
   iotjs_debuglog_release();
index 625eb1c6d021dfc383b0b578f612caa033db0c0f..0af5ca2b5f4d86dc150b5360091e33ac51bd7188 100644 (file)
 #include "iotjs_def.h"
 #include "iotjs_binding.h"
 #include "iotjs_js.h"
+#include "modules/iotjs_module_buffer.h"
 
 #include <string.h>
 
 
-static iotjs_jargs_t jargs_empty;
-
-
 jerry_value_t iotjs_jval_create_string(const iotjs_string_t* v) {
   jerry_value_t jval;
 
@@ -41,7 +39,9 @@ jerry_value_t iotjs_jval_create_string(const iotjs_string_t* v) {
 
 
 jerry_value_t iotjs_jval_create_byte_array(uint32_t len, const char* data) {
-  IOTJS_ASSERT(data != NULL);
+  if (data == NULL) {
+    len = 0;
+  }
 
   jerry_value_t jval = jerry_create_array(len);
 
@@ -67,9 +67,7 @@ jerry_value_t iotjs_jval_create_function(jerry_external_handler_t handler) {
 jerry_value_t iotjs_jval_create_error_without_error_flag(const char* msg) {
   jerry_value_t jval =
       jerry_create_error(JERRY_ERROR_COMMON, (const jerry_char_t*)(msg));
-  jerry_value_clear_error_flag(&jval);
-
-  return jval;
+  return jerry_get_value_from_error(jval, true);
 }
 
 
@@ -85,10 +83,140 @@ double iotjs_jval_as_number(jerry_value_t jval) {
 }
 
 
+bool iotjs_jbuffer_as_string(jerry_value_t jval, iotjs_string_t* out_string) {
+  if (out_string == NULL) {
+    return false;
+  }
+
+  if (jerry_value_is_string(jval)) {
+    jerry_size_t size = jerry_get_string_size(jval);
+
+    if (size == 0) {
+      return false;
+    }
+
+    char* buffer = iotjs_buffer_allocate(size + 1);
+    size_t check =
+        jerry_string_to_char_buffer(jval, (jerry_char_t*)buffer, size);
+
+    IOTJS_ASSERT(check == size);
+
+    buffer[size] = '\0';
+    *out_string = iotjs_string_create_with_buffer(buffer, size);
+    return true;
+  }
+
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_jbuffer_get_bufferwrap_ptr(jval);
+
+  if (buffer_wrap == NULL || buffer_wrap->length == 0) {
+    return false;
+  }
+
+  size_t size = buffer_wrap->length;
+
+  char* buffer = iotjs_buffer_allocate(size + 1);
+  memcpy(buffer, buffer_wrap->buffer, size);
+  buffer[size] = '\0';
+  *out_string = iotjs_string_create_with_buffer(buffer, size);
+  return true;
+}
+
+
+void iotjs_jval_as_tmp_buffer(jerry_value_t jval,
+                              iotjs_tmp_buffer_t* out_buffer) {
+  out_buffer->jval = jerry_create_undefined();
+  out_buffer->buffer = NULL;
+  out_buffer->length = 0;
+
+  if (jerry_value_is_undefined(jval)) {
+    return;
+  }
+
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_jbuffer_get_bufferwrap_ptr(jval);
+
+  if (buffer_wrap != NULL) {
+    IOTJS_ASSERT(buffer_wrap->jobject == jval);
+
+    jerry_acquire_value(jval);
+    out_buffer->jval = buffer_wrap->jobject;
+    out_buffer->buffer = buffer_wrap->buffer;
+    out_buffer->length = buffer_wrap->length;
+    return;
+  }
+
+  bool was_string = true;
+
+  if (!jerry_value_is_string(jval)) {
+    jval = jerry_value_to_string(jval);
+
+    if (jerry_value_is_error(jval)) {
+      out_buffer->jval = jval;
+      return;
+    }
+
+    was_string = false;
+  }
+
+  jerry_size_t size = jerry_get_string_size(jval);
+
+  if (size == 0) {
+    if (!was_string) {
+      jerry_release_value(jval);
+    }
+    return;
+  }
+
+  char* buffer = iotjs_buffer_allocate(size);
+  size_t check = jerry_string_to_char_buffer(jval, (jerry_char_t*)buffer, size);
+
+  IOTJS_ASSERT(check == size);
+
+  out_buffer->buffer = buffer;
+  out_buffer->length = size;
+
+  if (!was_string) {
+    jerry_release_value(jval);
+  }
+}
+
+
+void iotjs_jval_get_jproperty_as_tmp_buffer(jerry_value_t jobj,
+                                            const char* name,
+                                            iotjs_tmp_buffer_t* out_buffer) {
+  jerry_value_t jproperty = iotjs_jval_get_property(jobj, name);
+
+  if (jerry_value_is_error(jproperty)) {
+    out_buffer->jval = jproperty;
+    out_buffer->buffer = NULL;
+    out_buffer->length = 0;
+    return;
+  }
+
+  iotjs_jval_as_tmp_buffer(jproperty, out_buffer);
+
+  jerry_release_value(jproperty);
+}
+
+
+void iotjs_free_tmp_buffer(iotjs_tmp_buffer_t* tmp_buffer) {
+  if (jerry_value_is_undefined(tmp_buffer->jval)) {
+    if (tmp_buffer->buffer != NULL) {
+      iotjs_buffer_release(tmp_buffer->buffer);
+    }
+    return;
+  }
+
+  IOTJS_ASSERT(!jerry_value_is_error(tmp_buffer->jval) ||
+               tmp_buffer->buffer == NULL);
+
+  jerry_release_value(tmp_buffer->jval);
+}
+
+
 iotjs_string_t iotjs_jval_as_string(jerry_value_t jval) {
   IOTJS_ASSERT(jerry_value_is_string(jval));
 
-  jerry_size_t size = jerry_get_string_size(jval);
+  jerry_size_t size = jerry_get_utf8_string_size(jval);
 
   if (size == 0)
     return iotjs_string_create();
@@ -96,7 +224,7 @@ iotjs_string_t iotjs_jval_as_string(jerry_value_t jval) {
   char* buffer = iotjs_buffer_allocate(size + 1);
   jerry_char_t* jerry_buffer = (jerry_char_t*)(buffer);
 
-  size_t check = jerry_string_to_char_buffer(jval, jerry_buffer, size);
+  size_t check = jerry_string_to_utf8_char_buffer(jval, jerry_buffer, size);
 
   IOTJS_ASSERT(check == size);
   buffer[size] = '\0';
@@ -127,7 +255,7 @@ jerry_value_t iotjs_jval_as_function(jerry_value_t jval) {
 
 bool iotjs_jval_set_prototype(const jerry_value_t jobj, jerry_value_t jproto) {
   jerry_value_t ret = jerry_set_prototype(jobj, jproto);
-  bool error_found = jerry_value_has_error_flag(ret);
+  bool error_found = jerry_value_is_error(ret);
   jerry_release_value(ret);
 
   return !error_found;
@@ -152,7 +280,7 @@ void iotjs_jval_set_property_jval(jerry_value_t jobj, const char* name,
   jerry_value_t ret_val = jerry_set_property(jobj, prop_name, value);
   jerry_release_value(prop_name);
 
-  IOTJS_ASSERT(!jerry_value_has_error_flag(ret_val));
+  IOTJS_ASSERT(!jerry_value_is_error(ret_val));
   jerry_release_value(ret_val);
 }
 
@@ -204,7 +332,7 @@ jerry_value_t iotjs_jval_get_property(jerry_value_t jobj, const char* name) {
   jerry_value_t res = jerry_get_property(jobj, prop_name);
   jerry_release_value(prop_name);
 
-  if (jerry_value_has_error_flag(res)) {
+  if (jerry_value_is_error(res)) {
     jerry_release_value(res);
     return jerry_create_undefined();
   }
@@ -213,12 +341,17 @@ jerry_value_t iotjs_jval_get_property(jerry_value_t jobj, const char* name) {
 }
 
 
-uintptr_t iotjs_jval_get_object_native_handle(jerry_value_t jobj) {
+void* iotjs_jval_get_object_native_handle(jerry_value_t jobj,
+                                          JNativeInfoType* required_info) {
   IOTJS_ASSERT(jerry_value_is_object(jobj));
 
-  uintptr_t ptr = 0x0;
+  void* ptr = NULL;
   JNativeInfoType* out_info;
-  jerry_get_object_native_pointer(jobj, (void**)&ptr, &out_info);
+  bool has_p = jerry_get_object_native_pointer(jobj, (void**)&ptr, &out_info);
+
+  if (!has_p || (required_info != NULL && out_info != required_info)) {
+    return NULL;
+  }
 
   return ptr;
 }
@@ -229,7 +362,7 @@ void iotjs_jval_set_property_by_index(jerry_value_t jarr, uint32_t idx,
   IOTJS_ASSERT(jerry_value_is_object(jarr));
 
   jerry_value_t ret_val = jerry_set_property_by_index(jarr, idx, jval);
-  IOTJS_ASSERT(!jerry_value_has_error_flag(ret_val));
+  IOTJS_ASSERT(!jerry_value_is_error(ret_val));
   jerry_release_value(ret_val);
 }
 
@@ -240,7 +373,7 @@ jerry_value_t iotjs_jval_get_property_by_index(jerry_value_t jarr,
 
   jerry_value_t res = jerry_get_property_by_index(jarr, idx);
 
-  if (jerry_value_has_error_flag(res)) {
+  if (jerry_value_is_error(res)) {
     jerry_release_value(res);
     return jerry_create_undefined();
   }
@@ -249,18 +382,6 @@ jerry_value_t iotjs_jval_get_property_by_index(jerry_value_t jarr,
 }
 
 
-jerry_value_t iotjs_jhelper_call(jerry_value_t jfunc, jerry_value_t jthis,
-                                 const iotjs_jargs_t* jargs) {
-  IOTJS_ASSERT(jerry_value_is_object(jfunc));
-
-  jerry_length_t jargc_ = iotjs_jargs_length(jargs);
-
-  jerry_value_t jres = jerry_call_function(jfunc, jthis, jargs->argv, jargc_);
-
-  return jres;
-}
-
-
 jerry_value_t iotjs_jhelper_eval(const char* name, size_t name_len,
                                  const uint8_t* data, size_t size,
                                  bool strict_mode) {
@@ -269,7 +390,7 @@ jerry_value_t iotjs_jhelper_eval(const char* name, size_t name_len,
   jerry_value_t jres = jerry_parse((const jerry_char_t*)name, name_len,
                                    (const jerry_char_t*)data, size, opts);
 
-  if (!jerry_value_has_error_flag(jres)) {
+  if (!jerry_value_is_error(jres)) {
     jerry_value_t func = jres;
     jres = jerry_run(func);
     jerry_release_value(func);
@@ -288,105 +409,3 @@ jerry_value_t vm_exec_stop_callback(void* user_p) {
 
   return jerry_create_string((const jerry_char_t*)"Abort script");
 }
-
-
-iotjs_jargs_t iotjs_jargs_create(uint16_t capacity) {
-  if (capacity == 0) {
-    return jargs_empty;
-  }
-
-  iotjs_jargs_t jargs;
-
-  jargs.capacity = capacity;
-  jargs.argc = 0;
-  unsigned buffer_size = sizeof(jerry_value_t) * capacity;
-  jargs.argv = (jerry_value_t*)iotjs_buffer_allocate(buffer_size);
-
-  return jargs;
-}
-
-
-const iotjs_jargs_t* iotjs_jargs_get_empty() {
-  return &jargs_empty;
-}
-
-
-void iotjs_jargs_destroy(iotjs_jargs_t* jargs) {
-  IOTJS_ASSERT(jargs && jargs->argc <= jargs->capacity);
-
-  if (jargs->capacity > 0) {
-    IOTJS_ASSERT(jargs->argv);
-    for (unsigned i = 0; i < jargs->argc; ++i) {
-      jerry_release_value(jargs->argv[i]);
-    }
-    IOTJS_RELEASE(jargs->argv);
-  } else {
-    IOTJS_ASSERT(jargs->argv == NULL);
-  }
-}
-
-
-uint16_t iotjs_jargs_length(const iotjs_jargs_t* jargs) {
-  IOTJS_ASSERT(jargs);
-  return jargs->argc;
-}
-
-
-void iotjs_jargs_append_jval(iotjs_jargs_t* jargs, jerry_value_t x) {
-  IOTJS_ASSERT(jargs && jargs->argc < jargs->capacity);
-  IOTJS_ASSERT(jargs->argv);
-  jargs->argv[jargs->argc++] = jerry_acquire_value(x);
-}
-
-
-void iotjs_jargs_append_undefined(iotjs_jargs_t* jargs) {
-  iotjs_jargs_append_jval(jargs, jerry_create_undefined());
-}
-
-
-void iotjs_jargs_append_null(iotjs_jargs_t* jargs) {
-  iotjs_jargs_append_jval(jargs, jerry_create_null());
-}
-
-
-void iotjs_jargs_append_bool(iotjs_jargs_t* jargs, bool x) {
-  iotjs_jargs_append_jval(jargs, jerry_create_boolean(x));
-}
-
-
-void iotjs_jargs_append_number(iotjs_jargs_t* jargs, double x) {
-  jerry_value_t jval = jerry_create_number(x);
-  iotjs_jargs_append_jval(jargs, jval);
-  jerry_release_value(jval);
-}
-
-
-void iotjs_jargs_append_string(iotjs_jargs_t* jargs, const iotjs_string_t* x) {
-  jerry_value_t jval = iotjs_jval_create_string(x);
-  iotjs_jargs_append_jval(jargs, jval);
-  jerry_release_value(jval);
-}
-
-
-void iotjs_jargs_append_error(iotjs_jargs_t* jargs, const char* msg) {
-  jerry_value_t error = iotjs_jval_create_error_without_error_flag(msg);
-  iotjs_jargs_append_jval(jargs, error);
-  jerry_release_value(error);
-}
-
-
-void iotjs_jargs_append_string_raw(iotjs_jargs_t* jargs, const char* x) {
-  jerry_value_t jval = jerry_create_string((const jerry_char_t*)x);
-  iotjs_jargs_append_jval(jargs, jval);
-  jerry_release_value(jval);
-}
-
-
-void iotjs_jargs_replace(iotjs_jargs_t* jargs, uint16_t index,
-                         jerry_value_t x) {
-  IOTJS_ASSERT(jargs && index < jargs->argc);
-  IOTJS_ASSERT(jargs->argv);
-
-  jerry_release_value(jargs->argv[index]);
-  jargs->argv[index] = jerry_acquire_value(x);
-}
index 1ee2d8004f45b10293d3c3e4137e5e35beb13cd0..1802e4d4f1ff557c248cc673c778eb44f179013e 100644 (file)
@@ -40,6 +40,22 @@ iotjs_string_t iotjs_jval_as_string(jerry_value_t);
 jerry_value_t iotjs_jval_as_object(jerry_value_t);
 jerry_value_t iotjs_jval_as_array(jerry_value_t);
 jerry_value_t iotjs_jval_as_function(jerry_value_t);
+bool iotjs_jbuffer_as_string(jerry_value_t jval, iotjs_string_t* out_string);
+
+/* Temporary Buffers for JavaScript Values */
+
+typedef struct {
+  jerry_value_t jval;
+  char* buffer;
+  size_t length;
+} iotjs_tmp_buffer_t;
+
+void iotjs_jval_as_tmp_buffer(jerry_value_t jval,
+                              iotjs_tmp_buffer_t* out_buffer);
+void iotjs_jval_get_jproperty_as_tmp_buffer(jerry_value_t jobj,
+                                            const char* name,
+                                            iotjs_tmp_buffer_t* out_buffer);
+void iotjs_free_tmp_buffer(iotjs_tmp_buffer_t* tmp_buffer);
 
 /* Methods for General JavaScript Object */
 void iotjs_jval_set_method(jerry_value_t jobj, const char* name,
@@ -60,45 +76,14 @@ void iotjs_jval_set_property_string_raw(jerry_value_t jobj, const char* name,
 
 jerry_value_t iotjs_jval_get_property(jerry_value_t jobj, const char* name);
 
-uintptr_t iotjs_jval_get_object_native_handle(jerry_value_t jobj);
+void* iotjs_jval_get_object_native_handle(jerry_value_t jobj,
+                                          JNativeInfoType* required_info);
 
 void iotjs_jval_set_property_by_index(jerry_value_t jarr, uint32_t idx,
                                       jerry_value_t jval);
 jerry_value_t iotjs_jval_get_property_by_index(jerry_value_t jarr,
                                                uint32_t idx);
 
-
-typedef struct {
-  uint16_t capacity;
-  uint16_t argc;
-  jerry_value_t* argv;
-} iotjs_jargs_t;
-
-
-iotjs_jargs_t iotjs_jargs_create(uint16_t capacity);
-
-const iotjs_jargs_t* iotjs_jargs_get_empty();
-
-void iotjs_jargs_destroy(iotjs_jargs_t* jargs);
-
-uint16_t iotjs_jargs_length(const iotjs_jargs_t* jargs);
-
-void iotjs_jargs_append_jval(iotjs_jargs_t* jargs, jerry_value_t x);
-void iotjs_jargs_append_undefined(iotjs_jargs_t* jargs);
-void iotjs_jargs_append_null(iotjs_jargs_t* jargs);
-void iotjs_jargs_append_bool(iotjs_jargs_t* jargs, bool x);
-void iotjs_jargs_append_number(iotjs_jargs_t* jargs, double x);
-void iotjs_jargs_append_string(iotjs_jargs_t* jargs, const iotjs_string_t* x);
-void iotjs_jargs_append_string_raw(iotjs_jargs_t* jargs, const char* x);
-void iotjs_jargs_append_error(iotjs_jargs_t* jargs, const char* msg);
-
-
-void iotjs_jargs_replace(iotjs_jargs_t* jargs, uint16_t index, jerry_value_t x);
-
-// Calls JavaScript function.
-jerry_value_t iotjs_jhelper_call(jerry_value_t jfunc, jerry_value_t jthis,
-                                 const iotjs_jargs_t* jargs);
-
 // Evaluates javascript source file.
 jerry_value_t iotjs_jhelper_eval(const char* name, size_t name_len,
                                  const uint8_t* data, size_t size,
@@ -111,6 +96,9 @@ jerry_value_t iotjs_jhelper_eval(const char* name, size_t name_len,
 #define JS_CREATE_ERROR(TYPE, message) \
   jerry_create_error(JERRY_ERROR_##TYPE, (const jerry_char_t*)message)
 
+#define jerry_value_is_any(value) true
+#define iotjs_jval_as_any(value) (value)
+
 #define JS_CHECK(predicate)                           \
   if (!(predicate)) {                                 \
     return JS_CREATE_ERROR(COMMON, "Internal error"); \
@@ -180,43 +168,50 @@ jerry_value_t iotjs_jhelper_eval(const char* name, size_t name_len,
 #define DJS_CHECK_ARG_IF_EXIST(index, type) JS_CHECK_ARG_IF_EXIST(index, type)
 #endif
 
-#define __JS_DECLARE_PTR(type, name, value)                                  \
-  iotjs_##type##_t* name;                                                    \
+#define JS_DECLARE_PTR(JOBJ, TYPE, NAME)                                     \
+  TYPE* NAME;                                                                \
   do {                                                                       \
-    JNativeInfoType* out_native_info;                                        \
-    jerry_get_object_native_pointer(value, (void**)&name, &out_native_info); \
-    if (!name || out_native_info != &this_module_native_info) {              \
-      return JS_CREATE_ERROR(COMMON, "");                                    \
+    NAME =                                                                   \
+        iotjs_jval_get_object_native_handle(JOBJ, &this_module_native_info); \
+    if (NAME == NULL) {                                                      \
+      return JS_CREATE_ERROR(COMMON, "Internal");                            \
     }                                                                        \
   } while (0)
 
-#define JS_DECLARE_THIS_PTR(type, name) __JS_DECLARE_PTR(type, name, jthis)
+#define JS_DECLARE_THIS_PTR(type, name) \
+  JS_DECLARE_PTR(jthis, iotjs_##type##_t, name)
 
 #define JS_DECLARE_OBJECT_PTR(index, type, name) \
-  __JS_DECLARE_PTR(type, name, jargv[index])
+  JS_DECLARE_PTR(jargv[index], iotjs_##type##_t, name)
 
-#define __JS_GET_REQUIRED_VALUE(target, property, type, value)              \
+#define JS_GET_REQUIRED_ARG_VALUE(index, target, property, type)            \
   do {                                                                      \
+    if (jerry_value_is_undefined(jargv[index])) {                           \
+      return JS_CREATE_ERROR(TYPE, "Missing argument, required " property); \
+    } else if (jerry_value_is_##type(jargv[index])) {                       \
+      target = iotjs_jval_as_##type(jargv[index]);                          \
+    } else {                                                                \
+      return JS_CREATE_ERROR(TYPE, "Bad arguments, required " property      \
+                                   " is not a " #type);                     \
+    }                                                                       \
+  } while (0)
+
+#define JS_GET_REQUIRED_CONF_VALUE(src, target, property, type)             \
+  do {                                                                      \
+    jerry_value_t value = iotjs_jval_get_property(src, property);           \
     if (jerry_value_is_undefined(value)) {                                  \
+      jerry_release_value(value);                                           \
       return JS_CREATE_ERROR(TYPE, "Missing argument, required " property); \
     } else if (jerry_value_is_##type(value)) {                              \
       target = iotjs_jval_as_##type(value);                                 \
+      jerry_release_value(value);                                           \
     } else {                                                                \
+      jerry_release_value(value);                                           \
       return JS_CREATE_ERROR(TYPE, "Bad arguments, required " property      \
                                    " is not a " #type);                     \
     }                                                                       \
   } while (0)
 
-#define JS_GET_REQUIRED_ARG_VALUE(index, target, property, type) \
-  __JS_GET_REQUIRED_VALUE(target, property, type, jargv[index])
-
-#define JS_GET_REQUIRED_CONF_VALUE(src, target, property, type)  \
-  do {                                                           \
-    jerry_value_t jtmp = iotjs_jval_get_property(src, property); \
-    __JS_GET_REQUIRED_VALUE(target, property, type, jtmp);       \
-    jerry_release_value(jtmp);                                   \
-  } while (0)
-
 jerry_value_t vm_exec_stop_callback(void* user_p);
 
 /**
index 3c6caf5f8401792fe48ea33d844fd26665f777b6..595b41acec486a2028af3b02de1b416a0b1f733a 100644 (file)
@@ -27,15 +27,12 @@ void iotjs_uncaught_exception(jerry_value_t jexception) {
       iotjs_jval_get_property(process, IOTJS_MAGIC_STRING__ONUNCAUGHTEXCEPTION);
   IOTJS_ASSERT(jerry_value_is_function(jonuncaughtexception));
 
-  iotjs_jargs_t args = iotjs_jargs_create(1);
-  iotjs_jargs_append_jval(&args, jexception);
-
-  jerry_value_t jres = iotjs_jhelper_call(jonuncaughtexception, process, &args);
+  jerry_value_t jres =
+      jerry_call_function(jonuncaughtexception, process, &jexception, 1);
 
-  iotjs_jargs_destroy(&args);
   jerry_release_value(jonuncaughtexception);
 
-  if (jerry_value_has_error_flag(jres)) {
+  if (jerry_value_is_error(jres)) {
     iotjs_environment_t* env = iotjs_environment_get();
 
     if (!iotjs_environment_is_exiting(env)) {
@@ -55,16 +52,14 @@ void iotjs_process_emit_exit(int code) {
       iotjs_jval_get_property(process, IOTJS_MAGIC_STRING_EMITEXIT);
 
   if (jerry_value_is_function(jexit)) {
-    iotjs_jargs_t jargs = iotjs_jargs_create(1);
-    iotjs_jargs_append_number(&jargs, code);
+    jerry_value_t jcode = jerry_create_number(code);
+    jerry_value_t jres = jerry_call_function(jexit, process, &jcode, 1);
 
-    jerry_value_t jres = iotjs_jhelper_call(jexit, process, &jargs);
-
-    if (jerry_value_has_error_flag(jres)) {
+    if (jerry_value_is_error(jres)) {
       iotjs_set_process_exitcode(2);
     }
 
-    iotjs_jargs_destroy(&jargs);
+    jerry_release_value(jcode);
     jerry_release_value(jres);
   }
 
@@ -87,12 +82,11 @@ bool iotjs_process_next_tick() {
   IOTJS_ASSERT(jerry_value_is_function(jon_next_tick));
 
   jerry_value_t jres =
-      iotjs_jhelper_call(jon_next_tick, jerry_create_undefined(),
-                         iotjs_jargs_get_empty());
+      jerry_call_function(jon_next_tick, jerry_create_undefined(), NULL, 0);
 
   bool ret = false;
 
-  if (!jerry_value_has_error_flag(jres)) {
+  if (!jerry_value_is_error(jres)) {
     ret = iotjs_jval_as_boolean(jres);
   }
 
@@ -106,25 +100,27 @@ bool iotjs_process_next_tick() {
 // Make a callback for the given `function` with `this_` binding and `args`
 // arguments. The next tick callbacks registered via `process.nextTick()`
 // will be called after the callback function `function` returns.
-void iotjs_make_callback(jerry_value_t jfunction, jerry_value_t jthis,
-                         const iotjs_jargs_t* jargs) {
+void iotjs_invoke_callback(jerry_value_t jfunc, jerry_value_t jthis,
+                           const jerry_value_t* jargv, size_t jargc) {
   jerry_value_t result =
-      iotjs_make_callback_with_result(jfunction, jthis, jargs);
+      iotjs_invoke_callback_with_result(jfunc, jthis, jargv, jargc);
   jerry_release_value(result);
 }
 
+jerry_value_t iotjs_invoke_callback_with_result(jerry_value_t jfunc,
+                                                jerry_value_t jthis,
+                                                const jerry_value_t* jargv,
+                                                size_t jargc) {
+  IOTJS_ASSERT(jerry_value_is_function(jfunc));
 
-jerry_value_t iotjs_make_callback_with_result(jerry_value_t jfunction,
-                                              jerry_value_t jthis,
-                                              const iotjs_jargs_t* jargs) {
   // If the environment is already exiting just return an undefined value.
   if (iotjs_environment_is_exiting(iotjs_environment_get())) {
     return jerry_create_undefined();
   }
   // Calls back the function.
-  jerry_value_t jres = iotjs_jhelper_call(jfunction, jthis, jargs);
-  if (jerry_value_has_error_flag(jres)) {
-    jerry_value_t errval = jerry_get_value_without_error_flag(jres);
+  jerry_value_t jres = jerry_call_function(jfunc, jthis, jargv, jargc);
+  if (jerry_value_is_error(jres)) {
+    jerry_value_t errval = jerry_get_value_from_error(jres, false);
     iotjs_uncaught_exception(errval);
     jerry_release_value(errval);
   }
@@ -144,12 +140,16 @@ int iotjs_process_exitcode() {
       iotjs_jval_get_property(process, IOTJS_MAGIC_STRING_EXITCODE);
   uint8_t exitcode = 0;
   jerry_value_t num_val = jerry_value_to_number(jexitcode);
-  if (jerry_value_has_error_flag(num_val)) {
+  if (jerry_value_is_error(num_val)) {
     exitcode = 1;
-    jerry_value_clear_error_flag(&num_val);
   } else {
     exitcode = (uint8_t)iotjs_jval_as_number(num_val);
   }
+
+  uint8_t native_exitcode = iotjs_environment_get()->exitcode;
+  if (native_exitcode != exitcode && native_exitcode) {
+    exitcode = native_exitcode;
+  }
   jerry_release_value(num_val);
   jerry_release_value(jexitcode);
   return (int)exitcode;
@@ -158,5 +158,15 @@ int iotjs_process_exitcode() {
 
 void iotjs_set_process_exitcode(int code) {
   const jerry_value_t process = iotjs_module_get("process");
-  iotjs_jval_set_property_number(process, IOTJS_MAGIC_STRING_EXITCODE, code);
+  jerry_value_t jstring =
+      jerry_create_string((jerry_char_t*)IOTJS_MAGIC_STRING_EXITCODE);
+  jerry_value_t jcode = jerry_create_number(code);
+  jerry_value_t ret_val = jerry_set_property(process, jstring, jcode);
+  if (jerry_value_is_error(ret_val)) {
+    iotjs_environment_get()->exitcode = 1;
+  }
+
+  jerry_release_value(ret_val);
+  jerry_release_value(jstring);
+  jerry_release_value(jcode);
 }
index 3bcc3dd2065fbff47dbb820859195207fb08c258..c852572fe13d63871cfecfd73c6099e62221239b 100644 (file)
@@ -26,12 +26,12 @@ void iotjs_process_emit_exit(int code);
 
 bool iotjs_process_next_tick();
 
-void iotjs_make_callback(jerry_value_t jfunction, jerry_value_t jthis,
-                         const iotjs_jargs_t* jargs);
-
-jerry_value_t iotjs_make_callback_with_result(jerry_value_t jfunction,
-                                              jerry_value_t jthis,
-                                              const iotjs_jargs_t* jargs);
+void iotjs_invoke_callback(jerry_value_t jfunc, jerry_value_t jthis,
+                           const jerry_value_t* jargv, size_t jargc);
+jerry_value_t iotjs_invoke_callback_with_result(jerry_value_t jfunc,
+                                                jerry_value_t jthis,
+                                                const jerry_value_t* jargv,
+                                                size_t jargc);
 
 int iotjs_process_exitcode();
 void iotjs_set_process_exitcode(int code);
diff --git a/src/iotjs_compatibility.h b/src/iotjs_compatibility.h
new file mode 100644 (file)
index 0000000..b65f8b9
--- /dev/null
@@ -0,0 +1,43 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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 IOTJS_COMPATIBILITY_H
+#define IOTJS_COMPATIBILITY_H
+
+/* Windows compatiblity defines */
+#ifdef WIN32
+#include <fcntl.h>
+#include <windows.h>
+/* Map windows _O_* to O_* defines as on Linux systems. */
+#define O_APPEND _O_APPEND
+#define O_CREAT _O_CREAT
+#define O_EXCL _O_EXCL
+#define O_RDONLY _O_RDONLY
+#define O_RDWR _O_RDWR
+#define O_TRUNC _O_TRUNC
+#define O_WRONLY _O_WRONLY
+/* On windows there is no O_SYNC directly, disable it for now. */
+#define O_SYNC 0x0
+
+#ifndef PATH_MAX
+#define PATH_MAX MAX_PATH
+#endif
+
+#endif
+
+#ifndef S_ISREG
+#define S_ISREG(mode) (((mode) & (S_IFMT)) == S_IFREG)
+#endif
+
+#endif /* IOTJS_COMPATIBILITY_H */
index fb35ca68038ec3da06fc41f931032a1435daf508..3a5417ce8de74e2f06baf2bbe3855e4760a3bea2 100644 (file)
@@ -70,11 +70,13 @@ extern void force_terminate();
 #define TARGET_OS "darwin"
 #elif defined(__TIZENRT__)
 #define TARGET_OS "tizenrt"
-#else /* !__linux__ && !__NUTTX__ !__APPLE__ && !__TIZENRT__*/
+#elif defined(WIN32)
+#define TARGET_OS "windows"
+#else /* !__linux__ && !__NUTTX__ !__APPLE__ && !__TIZENRT__ && !WIN32 */
 #define TARGET_OS "unknown"
 #endif /* __linux__ */
 
-#define IOTJS_VERSION "1.0.0"
+#define IOTJS_VERSION "1.0.0" "181221_630f029"
 
 #if !defined(STRINGIFY)
 #define STRINGIFY(x) #x
index e15dea4003af5dd8623dade67627ee4b7075faf1..e6df9c0a5a4d9f3b4ea4cbba0a71ccba40c5b69d 100644 (file)
@@ -24,9 +24,11 @@ typedef enum {
   OPT_HELP,
   OPT_MEM_STATS,
   OPT_SHOW_OP,
+#ifdef JERRY_DEBUGGER
   OPT_DEBUG_SERVER,
   OPT_DEBUGGER_WAIT_SOURCE,
   OPT_DEBUG_PORT,
+#endif
   NUM_OF_OPTIONS
 } cli_option_id_t;
 
@@ -66,7 +68,9 @@ void iotjs_environment_release() {
     return;
 
   iotjs_environment_t* env = iotjs_environment_get();
+#ifdef JERRY_DEBUGGER
   IOTJS_RELEASE(env->config.debugger);
+#endif
   IOTJS_RELEASE(env->argv);
   initialized = false;
 }
@@ -79,7 +83,10 @@ static void initialize(iotjs_environment_t* env) {
   env->state = kInitializing;
   env->config.memstat = false;
   env->config.show_opcode = false;
+#ifdef JERRY_DEBUGGER
   env->config.debugger = NULL;
+#endif
+  env->exitcode = 0;
 }
 
 
@@ -107,6 +114,7 @@ bool iotjs_environment_parse_command_line_arguments(iotjs_environment_t* env,
         .longopt = "show-opcodes",
         .help = "dump parser byte-code",
     },
+#ifdef JERRY_DEBUGGER
     {
         .id = OPT_DEBUG_SERVER,
         .opt = "d",
@@ -125,6 +133,7 @@ bool iotjs_environment_parse_command_line_arguments(iotjs_environment_t* env,
         .more = 1,
         .help = "debug server port (default: 5001)",
     },
+#endif
   };
 
   const cli_option_t* cur_opt;
@@ -167,14 +176,17 @@ bool iotjs_environment_parse_command_line_arguments(iotjs_environment_t* env,
       case OPT_SHOW_OP: {
         env->config.show_opcode = true;
       } break;
+#ifdef JERRY_DEBUGGER
+      case OPT_DEBUGGER_WAIT_SOURCE:
       case OPT_DEBUG_SERVER: {
         if (!env->config.debugger) {
           env->config.debugger =
               (DebuggerConfig*)iotjs_buffer_allocate(sizeof(DebuggerConfig));
         }
         env->config.debugger->port = 5001;
-        env->config.debugger->wait_source = false;
         env->config.debugger->context_reset = false;
+        env->config.debugger->wait_source =
+            cur_opt->id == OPT_DEBUGGER_WAIT_SOURCE;
       } break;
       case OPT_DEBUG_PORT: {
         if (env->config.debugger) {
@@ -182,10 +194,7 @@ bool iotjs_environment_parse_command_line_arguments(iotjs_environment_t* env,
           env->config.debugger->port = (uint16_t)strtoul(argv[i + 1], &pos, 10);
         }
       } break;
-      case OPT_DEBUGGER_WAIT_SOURCE: {
-        if (env->config.debugger)
-          env->config.debugger->wait_source = true;
-      } break;
+#endif
       default:
         break;
     }
@@ -194,10 +203,12 @@ bool iotjs_environment_parse_command_line_arguments(iotjs_environment_t* env,
     i += (1 + cur_opt->more);
   }
 
+#ifdef JERRY_DEBUGGER
   // If IoT.js is waiting for source from the debugger client,
   // Further processing over command line argument is not needed.
   if (env->config.debugger && env->config.debugger->wait_source)
     return true;
+#endif
 
   // There must be at least one argument after processing the IoT.js args,
   if (argc - i < 1) {
index d5041b06f7ab626a30d10cbe1fc8ffbcdb4c7a37..23b4017d32c369b5d4d4a35fbbfa4a817208dfeb 100644 (file)
 
 #include "uv.h"
 
+#ifdef JERRY_DEBUGGER
 typedef struct {
   bool wait_source;
   bool context_reset;
   uint16_t port;
 } DebuggerConfig;
+#endif
 
 typedef struct {
   uint32_t memstat : 1;
   uint32_t show_opcode : 1;
+#ifdef JERRY_DEBUGGER
   DebuggerConfig* debugger;
+#endif
 } Config;
 
 typedef enum {
@@ -53,6 +57,9 @@ typedef struct {
 
   // Run config
   Config config;
+
+  // Exitcode
+  uint8_t exitcode;
 } iotjs_environment_t;
 
 
@@ -70,7 +77,9 @@ uv_loop_t* iotjs_environment_loop(const iotjs_environment_t* env);
 void iotjs_environment_set_loop(iotjs_environment_t* env, uv_loop_t* loop);
 
 const Config* iotjs_environment_config(const iotjs_environment_t* env);
+#ifdef JERRY_DEBUGGER
 const DebuggerConfig* iotjs_environment_dconfig(const iotjs_environment_t* env);
+#endif
 
 void iotjs_environment_set_state(iotjs_environment_t* env, State s);
 bool iotjs_environment_is_exiting(iotjs_environment_t* env);
diff --git a/src/iotjs_handlewrap.c b/src/iotjs_handlewrap.c
deleted file mode 100644 (file)
index 50b5be5..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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 "iotjs_def.h"
-#include "iotjs_handlewrap.h"
-
-
-void iotjs_handlewrap_initialize(iotjs_handlewrap_t* handlewrap,
-                                 jerry_value_t jobject, uv_handle_t* handle,
-                                 JNativeInfoType* native_info) {
-  // Increase ref count of Javascript object to guarantee it is alive until the
-  // handle has closed.
-  jerry_value_t jobjectref = jerry_acquire_value(jobject);
-  handlewrap->jobject = jobjectref;
-  jerry_set_object_native_pointer(jobjectref, handlewrap, native_info);
-
-  handlewrap->handle = handle;
-  handlewrap->on_close_cb = NULL;
-
-  handle->data = handlewrap;
-
-  iotjs_handlewrap_validate(handlewrap);
-}
-
-
-void iotjs_handlewrap_destroy(iotjs_handlewrap_t* handlewrap) {
-  // Handle should have been release before this.
-  IOTJS_ASSERT(handlewrap->handle == NULL);
-}
-
-
-iotjs_handlewrap_t* iotjs_handlewrap_from_handle(uv_handle_t* handle) {
-  iotjs_handlewrap_t* handlewrap = (iotjs_handlewrap_t*)(handle->data);
-  iotjs_handlewrap_validate(handlewrap);
-  return handlewrap;
-}
-
-
-iotjs_handlewrap_t* iotjs_handlewrap_from_jobject(jerry_value_t jobject) {
-  iotjs_handlewrap_t* handlewrap =
-      (iotjs_handlewrap_t*)(iotjs_jval_get_object_native_handle(jobject));
-  iotjs_handlewrap_validate(handlewrap);
-  return handlewrap;
-}
-
-
-uv_handle_t* iotjs_handlewrap_get_uv_handle(iotjs_handlewrap_t* handlewrap) {
-  iotjs_handlewrap_validate(handlewrap);
-  return handlewrap->handle;
-}
-
-
-jerry_value_t iotjs_handlewrap_jobject(iotjs_handlewrap_t* handlewrap) {
-  iotjs_handlewrap_validate(handlewrap);
-  return handlewrap->jobject;
-}
-
-
-static void iotjs_handlewrap_on_close(iotjs_handlewrap_t* handlewrap) {
-  // The handle closed.
-  // Calls registered close handler function.
-  if (handlewrap->on_close_cb) {
-    handlewrap->on_close_cb(handlewrap->handle);
-  }
-
-  // Set handle null.
-  handlewrap->handle = NULL;
-
-  // Decrease ref count of Javascript object. From now the object can be
-  // reclaimed.
-  jerry_release_value(handlewrap->jobject);
-}
-
-
-static void iotjs_on_handle_closed(uv_handle_t* handle) {
-  iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_handle(handle);
-  iotjs_handlewrap_on_close(handlewrap);
-}
-
-
-void iotjs_handlewrap_close(iotjs_handlewrap_t* handlewrap,
-                            OnCloseHandler on_close_cb) {
-  if (handlewrap->handle != NULL && !uv_is_closing(handlewrap->handle)) {
-    handlewrap->on_close_cb = on_close_cb;
-    uv_close(handlewrap->handle, iotjs_on_handle_closed);
-  } else {
-    DDLOG("Attempt to close uninitialized or already closed handle");
-  }
-}
-
-
-void iotjs_handlewrap_validate(iotjs_handlewrap_t* handlewrap) {
-  IOTJS_ASSERT(handlewrap);
-  IOTJS_ASSERT((void*)handlewrap == handlewrap->handle->data);
-  IOTJS_ASSERT((uintptr_t)handlewrap ==
-               iotjs_jval_get_object_native_handle(handlewrap->jobject));
-}
diff --git a/src/iotjs_handlewrap.h b/src/iotjs_handlewrap.h
deleted file mode 100644 (file)
index 4994456..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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 IOTJS_HANDLEWRAP_H
-#define IOTJS_HANDLEWRAP_H
-
-
-#include <uv.h>
-
-#include "iotjs_binding.h"
-
-
-typedef void (*OnCloseHandler)(uv_handle_t*);
-
-
-// UV handle wrapper.
-// This wrapper connects a Javascript object and a libuv handler.
-// This wrapper will increase ref count for the Javascript object and decrease
-//  it after corresponding handle has closed. Hence the Javascript object will
-//  not turn into garbage until the handle is open.
-
-// Javascript object
-//   ->
-// Create a handle wrap, initializing uv handle, increase ref count.
-//   ->
-// The javascript object will be alive until handle has closed.
-//   ->
-// Handle closed, release handle, decrease ref count.
-//   ->
-// The javascript object now can be reclaimed by GC.
-
-typedef struct {
-  jerry_value_t jobject;
-  uv_handle_t* handle;
-  OnCloseHandler on_close_cb;
-} iotjs_handlewrap_t;
-
-
-// jobject: Object that connect with the uv handle
-void iotjs_handlewrap_initialize(iotjs_handlewrap_t* handlewrap,
-                                 jerry_value_t jobject, uv_handle_t* handle,
-                                 JNativeInfoType* native_info);
-
-void iotjs_handlewrap_destroy(iotjs_handlewrap_t* handlewrap);
-
-void iotjs_handlewrap_close(iotjs_handlewrap_t* handlewrap,
-                            OnCloseHandler on_close_cb);
-
-iotjs_handlewrap_t* iotjs_handlewrap_from_handle(uv_handle_t* handle);
-iotjs_handlewrap_t* iotjs_handlewrap_from_jobject(jerry_value_t jobject);
-
-uv_handle_t* iotjs_handlewrap_get_uv_handle(iotjs_handlewrap_t* handlewrap);
-jerry_value_t iotjs_handlewrap_jobject(iotjs_handlewrap_t* handlewrap);
-
-void iotjs_handlewrap_validate(iotjs_handlewrap_t* handlewrap);
-
-
-#endif /* IOTJS_HANDLEWRAP_H */
index b4ba182a5c4a9fb25fe1d8e726e7104ae663e262..6437106d8d87f2f3bd83344615aacafc203453fa 100644 (file)
@@ -37,6 +37,9 @@
 #define IOTJS_MAGIC_STRING_ARCH "arch"
 #define IOTJS_MAGIC_STRING_ARGV "argv"
 #define IOTJS_MAGIC_STRING_BASE64 "base64"
+#ifdef ENABLE_MODULE_CRYPTO
+#define IOTJS_MAGIC_STRING_BASE64ENCODE "base64Encode"
+#endif
 #if ENABLE_MODULE_UART
 #define IOTJS_MAGIC_STRING_BAUDRATE "baudRate"
 #endif
@@ -65,6 +68,7 @@
 #endif
 #define IOTJS_MAGIC_STRING_BYTELENGTH "byteLength"
 #define IOTJS_MAGIC_STRING_BYTEPARSED "byteParsed"
+#define IOTJS_MAGIC_STRING_FROM_ARRAYBUFFER "fromArrayBuffer"
 #if ENABLE_MODULE_HTTPS || ENABLE_MODULE_TLS
 #define IOTJS_MAGIC_STRING_CA "ca"
 #define IOTJS_MAGIC_STRING_CERT "cert"
 #endif
 #define IOTJS_MAGIC_STRING_DEBUGGERGETSOURCE "debuggerGetSource"
 #define IOTJS_MAGIC_STRING_DEBUGGERWAITSOURCE "debuggerWaitSource"
+#if ENABLE_MODULE_WEBSOCKET
+#define IOTJS_MAGIC_STRING_DECODEFRAME "decodeFrame"
+#endif
 #define IOTJS_MAGIC_STRING_DEVICE "device"
 #if ENABLE_MODULE_GPIO
 #define IOTJS_MAGIC_STRING_DIRECTION "direction"
 #define IOTJS_MAGIC_STRING_HOME_U "HOME"
 #define IOTJS_MAGIC_STRING_HOST "host"
 #define IOTJS_MAGIC_STRING_HTTPPARSER "HTTPParser"
+#define IOTJS_MAGIC_STRING_HTTP_VERSION_MAJOR "http_major"
+#define IOTJS_MAGIC_STRING_HTTP_VERSION_MINOR "http_minor"
 #if ENABLE_MODULE_GPIO
 #define IOTJS_MAGIC_STRING_IN "IN"
 #endif
 #define IOTJS_MAGIC_STRING_LSB "LSB"
 #define IOTJS_MAGIC_STRING_MAXSPEED "maxSpeed"
 #endif
-#if ENABLE_MODULE_MQTT
+#if ENABLE_MODULE_MQTT || ENABLE_MODULE_WEBSOCKET
 #define IOTJS_MAGIC_STRING_MESSAGE "message"
 #endif
 #define IOTJS_MAGIC_STRING_METHOD "method"
 #if ENABLE_MODULE_MQTT
 #define IOTJS_MAGIC_STRING_MQTTINIT "MqttInit"
 #define IOTJS_MAGIC_STRING_MQTTMESSAGE "MqttMessage"
-#define IOTJS_MAGIC_STRING_MQTTHANDLE "MqttHandle"
+#define IOTJS_MAGIC_STRING_MQTTRECEIVE "MqttReceive"
 #endif
 #if ENABLE_MODULE_SPI
 #define IOTJS_MAGIC_STRING_MSB "MSB"
 #if ENABLE_MODULE_SPI || ENABLE_MODULE_GPIO
 #define IOTJS_MAGIC_STRING_NONE_U "NONE"
 #endif
+#if ENABLE_MODULE_MQTT
+#define IOTJS_MAGIC_STRING_ONACK "onack"
+#endif
 #define IOTJS_MAGIC_STRING_ONBODY "OnBody"
 #define IOTJS_MAGIC_STRING_ONCLOSE "onclose"
 #define IOTJS_MAGIC_STRING_ONCLOSED "onClosed"
-#if ENABLE_MODULE_MQTT
-#define IOTJS_MAGIC_STRING__ONCONNECT "_onconnect"
-#endif
 #define IOTJS_MAGIC_STRING_ONCONNECTION "onconnection"
 #define IOTJS_MAGIC_STRING_ONDATA "onData"
-#ifdef ENABLE_MODULE_MQTT
-#define IOTJS_MAGIC_STRING__ONDISCONNECT "_ondisconnect"
-#endif
 #define IOTJS_MAGIC_STRING_ONEND "onEnd"
 #define IOTJS_MAGIC_STRING_ONERROR "onError"
 #if ENABLE_MODULE_TLS
 #define IOTJS_MAGIC_STRING_ONHEADERSCOMPLETE "OnHeadersComplete"
 #define IOTJS_MAGIC_STRING_ONHEADERS "OnHeaders"
 #define IOTJS_MAGIC_STRING_ONMESSAGECOMPLETE "OnMessageComplete"
-#if ENABLE_MODULE_MQTT
-#define IOTJS_MAGIC_STRING__ONMESSAGE "_onmessage"
-#endif
 #define IOTJS_MAGIC_STRING_ONMESSAGE "onmessage"
 #define IOTJS_MAGIC_STRING__ONNEXTTICK "_onNextTick"
+#if ENABLE_MODULE_WEBSOCKET
+#define IOTJS_MAGIC_STRING_ONPING "onping"
+#endif
+#if ENABLE_MODULE_MQTT || ENABLE_MODULE_WEBSOCKET
+#define IOTJS_MAGIC_STRING_ONPINGRESP "onpingresp"
+#endif
 #if ENABLE_MODULE_MQTT
-#define IOTJS_MAGIC_STRING__ONPINGRESP "_onpingresp"
-#define IOTJS_MAGIC_STRING__ONPUBACK "_onpuback"
-#define IOTJS_MAGIC_STRING__ONPUBCOMP "_onpubcomp"
-#define IOTJS_MAGIC_STRING__ONPUBREC "_onpubrec"
-#define IOTJS_MAGIC_STRING__ONPUBREL "_onpubrel"
+#define IOTJS_MAGIC_STRING_ONPUBREC "onpubrec"
+#define IOTJS_MAGIC_STRING_ONPUBREL "onpubrel"
 #endif
 #define IOTJS_MAGIC_STRING_ONREAD "onread"
 #define IOTJS_MAGIC_STRING_ONSOCKET "onSocket"
-#if ENABLE_MODULE_MQTT
-#define IOTJS_MAGIC_STRING__ONSUBACK "_onsuback"
-#define IOTJS_MAGIC_STRING__ONUNSUBACK "_onunsuback"
-#endif
 #define IOTJS_MAGIC_STRING_ONTIMEOUT "onTimeout"
 #define IOTJS_MAGIC_STRING__ONUNCAUGHTEXCEPTION "_onUncaughtException"
 #if ENABLE_MODULE_TLS
 #define IOTJS_MAGIC_STRING_OUT_U "OUT"
 #endif
 #define IOTJS_MAGIC_STRING_OWNER "owner"
+#if ENABLE_MODULE_WEBSOCKET
+#define IOTJS_MAGIC_STRING_PARSEHANDSHAKEDATA "parseHandshakeData"
+#endif
 #if ENABLE_MODULE_MQTT
-#define IOTJS_MAGIC_STRING_PACKETID "packet_id"
 #define IOTJS_MAGIC_STRING_PASSWORD "password"
 #endif
 #define IOTJS_MAGIC_STRING_PAUSE "pause"
 #define IOTJS_MAGIC_STRING_PERIOD "period"
 #define IOTJS_MAGIC_STRING_PIN "pin"
-#if ENABLE_MODULE_MQTT
+#if ENABLE_MODULE_MQTT || ENABLE_MODULE_WEBSOCKET
 #define IOTJS_MAGIC_STRING_PING "ping"
 #endif
 #define IOTJS_MAGIC_STRING_PLATFORM "platform"
+#if ENABLE_MODULE_WEBSOCKET
+#define IOTJS_MAGIC_STRING_PONG "pong"
+#endif
 #define IOTJS_MAGIC_STRING_PORT "port"
+#if ENABLE_MODULE_WEBSOCKET
+#define IOTJS_MAGIC_STRING_PREPAREHANDSHAKE "prepareHandshake"
+#endif
 #define IOTJS_MAGIC_STRING_PRIVATE "_private"
 #define IOTJS_MAGIC_STRING_PROTOTYPE "prototype"
 #if ENABLE_MODULE_MQTT
 #define IOTJS_MAGIC_STRING_RECVSTOP "recvStop"
 #endif
 #define IOTJS_MAGIC_STRING_REF "ref"
-#define IOTJS_MAGIC_STRING_REINITIALIZE "reinitialize"
 #if ENABLE_MODULE_TLS || ENABLE_MODULE_HTTPS
 #define IOTJS_MAGIC_STRING_REJECTUNAUTHORIZED "rejectUnauthorized"
 #endif
+#if ENABLE_MODULE_MQTT
+#define IOTJS_MAGIC_STRING_REMAINING "remaining"
+#endif
 #define IOTJS_MAGIC_STRING_RENAME "rename"
 #define IOTJS_MAGIC_STRING_REQUEST_U "REQUEST"
 #define IOTJS_MAGIC_STRING_RESPONSE_U "RESPONSE"
 #define IOTJS_MAGIC_STRING_RISING_U "RISING"
 #endif
 #define IOTJS_MAGIC_STRING_RMDIR "rmdir"
+#if ENABLE_MODULE_CRYPTO
+#define IOTJS_MAGIC_STRING_RSAVERIFY "rsaVerify"
+#endif
 #define IOTJS_MAGIC_STRING_SEND "send"
 #if ENABLE_MODULE_MQTT
 #define IOTJS_MAGIC_STRING_SENDACK "sendAck"
 #define IOTJS_MAGIC_STRING_SETADDRESS "setAddress"
 #endif
 #if ENABLE_MODULE_UDP
-#define IOTJS_MAGIC_STRING_SETBROADCAST "setBroadcast"
+#define IOTJS_MAGIC_STRING_CONFIGURE "configure"
+#endif
+#if ENABLE_MODULE_GPIO
+#define IOTJS_MAGIC_STRING_SETDIRECTIONSYNC "setDirectionSync"
 #endif
 #if ENABLE_MODULE_PWM
 #define IOTJS_MAGIC_STRING_SETDUTYCYCLE "setDutyCycle"
 #define IOTJS_MAGIC_STRING_SETFILTER "setFilter"
 #endif
 #define IOTJS_MAGIC_STRING_SETKEEPALIVE "setKeepAlive"
-#define IOTJS_MAGIC_STRING_SETMULTICASTLOOPBACK "setMulticastLoopback"
-#if ENABLE_MODULE_DGRAM
-#define IOTJS_MAGIC_STRING_SETMULTICASTTTL "setMulticastTTL"
-#endif
 #if ENABLE_MODULE_PWM
 #define IOTJS_MAGIC_STRING_SETPERIOD "setPeriod"
 #define IOTJS_MAGIC_STRING_SETPERIODSYNC "setPeriodSync"
 #endif
 #define IOTJS_MAGIC_STRING_SETTIMEOUT "setTimeout"
-#if ENABLE_MODULE_DGRAM
-#define IOTJS_MAGIC_STRING_SETTTL "setTTL"
+#ifdef ENABLE_MODULE_CRYPTO
+#define IOTJS_MAGIC_STRING_SHAENCODE "shaEncode"
 #endif
 #define IOTJS_MAGIC_STRING_SHOULDKEEPALIVE "shouldkeepalive"
 #define IOTJS_MAGIC_STRING_SHUTDOWN "shutdown"
 #if ENABLE_MODULE_HTTPS
 #define IOTJS_MAGIC_STRING__WRITE "_write"
 #endif
+#ifdef ENABLE_MODULE_WEBSOCKET
+#define IOTJS_MAGIC_STRING_WSINIT "wsInit"
+#define IOTJS_MAGIC_STRING_WSRECEIVE "wsReceive"
+#define IOTJS_MAGIC_STRING_WSRECEIVEHANDSHAKEDATA "ReceiveHandshakeData"
+#endif
 #if ENABLE_MODULE_BRIDGE
 #define IOTJS_MAGIC_STRING_MODULE_NAME "MODULE_NAME"
 #endif
diff --git a/src/iotjs_reqwrap.c b/src/iotjs_reqwrap.c
deleted file mode 100644 (file)
index 60da0af..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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 "iotjs_def.h"
-#include "iotjs_reqwrap.h"
-
-
-void iotjs_reqwrap_initialize(iotjs_reqwrap_t* reqwrap, jerry_value_t jcallback,
-                              uv_req_t* request) {
-  reqwrap->jcallback = jerry_acquire_value(jcallback);
-  reqwrap->request = request;
-  reqwrap->request->data = reqwrap;
-}
-
-
-void iotjs_reqwrap_destroy(iotjs_reqwrap_t* reqwrap) {
-  jerry_release_value(reqwrap->jcallback);
-}
-
-
-static void iotjs_reqwrap_validate(iotjs_reqwrap_t* reqwrap) {
-  IOTJS_ASSERT(reqwrap->request->data == reqwrap);
-}
-
-
-jerry_value_t iotjs_reqwrap_jcallback(iotjs_reqwrap_t* reqwrap) {
-  iotjs_reqwrap_validate(reqwrap);
-  return reqwrap->jcallback;
-}
-
-
-uv_req_t* iotjs_reqwrap_req(iotjs_reqwrap_t* reqwrap) {
-  iotjs_reqwrap_validate(reqwrap);
-  return reqwrap->request;
-}
-
-
-iotjs_reqwrap_t* iotjs_reqwrap_from_request(uv_req_t* req) {
-  iotjs_reqwrap_t* reqwrap = req->data;
-  iotjs_reqwrap_validate(reqwrap);
-  return reqwrap;
-}
diff --git a/src/iotjs_reqwrap.h b/src/iotjs_reqwrap.h
deleted file mode 100644 (file)
index 2f41eed..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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 IOTJS_REQWRAP_H
-#define IOTJS_REQWRAP_H
-
-
-#include <uv.h>
-
-#include "iotjs_binding.h"
-
-
-// UV request wrapper.
-// Wrapping UV request and JavaScript callback.
-// When an instance of request wrapper is created. it will increase ref count
-// for JavaScript callback function to prevent it from reclaimed by GC. The
-// reference count will decrease back when wrapper is being freed.
-typedef struct {
-  jerry_value_t jcallback;
-  uv_req_t* request;
-} iotjs_reqwrap_t;
-
-
-void iotjs_reqwrap_initialize(iotjs_reqwrap_t* reqwrap, jerry_value_t jcallback,
-                              uv_req_t* request);
-void iotjs_reqwrap_destroy(iotjs_reqwrap_t* reqwrap);
-
-// To retrieve javascript callback function object.
-jerry_value_t iotjs_reqwrap_jcallback(iotjs_reqwrap_t* reqwrap);
-
-// To retrieve pointer to uv request.
-uv_req_t* iotjs_reqwrap_req(iotjs_reqwrap_t* reqwrap);
-
-
-iotjs_reqwrap_t* iotjs_reqwrap_from_request(uv_req_t* req);
-
-
-#endif /* IOTJS_REQWRAP_H */
index b4fddc1177cc7bfd139ad22eba009460a063c619..c8a4f95f164186be11c9c4cd4f206efc36080b27 100644 (file)
@@ -36,8 +36,7 @@ iotjs_string_t iotjs_string_create_with_size(const char* data, size_t size) {
 
   str.size = size;
 
-  if (size > 0) {
-    IOTJS_ASSERT(data != NULL);
+  if (data && size > 0) {
     str.data = iotjs_buffer_allocate(size);
     memcpy(str.data, data, size);
   } else {
@@ -77,7 +76,7 @@ bool iotjs_string_is_empty(const iotjs_string_t* str) {
 void iotjs_string_append(iotjs_string_t* str, const char* data, size_t size) {
   IOTJS_ASSERT(data != NULL);
 
-  if (size == 0) {
+  if (data == NULL || size == 0) {
     return;
   }
 
index 9cadefbac5096684081e28fa42f144c2d3c04693..4f28c420b3d3f0bc5cc7365e3ce69e88204f89aa 100644 (file)
@@ -48,9 +48,9 @@ static const jerry_length_t magic_string_lengths[] = {
 //
 // declare strings table
 //
-static const jerry_char_ptr_t magic_string_items[] = {
+static const jerry_char_t *const magic_string_items[] = {
 #define MAGICSTR_EX_DEF(NAME, STRING) \
-  (const jerry_char_ptr_t) jerry_magic_string_ex_##NAME,
+  (const jerry_char_t *)jerry_magic_string_ex_##NAME,
 
   JERRY_MAGIC_STRING_ITEMS
 
@@ -60,7 +60,7 @@ static const jerry_char_ptr_t magic_string_items[] = {
 
 void iotjs_register_jerry_magic_string(void) {
   uint32_t num_magic_string_items =
-      (uint32_t)(sizeof(magic_string_items) / sizeof(jerry_char_ptr_t));
+      (uint32_t)(sizeof(magic_string_items) / sizeof(jerry_char_t *));
   jerry_register_magic_strings(magic_string_items, num_magic_string_items,
                                magic_string_lengths);
 }
index adccee216159bf97d593523450f1f82d89331700..a8916040070ba8ad6c5fba178c72e433e1325354 100644 (file)
@@ -36,10 +36,10 @@ void iotjs_buffer_release(char* buff);
   (type*)iotjs_buffer_allocate((num * sizeof(type)))
 
 #define IOTJS_RELEASE(ptr) /* Release memory allocated by IOTJS_ALLOC() */ \
-  ({                                                                       \
+  do {                                                                     \
     iotjs_buffer_release((char*)ptr);                                      \
     ptr = NULL;                                                            \
-  })
+  } while (0)
 
 
 #endif /* IOTJS_UTIL_H */
diff --git a/src/iotjs_uv_handle.c b/src/iotjs_uv_handle.c
new file mode 100644 (file)
index 0000000..defa162
--- /dev/null
@@ -0,0 +1,68 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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 "iotjs_def.h"
+
+#include "iotjs_uv_handle.h"
+
+
+uv_handle_t* iotjs_uv_handle_create(size_t handle_size,
+                                    const jerry_value_t jobject,
+                                    JNativeInfoType* native_info,
+                                    size_t extra_data_size) {
+  IOTJS_ASSERT(jerry_value_is_object(jobject));
+
+  /* Make sure that the jerry_value_t is aligned */
+  size_t aligned_request_size = IOTJS_ALIGNUP(handle_size, 8u);
+
+  char* request_memory = iotjs_buffer_allocate(
+      aligned_request_size + sizeof(iotjs_uv_handle_data) + extra_data_size);
+  uv_handle_t* uv_handle = (uv_handle_t*)request_memory;
+  uv_handle->data = request_memory + aligned_request_size;
+
+  IOTJS_UV_HANDLE_DATA(uv_handle)->jobject = jobject;
+  IOTJS_UV_HANDLE_DATA(uv_handle)->on_close_cb = NULL;
+  jerry_acquire_value(jobject);
+
+  jerry_set_object_native_pointer(jobject, uv_handle, native_info);
+
+  return uv_handle;
+}
+
+
+static void iotjs_uv_handle_close_processor(uv_handle_t* handle) {
+  iotjs_uv_handle_data* handle_data = IOTJS_UV_HANDLE_DATA(handle);
+
+  if (handle_data->on_close_cb != NULL) {
+    handle_data->on_close_cb(handle);
+  }
+
+  // Decrease ref count of Javascript object. From now the object can be
+  // reclaimed.
+  jerry_release_value(handle_data->jobject);
+  IOTJS_RELEASE(handle);
+}
+
+
+void iotjs_uv_handle_close(uv_handle_t* handle, OnCloseHandler close_handler) {
+  if (handle == NULL || uv_is_closing(handle)) {
+    DDLOG("Attempt to close uninitialized or already closed handle");
+    return;
+  }
+
+  iotjs_uv_handle_data* handle_data = IOTJS_UV_HANDLE_DATA(handle);
+  handle_data->on_close_cb = close_handler;
+  uv_close(handle, iotjs_uv_handle_close_processor);
+}
diff --git a/src/iotjs_uv_handle.h b/src/iotjs_uv_handle.h
new file mode 100644 (file)
index 0000000..570ff28
--- /dev/null
@@ -0,0 +1,75 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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 IOTJS_UV_HANDLE
+#define IOTJS_UV_HANDLE
+
+#include <uv.h>
+
+#include "iotjs_binding.h"
+
+typedef void (*OnCloseHandler)(uv_handle_t*);
+
+typedef struct {
+  jerry_value_t jobject;
+  OnCloseHandler on_close_cb;
+} iotjs_uv_handle_data;
+
+#define IOTJS_ALIGNUP(value, alignment) \
+  (((value) + ((alignment)-1)) & ~((alignment)-1))
+
+/**
+ * Allocate and initialize an uv_handle_t structure with a jerry callback and
+ * extra data.
+ *
+ * The allocated memory has the following layout:
+ *
+ *  |-------------|  <- start of uv_handle_t*
+ *  | uv_handle_t |
+ *  |             |
+ *  |-------------|
+ *  | PADDING     |  <- alignment padding
+ *  |-------------|  <- start of the iotjs_uv_handle_data struct
+ *  | handle_data |
+ *  |-------------|  <- start of the extra data if required
+ *  |  extra      |
+ *  |-------------|
+ *
+ */
+uv_handle_t* iotjs_uv_handle_create(size_t handle_size,
+                                    const jerry_value_t jobject,
+                                    JNativeInfoType* native_info,
+                                    size_t extra_data_size);
+void iotjs_uv_handle_close(uv_handle_t* handle, OnCloseHandler close_handler);
+
+/**
+ * Returns a pointer to the handle data struct referenced
+ * by the uv_handle_t->data member.
+ */
+#define IOTJS_UV_HANDLE_DATA(UV_HANDLE) \
+  ((iotjs_uv_handle_data*)((UV_HANDLE)->data))
+
+/**
+ * Returns a char* pointer for any extra data.
+ *
+ * IMPORTANT!
+ * Make sure that the extra data is correctly allocated by using the
+ * iotjs_uv_handle_create method call.
+ */
+#define IOTJS_UV_HANDLE_EXTRA_DATA(UV_HANDLE) \
+  ((char*)((char*)((UV_HANDLE)->data) + sizeof(iotjs_uv_handle_data)))
+
+
+#endif /* IOTJS_UV_HANDLE */
diff --git a/src/iotjs_uv_request.c b/src/iotjs_uv_request.c
new file mode 100644 (file)
index 0000000..77acdee
--- /dev/null
@@ -0,0 +1,53 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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 "iotjs_uv_request.h"
+
+#include "iotjs_def.h"
+
+/**
+ * Aligns @a value to @a alignment. @a must be the power of 2.
+ *
+ * Returns minimum positive value, that divides @a alignment and is more than or
+ * equal to @a value
+ */
+#define IOTJS_ALIGNUP(value, alignment) \
+  (((value) + ((alignment)-1)) & ~((alignment)-1))
+
+
+uv_req_t* iotjs_uv_request_create(size_t request_size,
+                                  const jerry_value_t jcallback,
+                                  size_t extra_data_size) {
+  IOTJS_ASSERT(jerry_value_is_function(jcallback));
+
+  /* Make sure that the jerry_value_t is aligned */
+  size_t aligned_request_size = IOTJS_ALIGNUP(request_size, 8u);
+
+  char* request_memory = iotjs_buffer_allocate(
+      aligned_request_size + sizeof(jerry_value_t) + extra_data_size);
+  uv_req_t* uv_request = (uv_req_t*)request_memory;
+  uv_request->data = request_memory + aligned_request_size;
+
+  *IOTJS_UV_REQUEST_JSCALLBACK(uv_request) = jcallback;
+  jerry_acquire_value(jcallback);
+
+  return uv_request;
+}
+
+
+void iotjs_uv_request_destroy(uv_req_t* request) {
+  jerry_release_value(*IOTJS_UV_REQUEST_JSCALLBACK(request));
+  IOTJS_RELEASE(request);
+}
diff --git a/src/iotjs_uv_request.h b/src/iotjs_uv_request.h
new file mode 100644 (file)
index 0000000..a4de22b
--- /dev/null
@@ -0,0 +1,61 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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 IOTJS_UV_REQUEST
+#define IOTJS_UV_REQUEST
+
+#include <uv.h>
+
+#include "iotjs_binding.h"
+
+/**
+ * Allocate and initialize an uv_req_t structure with a jerry callback and extra
+ * data.
+ *
+ * The allocated memory has the following layout:
+ *
+ *  |----------|  <- start of uv_req_t*
+ *  | uv_req_t |
+ *  |          |
+ *  |----------|
+ *  | PADDING  |  <- alignment padding
+ *  |----------|  <- start of jerry_value_t* which is the callback
+ *  | callback |
+ *  |----------|  <- start of the extra data if required
+ *  |  extra   |
+ *  |----------|
+ *
+ */
+uv_req_t* iotjs_uv_request_create(size_t request_size,
+                                  const jerry_value_t jcallback,
+                                  size_t extra_data_size);
+void iotjs_uv_request_destroy(uv_req_t* request);
+
+/**
+ * Returns a pointer to the js callback referenced by the uv_req_t->data member.
+ */
+#define IOTJS_UV_REQUEST_JSCALLBACK(UV_REQ) ((jerry_value_t*)(UV_REQ->data))
+
+/**
+ * Returns a char* pointer for any extra data.
+ *
+ * IMPORTANT!
+ * Make sure that the extra data is correctly allocated via the
+ * iotjs_uv_request_create method call.
+ */
+#define IOTJS_UV_REQUEST_EXTRA_DATA(UV_REQ) \
+  ((char*)((char*)(UV_REQ->data) + sizeof(jerry_value_t)))
+
+#endif /* IOTJS_UV_REQUEST */
index a02e71bcac6dbb26241f18b822ea5ab7200ded85..cbb82bb2eaae99651add0ff2a90776f04e4466e1 100644 (file)
@@ -298,7 +298,7 @@ Hci.prototype.setAdvertisingParameters = function() {
   // length
   cmd.writeUInt8(15, 3);
 
-  var advertisementInterval = Math.floor((process.env.BLENO_ADVERTISING_INTERVAL ? parseInt(process.env.BLENO_ADVERTISING_INTERVAL) : 100) * 1.6);
+  var advertisementInterval = Math.floor((process.env.BLENO_ADVERTISING_INTERVAL ? parseInt(process.env.BLENO_ADVERTISING_INTERVAL) : 100) * '1.6');
 
   // data
   cmd.writeUInt16LE(advertisementInterval, 4); // min interval
@@ -607,7 +607,7 @@ Hci.prototype.processLeConnComplete = function(status, data) {
   var role = data.readUInt8(2);
   var addressType = data.readUInt8(3) === 0x01 ? 'random': 'public';
   var address = uuidUtil.reverseByteOrder(data.slice(4, 10).toString('hex'), ':');
-  var interval = data.readUInt16LE(10) * 1.25;
+  var interval = (data.readUInt16LE(10) * 5) >> 2;
   var latency = data.readUInt16LE(12); // TODO: multiplier?
   var supervisionTimeout = data.readUInt16LE(14) * 10;
   var masterClockAccuracy = data.readUInt8(16); // TODO: multiplier?
@@ -626,7 +626,7 @@ Hci.prototype.processLeConnComplete = function(status, data) {
 
 Hci.prototype.processLeConnUpdateComplete = function(status, data) {
   var handle = data.readUInt16LE(0);
-  var interval = data.readUInt16LE(2) * 1.25;
+  var interval = (data.readUInt16LE(2) * 5) >> 2;
   var latency = data.readUInt16LE(4); // TODO: multiplier?
   var supervisionTimeout = data.readUInt16LE(6) * 10;
 
index ef621d7fb7a683177fb616143f23efa6ae23c12d..46798ca4a7d8e65f922342b29236e7e0c0fed289 100644 (file)
@@ -34,7 +34,7 @@
  * SOFTWARE.
  */
 
-[
+module.exports = [
   "Success",
   "Unknown HCI Command",
   "Unknown Connection Identifier",
   "Connection Failed to be Established",
   "MAC Connection Failed",
   "Coarse Clock Adjustment Rejected but Will Try to Adjust Using Clock Dragging"
-]
+];
index 81cae168ad520a34d858ff9e4a91d9724b5547b4..d55a0f8f9fda70502a80eb9cd070dd057bdaffb7 100644 (file)
@@ -13,8 +13,6 @@
  * limitations under the License.
  */
 
-var util = require('util');
-
 
 function checkInt(buffer, value, offset, ext, max, min) {
   if (value > max || value < min)
@@ -49,15 +47,15 @@ function getEncodingType(encoding) {
 // [4] new Buffer(string, encoding)
 // [5] new Buffer(array)
 function Buffer(subject, encoding) {
-  if (!util.isBuffer(this)) {
+  if (!Buffer.isBuffer(this)) {
     return new Buffer(subject, encoding);
   }
 
-  if (util.isNumber(subject)) {
+  if (typeof subject === 'number') {
     this.length = subject > 0 ? subject >>> 0 : 0;
-  } else if (util.isString(subject)) {
+  } else if (typeof subject === 'string') {
     this.length = Buffer.byteLength(subject, encoding);
-  } else if (util.isBuffer(subject) || util.isArray(subject)) {
+  } else if (Buffer.isBuffer(subject) || Array.isArray(subject)) {
     this.length = subject.length;
   } else {
     throw new TypeError('Bad arguments: Buffer(string|number|Buffer|Array)');
@@ -66,7 +64,7 @@ function Buffer(subject, encoding) {
   // 'native' is the buffer object created via the C API.
   native(this, this.length);
 
-  if (util.isString(subject)) {
+  if (typeof subject === 'string') {
     if (typeof encoding === 'string') {
       encoding = getEncodingType(encoding);
       if (encoding != -1) {
@@ -77,9 +75,9 @@ function Buffer(subject, encoding) {
     } else {
       this.write(subject);
     }
-  } else if (util.isBuffer(subject)) {
+  } else if (Buffer.isBuffer(subject)) {
     subject.copy(this);
-  } else if (util.isArray(subject)) {
+  } else if (Array.isArray(subject)) {
     for (var i = 0; i < this.length; ++i) {
       native.writeUInt8(this, subject[i], i);
     }
@@ -116,14 +114,14 @@ Buffer.byteLength = function(str, encoding) {
 
 // Buffer.concat(list)
 Buffer.concat = function(list) {
-  if (!util.isArray(list)) {
+  if (!Array.isArray(list)) {
     throw new TypeError('Bad arguments: Buffer.concat([Buffer])');
   }
 
   var length = 0;
   var i;
   for (i = 0; i < list.length; ++i) {
-    if (!util.isBuffer(list[i])) {
+    if (!Buffer.isBuffer(list[i])) {
       throw new TypeError('Bad arguments: Buffer.concat([Buffer])');
     }
     length += list[i].length;
@@ -141,12 +139,14 @@ Buffer.concat = function(list) {
 
 
 // Buffer.isBuffer(object)
-Buffer.isBuffer = util.isBuffer;
+Buffer.isBuffer = function(arg) {
+  return arg instanceof Buffer;
+};
 
 
 // buffer.equals(otherBuffer)
 Buffer.prototype.equals = function(otherBuffer) {
-  if (!util.isBuffer(otherBuffer)) {
+  if (!Buffer.isBuffer(otherBuffer)) {
     throw new TypeError('Bad arguments: buffer.equals(Buffer)');
   }
 
@@ -156,7 +156,7 @@ Buffer.prototype.equals = function(otherBuffer) {
 
 // buffer.compare(otherBuffer)
 Buffer.prototype.compare = function(otherBuffer) {
-  if (!util.isBuffer(otherBuffer)) {
+  if (!Buffer.isBuffer(otherBuffer)) {
     throw new TypeError('Bad arguments: buffer.compare(Buffer)');
   }
 
@@ -173,7 +173,7 @@ Buffer.prototype.compare = function(otherBuffer) {
 // * sourceStart - default to 0
 // * sourceEnd - default to buffer.length
 Buffer.prototype.copy = function(target, targetStart, sourceStart, sourceEnd) {
-  if (!util.isBuffer(target)) {
+  if (!Buffer.isBuffer(target)) {
     throw new TypeError('Bad arguments: buff.copy(Buffer)');
   }
 
@@ -196,7 +196,7 @@ Buffer.prototype.copy = function(target, targetStart, sourceStart, sourceEnd) {
 // * offset - default to 0
 // * length - default to buffer.length - offset
 Buffer.prototype.write = function(string, offset, length, encoding) {
-  if (!util.isString(string)) {
+  if (typeof string !== 'string') {
     throw new TypeError('Bad arguments: buff.write(string)');
   }
 
@@ -334,7 +334,7 @@ Buffer.prototype.readUInt16LE = function(offset, noAssert) {
 
 // buff.fill(value)
 Buffer.prototype.fill = function(value) {
-  if (util.isNumber(value)) {
+  if (typeof value === 'number') {
     value = value & 255;
     for (var i = 0; i < this.length; i++) {
       native.writeUInt8(this, value, i);
@@ -344,5 +344,33 @@ Buffer.prototype.fill = function(value) {
 };
 
 
+// Method: Buffer.from()
+// Buffer.from(Array)
+// Buffer.from(string,encoding)
+// Buffer.from(Buffer)
+// Buffer.from(ArrayBuffer)
+function from(value, encoding, length) {
+
+  var arrayBuffer = native.fromArrayBuffer(value, encoding, length);
+
+  if (arrayBuffer) {
+    return arrayBuffer;
+  }
+  if (Buffer.isBuffer(value) || (typeof value) === 'string'
+      || Array.isArray(value)) {
+    return new Buffer(value, encoding);
+  }
+  throw new TypeError('First argument must be' +
+  'a string, Buffer, ArrayBuffer, Array, or array-like object');
+}
+
+
+/* Register the Buffer object back to the native C
+ * so the other side can get the prototype in a consistent
+ * and safe manner.
+ */
+native.Buffer = Buffer;
+
 module.exports = Buffer;
 module.exports.Buffer = Buffer;
+module.exports.from = from;
diff --git a/src/js/crypto.js b/src/js/crypto.js
new file mode 100644 (file)
index 0000000..81c7df5
--- /dev/null
@@ -0,0 +1,137 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var shaTypes = {
+  'sha1': 4,
+  'sha256': 6,
+};
+
+var hashes = ['sha1', 'sha256'];
+
+function Verify(signtype) {
+  if (!(this instanceof Verify)) {
+    return new Verify(signtype);
+  }
+
+  signtype = signtype.toLowerCase();
+
+  if (hashes.indexOf(signtype) < 0) {
+    throw new Error('Unknown signing algorithm.' +
+                    'Please use crypto.getSignatures()');
+  }
+
+  Object.defineProperty(this, 'hashtype', {
+    // defaults to writable: false, configurable: false
+    value: signtype,
+    enumerable: true,
+  });
+}
+
+Verify.prototype.update = function(data) {
+  if (this.data) {
+    if (Buffer.isBuffer(data)) {
+      this.data = Buffer.concat([this.data, data]);
+      return;
+    }
+
+    this.data = Buffer.concat([this.data, new Buffer(data)]);
+    return;
+  }
+
+  if (Buffer.isBuffer(data)) {
+    this.data = data;
+    return;
+  }
+
+  this.data = new Buffer(data);
+};
+
+Verify.prototype.verify = function(publicKey, signature) {
+  if (this.data) {
+    var type = shaTypes[this.hashtype];
+    var hash = native.shaEncode(this.data, type);
+    return native.rsaVerify(type, hash, publicKey, signature);
+  }
+
+  throw new Error('verify shouldn\'t be called on an empty Verify');
+};
+
+function Hash(hashtype) {
+  if (!(this instanceof Hash)) {
+    return new Hash(hashtype);
+  }
+
+  if (hashes.indexOf(hashtype) < 0) {
+    throw new Error('Unknown hashing algorithm. Please use crypto.getHashes()');
+  }
+  Object.defineProperty(this, 'hashtype', {
+    value: hashtype,
+    writable: false,
+    enumerable: true,
+  });
+}
+
+Hash.prototype.update = function(data) {
+  if (this.data) {
+    if (Buffer.isBuffer(data)) {
+      this.data = Buffer.concat(this.data, data);
+      return;
+    }
+
+    this.data = Buffer.concat([this.data, new Buffer(data)]);
+    return;
+  }
+  this.data = new Buffer(data);
+};
+
+Hash.prototype.digest = function(encoding) {
+  if (this._finished) {
+    throw new Error('Digest can not be called twice on the same Hash object');
+  }
+
+  var result;
+  var type = shaTypes[this.hashtype];
+  result = native.shaEncode(this.data, type);
+
+  if (encoding == 'base64') {
+    result = native.base64Encode(result);
+  } else if (encoding == 'hex') {
+    result = result.toString('hex');
+  }
+
+  Object.defineProperty(this, '_finished', {
+    value: true,
+    writable: false,
+    enumerable: false,
+  });
+
+  return result;
+};
+
+function getHashes() {
+  return hashes;
+}
+
+function createHash(hashtype) {
+  return new Hash(hashtype);
+}
+
+function createVerify(signtype) {
+  return new Verify(signtype);
+}
+
+exports.createHash = createHash;
+exports.getHashes = getHashes;
+exports.createVerify = createVerify;
index 7318c9bd550ca0f20685c238dc945a57b550af14..d30f245b45c003ec99d4682e4738b33181806c70 100644 (file)
@@ -350,8 +350,18 @@ Socket.prototype.address = function() {
 };
 
 
+// These object represents the different config types that
+// this._handle.configure can do.
+// The order of these must match the order in the udp C module.
+var configTypes = {
+  'BROADCAST': 0,
+  'TTL': 1,
+  'MULTICASTTTL': 2,
+  'MULTICASTLOOPBACK': 3,
+};
+
 Socket.prototype.setBroadcast = function(arg) {
-  var err = this._handle.setBroadcast(arg ? 1 : 0);
+  var err = this._handle.configure(configTypes.BROADCAST, arg ? 1 : 0);
   if (err) {
     throw util.errnoException(err, 'setBroadcast');
   }
@@ -363,7 +373,7 @@ Socket.prototype.setTTL = function(arg) {
     throw new TypeError('Argument must be a number');
   }
 
-  var err = this._handle.setTTL(arg);
+  var err = this._handle.configure(configTypes.TTL, arg);
   if (err) {
     throw util.errnoException(err, 'setTTL');
   }
@@ -377,7 +387,7 @@ Socket.prototype.setMulticastTTL = function(arg) {
     throw new TypeError('Argument must be a number');
   }
 
-  var err = this._handle.setMulticastTTL(arg);
+  var err = this._handle.configure(configTypes.MULTICASTTTL, arg);
   if (err) {
     throw util.errnoException(err, 'setMulticastTTL');
   }
@@ -387,7 +397,8 @@ Socket.prototype.setMulticastTTL = function(arg) {
 
 
 Socket.prototype.setMulticastLoopback = function(arg) {
-  var err = this._handle.setMulticastLoopback(arg ? 1 : 0);
+  var err = this._handle.configure(configTypes.MULTICASTLOOPBACK,
+                                   arg ? 1 : 0);
   if (err) {
     throw util.errnoException(err, 'setMulticastLoopback');
   }
index fa4e852db159435edb931c713884eae010917ab3..8401696c93b618cc4318c3c7963b39cb03c8085d 100644 (file)
@@ -45,7 +45,7 @@ exports.lookup = function lookup(hostname, options, callback) {
   if (family !== 0 && family !== 4 && family !== 6)
     throw new TypeError('invalid argument: family must be 4 or 6');
 
-  if (process.platform != 'nuttx' && process.platform != 'tizenrt') {
+  if (process.platform != 'nuttx') {
     native.getaddrinfo(hostname, family, hints, callback);
   } else {
     // native.getaddrinfo is synchronous on these platforms.
index 2019af22b3d6ed32e15efca3d2409882b34b8b66..ecd9e76d23dbf340d149562738289e49ee255091 100644 (file)
@@ -382,6 +382,166 @@ fs.readdirSync = function(path) {
 };
 
 
+try {
+  var stream = require('stream');
+  var Readable = stream.Readable;
+  var Writable = stream.Writable;
+
+
+  function ReadStream(path, options) {
+    if (!(this instanceof ReadStream)) {
+      return new ReadStream(path, options);
+    }
+
+    options = options || {};
+
+    Readable.call(this, {defaultEncoding: options.encoding || null});
+
+    this.bytesRead = 0;
+    this.path = path;
+    this._autoClose = util.isNullOrUndefined(options.autoClose) ||
+                                             options.autoClose;
+    this._fd = options.fd;
+    this._buff = new Buffer(options.bufferSize || 4096);
+
+    var self = this;
+    if (util.isNullOrUndefined(this._fd)) {
+      fs.open(this.path, options.flags || 'r', options.mode || 438,
+              function(err, _fd) {
+        if (err) {
+          throw err;
+        }
+        self._fd = _fd;
+        self.emit('open', self._fd);
+        self.doRead();
+      });
+    }
+
+    this.once('open', function(/* _fd */) {
+      this.emit('ready');
+    });
+
+    if (this._autoClose) {
+      this.on('end', function() {
+        closeFile(self);
+      });
+    }
+  }
+
+
+  util.inherits(ReadStream, Readable);
+
+
+  ReadStream.prototype.doRead = function() {
+    var self = this;
+    fs.read(this._fd, this._buff, 0, this._buff.length, null,
+            function(err, bytes_read/* , buffer*/) {
+      if (err) {
+        if (self._autoClose) {
+          closeFile(self);
+        }
+        throw err;
+      }
+
+      self.bytesRead += bytes_read;
+      if (bytes_read === 0) {
+        // Reached end of file.
+        // null must be pushed so the 'end' event will be emitted.
+        self.push(null);
+      } else {
+        self.push(bytes_read == self._buff.length ?
+                  self._buff : self._buff.slice(0, bytes_read));
+        self.doRead();
+      }
+    });
+  };
+
+
+  fs.createReadStream = function(path, options) {
+    return new ReadStream(path, options);
+  };
+
+
+  function WriteStream(path, options) {
+    if (!(this instanceof WriteStream)) {
+      return new WriteStream(path, options);
+    }
+
+    options = options || {};
+
+    Writable.call(this);
+
+    this._fd = options._fd;
+    this._autoClose = util.isNullOrUndefined(options.autoClose) ||
+                                             options.autoClose;
+    this.bytesWritten = 0;
+
+    var self = this;
+    if (!this._fd) {
+      fs.open(path, options.flags || 'w', options.mode || 438,
+              function(err, _fd) {
+        if (err) {
+          throw err;
+        }
+        self._fd = _fd;
+        self.emit('open', self._fd);
+      });
+    }
+
+    this.once('open', function(/* _fd */) {
+      self.emit('ready');
+    });
+
+    if (this._autoClose) {
+      this.on('finish', function() {
+        closeFile(self);
+      });
+    }
+
+    this._readyToWrite();
+  }
+
+
+  util.inherits(WriteStream, Writable);
+
+
+  WriteStream.prototype._write = function(chunk, callback, onwrite) {
+    var self = this;
+    fs.write(this._fd, chunk, 0, chunk.length,
+             function(err, bytes_written/* , buffer */) {
+      if (err) {
+        if (self._autoClose) {
+          closeFile(self);
+        }
+        throw err;
+      }
+      this.bytesWritten += bytes_written;
+
+      if (callback) {
+        callback();
+      }
+      onwrite();
+    });
+  };
+
+
+  fs.createWriteStream = function(path, options) {
+    return new WriteStream(path, options);
+  };
+
+
+  function closeFile(stream) {
+    fs.close(stream._fd, function(err) {
+      if (err) {
+        throw err;
+      }
+      stream.emit('close');
+    });
+  }
+} catch(e) {
+}
+
+
 function convertFlags(flag) {
   var O_APPEND = constants.O_APPEND;
   var O_CREAT = constants.O_CREAT;
index 1ff4c2cb89ee76cb4697ee3cda5328b11367e001..1a9ababbe81ed37e08e961186e00ce7601ad5221 100644 (file)
@@ -15,7 +15,8 @@
 
 var net = require('net');
 var ClientRequest = require('http_client').ClientRequest;
-var HTTPParser = require('http_parser');
+var IncomingMessage = require('http_incoming').IncomingMessage;
+var HTTPParser = require('http_parser').HTTPParser;
 var HTTPServer = require('http_server');
 var util = require('util');
 
@@ -30,15 +31,15 @@ exports.request = function(options, cb) {
   return new ClientRequest(options, cb, socket);
 };
 
-function Server(requestListener) {
+function Server(options, requestListener) {
   if (!(this instanceof Server)) {
-    return new Server(requestListener);
+    return new Server(options, requestListener);
   }
 
   net.Server.call(this, {allowHalfOpen: true},
                   HTTPServer.connectionListener);
 
-  HTTPServer.initServer.call(this, {}, requestListener);
+  HTTPServer.initServer.call(this, options, requestListener);
 }
 util.inherits(Server, net.Server);
 
@@ -51,8 +52,8 @@ Server.prototype.setTimeout = function(ms, cb) {
 
 exports.Server = Server;
 
-exports.createServer = function(requestListener) {
-  return new Server(requestListener);
+exports.createServer = function(options, requestListener) {
+  return new Server(options, requestListener);
 };
 
 
@@ -64,3 +65,6 @@ exports.get = function(options, cb) {
   req.end();
   return req;
 };
+
+exports.IncomingMessage = IncomingMessage;
+exports.ServerResponse = HTTPServer.ServerResponse;
index 1668375280945f5e71156d8ba48c133bc514b3de..4d43747baf648f5bd181746f8e4e5d24ba52aa2d 100644 (file)
@@ -74,8 +74,7 @@ ClientRequest.prototype.end = function(data, encoding, callback) {
 
 function setupConnection(req) {
   var socket = req.socket;
-  var parser = common.createHTTPParser();
-  parser.reinitialize(HTTPParser.RESPONSE);
+  var parser = common.createHTTPParser(HTTPParser.RESPONSE);
   socket.parser = parser;
   socket._httpMessage = req;
 
@@ -118,7 +117,7 @@ function emitError(socket, err) {
   if (err) {
     var host;
     if ((host = req.getHeader('host'))) {
-      err.message += ': ' + (host ? host : '');
+      err.message += ': ' + host;
     }
     req.emit('error', err);
   }
index 625049233be46cc475cd5aafbbe47a8e8e69dbf7..e207865ef8e55a391deac12a89323a1732e2cfb4 100644 (file)
@@ -17,21 +17,17 @@ var util = require('util');
 var IncomingMessage = require('http_incoming').IncomingMessage;
 var HTTPParser = require('http_parser').HTTPParser;
 
-var createHTTPParser = function() {
-  // REQUEST is the default type.
-  // For RESPONSE, use HTTPParser.reinitialize(HTTPParser.RESPONSE)
-  var parser = new HTTPParser(HTTPParser.REQUEST);
+exports.createHTTPParser = function(type) {
+  var parser = new HTTPParser(type);
   // cb during  http parsing from C side(http_parser)
   parser.OnHeaders = parserOnHeaders;
   parser.OnHeadersComplete = parserOnHeadersComplete;
   parser.OnBody = parserOnBody;
   parser.OnMessageComplete = parserOnMessageComplete;
+  parser._IncomingMessage = IncomingMessage;
   return parser;
 };
 
-exports.createHTTPParser = createHTTPParser;
-
-
 // This is called when parsing of incoming http msg done
 function parserOnMessageComplete() {
   var stream = this.incoming;
@@ -63,8 +59,9 @@ function parserOnHeadersComplete(info) {
   }
 
 
-  this.incoming = new IncomingMessage(this.socket);
+  this.incoming = new this._IncomingMessage(this.socket);
   this.incoming.url = url;
+  this.incoming.httpVersion = info.http_major + '.' + info.http_minor;
 
   // add header fields of headers to incoming.headers
   this.incoming.addHeaders(headers);
index df16f6b5d68e87377df98a679cd268e122b3c7d8..b3dc5391f6b781f47f211264fd3a51dfdbbfcf01 100644 (file)
@@ -31,6 +31,7 @@ function IncomingMessage(socket) {
   // for request (server)
   this.url = '';
   this.method = null;
+  this.httpVersion = '';
 
   // for response (client)
   this.statusCode = null;
index 3c482164040cb5622d36ab285039c750c0bf191d..8ffa696d7763a145b71a2a41d259718f850d419f 100644 (file)
@@ -19,7 +19,7 @@ var stream = require('stream');
 
 
 function OutgoingMessage() {
-  stream.Stream.call(this);
+  stream.Writable.call(this);
 
   this.writable = true;
 
@@ -40,7 +40,7 @@ function OutgoingMessage() {
 
 }
 
-util.inherits(OutgoingMessage, stream.Stream);
+util.inherits(OutgoingMessage, stream.Writable);
 
 exports.OutgoingMessage = OutgoingMessage;
 
@@ -100,12 +100,8 @@ OutgoingMessage.prototype._send = function(chunk, encoding, callback) {
     callback = encoding;
   }
 
-  if (util.isBuffer(chunk)) {
-    chunk = chunk.toString();
-  }
-
   if (!this._sentHeader) {
-    chunk = this._header + '\r\n' + chunk;
+    this._chunks.push(this._header + '\r\n');
     this._sentHeader = true;
   }
 
@@ -162,7 +158,7 @@ OutgoingMessage.prototype.setHeader = function(name, value) {
     throw new TypeError('Name must be string.');
   }
 
-  if (!value) {
+  if (util.isNullOrUndefined(value)) {
     throw new Error('value required in setHeader(' + name + ', value)');
   }
 
index 8aeb9f7b063aa8f37eec2a2f0820a219d0ff6c1c..9bc1c4c654d6cfabc75c933fdf25bde3728d8eeb 100644 (file)
  */
 
 var util = require('util');
+var IncomingMessage = require('http_incoming').IncomingMessage;
 var OutgoingMessage = require('http_outgoing').OutgoingMessage;
 var common = require('http_common');
+var HTTPParser = require('http_parser').HTTPParser;
 
 // RFC 7231 (http://tools.ietf.org/html/rfc7231#page-49)
 var STATUS_CODES = exports.STATUS_CODES = {
@@ -71,7 +73,7 @@ function ServerResponse(req) {
 }
 
 util.inherits(ServerResponse, OutgoingMessage);
-
+exports.ServerResponse = ServerResponse;
 
 // default status code : 200
 ServerResponse.prototype.statusCode = 200;
@@ -144,10 +146,20 @@ ServerResponse.prototype.detachSocket = function() {
 
 
 function initServer(options, requestListener) {
+  if (util.isFunction(options)) {
+    requestListener = options;
+  }
+
+  if (typeof options !== 'object') {
+    options = {};
+  }
+
   if (util.isFunction(requestListener)) {
     this.addListener('request', requestListener);
   }
 
+  this._IncomingMessage = options.IncomingMessage || IncomingMessage;
+  this._ServerResponse = options.ServerResponse || ServerResponse;
   this.httpAllowHalfOpen = false;
 
   this.on('clientError', function(err, conn) {
@@ -164,11 +176,12 @@ function connectionListener(socket) {
 
   // cf) In Node.js, freelist returns a new parser.
   // parser initialize
-  var parser = common.createHTTPParser();
+  var parser = common.createHTTPParser(HTTPParser.REQUEST);
   parser._headers = [];
   parser._url = '';
 
   parser.onIncoming = parserOnIncoming;
+  parser._IncomingMessage = server._IncomingMessage;
 
   parser.socket = socket;
   parser.incoming = null;
@@ -258,7 +271,7 @@ function parserOnIncoming(req/* , shouldKeepAlive */) {
   var socket = req.socket;
   var server = socket._server;
 
-  var res = new ServerResponse(req);
+  var res = new server._ServerResponse(req);
   res.assignSocket(socket);
   res.on('prefinish', resOnFinish);
 
diff --git a/src/js/http_signature.js b/src/js/http_signature.js
new file mode 100644 (file)
index 0000000..514af26
--- /dev/null
@@ -0,0 +1,97 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var crypto = require('crypto');
+
+function parseRequest(request) {
+  var authHeader = false;
+  var authType = false;
+  if (request.headers['authorization']) {
+    authType = 'authorization';
+    authHeader = request.headers['authorization'];
+  } else if (request.headers['Authorization']) {
+    authType = 'Authorization';
+    authHeader = request.headers['Authorization'];
+  }
+
+  if (!authHeader) {
+    throw new Error('Authorization header is not present, invalid request.');
+  }
+
+  var requestHeaders = {
+    'request-line': request.method + ' ' + request.url + ' HTTP/' +
+                    request.httpVersion,
+    '(request-target)': '(request-target): ' + request.method.toLowerCase() +
+                        ' ' + request.url,
+  };
+
+  for (var key in request.headers) {
+    if (key !== authType) {
+      var keyData = key.toLowerCase();
+      requestHeaders[keyData] = keyData + ': ' + request.headers[key];
+    }
+  }
+
+  var authObject = {};
+
+  var idx = 0;
+  var types = ['keyId=', 'signature=', 'algorithm=', 'headers='];
+  // TODO: We currently only accept data that's enclosed with double quotes.
+  // The newest RFC doesn't state if the data in the authorization header needs
+  // to be in double quotes, or just simply be after the equals sign.
+  // reference: https://tools.ietf.org/html/draft-cavage-http-signatures-10
+  for (var i = 0; i < types.length; i++) {
+    if ((idx = authHeader.indexOf(types[i])) < 0) {
+      throw new Error('Couldn\'t find header: ', types[i]);
+    }
+
+    idx += types[i].length + 1;
+    var endIdx = authHeader.substring(idx).indexOf('"') + idx;
+    authObject[types[i].slice(0, -1)] = authHeader.substring(idx, endIdx);
+  }
+
+  var parsedRequest = {
+    requestObject: requestHeaders,
+    authObject: authObject,
+  };
+
+  return parsedRequest;
+}
+
+function verifySignature(parsedRequest, pubKey) {
+  // We only support RSA-SHAX signatures right now
+  var algorithm = parsedRequest.authObject.algorithm.toLowerCase();
+  if (algorithm.indexOf('rsa-sha') < 0) {
+    throw new Error('Only rsa-shaX signatures are supported');
+  }
+
+  // We know it begins with rsa-sha, so give only the sha info to crypto
+  var toVerify = crypto.createVerify(algorithm.split('-')[1]);
+  var headersToHash = parsedRequest.authObject.headers.split(' ');
+
+  for (var i = 0; i < headersToHash.length; i++) {
+    toVerify.update(parsedRequest.requestObject[headersToHash[i]]);
+    // 2.1.2.3 If value is not the last value then append an ASCII newline `\n`.
+    // The string MUST NOT include a trailing ASCII newline.
+    if (i + 1 != headersToHash.length) {
+      toVerify.update('\n');
+    }
+  }
+
+  return toVerify.verify(pubKey, parsedRequest.authObject.signature);
+}
+
+exports.verifySignature = verifySignature;
+exports.parseRequest = parseRequest;
index 2d0556c4a782246e0dbb38b99585acc9c98a01f0..a65ad1797307968b481baecebd2ce2e91d6918c9 100644 (file)
 var tls = require('tls');
 var net = require('net');
 var ClientRequest = require('http_client').ClientRequest;
-var HTTPParser = require('http_parser');
 var HTTPServer = require('http_server');
 var util = require('util');
 
-exports.ClientRequest = ClientRequest;
-
 exports.request = function(options, cb) {
   options.port = options.port || 443;
   // Create socket.
@@ -52,8 +49,6 @@ exports.createServer = function(options, requestListener) {
   return new Server(options, requestListener);
 };
 
-exports.METHODS = HTTPParser.methods;
-
 exports.get = function(options, cb) {
   var req = exports.request(options, cb);
   req.end();
index 7d51be3bf0e970393fb28b36b59bccaebbc61bf1..9b021f06e5429d14476bba91c09fbebb62a808ae 100644 (file)
   process.exitCode = 0;
   process._exiting = false;
   process.emitExit = function(code) {
+    code = code || process.exitCode;
     if (typeof code !== 'number') {
       code = 0;
     }
index 5627804544f32e15ed901e98c3b692325c0663cc..76646dce811bdfd9187d4db57fb4f3bcaff49b03 100644 (file)
 
 var Builtin = require('builtin');
 var fs = Builtin.require('fs');
-var dynamicloader = Builtin.require('dynamicloader');
+var dynamicloader;
+try {
+  dynamicloader = Builtin.require('dynamicloader');
+} catch (e) {
+  // the 'dynamicloader' module is not enabled, nothing to do.
+}
+
+function normalizePathString(path) {
+  // Assume all path separators are '/'
+  var input = path.split('/');
+  var output = [];
+  while (input.length > 0) {
+    if (input[0] === '.' || (input[0] === '' && input.length > 1)) {
+      input.shift();
+      continue;
+    }
+    if (input[0] === '..') {
+      input.shift();
+      if (output.length > 0 && output[output.length - 1] !== '..') {
+        output.pop();
+      } else {
+        throw new Error('Requested path is below root: ' + path);
+      }
+      continue;
+    }
+    output.push(input.shift());
+  }
+  return output;
+}
+
+var path;
+if (process.platform === 'windows') {
+  /* In case of windows:
+   * replace all '\' characters to '/' for ease of use for now.
+   */
+  path = {
+    pathReplacer: new RegExp('\\\\', 'g'),
+    pathSeparator: '\\',
+    normalizeSeparators: function(pathString) {
+      return pathString.replace(path.pathReplacer, '/');
+    },
+    isDeviceRoot: function(pathString) {
+      if (pathString.charCodeAt(1) !== 0x3A /* ':' */) {
+        return false;
+      }
+      var drive = pathString.charCodeAt(0);
+      return (drive >= 0x61 /* a */ && drive <= 0x7A /* z */)
+             || (drive >= 0x41 /* A */ && drive <= 0x5A /* Z */);
+    },
+    normalizePath: function(pathString) {
+      pathString = path.normalizeSeparators(pathString);
+
+      var deviceRoot = '';
+      if (!path.isDeviceRoot(pathString)) {
+        deviceRoot = path.cwd().substr(0, 2) + '/';
+      }
+
+      var pathElements = normalizePathString(pathString);
+      return deviceRoot + pathElements.join('/');
+    },
+    cwd: function() {
+      return path.normalizeSeparators(process.cwd());
+    },
+  };
+} else {
+  path = {
+    isDeviceRoot: function(pathString) {
+      return pathString.charCodeAt(0) === 0x2F; /* '/' */
+    },
+    normalizePath: function(path) {
+      var beginning = '';
+      if (path.indexOf('/') === 0) {
+        beginning = '/';
+      }
+
+      var pathElements = normalizePathString(path);
+      return beginning + pathElements.join('/');
+    },
+    cwd: process.cwd,
+  };
+}
 
 function Module(id, parent) {
   this.id = id;
@@ -36,7 +116,7 @@ var moduledirs = [''];
 
 var cwd;
 try {
-  cwd = process.env.IOTJS_WORKING_DIR_PATH || process.cwd();
+  cwd = process.env.IOTJS_WORKING_DIR_PATH || path.cwd();
 } catch (e) { }
 if (cwd) {
   moduledirs.push(cwd + '/');
@@ -83,13 +163,13 @@ Module.resolveFilepath = function(id, directories) {
     var dir = directories[i];
     var modulePath = dir + id;
 
-    if (modulePath[0] !== '/') {
-      modulePath = process.cwd() + '/' + modulePath;
+    if (!path.isDeviceRoot(modulePath)) {
+      modulePath = path.cwd() + '/' + modulePath;
     }
 
     if ((process.platform === 'tizenrt' || process.platform === 'nuttx') &&
         (modulePath.indexOf('../') != -1 || modulePath.indexOf('./') != -1)) {
-      modulePath = Module.normalizePath(modulePath);
+      modulePath = path.normalizePath(modulePath);
     }
 
     var filepath,
@@ -140,41 +220,13 @@ Module.resolveModPath = function(id, parent) {
   var filepath = Module.resolveFilepath(id, directories);
 
   if (filepath) {
-    return Module.normalizePath(filepath);
+    return path.normalizePath(filepath);
   }
 
   return false;
 };
 
 
-Module.normalizePath = function(path) {
-  var beginning = '';
-  if (path.indexOf('/') === 0) {
-    beginning = '/';
-  }
-
-  var input = path.split('/');
-  var output = [];
-  while (input.length > 0) {
-    if (input[0] === '.' || (input[0] === '' && input.length > 1)) {
-      input.shift();
-      continue;
-    }
-    if (input[0] === '..') {
-      input.shift();
-      if (output.length > 0 && output[output.length - 1] !== '..') {
-        output.pop();
-      } else {
-        throw new Error('Requested path is below root: ' + path);
-      }
-      continue;
-    }
-    output.push(input.shift());
-  }
-  return beginning + output.join('/');
-};
-
-
 Module.tryPath = function(path) {
   try {
     var stats = fs.statSync(path);
@@ -256,6 +308,12 @@ Module.prototype.compile = function(filename, source) {
 Module.runMain = function() {
   if (Builtin.debuggerWaitSource) {
     var sources = Builtin.debuggerGetSource();
+
+    if (sources.length == 0) {
+      var err = new Error('No remote source received!');
+      return process._onUncaughtException(err);
+    }
+
     sources.forEach(function(rModule) {
       Module.remoteCache[rModule[0]] = rModule[1];
     });
index 77c8ef2938ab9ce1888b492bb1820bf8cedfe986..e3142591d41cae2f7ba8f2db621058a30ef240c1 100644 (file)
  * limitations under the License.
  */
 
-var net = require('net');
 var util = require('util');
 var EventEmitter = require('events').EventEmitter;
-
-util.inherits(MQTTClient, EventEmitter);
+var net, tls;
 
 var PacketTypeEnum = {
   PUBACK: 4,
@@ -26,312 +24,436 @@ var PacketTypeEnum = {
   PUBCOMP: 7,
 };
 
-function MQTTClient(options) {
-  if (!(this instanceof MQTTClient)) {
-    return new MQTTClient(options);
-  }
-
-  EventEmitter.call(this);
+// In seconds (should be divisible by 8)
+var MQTTTimeout = 64;
 
-  this._clientOptions = Object.create(options, {
-    host: { value: options.host || '127.0.0.1'},
-    port: { value: options.port || 8883 },
-    qos: { value: options.qos || 0 },
-    keepalive: { value: options.keepalive || 60 },
-  });
+function MQTTHandle(client, keepalive) {
+  this.client = client;
+  this.isConnected = false;
+  this.nextPacketId = 0;
+  this.keepalive = keepalive;
+  this.keepaliveCounter = 0;
+  this.pingrespCounter = 0;
+  this.storage = { };
+  this.storageCount = 0;
 
-  this._socket = options.socket || new net.Socket();
-  this._socket.on('error', onerror);
-
-  this._isConnected = false;
-  this._reconnecting = false;
-  this._package_id = 0;
-
-  // Set the native callbacks
-  this._onconnect = onconnect;
-  this._ondisconnect = ondisconnect;
-  this._onmessage = onmessage;
-  this._onpingresp = onpingresp;
-  this._onpuback = onpuback;
-  this._onpubcomp = onpubcomp;
-  this._onpubrec = onpubrec;
-  this._onpubrel = onpubrel;
-  this._onsuback = onsuback;
+  native.MqttInit(this);
 }
+MQTTHandle.prototype = {};
 
-/*
- * Connect to an MQTT broker.
- */
-function MqttConnect(socket, options) {
-  var buff = native.connect(options);
-  socket.write(buff);
-}
-
-MQTTClient.prototype.connect = function(callback) {
-  this._clientOptions.cb = callback;
-  var jsref = this;
-  if (this._socket instanceof net.Socket) {
-    this._socket = net.connect(this._clientOptions);
-    this._socket.on('connect', function() {
-      MqttConnect(this, jsref._clientOptions);
-    });
-  }
-
-  if (util.isFunction(callback)) {
-    this.on('connect', callback);
-  }
-
-  this._socket.on('data', function(data) {
-    ondata(jsref, data);
-  });
-  this._socket.on('error', function(e) {
-    jsref.emit('error', e);
-  });
-  this._socket.on('end', function() {
-    ondisconnect(jsref);
-  });
+MQTTHandle.prototype.write = function(buf) {
+  this.socket.write(buf);
+  this.keepaliveCounter = 0;
 };
 
-MQTTClient.prototype.disconnect = function(error) {
-  if (error) {
-    this.emit('error', error);
-  }
-
-  this._isConnected = false;
-  var buf = native.disconnect();
-  this._socket.write(buf);
-  this._socket.end();
+MQTTHandle.prototype.sendAck = function(type, packet_id) {
+  this.write(native.sendAck(type, packet_id));
 };
 
-MQTTClient.prototype.reconnect = function() {
-  if (this._reconnecting) {
-    return;
-  }
+MQTTHandle.prototype.onconnection = function() {
+  this.isConnected = true;
+  this.timer = setInterval(storageTimerHit.bind(this), 1000);
 
-  this.disconnect();
-  setTimeout(this.connect, this._options.reconnectPeriod);
+  this.client.emit('connect');
 };
 
-MQTTClient.prototype.publish = function(options) {
-  if (!Buffer.isBuffer(options.message)) {
-    options.message = new Buffer(options.message);
-  }
-  if (!Buffer.isBuffer(options.topic)) {
-    options.topic = new Buffer(options.topic);
-  }
-
-  if (util.isNumber(options.qos) && options.qos > 0) {
-    options.packet_id = this._package_id;
-    this._package_id++;
+MQTTHandle.prototype.onEnd = function() {
+  this.isConnected = false;
 
-    var buffer = native.publish(options);
-    this._socket.write(buffer);
+  // Abort outgoing messages.
+  clearInterval(this.timer);
+  this.storage = null;
+  this.storageCount = 0;
 
-    var self = this;
+  this.client.emit('end');
+};
 
-    var interval = setInterval(function() {
-      self._socket.write(buffer);
-    }, 3000);
+MQTTHandle.prototype.onmessage = function(message, topic, qos, packet_id) {
+  var data = {
+    message: message,
+    topic: topic,
+    qos: qos,
+    packet_id: packet_id,
+  };
 
-    this.on('puback', function() {
-      clearInterval(interval);
-    });
-    this.on('pubrec', function() {
-      clearInterval(interval);
-    });
+  if (qos >= 1) {
+    var type = (qos == 1) ? PacketTypeEnum.PUBACK : PacketTypeEnum.PUBREC;
 
-    return;
+    this.sendAck(type, packet_id);
   }
 
-  this._socket.write(native.publish(options));
+  this.client.emit('message', data);
 };
 
-MQTTClient.prototype.subscribe = function(options) {
-  if (!Buffer.isBuffer(options.topic)) {
-    options.topic = new Buffer(options.topic);
-  }
+MQTTHandle.prototype.getPacketId = function() {
+  while (true) {
+    var packet_id = this.nextPacketId;
+    this.nextPacketId = (this.nextPacketId + 1) & 0xffff;
 
-  var buff = native.subscribe(options);
-  this._socket.write(buff);
-};
+    if (!(packet_id in this.storage)) {
+      this.storage[packet_id] = { remainingTime: MQTTTimeout };
+      this.storageCount++;
 
-MQTTClient.prototype.ping = function() {
-  var buff = native.ping();
-  this._socket.write(buff);
+      return packet_id;
+    }
+  }
 };
 
-MQTTClient.prototype.unsubscribe = function(topic) {
-  if (!Buffer.isBuffer(topic)) {
-    topic = new Buffer(topic);
+MQTTHandle.prototype.releasePacket = function(packet_id, error) {
+  // callback will be invalid after delete
+  var callback = this.storage[packet_id].callback;
+
+  delete this.storage[packet_id];
+  this.storageCount--;
+
+  // This function should never fail.
+  try {
+    if (typeof callback == 'function') {
+      callback(error);
+    } else if (error) {
+      this.client.emit('error', error);
+    }
+  } catch (e) {
+    // Do nothing.
   }
+};
 
-  var buf = native.unsubscribe(topic);
-  this._socket.write(buf);
+MQTTHandle.prototype.onpingresp = function() {
+  this.pingrespCounter = 0;
 };
 
-MQTTClient.prototype.sendAcknowledge = function(options) {
-  var buff = native.sendAck(options);
-  this._socket.write(buff);
+MQTTHandle.prototype.onack = function(packet_id, error) {
+  this.releasePacket(packet_id, error);
 };
 
-function onpubcomp(jsref, data) {
+MQTTHandle.prototype.onpubrec = function(packet_id) {
   /*
    * Qos level 2
-   * Handle PUBCOMP package. If this package is arrived, the sending process
-   * is done.
+   * Handle PUBREC package. If this package is arrived, we have to send back
+   * a PUBREL package to the server.
    */
-  jsref.emit('pubcomp', data);
-}
+  var buffer = native.sendAck(PacketTypeEnum.PUBREL, packet_id);
+  this.write(buffer);
+
+  // Upodate packet rather than create a new one
+  var packet = this.storage[packet_id];
+  packet.remainingTime = MQTTTimeout;
+  packet.packet = buffer;
+};
 
-function onpubrel(jsref, data) {
+MQTTHandle.prototype.onpubrel = function(data) {
   /*
    * Qos level 2
    * Handle PUBREL package. If this package is arrived, we have to send back
    * a PUBCOMP package to the server.
    */
-  var options = {
-    type: PacketTypeEnum.PUBCOMP,
-    packet_id: data,
-  };
+  this.sendAck(PacketTypeEnum.PUBCOMP, data);
+};
 
-  jsref.sendAcknowledge(options);
-}
+function MQTTClient(url, options, callback) {
+  if (!(this instanceof MQTTClient)) {
+    return new MQTTClient(url, options, callback);
+  }
+
+  EventEmitter.call(this);
+
+  var socket;
 
-function ondata(jsref, data) {
-  var ret_val = native.MqttHandle(jsref, data);
-  if (ret_val instanceof Error) {
-    jsref.disconnect();
-    onerror(jsref, ret_val);
+  if (typeof url == 'string') {
+    if (typeof options == 'function') {
+      callback = options;
+      options = {};
+    }
+  } else {
+    if (typeof url == 'function') {
+      callback = url;
+      options = {};
+    } else if (typeof options == 'function') {
+      callback = options;
+      options = url;
+    } else {
+      options = url;
+    }
+
+    if (options.socket) {
+      socket = options.socket;
+    } else {
+      url = options.host || '127.0.0.1';
+    }
   }
-}
 
-function onconnect(jsref) {
-  jsref.emit('connect');
-}
+  if (typeof callback == 'function') {
+    this.on('connect', callback);
+  }
 
-function onpingresp(jsref) {
-  jsref.emit('pingresp');
-}
+  if (options.will) {
+    if (typeof options.topic == 'undefined' ||
+        typeof options.message == 'undefined' ||
+        options.qos < 0 || options.qos > 2) {
+      throw new Error('Incorrect mqtt will options');
+    }
+  }
 
-function onmessage(jsref, message, topic, qos, packet_id) {
-  var data = {
-    message: message,
-    topic: topic,
-    qos: qos,
-    packet_id: packet_id,
+  var host = '';
+  var create_tls = false;
+
+  if (!socket) {
+    if (url.substring(0, 8) == 'mqtts://') {
+      create_tls = true;
+      host = url.substring(8);
+    } else if (url.substring(0, 7) == 'mqtt://') {
+      host = url.substring(7);
+    } else {
+      host = url;
+    }
+  }
+
+  var keepalive = (options.keepalive || 60) | 0;
+
+  if (keepalive < 30) {
+    keepalive = 30;
+  }
+
+  if (keepalive > 65535) {
+    keepalive = 65535;
+  }
+
+  options = Object.create(options, {
+    clientId: { value: options.clientId || defaultClientId() },
+    host: { value: host },
+    port: { value: options.port || 8883 },
+    qos: { value: options.qos || 0 },
+    keepalive: { value: keepalive },
+  });
+
+  // Since network transmission takes time, the
+  // actual keepalive message is sent a bit earlier
+  this._handle = new MQTTHandle(this, keepalive - 5);
+
+  var connectionMessage = native.connect(options);
+
+  var onconnect = function() {
+    // Currently the connect message is tried only once.
+    // Multiple tries can be implemented later.
+    this.write(connectionMessage);
   };
 
-  if (qos == 1) {
-    var opts = {
-      type: PacketTypeEnum.PUBACK,
-      packet_id: packet_id,
-    };
-
-    jsref.sendAcknowledge(opts);
-  } else if (qos == 2) {
-    var options = {
-      type: PacketTypeEnum.PUBREC,
-      packet_id: packet_id,
-    };
-    jsref.sendAcknowledge(options);
+  if (socket) {
+    onconnect.call(socket);
+  } else {
+    if (create_tls) {
+      if (!tls) {
+        tls = require('tls');
+      }
+
+      socket = tls.connect(options, onconnect);
+    } else {
+      if (!net) {
+        net = require('net');
+      }
+
+      socket = net.connect(options, onconnect);
+    }
   }
 
-  jsref.emit('message', data);
-}
+  this._handle.socket = socket;
+  socket._mqttSocket = this;
 
-function ondisconnect(jsref, message) {
-  jsref._isConnected = false;
-  jsref.emit('disconnect', message);
+  socket.on('error', onerror);
+  socket.on('data', ondata);
+  socket.on('finish', onfinish);
 }
+util.inherits(MQTTClient, EventEmitter);
 
-function onpuback(jsref, data) {
-  /*
-   * QoS level 1
-   * Handle PUBACK package. If this package isn't arrived (properly),
-   * we have to resend the last message.
-   *
-   * The 'data' contains the packet identifier.
-   */
+MQTTClient.prototype.end = function(force) {
+  var handle = this._handle;
 
-  jsref.emit('puback', data);
-}
+  handle.isConnected = false;
 
-function onpubrec(jsref, data) {
-  /*
-   * Qos level 2
-   * Handle PUBREC package. If this package is arrived, we have to send back
-   * a PUBREL package to the server.
-   */
-  var options = {
-    type: PacketTypeEnum.PUBREL,
-    packet_id: data,
-  };
+  if (force || handle.storageCount == 0) {
+    handle.socket.end(native.disconnect());
 
-  jsref.sendAcknowledge(options);
+    // Abort ongoing messages.
+    clearInterval(this.timer);
+    this.storage = null;
+    this.storageCount = 0;
+  }
+};
 
-  var interval = setInterval(function() {
-    jsref.sendAcknowledge(options);
-  }, 3000);
+MQTTClient.prototype.checkConnection = function() {
+  if (!this._handle.isConnected) {
+    throw new Error('MQTT client is not connected');
+  }
+};
 
-  jsref.on('pubcomp', function() {
-    clearInterval(interval);
-  });
+MQTTClient.prototype.publish = function(topic, message, options, callback) {
+  this.checkConnection();
 
-  jsref.emit('pubrec', data);
-}
+  var handle = this._handle;
 
-function onsuback(jsref, data) {
-  /*
-   * Successful subscription, the client will get messages from the requested
-   * topic. The granted QoS is given in data.
-   */
-   jsref.emit('suback', data);
-}
+  // header bits: | 16 bit packet id | 4 bit PUBLISH header |
+  var header = 0;
+  var qos = 0;
 
-function onerror(jsref, error) {
-  jsref.emit('error', error);
-}
+  if (options) {
+    if (options.retain) {
+      header = 0x1;
+    }
 
-/*
- * Returns an unique client ID based on current time.
- */
-function defaultClientId() {
-  return 'iotjs_mqtt_client_' + Date.now();
-}
+    qos = options.qos;
+
+    if (qos !== 1 && qos !== 2) {
+      qos = 0;
+    }
 
-function getClient(connectOptions) {
-  if (util.isUndefined(connectOptions.clientId)) {
-    connectOptions.clientId = defaultClientId();
+    header |= (qos << 1);
   }
-  if (!Buffer.isBuffer(connectOptions.clientId)) {
-    connectOptions.clientId =
-        new Buffer(connectOptions.clientId.toString());
+
+  if (qos > 0) {
+    var packet_id = handle.getPacketId();
+    header |= (packet_id << 4);
+
+    var buffer = native.publish(topic, message, header);
+    handle.write(buffer);
+
+    // Set dup flag.
+    buffer.writeUInt8(buffer.readUInt8(0) | 0x08, 0);
+
+    var packet = handle.storage[packet_id];
+
+    packet.packet = buffer;
+    packet.callback = callback;
+    return;
   }
-  if (!util.isUndefined(connectOptions.username) &&
-      !Buffer.isBuffer(connectOptions.username)) {
-    connectOptions.username = new Buffer(connectOptions.username.toString());
+
+  handle.write(native.publish(topic, message, header));
+
+  if (typeof callback == 'function') {
+    process.nextTick(callback);
   }
-  if (!util.isUndefined(connectOptions.password) &&
-      !Buffer.isBuffer(connectOptions.password)) {
-    connectOptions.password = new Buffer(connectOptions.password.toString());
+};
+
+MQTTClient.prototype.subscribe = function(topic, options, callback) {
+  this.checkConnection();
+
+  var handle = this._handle;
+
+  var packet_id = handle.getPacketId();
+
+  // header bits: | 2 bit qos | 16 bit packet id |
+  var header = packet_id;
+
+  var qos = 0;
+
+  if (options) {
+    qos = options.qos;
+
+    if (qos !== 1 || qos !== 2) {
+      qos = 0;
+    }
+
+    header |= (qos << 16);
   }
-  if (connectOptions.will) {
-    if (util.isUndefined(connectOptions.topic) ||
-        util.isUndefined(connectOptions.message) ||
-        connectOptions.qos < 0 || connectOptions.qos > 2) {
-      throw new Error('Wrong options given! Please refer to the documentation');
+
+  var buffer = native.subscribe(topic, header);
+
+  handle.write(buffer);
+
+  var packet = handle.storage[packet_id];
+
+  packet.packet = buffer;
+  packet.callback = callback;
+};
+
+MQTTClient.prototype.unsubscribe = function(topic, callback) {
+  this.checkConnection();
+
+  var handle = this._handle;
+
+  var packet_id = handle.getPacketId();
+
+  // header bits: | 16 bit packet id |
+  var header = packet_id;
+
+  var buffer = native.unsubscribe(topic, header);
+
+  handle.write(buffer);
+
+  var packet = handle.storage[packet_id];
+
+  packet.packet = buffer;
+  packet.callback = callback;
+};
+
+function onerror(error) {
+  this._mqttSocket.emit('error', error);
+}
+
+function ondata(data) {
+  native.MqttReceive(this._mqttSocket._handle, data);
+}
+
+function onfinish() {
+  this._mqttSocket._handle.onEnd();
+}
+
+function storageTimerHit() {
+  // this: MQTTHandle
+
+  // eslint-disable-next-line guard-for-in
+  for (var packet_id in this.storage) {
+    var packet = this.storage[packet_id];
+
+    packet.remainingTime--;
+
+    if (packet.remainingTime <= 0) {
+      this.releasePacket(packet_id, new Error('Undelivered message'));
+      continue;
     }
 
-    if (!util.isUndefined(connectOptions.topic) &&
-        !Buffer.isBuffer(connectOptions.topic)) {
-      connectOptions.topic = new Buffer(connectOptions.topic.toString());
+    // Every 8 seconds, the message is retransmitted.
+    if (!(packet.remainingTime & 0x7)) {
+      this.write(packet.packet);
     }
-    if (!util.isUndefined(connectOptions.message) &&
-        !Buffer.isBuffer(connectOptions.message)) {
-      connectOptions.message = new Buffer(connectOptions.message.toString());
+  }
+
+  if (this.storageCount == 0 && !this.isConnected) {
+    // Graceful disconnect after all messages transmitted.
+    this.socket.end(native.disconnect());
+
+    clearInterval(this.timer);
+    this.storage = null;
+    return;
+  }
+
+  if (this.pingrespCounter > 0) {
+    this.pingrespCounter--;
+
+    if (this.pingrespCounter <= 0) {
+      this.onEnd();
+    }
+  }
+
+  this.keepaliveCounter++;
+
+  if (this.keepaliveCounter >= this.keepalive) {
+    this.write(native.ping());
+
+    if (this.pingrespCounter == 0) {
+      this.pingrespCounter = (this.keepalive + 5) * 3 >> 1;
     }
   }
-  return new MQTTClient(connectOptions);
 }
 
-exports.getClient = getClient;
+/*
+ * Returns an unique client ID based on current time.
+ */
+function defaultClientId() {
+  return 'iotjs_mqtt_client_' + Date.now();
+}
+
+function connect(url, options, callback) {
+  return new MQTTClient(url, options, callback);
+}
+
+exports.connect = connect;
index e3e7038cf61b2c41efb9ec64e5e827225c213622..4be05a61df75ea8e593248f47e5f1df32150247a 100644 (file)
@@ -25,6 +25,13 @@ function createTCP() {
   return _tcp;
 }
 
+// Expected end message on nuttx platform.
+var expectedEnding;
+
+if (process.platform == 'nuttx') {
+   expectedEnding = new Buffer('\\e\\n\\d');
+}
+
 
 function SocketState(options) {
   // 'true' during connection handshaking.
@@ -403,15 +410,20 @@ function onread(socket, nread, isEOF, buffer) {
       return;
     }
 
-    var str = buffer.toString();
+    // We know for sure the last 6 characters are going to be the ending.
+    // Lets create a buffer with those 6 characters without toString conversion.
+    var eofLength = 6;
+    var bufferLength = buffer.length;
+
     var eofNeeded = false;
-    if (str.length >= 6
-      && str.substr(str.length - 6, str.length) == '\\e\\n\\d') {
+    if (bufferLength >= eofLength &&
+        expectedEnding.compare(buffer.slice(bufferLength - eofLength,
+                                            bufferLength)) == 0) {
       eofNeeded = true;
-      buffer = buffer.slice(0, str.length - 6);
+      buffer = buffer.slice(0, bufferLength - eofLength);
     }
 
-    if (str.length == 6 && eofNeeded) {
+    if (bufferLength == eofLength && eofNeeded) {
       // Socket.prototype.end with no argument
     } else {
       stream.Readable.prototype.push.call(socket, buffer);
index eb53461c563379438b550583b1a564c82fb20b4f..cf4465a6c67a22cbca8c8c400cbd124c78d0d641 100644 (file)
@@ -15,6 +15,7 @@
 
 
 var Stream = require('stream_internal');
+var Writable = require('stream_writable');
 var util = require('util');
 
 
@@ -138,6 +139,76 @@ Readable.prototype.push = function(chunk, encoding) {
 };
 
 
+Readable.prototype.pipe = function(destination, options) {
+  if (!(destination instanceof Writable || isDuplex(destination))) {
+    throw new TypeError('pipe excepts stream.Writable or' +
+                        ' stream.Duplex as argument');
+  }
+
+  options = options || {'end': true};
+
+  var listeners = {
+    readableListener: readableListener.bind(this),
+    dataListener: dataListener.bind(destination),
+    endListener: endListener.bind(destination),
+  };
+
+  this.on('readable', listeners.readableListener);
+  this.on('data', listeners.dataListener);
+
+  if (options.end) {
+    this.on('end', listeners.endListener);
+  }
+
+  this._piped = this._piped || [];
+  this._piped.push(destination);
+
+  this._piped_listeners = this._piped_listeners || [];
+  this._piped_listeners.push(listeners);
+
+  return destination;
+};
+
+
+Readable.prototype.unpipe = function(destination) {
+  if (destination === undefined) {
+    this.removeAllListeners();
+    this._piped = undefined;
+    this._piped_listeners = undefined;
+    return;
+  }
+
+  var idx = this._piped.indexOf(destination);
+  if (idx === -1) {
+    return;
+  }
+
+  this._piped.splice(idx, 1);
+  var listeners = this._piped_listeners.splice(idx, 1)[0];
+
+  this.removeListener('readable', listeners.readableListener);
+  this.removeListener('data', listeners.dataListener);
+  this.removeListener('end', listeners.endListener);
+
+  return destination;
+};
+
+
+function readableListener() {
+  this.resume();
+}
+
+
+function dataListener(data) {
+  this.write(data);
+}
+
+
+function endListener() {
+  this.end();
+}
+
+
 function readBuffer(stream, n) {
   var state = stream._readableState;
   var res;
@@ -198,4 +269,21 @@ function onEof(stream) {
 }
 
 
+function isDuplex(stream) {
+  if (!(stream instanceof Readable)) {
+    return false;
+  }
+
+  var wr_keys = Object.keys(Writable.prototype);
+  for (var i = 0; i < wr_keys.length; i++) {
+      var wr_key = wr_keys[i];
+      if (!stream[wr_key]) {
+          return false;
+      }
+  }
+
+  return true;
+}
+
+
 module.exports = Readable;
index cdefbf4926c71a3f53631b8f92bfdfd3be89090f..db1bdab85f8dbb8534dd275ae3eefec4049e18a1 100644 (file)
@@ -111,10 +111,13 @@ Writable.prototype.end = function(chunk, callback) {
   // Because NuttX cannot poll 'EOF',so forcely raise EOF event.
   if (process.platform === 'nuttx') {
     if (!state.ending) {
+      var eof = '\\e\\n\\d';
       if (util.isNullOrUndefined(chunk)) {
-        chunk = '\\e\\n\\d';
+        chunk = eof;
+      } else if (Buffer.isBuffer(chunk)) {
+        chunk = Buffer.concat([chunk, new Buffer(eof)]);
       } else {
-        chunk += '\\e\\n\\d';
+        chunk += eof;
       }
     }
   }
index 19dd4225e778d623bdd1a4e5a99e3cadc3845960..718df9f4f1c5ec712754f97ac95bbd317fbfb181 100644 (file)
@@ -15,7 +15,7 @@
 
 var util = require('util');
 
-var TIMEOUT_MAX = 2147483647; // 2^31-1
+var TIMEOUT_MAX = '2147483647.0' - 0; // 2^31-1
 
 
 function Timeout(after) {
index ccce7849dcb9dfeb7544929805e93a2aa9b46489..8af7a9bc04670dc5c68126793ec32c4338efcd6e 100644 (file)
@@ -138,8 +138,14 @@ var getResPath = function() {
 };
 
 
+var getDataPath = function() {
+  return bridge.sendSync('getDataPath', '');
+};
+
+
 module.exports = util.mixin(native, EventEmitter.prototype, {
   launchAppControl: launchAppControl,
   getResPath: getResPath,
+  getDataPath: getDataPath,
   on: on,
 });
index 47341f551562739ad4183e190b2e5b51a381487c..eab02f64e8ecac78ce2ac80e73a4f35f8ba803ae 100644 (file)
@@ -15,7 +15,7 @@
 
 var net = require('net');
 var util = require('util');
-var EventEmitter = require('events').EventEmitter;
+var Duplex = require('stream').Duplex;
 
 function TLSSocket(socket, options) {
   if (!(this instanceof TLSSocket)) {
@@ -29,7 +29,7 @@ function TLSSocket(socket, options) {
   this._socket = socket;
   socket._tlsSocket = this;
 
-  EventEmitter.call(this);
+  Duplex.call(this);
 
   this.authorized = false;
 
@@ -37,7 +37,11 @@ function TLSSocket(socket, options) {
   this._socket.on('data', this.ondata);
   this._socket.on('error', this.onerror);
   this._socket.on('close', this.onclose);
-  this._socket.on('finish', this.onfinish);
+  if (this._socket instanceof net.Socket) {
+    this._socket.on('finish', this.onfinish);
+  } else {
+    this._socket.on('finish', this.onend);
+  }
   this._socket.on('end', this.onend);
 
   // Native handle
@@ -48,15 +52,23 @@ function TLSSocket(socket, options) {
 
   native.TlsInit(this, options, secureContext);
   this._socketState = socket._socketState;
+
+  var self = this;
+  if (socket._writableState.ready && !options.isServer) {
+    process.nextTick(function() {
+      self._native_connect(options.servername || options.host || 'localhost');
+      self._native_read(null);
+    });
+  }
 }
-util.inherits(TLSSocket, EventEmitter);
+util.inherits(TLSSocket, Duplex);
 
-TLSSocket.prototype._read = native.read;
-TLSSocket.prototype._write = native.write;
-TLSSocket.prototype._connect = native.connect;
+TLSSocket.prototype._native_read = native.read;
+TLSSocket.prototype._native_write = native.write;
+TLSSocket.prototype._native_connect = native.connect;
 
 TLSSocket.prototype.connect = function(options, callback) {
-  this._connect(options.servername || options.host || 'localhost');
+  this._native_connect(options.servername || options.host || 'localhost');
 
   if (util.isFunction(callback)) {
     this.on('secureConnect', callback);
@@ -65,34 +77,15 @@ TLSSocket.prototype.connect = function(options, callback) {
   this._socket.connect(options);
 };
 
-TLSSocket.prototype.write = function(data, callback) {
-  if (!Buffer.isBuffer(data)) {
-    data = new Buffer(data);
-  }
-
-  data = this._write(data);
-  return this._socket.write(data, callback);
-};
-
-TLSSocket.prototype.pause = function() {
-  this._socket.pause();
-};
-
-TLSSocket.prototype.resume = function() {
-  this._socket.resume();
+TLSSocket.prototype._write = function(chunk, callback, onwrite) {
+  chunk = this._native_write(chunk);
+  this._socket.write(chunk, callback);
+  onwrite();
 };
 
 TLSSocket.prototype.end = function(data, callback) {
-  if (data) {
-    if (!Buffer.isBuffer(data)) {
-      data = new Buffer(data);
-    }
-    data = this._write(data, true);
-  } else {
-    data = this._write(null, true);
-  }
-
-  this._socket.end(data, callback);
+  Duplex.prototype.end.call(this, data, callback);
+  this._socket.end();
 };
 
 TLSSocket.prototype.destroy = function() {
@@ -104,8 +97,7 @@ TLSSocket.prototype.destroySoon = function() {
 };
 
 TLSSocket.prototype.onconnect = function() {
-  var self = this._tlsSocket;
-  self._read(null);
+  this._tlsSocket._native_read(null);
 };
 
 TLSSocket.prototype.encrypted = function() {
@@ -126,7 +118,7 @@ TLSSocket.prototype.setTimeout = function(msecs, callback) {
 
 TLSSocket.prototype.ondata = function(data) {
   var self = this._tlsSocket;
-  self._read(data);
+  self._native_read(data);
 };
 
 TLSSocket.prototype.onerror = function(error) {
@@ -170,6 +162,8 @@ TLSSocket.prototype.onhandshakedone = function(error, authorized) {
     return;
   }
 
+  this._readyToWrite();
+
   if (server) {
     server.emit('secureConnection', this);
   } else {
@@ -211,8 +205,7 @@ function createServer(options, secureConnectionListener) {
 }
 
 function connect(arg0, arg1, arg2, callback) {
-  var options;
-  var tlsSocket;
+  var options = {};
   if (typeof arg0 == 'object') {
     options = Object.create(arg0, {
       isServer: { value: false, enumerable: true },
@@ -257,8 +250,13 @@ function connect(arg0, arg1, arg2, callback) {
       callback = arg1;
     }
   }
-  tlsSocket = new TLSSocket(new net.Socket(), options);
-  tlsSocket.connect(options, callback);
+
+  var tlsSocket = new TLSSocket(options.socket || new net.Socket(), options);
+  if (tlsSocket._socket instanceof net.Socket) {
+    tlsSocket.connect(options, callback);
+  } else if (util.isFunction(callback)) {
+    tlsSocket.on('secureConnect', callback);
+  }
 
   return tlsSocket;
 }
index 1a5fe075c483f27981264e2f7851974109e7d7ae..3b9787e8568303bfaaefc205834d7d71a636135d 100644 (file)
@@ -13,6 +13,8 @@
  * limitations under the License.
  */
 
+var Buffer = require('buffer');
+
 
 function isNull(arg) {
   return arg === null;
@@ -57,11 +59,6 @@ function isFunction(arg) {
 }
 
 
-function isBuffer(arg) {
-  return arg instanceof Buffer;
-}
-
-
 function inherits(ctor, superCtor) {
   ctor.prototype = Object.create(superCtor.prototype, {
     constructor: {
@@ -231,7 +228,7 @@ exports.isString = isString;
 exports.isObject = isObject;
 exports.isFinite = isFinite;
 exports.isFunction = isFunction;
-exports.isBuffer = isBuffer;
+exports.isBuffer = Buffer.isBuffer;
 exports.isArray = Array.isArray;
 exports.exceptionWithHostPort = exceptionWithHostPort;
 exports.errnoException = errnoException;
diff --git a/src/js/websocket.js b/src/js/websocket.js
new file mode 100644 (file)
index 0000000..42c4ccc
--- /dev/null
@@ -0,0 +1,445 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+ var net = require('net');
+ var util = require('util');
+ var EventEmitter = require('events').EventEmitter;
+ var tls = require('tls');
+
+util.inherits(Websocket, EventEmitter);
+util.inherits(WebsocketClient, EventEmitter);
+util.inherits(Server, EventEmitter);
+
+function WebSocketHandle(client) {
+  this.client = client;
+  this.pings = [];
+  this.connected = false;
+
+  native.wsInit(this);
+}
+
+function Websocket(options) {
+  if (!(this instanceof Websocket)) {
+    return new Websocket(options);
+  }
+
+  EventEmitter.call(this);
+  this._firstMessage = true;
+  this._handle = new WebSocketHandle(this);
+  this._secure = false;
+}
+
+function WebsocketClient(socket, handle) {
+  if (!(this instanceof WebsocketClient)) {
+    return new WebsocketClient(socket, handle);
+  }
+
+  if ((Object.keys(tls).length != 0 &&
+      socket instanceof tls.TLSSocket) ||
+      (socket instanceof net.Socket)) {
+    this._socket = socket;
+    this.readyState = 'CONNECTING';
+  } else {
+    this._firstMessage = true;
+  }
+  this._handle = handle;
+
+  EventEmitter.call(this);
+}
+
+function ServerHandle() {
+  this.clients = [];
+
+  native.wsInit(this);
+}
+
+function connectionListener(socket) {
+  var ws = new WebsocketClient(socket, this._serverHandle);
+  this._serverHandle.clients.push(ws);
+  var self = this;
+
+  ws._socket.on('data', function(data) {
+    if (ws.readyState === 'CONNECTING') {
+      parseServerHandshakeData(data, ws, self);
+    } else if (ws.readyState === 'OPEN') {
+      self._serverHandle.ondata(data, ws);
+    }
+  });
+}
+
+function parseServerHandshakeData(data, client, server) {
+  data = data.toString();
+  var res = data.split('\r\n');
+  var method = res[0].split(' ');
+
+  var headers = { 'Connection': '',
+                  'Upgrade': '',
+                  'Host': '',
+                  'Sec-WebSocket-Key': '',
+                  'Sec-WebSocket-Version': -1,
+                };
+
+  for (var i = 1; i < res.length; i++) {
+    var temp = res[i].split(': ');
+    headers[temp[0]] = temp[1];
+  }
+
+  var response = '';
+  if (method[0] === 'GET' &&
+      method[2] === 'HTTP/1.1' &&
+      method[1] === server.path &&
+      headers['Connection'] === 'Upgrade' &&
+      headers['Upgrade'] === 'websocket' &&
+      headers['Sec-WebSocket-Version'] === '13') {
+    response = native.ReceiveHandshakeData(
+      headers['Sec-WebSocket-Key']
+    ).toString();
+    client.readyState = 'OPEN';
+    client._socket.write(response);
+    server.emit('open', client);
+  } else {
+    response = method[2] + ' 400 Bad Request';
+    client._socket.write(response);
+  }
+}
+
+function Server(options, listener) {
+  if (!(this instanceof Server)) {
+    return new Server(options);
+  }
+
+  EventEmitter.call(this);
+  var emit_type = 'connection';
+  this._netserver = null;
+
+  if (options.server) {
+    if (Object.keys(tls).length != 0 && options.server instanceof tls.Server) {
+      this._netserver = options.server;
+      emit_type = 'secureConnection';
+    } else if (options.server instanceof net.Server) {
+      this._netserver = options.server;
+    }
+  } else if (options.port) {
+    if (options.secure == true) {
+      if (Object.keys(tls).length == 0) {
+        throw new Error('TLS module is required to create a secure server.');
+      }
+      this._netserver = tls.createServer(options);
+      this._netserver.on('error', this.onError);
+      this._netserver.listen(options.port);
+      emit_type = 'secureConnection';
+    } else {
+      this._netserver = net.createServer(options);
+      this._netserver.on('error', this.onError);
+      this._netserver.listen(options.port);
+    }
+  } else {
+    throw new Error('One of port or server must be provided as option');
+  }
+  this._netserver.path = options.path || '/';
+
+  this._netserver.on('error', this.onError);
+  this._netserver.on(emit_type, connectionListener);
+  this._netserver._serverHandle = new ServerHandle();
+
+  if (listener) {
+    this._netserver.on('open', listener);
+  }
+
+  this.options = options;
+}
+
+ServerHandle.prototype.ondata = function(data, client) {
+  native.wsReceive(this, data, client);
+};
+
+ServerHandle.prototype.onmessage = function(msg, client) {
+  client.emit('message', msg);
+};
+
+ServerHandle.prototype.pong = function(msg, client) {
+  client.emit('ping', msg);
+  this.sendFrame(native.ping(false, msg, true), client);
+};
+
+ServerHandle.prototype.onError = function(err, client) {
+  client.emit('error', err);
+};
+
+ServerHandle.prototype.sendFrame = function(msg, client) {
+  if (client._socket._socketState.writable) {
+    client._socket.write(msg);
+  } else {
+    if (this.clients.indexOf(client) > -1) {
+      this.onError('Underlying socket', client);
+    }
+  }
+};
+
+ServerHandle.prototype.onclose = function(msg, client) {
+  client.readyState = 'CLOSING';
+  if (msg) {
+    // If there is msg we know the following:
+    // 4 characters status code (1000-4999)
+    // rest is msg payload
+    var msg_str = msg.toString();
+    msg = {
+      code: msg_str.substr(0, 4),
+      reason: msg_str.substr(4, msg_str.length),
+    };
+  } else {
+    msg = {};
+  }
+
+  client.close(msg);
+};
+
+Server.prototype.close = function(reason, code) {
+  var msg = {
+    code: code || 1000,
+    reason: reason || 'Connection successfully closed',
+  };
+
+  var i = 0;
+  while (this._netserver._serverHandle.clients.length != 0) {
+    this._netserver._serverHandle.clients[i].readyState = 'CLOSING';
+    this._netserver._serverHandle.clients[i].close(msg);
+  }
+
+  this._netserver.close();
+  this.emit('close', msg);
+};
+
+Server.prototype.broadcast = function(msg, options) {
+  if (options) {
+    var mask = options.mask || true;
+    var binary = options.binary || false;
+    var compress = options.compress;
+    if (compress) {
+      // Currently not supported, needs zlib
+      this.onError('Compression is not supported');
+    }
+  }
+  var buff = native.send(msg, binary, mask);
+
+  var self = this;
+  this._netserver._serverHandle.clients.forEach(function each(client) {
+    if (client.readyState === 'OPEN') {
+      self._netserver._serverHandle.sendFrame(buff, client);
+    }
+  });
+};
+
+Server.prototype.address = function() {
+  return this._netserver.address();
+};
+
+Server.prototype.onError = function(err) {
+  this.emit('error', err);
+};
+
+WebsocketClient.prototype.send = function(message, opts) {
+  if (opts) {
+    var mask = opts.mask;
+    var binary = opts.binary;
+    var compress = opts.compress;
+    if (compress) {
+      // Currently not supported, needs zlib
+      this._handle.onError('Compression is not supported');
+    }
+  }
+  var buff = native.send(message, binary, mask, compress);
+  if (buff) {
+    this._handle.sendFrame(buff, this);
+  }
+};
+
+WebsocketClient.prototype.close = function(msg) {
+  msg = {
+    reason: msg.reason || 'Connection successfully closed',
+    code: msg.code || 1000,
+  };
+
+  var buff = native.close(msg.reason, msg.code);
+  this._handle.sendFrame(buff, this);
+  this.emit('close', msg);
+  this._socket.end();
+  var id = this._handle.clients.indexOf(this);
+  this._handle.clients.splice(id, 1);
+};
+
+WebsocketClient.prototype.onError = function(err) {
+  this.emit('error', err);
+};
+
+WebSocketHandle.prototype.onmessage = function(msg) {
+  this.client.emit('message', msg);
+};
+
+WebSocketHandle.prototype.ondata = function(data) {
+  native.wsReceive(this, data, this);
+};
+
+WebSocketHandle.prototype.onhandshakedone = function(remaining) {
+  this.client.emit('open');
+  this.client._firstMessage = false;
+  if (remaining) {
+    this.ondata(remaining);
+  }
+};
+
+WebSocketHandle.prototype.onError = function(err) {
+  this.client.emit('error', err);
+};
+
+WebSocketHandle.prototype.onclose = function(msg) {
+  if (msg) {
+    // If there is msg we know the following:
+    // 4 characters status code (1000-4999)
+    // rest is msg payload
+    var msg_str = msg.toString();
+    msg = {
+      code: msg_str.substr(0, 4),
+      reason: msg_str.substr(4, msg_str.length),
+    };
+  } else {
+    msg = {};
+  }
+
+  this.client.emit('close', msg);
+  for (var i = 0; i < this.pings.length; i++) {
+    clearInterval(this.pings[i].timer);
+  }
+  this.client._socket.end();
+};
+
+WebSocketHandle.prototype.sendFrame = function(msg, cb) {
+  if (this.connected) {
+    if (typeof cb == 'function') {
+      this.client._socket.write(msg, cb);
+    } else {
+      this.client._socket.write(msg);
+    }
+  } else {
+    this.onError('Underlying socket connection is closed');
+  }
+};
+
+WebSocketHandle.prototype.pong = function(msg) {
+  this.client._socket.write(native.ping(false, msg, true));
+};
+
+WebSocketHandle.prototype.onpingresp = function(msg) {
+  for (var i = 0; i < this.pings.length; i++) {
+    if (this.pings[i].id == msg) {
+      clearInterval(this.pings[i].timer);
+      this.pings[i].callback(msg);
+      this.pings.splice(i, 1);
+      return;
+    }
+  }
+};
+
+function sendHandshake(jsref, host, path) {
+  return native.prepareHandshake(jsref, host, path);
+}
+
+Websocket.prototype.connect = function(url, port, path, callback) {
+  var host = url.toString() || '127.0.0.1';
+  path = path || '/';
+
+  var emit_type = 'connect';
+
+  if (host.substr(0, 3) == 'wss') {
+    this._secure = true;
+    if (Object.keys(tls).length == 0) {
+      this._handle.onError('TLS module was not found!');
+    }
+    port = port || 443;
+    host = host.substr(6);
+    this._socket = tls.connect(port, host);
+    emit_type = 'secureConnect';
+  } else if (host.substr(0, 2) == 'ws') {
+    port = port || 80;
+    this._socket = new net.Socket();
+    host = host.substr(5);
+  } else {
+    port = port || 80;
+    this._socket = new net.Socket();
+  }
+
+  if (typeof callback == 'function') {
+    this.on('open', callback);
+  }
+
+  var self = this;
+
+  this._socket.on(emit_type, function() {
+    self._handle.connected = true;
+    self._socket.write(sendHandshake(self._handle, host, path));
+  });
+
+  this._socket.on('end', function() {
+    self._handle.connected = false;
+  });
+  if (emit_type == 'connect') {
+    this._socket.connect(port, host);
+  }
+
+  this._socket.on('data', function(data) {
+    if (self._firstMessage) {
+      var remaining_data = native.parseHandshakeData(data, self._handle);
+      self._handle.onhandshakedone(remaining_data);
+    } else {
+      self._handle.ondata(data);
+    }
+  });
+};
+
+Websocket.prototype.close = function(message, code, cb) {
+  this._handle.sendFrame(native.close(message, code), cb);
+};
+
+Websocket.prototype.ping = function(message, mask, cb) {
+  var self = this;
+  var obj = {
+    id: message,
+    callback: cb,
+    timer: setTimeout(function() {
+      self.close('Ping timeout limit exceeded', 1002);
+    }, 30000),
+  };
+  this._handle.pings.push(obj);
+  this._handle.sendFrame(native.ping(true, message, mask));
+};
+
+Websocket.prototype.send = function(message, opts, cb) {
+  if (opts) {
+    var mask = opts.mask;
+    var binary = opts.binary;
+    var compress = opts.compress;
+    if (compress) {
+      // Currently not supported, needs zlib
+      this._handle.onError('Compression is not supported');
+    }
+  }
+  var buff = native.send(message, binary, mask, compress);
+  if (buff) {
+    this._handle.sendFrame(buff, cb);
+  }
+};
+
+exports.Websocket = Websocket;
+exports.Server = Server;
index 9454159f1839ae0aaa022465570804689b31a85e..10c723b7b6e7a664de3857d4452c70d1826e1381 100644 (file)
@@ -33,7 +33,7 @@
     },
     "ble": {
       "js_file": "js/ble.js",
-      "require": ["blehcisocket", "ble_characteristic", "ble_descriptor",
+      "require": ["ble_hci_socket", "ble_characteristic", "ble_descriptor",
                   "ble_hci_socket_acl_stream", "ble_hci_socket_bindings",
                   "ble_hci_socket_crypto", "ble_hci_socket_gap",
                   "ble_hci_socket_gatt", "ble_hci_socket_hci",
     "ble_hci_socket_hci": {
       "js_file": "js/ble_hci_socket_hci.js",
       "require": ["console", "events", "util", "ble_uuid_util",
-                  "blehcisocket"]
+                  "ble_hci_socket"]
     },
     "ble_hci_socket_hci_status": {
       "js_file": "js/ble_hci_socket_hci_status.js"
     },
     "ble_hci_socket_mgmt": {
       "js_file": "js/ble_hci_socket_mgmt.js",
-      "require": ["console", "events", "util", "blehcisocket"]
+      "require": ["console", "events", "util", "ble_hci_socket"]
     },
     "ble_hci_socket_smp": {
       "js_file": "js/ble_hci_socket_smp.js",
@@ -94,7 +94,7 @@
     "ble_uuid_util": {
       "js_file": "js/ble_uuid_util.js"
     },
-    "blehcisocket": {
+    "ble_hci_socket": {
       "platforms": {
         "linux": {
           "native_files": ["modules/linux/iotjs_module_blehcisocket-linux.c"]
       "native_files": ["modules/iotjs_module_constants.c"],
       "init": "InitConstants"
     },
+    "crypto": {
+      "native_files": ["modules/iotjs_module_crypto.c"],
+      "init": "InitCrypto",
+      "js_file": "js/crypto.js"
+    },
     "dgram": {
       "js_file": "js/dgram.js",
       "require": ["events", "udp", "util"]
         "linux": {
           "native_files": ["modules/linux/iotjs_module_gpio-linux.c"]
         },
+        "mocklinux": {
+          "native_files": ["modules/mock/iotjs_module_gpio-mock.c"]
+        },
         "nuttx": {
           "native_files": ["modules/nuttx/iotjs_module_gpio-nuttx.c"]
         },
       "js_file": "js/http_server.js",
       "require": ["http_common", "http_outgoing", "net", "util"]
     },
+    "http_signature": {
+      "js_file": "js/http_signature.js",
+      "require": ["tls", "crypto"]
+    },
     "http_parser": {
       "native_files": ["modules/iotjs_module_http_parser.c"],
       "init": "InitHttpParser"
         "linux": {
           "native_files": ["modules/linux/iotjs_module_i2c-linux.c"]
         },
+        "mocklinux": {
+          "native_files": ["modules/mock/iotjs_module_i2c-mock.c"]
+        },
         "nuttx": {
           "native_files": ["modules/nuttx/iotjs_module_i2c-nuttx.c"]
         },
     "util": {
       "js_file": "js/util.js"
     },
+    "websocket": {
+      "native_files": ["modules/iotjs_module_websocket.h",
+                       "modules/iotjs_module_websocket.c"],
+      "init": "InitWebsocket",
+      "js_file": "js/websocket.js",
+      "require": ["crypto", "events", "net", "util"]
+    },
     "bridge": {
       "native_files": ["modules/iotjs_module_bridge.c"],
       "init": "InitBridge",
index 533941ce9c6572e98561b4d5e5182689db54027d..5cf9bc97a9b44995a22a61088281ab12844c4031 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "iotjs_def.h"
 #include "iotjs_module_adc.h"
+#include "iotjs_uv_request.h"
 
 
 IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(adc);
@@ -27,20 +28,19 @@ static void iotjs_adc_destroy(iotjs_adc_t* adc) {
 }
 
 static void adc_worker(uv_work_t* work_req) {
-  iotjs_periph_reqwrap_t* req_wrap =
-      (iotjs_periph_reqwrap_t*)(iotjs_reqwrap_from_request(
-          (uv_req_t*)work_req));
-  iotjs_adc_t* adc = (iotjs_adc_t*)req_wrap->data;
+  iotjs_periph_data_t* worker_data =
+      (iotjs_periph_data_t*)IOTJS_UV_REQUEST_EXTRA_DATA(work_req);
+  iotjs_adc_t* adc = (iotjs_adc_t*)worker_data->data;
 
-  switch (req_wrap->op) {
+  switch (worker_data->op) {
     case kAdcOpOpen:
-      req_wrap->result = iotjs_adc_open(adc);
+      worker_data->result = iotjs_adc_open(adc);
       break;
     case kAdcOpRead:
-      req_wrap->result = iotjs_adc_read(adc);
+      worker_data->result = iotjs_adc_read(adc);
       break;
     case kAdcOpClose:
-      req_wrap->result = iotjs_adc_close(adc);
+      worker_data->result = iotjs_adc_close(adc);
       break;
     default:
       IOTJS_ASSERT(!"Invalid Adc Operation");
@@ -55,14 +55,14 @@ JS_FUNCTION(AdcCons) {
   // Create ADC object
   const jerry_value_t jadc = JS_GET_THIS();
   iotjs_adc_t* adc = adc_create(jadc);
-  IOTJS_ASSERT(adc ==
-               (iotjs_adc_t*)(iotjs_jval_get_object_native_handle(jadc)));
+  IOTJS_ASSERT(adc == (iotjs_adc_t*)(iotjs_jval_get_object_native_handle(
+                          jadc, &this_module_native_info)));
 
   jerry_value_t jconfig;
   JS_GET_REQUIRED_ARG_VALUE(0, jconfig, IOTJS_MAGIC_STRING_CONFIG, object);
 
   jerry_value_t config_res = iotjs_adc_set_platform_config(adc, jconfig);
-  if (jerry_value_has_error_flag(config_res)) {
+  if (jerry_value_is_error(config_res)) {
     return config_res;
   }
   IOTJS_ASSERT(jerry_value_is_undefined(config_res));
index 16020c84eb27413ce0df9c02a594e670d97d5693..187263fcf405b733bcd28f1bc59cd719f96d7559 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "iotjs_def.h"
 #include "iotjs_module_periph_common.h"
-#include "iotjs_reqwrap.h"
 
 // Forward declaration of platform data. These are only used by platform code.
 // Generic ADC module never dereferences platform data pointer.
index bad2b7a608b767361f33a5752ac557b58b394110..6211bf4f621e4940df09278af6de6ed5500686a1 100644 (file)
@@ -167,9 +167,10 @@ JS_FUNCTION(BleHciSocketCons) {
   // Create object
   jerry_value_t jblehcisocket = JS_GET_THIS();
   iotjs_blehcisocket_t* blehcisocket = iotjs_blehcisocket_create(jblehcisocket);
-  IOTJS_ASSERT(blehcisocket ==
-               (iotjs_blehcisocket_t*)(iotjs_jval_get_object_native_handle(
-                   jblehcisocket)));
+  IOTJS_ASSERT(
+      blehcisocket ==
+      (iotjs_blehcisocket_t*)(iotjs_jval_get_object_native_handle(jblehcisocket,
+                                                                  NULL)));
   return jerry_create_undefined();
 }
 
index e6560cbbba059584b88dad892b86e89d732e4cbb..6a82eb800b8e25ed4d5917872470eccfed492583 100644 (file)
@@ -38,7 +38,6 @@
 #define IOTJS_MODULE_BLE_HCI_SOCKET_H
 
 #include "iotjs_def.h"
-#include "iotjs_reqwrap.h"
 
 typedef struct {
   jerry_value_t jobject;
index f8dadb760d3552e7bc22cd580204dcb57be648cb..423e1fe8cf54ad1fb2312bd459817ae387e7cf35 100644 (file)
@@ -14,7 +14,6 @@
  */
 #include "iotjs_def.h"
 #include "iotjs_module_bridge.h"
-#include "iotjs_reqwrap.h"
 #include <stdio.h>
 
 typedef enum {
@@ -204,10 +203,11 @@ static void iotjs_bridge_call_destroy(iotjs_bridge_call_t* bridgecall) {
 }
 
 static iotjs_bridge_object_t* iotjs_bridge_get_object(jerry_value_t obj_val) {
-  iotjs_bridge_object_t* bridgeobj = NULL;
-  bool is_ok = false;
-  is_ok = jerry_get_object_native_pointer(obj_val, (void**)&bridgeobj, NULL);
-  if (!is_ok) {
+  iotjs_bridge_object_t* bridgeobj =
+      (iotjs_bridge_object_t*)iotjs_jval_get_object_native_handle(obj_val,
+                                                                  NULL);
+
+  if (bridgeobj == NULL) {
     bridgeobj = IOTJS_ALLOC(iotjs_bridge_object_t);
     bridgeobj->jobject = obj_val;
     bridgeobj->calls = NULL;
@@ -290,20 +290,22 @@ static int iotjs_bridge_remove_call(iotjs_bridge_call_t* callobj) {
 }
 
 static void iotjs_bridge_js_call(iotjs_bridge_call_t* bridgecall) {
-  iotjs_jargs_t jargs = iotjs_jargs_create(2);
+  jerry_value_t jargs[2] = { 0 };
   if (bridgecall->status == CALL_STATUS_ERROR) { // internal error
-    iotjs_jargs_append_error(&jargs, iotjs_string_data(&bridgecall->ret_msg));
-    iotjs_jargs_append_null(&jargs);
+    jargs[0] = iotjs_jval_create_error_without_error_flag(
+        iotjs_string_data(&bridgecall->ret_msg));
+    jargs[1] = jerry_create_null();
   } else {
-    iotjs_jargs_append_null(&jargs);
-    iotjs_jargs_append_string_raw(&jargs,
-                                  iotjs_string_data(&bridgecall->ret_msg));
+    jargs[0] = jerry_create_null();
+    jargs[1] = jerry_create_string_from_utf8(
+        (const jerry_char_t*)iotjs_string_data(&bridgecall->ret_msg));
   }
   jerry_value_t jcallback = bridgecall->jcallback;
   if (jerry_value_is_function(jcallback)) {
-    iotjs_make_callback(jcallback, jerry_create_undefined(), &jargs);
+    iotjs_invoke_callback(jcallback, jerry_create_undefined(), jargs, 2);
   }
-  iotjs_jargs_destroy(&jargs);
+  jerry_release_value(jargs[0]);
+  jerry_release_value(jargs[1]);
 }
 
 static void aysnc_callback(uv_async_t* async) {
index b69c41b4626b59e09f139d15a66dbe995e81e502..7b1ffda2e91d7b0313334b7b058f986f2de81924 100644 (file)
@@ -31,46 +31,43 @@ IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(bufferwrap);
 
 iotjs_bufferwrap_t* iotjs_bufferwrap_create(const jerry_value_t jobject,
                                             size_t length) {
-  iotjs_bufferwrap_t* bufferwrap = IOTJS_ALLOC(iotjs_bufferwrap_t);
+  iotjs_bufferwrap_t* bufferwrap = (iotjs_bufferwrap_t*)iotjs_buffer_allocate(
+      sizeof(iotjs_bufferwrap_t) + length);
 
   bufferwrap->jobject = jobject;
   jerry_set_object_native_pointer(jobject, bufferwrap,
                                   &this_module_native_info);
 
-  if (length > 0) {
-    bufferwrap->length = length;
-    bufferwrap->buffer = iotjs_buffer_allocate(length);
-    IOTJS_ASSERT(bufferwrap->buffer != NULL);
-  } else {
-    bufferwrap->length = 0;
-    bufferwrap->buffer = NULL;
-  }
+  bufferwrap->length = length;
 
   IOTJS_ASSERT(
       bufferwrap ==
-      (iotjs_bufferwrap_t*)(iotjs_jval_get_object_native_handle(jobject)));
+      (iotjs_bufferwrap_t*)(iotjs_jval_get_object_native_handle(jobject,
+                                                                NULL)));
 
   return bufferwrap;
 }
 
 
 static void iotjs_bufferwrap_destroy(iotjs_bufferwrap_t* bufferwrap) {
-  IOTJS_RELEASE(bufferwrap->buffer);
   IOTJS_RELEASE(bufferwrap);
 }
 
 
 iotjs_bufferwrap_t* iotjs_bufferwrap_from_jbuffer(const jerry_value_t jbuffer) {
   IOTJS_ASSERT(jerry_value_is_object(jbuffer));
-  iotjs_bufferwrap_t* buffer =
-      (iotjs_bufferwrap_t*)iotjs_jval_get_object_native_handle(jbuffer);
+  iotjs_bufferwrap_t* buffer = (iotjs_bufferwrap_t*)
+      iotjs_jval_get_object_native_handle(jbuffer, &this_module_native_info);
   IOTJS_ASSERT(buffer != NULL);
   return buffer;
 }
 
 
 size_t iotjs_bufferwrap_length(iotjs_bufferwrap_t* bufferwrap) {
-  IOTJS_ASSERT(bufferwrap != NULL);
+  if (bufferwrap == NULL) {
+    IOTJS_ASSERT(0);
+    return 0;
+  }
 #ifndef NDEBUG
   jerry_value_t jlength =
       iotjs_jval_get_property(bufferwrap->jobject, IOTJS_MAGIC_STRING_LENGTH);
@@ -82,6 +79,22 @@ size_t iotjs_bufferwrap_length(iotjs_bufferwrap_t* bufferwrap) {
 }
 
 
+iotjs_bufferwrap_t* iotjs_jbuffer_get_bufferwrap_ptr(
+    const jerry_value_t jbuffer) {
+  if (!jerry_value_is_object(jbuffer)) {
+    return NULL;
+  }
+
+  iotjs_bufferwrap_t* buffer = (iotjs_bufferwrap_t*)
+      iotjs_jval_get_object_native_handle(jbuffer, &this_module_native_info);
+  if (buffer != NULL) {
+    return buffer;
+  }
+
+  return NULL;
+}
+
+
 static size_t bound_range(size_t index, size_t low, size_t upper) {
   if (index == SIZE_MAX) {
     return low;
@@ -158,27 +171,59 @@ static int32_t base64_to_bin(char c) {
 }
 
 
-static size_t base64_decode(char* buf, size_t len, const char* src,
+static size_t base64_decode(char* dst, size_t len, const char* src,
                             const size_t srcLen) {
   if (srcLen == 0) {
-    return 0 + 1;
+    return 1;
+  }
+
+  char* decoded_base64 = NULL;
+  size_t decoded_len = iotjs_base64_decode(&decoded_base64, src, srcLen);
+  size_t ret_val = 0;
+  if (decoded_len) {
+    char* buf = dst;
+    char* bufEnd = len > decoded_len ? dst + decoded_len : dst + len;
+
+    char* pos = decoded_base64;
+    while (buf < bufEnd) {
+      *buf++ = *pos++;
+    }
+    ret_val = (size_t)(buf - dst) + 1;
   }
 
-  if ((srcLen & 0x3) != 0) {
+  IOTJS_RELEASE(decoded_base64);
+  return ret_val;
+}
+
+
+size_t iotjs_base64_decode(char** out_buff, const char* src,
+                           const size_t srcLen) {
+  if ((srcLen & 0x3) != 0 || srcLen == 0) {
     return 0;
   }
 
-  const char* bufStart = buf;
-  const char* bufEnd = buf + len;
+  size_t len = (3 * (srcLen / 4));
+
   const char* srcEnd = src + srcLen;
 
   if (srcEnd[-1] == '=') {
     srcEnd--;
+    len--;
     if (srcEnd[-1] == '=') {
       srcEnd--;
+      len--;
     }
   }
 
+  if (*out_buff == NULL) {
+    *out_buff = IOTJS_CALLOC(len, char);
+  }
+
+  char* buf = *out_buff;
+
+  const char* bufStart = buf;
+  const char* bufEnd = buf + len;
+
   int32_t current_bits = 0;
   int32_t shift = 8;
 
@@ -203,12 +248,12 @@ static size_t base64_decode(char* buf, size_t len, const char* src,
       shift = 8;
     }
 
-    if (buf < bufEnd) {
-      *buf++ = (char)byte;
+    if (buf <= bufEnd) {
+      *buf++ = byte;
     }
   }
 
-  return (size_t)((buf - bufStart) + 1);
+  return (size_t)((buf - bufStart));
 }
 
 
@@ -284,23 +329,31 @@ static size_t index_normalizer(int64_t index, size_t max_length) {
 }
 
 jerry_value_t iotjs_bufferwrap_create_buffer(size_t len) {
-  jerry_value_t jglobal = jerry_get_global_object();
+  jerry_value_t jres_buffer = jerry_create_object();
+
+  iotjs_bufferwrap_create(jres_buffer, len);
+
+  iotjs_jval_set_property_number(jres_buffer, IOTJS_MAGIC_STRING_LENGTH, len);
 
+  // Support for 'instanceof' operator
+  jerry_value_t native_buffer = iotjs_module_get("buffer");
   jerry_value_t jbuffer =
-      iotjs_jval_get_property(jglobal, IOTJS_MAGIC_STRING_BUFFER);
-  jerry_release_value(jglobal);
-  IOTJS_ASSERT(jerry_value_is_function(jbuffer));
+      iotjs_jval_get_property(native_buffer, IOTJS_MAGIC_STRING_BUFFER);
 
-  jerry_value_t arg = jerry_create_number(len);
+  if (!jerry_value_is_error(jbuffer) && jerry_value_is_object(jbuffer)) {
+    jerry_value_t jbuffer_proto =
+        iotjs_jval_get_property(jbuffer, IOTJS_MAGIC_STRING_PROTOTYPE);
 
-  jerry_value_t jres = jerry_construct_object(jbuffer, &arg, 1);
-  IOTJS_ASSERT(!jerry_value_has_error_flag(jres));
-  IOTJS_ASSERT(jerry_value_is_object(jres));
+    if (!jerry_value_is_error(jbuffer_proto) &&
+        jerry_value_is_object(jbuffer_proto)) {
+      jerry_set_prototype(jres_buffer, jbuffer_proto);
+    }
 
-  jerry_release_value(arg);
+    jerry_release_value(jbuffer_proto);
+  }
   jerry_release_value(jbuffer);
 
-  return jres;
+  return jres_buffer;
 }
 
 
@@ -441,19 +494,17 @@ JS_FUNCTION(ReadUInt8) {
   DJS_CHECK_ARGS(2, object, number);
   JS_DECLARE_OBJECT_PTR(0, bufferwrap, buffer_wrap);
 
-
   size_t buffer_length = iotjs_bufferwrap_length(buffer_wrap);
+
+  if (buffer_length == 0) {
+    return jerry_create_number(0);
+  }
+
   size_t offset = iotjs_convert_double_to_sizet(JS_GET_ARG(1, number));
   offset = bound_range(offset, 0, buffer_length - 1);
 
   char* buffer = buffer_wrap->buffer;
-  uint8_t result = 0;
-
-  if (buffer != NULL) {
-    result = (uint8_t)buffer[offset];
-  }
-
-  return jerry_create_number(result);
+  return jerry_create_number((uint8_t)buffer[offset]);
 }
 
 
@@ -511,62 +562,73 @@ static jerry_value_t to_hex_string(const uint8_t* data, size_t length) {
   return ret_value;
 }
 
-static char to_base64_char(uint8_t digit) {
-  if (digit <= 25) {
-    return (char)digit + 'A';
-  }
-  if (digit <= 51) {
-    return (char)digit + 'a' - 26;
-  }
-  if (digit <= 61) {
-    return (char)digit + '0' - 52;
-  }
 
-  return (digit == 62) ? '+' : '/';
+static jerry_value_t to_base64_string(const uint8_t* data, size_t length) {
+  unsigned char* buffer = NULL;
+  size_t buffer_length = iotjs_base64_encode(&buffer, data, length);
+  jerry_value_t ret_value = jerry_create_string_sz(buffer, buffer_length);
+  IOTJS_RELEASE(buffer);
+
+  return ret_value;
 }
 
-static jerry_value_t to_base64_string(const uint8_t* data, size_t length) {
-  if (length == 0) {
-    return jerry_create_string_sz(NULL, 0);
-  }
+static const unsigned char base64_enc_map[65] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
-  const uint8_t* end = data + length;
 
-  size_t buffer_length = ((length + 2) / 3) * 4;
-  char* buffer = iotjs_buffer_allocate(buffer_length);
-  const jerry_char_t* str = (const jerry_char_t*)buffer;
+size_t iotjs_base64_encode(unsigned char** out_buff, const unsigned char* data,
+                           size_t buff_len) {
+  size_t i, n;
+  int C1, C2, C3;
+  unsigned char* p;
 
-  uint32_t current_bits = 0;
-  int32_t shift = 2;
+  if (buff_len == 0) {
+    return 0;
+  }
 
-  while (data < end) {
-    current_bits = (current_bits << 8) | *data++;
+  n = buff_len / 3 + (buff_len % 3 != 0);
 
-    *buffer++ = to_base64_char(current_bits >> shift);
-    current_bits &= (uint32_t)((1 << shift) - 1);
+  if (n > ((size_t)-2) / 4) {
+    return 0;
+  }
+
+  if (*out_buff == NULL) {
+    *out_buff = IOTJS_CALLOC(n * 4 + 1, unsigned char);
+  }
 
-    shift += 2;
+  n = (buff_len / 3) * 3;
 
-    if (shift == 8) {
-      *buffer++ = to_base64_char(current_bits);
-      current_bits = 0;
-      shift = 2;
-    }
+  for (i = 0, p = *out_buff; i < n; i += 3) {
+    C1 = *data++;
+    C2 = *data++;
+    C3 = *data++;
+
+    *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
+    *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
+    *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
+    *p++ = base64_enc_map[C3 & 0x3F];
   }
 
-  char* buffer_end = (char*)str + buffer_length;
-  if (buffer < buffer_end) {
-    buffer[0] = to_base64_char(current_bits << (8 - shift));
-    buffer[1] = '=';
+  if (i < buff_len) {
+    C1 = *data++;
+    C2 = ((i + 1) < buff_len) ? *data++ : 0;
 
-    if (buffer + 2 < buffer_end)
-      buffer[2] = '=';
+    *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
+    *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
+
+    if ((i + 1) < buff_len) {
+      *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
+    } else {
+      *p++ = '=';
+    }
+
+    *p++ = '=';
   }
 
-  jerry_value_t ret_value = jerry_create_string_sz(str, buffer_length);
-  IOTJS_RELEASE(str);
+  size_t ret_len = (size_t)(p - *out_buff);
+  *p = 0;
 
-  return ret_value;
+  return ret_len;
 }
 
 
@@ -625,6 +687,66 @@ JS_FUNCTION(ByteLength) {
 }
 
 
+JS_FUNCTION(FromArrayBuffer) {
+  if (jargc < 1 || !jerry_value_is_arraybuffer(jargv[0])) {
+    return jerry_create_undefined();
+  }
+  jerry_length_t offset = 0;
+  jerry_length_t length = jerry_get_arraybuffer_byte_length(jargv[0]);
+
+  if (jargc >= 2) {
+    jerry_value_t offset_num = jerry_value_to_number(jargv[1]);
+
+    if (jerry_value_is_error(offset_num)) {
+      return offset_num;
+    }
+
+    double offset_value = jerry_get_number_value(offset_num);
+    if (isnan(offset_value)) {
+      offset_value = 0;
+    }
+    jerry_release_value(offset_num);
+
+    if (offset_value < 0 || offset_value > length) {
+      return JS_CREATE_ERROR(RANGE, "'offset' is out of bounds");
+    }
+    offset = (jerry_length_t)offset_value;
+  }
+
+  length -= offset;
+
+  if (jargc >= 3) {
+    if (jerry_value_is_error(jargv[2])) {
+      return length;
+    }
+
+    if (jerry_value_is_number(jargv[2])) {
+      double length_value = (double)length;
+      length_value = jerry_get_number_value(jargv[2]);
+
+      if (isnan(length_value) || length_value < 0) {
+        length = 0;
+      } else if (length_value < length) {
+        length = (jerry_length_t)length_value;
+      } else if (length_value > length) {
+        return JS_CREATE_ERROR(RANGE, "'length' is out of bounds");
+      }
+    }
+  }
+
+  if (length < 1) {
+    return iotjs_bufferwrap_create_buffer(0);
+  }
+
+  jerry_value_t jres_bufferwrap = iotjs_bufferwrap_create_buffer(length);
+  iotjs_bufferwrap_t* jsres_buffer =
+      iotjs_jbuffer_get_bufferwrap_ptr(jres_bufferwrap);
+  jerry_arraybuffer_read(jargv[0], offset, (uint8_t*)jsres_buffer->buffer,
+                         length);
+  return jres_bufferwrap;
+}
+
+
 jerry_value_t InitBuffer() {
   jerry_value_t buffer = jerry_create_external_function(Buffer);
   iotjs_jval_set_method(buffer, IOTJS_MAGIC_STRING_BYTELENGTH, ByteLength);
@@ -636,6 +758,8 @@ jerry_value_t InitBuffer() {
   iotjs_jval_set_method(buffer, IOTJS_MAGIC_STRING_READUINT8, ReadUInt8);
   iotjs_jval_set_method(buffer, IOTJS_MAGIC_STRING_SLICE, Slice);
   iotjs_jval_set_method(buffer, IOTJS_MAGIC_STRING_TOSTRING, ToString);
+  iotjs_jval_set_method(buffer, IOTJS_MAGIC_STRING_FROM_ARRAYBUFFER,
+                        FromArrayBuffer);
 
   return buffer;
 }
index 29db89cb6f95a32defe671327d193c8b7d87a6e0..fc269cbf779566e18be4061647186332f874474d 100644 (file)
 
 typedef struct {
   jerry_value_t jobject;
-  char* buffer;
   size_t length;
+  char buffer[];
 } iotjs_bufferwrap_t;
 
-
+size_t iotjs_base64_decode(char** out_buff, const char* src,
+                           const size_t srcLen);
+size_t iotjs_base64_encode(unsigned char** out_buff, const uint8_t* data,
+                           size_t length);
 iotjs_bufferwrap_t* iotjs_bufferwrap_create(const jerry_value_t jbuiltin,
                                             size_t length);
 
@@ -36,8 +39,9 @@ int iotjs_bufferwrap_compare(const iotjs_bufferwrap_t* bufferwrap,
 
 size_t iotjs_bufferwrap_copy(iotjs_bufferwrap_t* bufferwrap, const char* src,
                              size_t len);
+iotjs_bufferwrap_t* iotjs_jbuffer_get_bufferwrap_ptr(const jerry_value_t);
 
-// Create buffer object.
+// Fail-safe creation of Buffer object.
 jerry_value_t iotjs_bufferwrap_create_buffer(size_t len);
 
 
index aa04bb8dbd36c6b7ad385bb4730c6451a7529f3b..ea303932b37e3cb57dfcc61a34140ddb571c3c49 100644 (file)
@@ -14,9 +14,9 @@
  */
 
 #include "iotjs_def.h"
+#include "iotjs_compatibility.h"
 #include "iotjs_module.h"
 
-
 #define SET_CONSTANT(object, constant)                           \
   do {                                                           \
     iotjs_jval_set_property_number(object, #constant, constant); \
diff --git a/src/modules/iotjs_module_crypto.c b/src/modules/iotjs_module_crypto.c
new file mode 100644 (file)
index 0000000..127e5c3
--- /dev/null
@@ -0,0 +1,541 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+/*
+ *  FIPS-180-1 compliant SHA-1 implementation
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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.
+ *
+ *  This file is part of mbed TLS (https://tls.mbed.org)
+ */
+
+/*
+ *  The SHA-1 standard was published by NIST in 1993.
+ *
+ *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
+ */
+
+#include "iotjs_def.h"
+#include "iotjs_module_crypto.h"
+#include "iotjs_module_buffer.h"
+
+/* These enum values are the same as the ones in crypto.js as well as the
+   corresponding ones in sha.h in mbedTLS.*/
+typedef enum {
+  IOTJS_CRYPTO_SHA1 = 4,
+  IOTJS_CRYPTO_SHA256 = 6,
+} iotjs_crypto_sha_t;
+
+#if !ENABLE_MODULE_TLS
+const char no_tls_err_str[] = "TLS module must be enabled to use this feature";
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n, b, i)                                          \
+  {                                                                     \
+    (n) = ((uint32_t)(b)[(i)] << 24) | ((uint32_t)(b)[(i) + 1] << 16) | \
+          ((uint32_t)(b)[(i) + 2] << 8) | ((uint32_t)(b)[(i) + 3]);     \
+  }
+#endif
+
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_BE(n, b, i)                 \
+  {                                            \
+    (b)[(i)] = (unsigned char)((n) >> 24);     \
+    (b)[(i) + 1] = (unsigned char)((n) >> 16); \
+    (b)[(i) + 2] = (unsigned char)((n) >> 8);  \
+    (b)[(i) + 3] = (unsigned char)((n));       \
+  }
+#endif
+
+static int iotjs_sha1_process(uint32_t state[5], const unsigned char data[64]) {
+  uint32_t temp, W[16], A, B, C, D, E;
+
+  GET_UINT32_BE(W[0], data, 0);
+  GET_UINT32_BE(W[1], data, 4);
+  GET_UINT32_BE(W[2], data, 8);
+  GET_UINT32_BE(W[3], data, 12);
+  GET_UINT32_BE(W[4], data, 16);
+  GET_UINT32_BE(W[5], data, 20);
+  GET_UINT32_BE(W[6], data, 24);
+  GET_UINT32_BE(W[7], data, 28);
+  GET_UINT32_BE(W[8], data, 32);
+  GET_UINT32_BE(W[9], data, 36);
+  GET_UINT32_BE(W[10], data, 40);
+  GET_UINT32_BE(W[11], data, 44);
+  GET_UINT32_BE(W[12], data, 48);
+  GET_UINT32_BE(W[13], data, 52);
+  GET_UINT32_BE(W[14], data, 56);
+  GET_UINT32_BE(W[15], data, 60);
+
+#define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
+
+#define R(t)                                                           \
+  (temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ W[(t - 14) & 0x0F] ^ \
+          W[t & 0x0F],                                                 \
+   (W[t & 0x0F] = S(temp, 1)))
+
+#define P(a, b, c, d, e, x)            \
+  {                                    \
+    e += S(a, 5) + F(b, c, d) + K + x; \
+    b = S(b, 30);                      \
+  }
+
+  A = state[0];
+  B = state[1];
+  C = state[2];
+  D = state[3];
+  E = state[4];
+
+#define F(x, y, z) (z ^ (x & (y ^ z)))
+#define K 0x5A827999
+
+  P(A, B, C, D, E, W[0]);
+  P(E, A, B, C, D, W[1]);
+  P(D, E, A, B, C, W[2]);
+  P(C, D, E, A, B, W[3]);
+  P(B, C, D, E, A, W[4]);
+  P(A, B, C, D, E, W[5]);
+  P(E, A, B, C, D, W[6]);
+  P(D, E, A, B, C, W[7]);
+  P(C, D, E, A, B, W[8]);
+  P(B, C, D, E, A, W[9]);
+  P(A, B, C, D, E, W[10]);
+  P(E, A, B, C, D, W[11]);
+  P(D, E, A, B, C, W[12]);
+  P(C, D, E, A, B, W[13]);
+  P(B, C, D, E, A, W[14]);
+  P(A, B, C, D, E, W[15]);
+  P(E, A, B, C, D, R(16));
+  P(D, E, A, B, C, R(17));
+  P(C, D, E, A, B, R(18));
+  P(B, C, D, E, A, R(19));
+
+#undef K
+#undef F
+
+#define F(x, y, z) (x ^ y ^ z)
+#define K 0x6ED9EBA1
+
+  P(A, B, C, D, E, R(20));
+  P(E, A, B, C, D, R(21));
+  P(D, E, A, B, C, R(22));
+  P(C, D, E, A, B, R(23));
+  P(B, C, D, E, A, R(24));
+  P(A, B, C, D, E, R(25));
+  P(E, A, B, C, D, R(26));
+  P(D, E, A, B, C, R(27));
+  P(C, D, E, A, B, R(28));
+  P(B, C, D, E, A, R(29));
+  P(A, B, C, D, E, R(30));
+  P(E, A, B, C, D, R(31));
+  P(D, E, A, B, C, R(32));
+  P(C, D, E, A, B, R(33));
+  P(B, C, D, E, A, R(34));
+  P(A, B, C, D, E, R(35));
+  P(E, A, B, C, D, R(36));
+  P(D, E, A, B, C, R(37));
+  P(C, D, E, A, B, R(38));
+  P(B, C, D, E, A, R(39));
+
+#undef K
+#undef F
+
+#define F(x, y, z) ((x & y) | (z & (x | y)))
+#define K 0x8F1BBCDC
+
+  P(A, B, C, D, E, R(40));
+  P(E, A, B, C, D, R(41));
+  P(D, E, A, B, C, R(42));
+  P(C, D, E, A, B, R(43));
+  P(B, C, D, E, A, R(44));
+  P(A, B, C, D, E, R(45));
+  P(E, A, B, C, D, R(46));
+  P(D, E, A, B, C, R(47));
+  P(C, D, E, A, B, R(48));
+  P(B, C, D, E, A, R(49));
+  P(A, B, C, D, E, R(50));
+  P(E, A, B, C, D, R(51));
+  P(D, E, A, B, C, R(52));
+  P(C, D, E, A, B, R(53));
+  P(B, C, D, E, A, R(54));
+  P(A, B, C, D, E, R(55));
+  P(E, A, B, C, D, R(56));
+  P(D, E, A, B, C, R(57));
+  P(C, D, E, A, B, R(58));
+  P(B, C, D, E, A, R(59));
+
+#undef K
+#undef F
+
+#define F(x, y, z) (x ^ y ^ z)
+#define K 0xCA62C1D6
+
+  P(A, B, C, D, E, R(60));
+  P(E, A, B, C, D, R(61));
+  P(D, E, A, B, C, R(62));
+  P(C, D, E, A, B, R(63));
+  P(B, C, D, E, A, R(64));
+  P(A, B, C, D, E, R(65));
+  P(E, A, B, C, D, R(66));
+  P(D, E, A, B, C, R(67));
+  P(C, D, E, A, B, R(68));
+  P(B, C, D, E, A, R(69));
+  P(A, B, C, D, E, R(70));
+  P(E, A, B, C, D, R(71));
+  P(D, E, A, B, C, R(72));
+  P(C, D, E, A, B, R(73));
+  P(B, C, D, E, A, R(74));
+  P(A, B, C, D, E, R(75));
+  P(E, A, B, C, D, R(76));
+  P(D, E, A, B, C, R(77));
+  P(C, D, E, A, B, R(78));
+  P(B, C, D, E, A, R(79));
+
+#undef K
+#undef F
+
+  state[0] += A;
+  state[1] += B;
+  state[2] += C;
+  state[3] += D;
+  state[4] += E;
+
+  return (0);
+}
+
+
+static const unsigned char sha1_padding[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                                0,    0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                                0,    0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                                0,    0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                                0,    0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                                0,    0, 0, 0, 0, 0, 0, 0, 0, 0,
+                                                0,    0, 0, 0 };
+
+
+static int iotjs_sha1_update(uint32_t total[2], uint32_t state[5],
+                             unsigned char buffer[64],
+                             const unsigned char *in_buff, size_t buff_len) {
+  int ret;
+  size_t fill;
+  uint32_t left;
+
+  if (buff_len == 0) {
+    return 0;
+  }
+
+  left = total[0] & 0x3F;
+  fill = 64 - left;
+
+  total[0] += (uint32_t)buff_len;
+  total[0] &= 0xFFFFFFFF;
+
+  if (total[0] < (uint32_t)buff_len) {
+    total[1]++;
+  }
+
+  if (left && buff_len >= fill) {
+    memcpy((void *)(buffer + left), in_buff, fill);
+
+    if ((ret = iotjs_sha1_process(state, buffer)) != 0) {
+      return ret;
+    }
+
+    in_buff += fill;
+    buff_len -= fill;
+    left = 0;
+  }
+
+  while (buff_len >= 64) {
+    if ((ret = iotjs_sha1_process(state, buffer)) != 0) {
+      return ret;
+    }
+  }
+
+  if (buff_len > 0) {
+    memcpy((void *)(buffer + left), in_buff, buff_len);
+  }
+
+  return 0;
+}
+
+
+static int iotjs_sha1_finish(uint32_t total[2], uint32_t state[5],
+                             unsigned char buffer[64],
+                             unsigned char *out_buff) {
+  int ret;
+  uint32_t last, padn;
+  uint32_t high, low;
+  unsigned char msglen[8];
+
+  high = (total[0] >> 29) | (total[1] << 3);
+  low = (total[0] << 3);
+
+  PUT_UINT32_BE(high, msglen, 0);
+  PUT_UINT32_BE(low, msglen, 4);
+
+  last = total[0] & 0x3F;
+  padn = (last < 56) ? (56 - last) : (120 - last);
+
+  if ((ret = iotjs_sha1_update(total, state, buffer, sha1_padding, padn)) !=
+      0) {
+    return ret;
+  }
+
+  if ((ret = iotjs_sha1_update(total, state, buffer, msglen, 8)) != 0) {
+    return ret;
+  }
+
+  PUT_UINT32_BE(state[0], out_buff, 0);
+  PUT_UINT32_BE(state[1], out_buff, 4);
+  PUT_UINT32_BE(state[2], out_buff, 8);
+  PUT_UINT32_BE(state[3], out_buff, 12);
+  PUT_UINT32_BE(state[4], out_buff, 16);
+
+  return 0;
+}
+#else /* ENABLE_MODULE_TLS */
+
+#include "mbedtls/pk.h"
+#include "mbedtls/sha1.h"
+#include "mbedtls/sha256.h"
+
+#endif /* !ENABLE_MODULE_TLS */
+
+size_t iotjs_sha1_encode(unsigned char **out_buff, const unsigned char *in_buff,
+                         size_t buff_len) {
+  size_t sha1_size = 20; // 160 bytes
+  *out_buff = IOTJS_CALLOC(sha1_size, unsigned char);
+#if !ENABLE_MODULE_TLS
+  uint32_t total[2] = { 0 };
+  uint32_t state[5] = { 0 };
+  unsigned char buffer[64] = { 0 };
+
+  total[0] = 0;
+  total[1] = 0;
+
+  state[0] = 0x67452301;
+  state[1] = 0xEFCDAB89;
+  state[2] = 0x98BADCFE;
+  state[3] = 0x10325476;
+  state[4] = 0xC3D2E1F0;
+
+  iotjs_sha1_update(total, state, buffer, in_buff, buff_len);
+  iotjs_sha1_finish(total, state, buffer, *out_buff);
+#else /* ENABLE_MODULE_TLS */
+  mbedtls_sha1_context sha_ctx;
+  mbedtls_sha1_init(&sha_ctx);
+#if defined(__TIZENRT__)
+  mbedtls_sha1_starts(&sha_ctx);
+  mbedtls_sha1_update(&sha_ctx, in_buff, buff_len);
+  mbedtls_sha1_finish(&sha_ctx, *out_buff);
+#else  /* !__TIZENRT__ */
+  mbedtls_sha1_starts_ret(&sha_ctx);
+  mbedtls_sha1_update_ret(&sha_ctx, in_buff, buff_len);
+  mbedtls_sha1_finish_ret(&sha_ctx, *out_buff);
+#endif /* __TIZENRT__ */
+  mbedtls_sha1_free(&sha_ctx);
+#endif /* ENABLE_MODULE_TLS */
+
+  return sha1_size;
+}
+
+
+#if ENABLE_MODULE_TLS
+size_t iotjs_sha256_encode(unsigned char **out_buff,
+                           const unsigned char *in_buff, size_t buff_len) {
+  size_t sha256_size = 32;
+  *out_buff = IOTJS_CALLOC(sha256_size, unsigned char);
+
+  mbedtls_sha256_context sha_ctx;
+  mbedtls_sha256_init(&sha_ctx);
+#if defined(__TIZENRT__)
+  mbedtls_sha256_starts(&sha_ctx, 0);
+  mbedtls_sha256_update(&sha_ctx, in_buff, buff_len);
+  mbedtls_sha256_finish(&sha_ctx, *out_buff);
+#else  /* !__TIZENRT__ */
+  mbedtls_sha256_starts_ret(&sha_ctx, 0);
+  mbedtls_sha256_update_ret(&sha_ctx, in_buff, buff_len);
+  mbedtls_sha256_finish_ret(&sha_ctx, *out_buff);
+#endif /* __TIZENRT__ */
+  mbedtls_sha256_free(&sha_ctx);
+
+  return sha256_size;
+}
+#endif /* ENABLE_MODULE_TLS */
+
+
+JS_FUNCTION(ShaEncode) {
+  DJS_CHECK_THIS();
+  DJS_CHECK_ARGS(2, any, number);
+
+  uint8_t type = JS_GET_ARG(1, number);
+
+  jerry_value_t jstring = JS_GET_ARG(0, any);
+  iotjs_string_t user_str = iotjs_string_create();
+
+  if (!iotjs_jbuffer_as_string(jstring, &user_str)) {
+    return jerry_create_undefined();
+  }
+
+  const unsigned char *user_str_data =
+      (const unsigned char *)iotjs_string_data(&user_str);
+  size_t user_str_sz = iotjs_string_size(&user_str);
+
+  size_t sha_sz = 0;
+
+  unsigned char *sha_ret = NULL;
+
+  switch (type) {
+    case IOTJS_CRYPTO_SHA1: {
+      sha_sz = iotjs_sha1_encode(&sha_ret, user_str_data, user_str_sz);
+      break;
+    }
+    case IOTJS_CRYPTO_SHA256: {
+#if !ENABLE_MODULE_TLS
+      iotjs_string_destroy(&user_str);
+      return JS_CREATE_ERROR(COMMON, no_tls_err_str);
+#else  /* ENABLE_MODULE_TLS */
+      sha_sz = iotjs_sha256_encode(&sha_ret, user_str_data, user_str_sz);
+      break;
+#endif /* !ENABLE_MODULE_TLS */
+    }
+    default: {
+      iotjs_string_destroy(&user_str);
+      return JS_CREATE_ERROR(COMMON, "Unknown SHA hashing algorithm");
+    }
+  }
+
+  iotjs_string_destroy(&user_str);
+
+  jerry_value_t ret_val;
+  ret_val = iotjs_bufferwrap_create_buffer(sha_sz);
+  iotjs_bufferwrap_t *ret_wrap = iotjs_bufferwrap_from_jbuffer(ret_val);
+  memcpy(ret_wrap->buffer, sha_ret, sha_sz);
+  ret_wrap->length = sha_sz;
+
+  IOTJS_RELEASE(sha_ret);
+  return ret_val;
+}
+
+
+JS_FUNCTION(RsaVerify) {
+#if !ENABLE_MODULE_TLS
+  return JS_CREATE_ERROR(COMMON, no_tls_err_str);
+#else  /* ENABLE_MODULE_TLS */
+  DJS_CHECK_THIS();
+  DJS_CHECK_ARGS(2, any, any);
+
+  uint8_t type = JS_GET_ARG(0, number);
+  jerry_value_t jdata = JS_GET_ARG(1, any);
+  jerry_value_t jkey = JS_GET_ARG(2, any);
+  jerry_value_t jsignature = JS_GET_ARG(3, any);
+
+  iotjs_string_t key = iotjs_string_create();
+  iotjs_string_t data = iotjs_string_create();
+  iotjs_string_t signature = iotjs_string_create();
+
+  if ((!iotjs_jbuffer_as_string(jkey, &key)) ||
+      (!iotjs_jbuffer_as_string(jdata, &data)) ||
+      (!iotjs_jbuffer_as_string(jsignature, &signature))) {
+    iotjs_string_destroy(&key);
+    iotjs_string_destroy(&data);
+    iotjs_string_destroy(&signature);
+
+    return jerry_create_boolean(false);
+  }
+
+  mbedtls_pk_context pk;
+
+  char *raw_signature = NULL;
+  size_t raw_signature_sz =
+      iotjs_base64_decode(&raw_signature, iotjs_string_data(&signature),
+                          iotjs_string_size(&signature));
+  mbedtls_pk_init(&pk);
+  int ret_val =
+      mbedtls_pk_parse_public_key(&pk, (const unsigned char *)iotjs_string_data(
+                                           &key),
+                                  iotjs_string_size(&key) + 1);
+
+
+  jerry_value_t js_ret_val = jerry_create_boolean(true);
+  if ((ret_val =
+           mbedtls_pk_verify(&pk, type,
+                             (const unsigned char *)iotjs_string_data(&data), 0,
+                             (const unsigned char *)raw_signature,
+                             raw_signature_sz))) {
+    js_ret_val = jerry_create_boolean(false);
+  }
+
+  iotjs_string_destroy(&key);
+  iotjs_string_destroy(&data);
+  iotjs_string_destroy(&signature);
+  mbedtls_pk_free(&pk);
+  IOTJS_RELEASE(raw_signature);
+
+  return js_ret_val;
+#endif /* !ENABLE_MODULE_TLS */
+}
+
+
+JS_FUNCTION(Base64Encode) {
+  DJS_CHECK_THIS();
+
+  jerry_value_t jstring = JS_GET_ARG(0, any);
+  iotjs_string_t user_str = iotjs_string_create();
+
+  if (!iotjs_jbuffer_as_string(jstring, &user_str)) {
+    return jerry_create_undefined();
+  }
+
+  unsigned char *out_buff = NULL;
+  size_t out_size =
+      iotjs_base64_encode(&out_buff,
+                          (const unsigned char *)iotjs_string_data(&user_str),
+                          iotjs_string_size(&user_str));
+
+  iotjs_string_destroy(&user_str);
+  jerry_value_t ret_val = jerry_create_string_sz(out_buff, out_size);
+
+  IOTJS_RELEASE(out_buff);
+  return ret_val;
+}
+
+
+jerry_value_t InitCrypto() {
+  jerry_value_t jcrypto = jerry_create_object();
+
+  iotjs_jval_set_method(jcrypto, IOTJS_MAGIC_STRING_SHAENCODE, ShaEncode);
+  iotjs_jval_set_method(jcrypto, IOTJS_MAGIC_STRING_BASE64ENCODE, Base64Encode);
+  iotjs_jval_set_method(jcrypto, IOTJS_MAGIC_STRING_RSAVERIFY, RsaVerify);
+
+  return jcrypto;
+}
diff --git a/src/modules/iotjs_module_crypto.h b/src/modules/iotjs_module_crypto.h
new file mode 100644 (file)
index 0000000..380fa54
--- /dev/null
@@ -0,0 +1,22 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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 IOTJS_MODULE_CRYPTO_H
+#define IOTJS_MODULE_CRYPTO_H
+
+size_t iotjs_sha1_encode(unsigned char **out_buff, const unsigned char *in_buff,
+                         size_t buff_len);
+size_t iotjs_sha256_encode(unsigned char **out_buff,
+                           const unsigned char *in_buff, size_t buff_len);
+#endif /* IOTJS_MODULE_CRYPTO_H */
index 9d852ed5b80aa66a1b4a4e48892dc914f7da6f98..1bc82ee0ac3ed1a9afb9ae28f944659ea1b2593e 100644 (file)
 
 #include "iotjs_def.h"
 
-#include "iotjs_module_dns.h"
+#include "iotjs_uv_request.h"
 
-#include "iotjs_reqwrap.h"
-#include "uv.h"
-
-
-iotjs_getaddrinfo_reqwrap_t* iotjs_getaddrinfo_reqwrap_create(
-    const jerry_value_t jcallback) {
-  iotjs_getaddrinfo_reqwrap_t* getaddrinfo_reqwrap =
-      IOTJS_ALLOC(iotjs_getaddrinfo_reqwrap_t);
-  iotjs_reqwrap_initialize(&getaddrinfo_reqwrap->reqwrap, jcallback,
-                           (uv_req_t*)&getaddrinfo_reqwrap->req);
-  return getaddrinfo_reqwrap;
-}
-
-
-static void iotjs_getaddrinfo_reqwrap_destroy(
-    iotjs_getaddrinfo_reqwrap_t* getaddrinfo_reqwrap) {
-  iotjs_reqwrap_destroy(&getaddrinfo_reqwrap->reqwrap);
-  IOTJS_RELEASE(getaddrinfo_reqwrap);
-}
-
-
-void iotjs_getaddrinfo_reqwrap_dispatched(
-    iotjs_getaddrinfo_reqwrap_t* getaddrinfo_reqwrap) {
-  iotjs_getaddrinfo_reqwrap_destroy(getaddrinfo_reqwrap);
-}
-
-
-jerry_value_t iotjs_getaddrinfo_reqwrap_jcallback(
-    iotjs_getaddrinfo_reqwrap_t* getaddrinfo_reqwrap) {
-  return iotjs_reqwrap_jcallback(&getaddrinfo_reqwrap->reqwrap);
-}
-
-
-#if !defined(__NUTTX__) && !defined(__TIZENRT__)
+#if !defined(__NUTTX__)
 char* getaddrinfo_error_str(int status) {
   switch (status) {
     case UV__EAI_ADDRFAMILY:
       return "EAI_ADDRFAMILY, address family for hostname not supported";
-      break;
     case UV__EAI_AGAIN:
       return "EAI_AGAIN, temporary failure in name resolution";
-      break;
     case UV__EAI_BADFLAGS:
       return "EAI_BADFLAGS, bad flags";
-      break;
     case UV__EAI_FAIL:
       return "EAI_FAIL, Non-recoverable failure in name resolution";
-      break;
     case UV__EAI_FAMILY:
       return "EAI_FAMILY, family not supported";
-      break;
     case UV__EAI_CANCELED:
       return "EAI_CANCELED, request canceled";
-      break;
     case UV__EAI_MEMORY:
       return "EAI_MEMORY, memory allocation failure";
-      break;
     case UV__EAI_NODATA:
       return "EAI_NODATA, no address association with hostname";
-      break;
     case UV__EAI_NONAME:
       return "EAI_NONAME, name or service not known";
-      break;
     case UV__EAI_OVERFLOW:
       return "EAI_OVERFLOW, argument buffer overflow";
-      break;
     case UV__EAI_SERVICE:
       return "EAI_SERVICE, service not supported";
-      break;
     case UV__EAI_SOCKTYPE:
       return "EAI_SOCKTYPE, socktype not supported";
-      break;
     case UV__EAI_PROTOCOL:
       return "EAI_PROTOCOL, unknown error";
-      break;
     default:
       return "unknown error";
-      break;
   }
 }
 
 static void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status,
                              struct addrinfo* res) {
-  iotjs_getaddrinfo_reqwrap_t* req_wrap =
-      (iotjs_getaddrinfo_reqwrap_t*)(req->data);
-
-  iotjs_jargs_t args = iotjs_jargs_create(3);
+  size_t argc = 0;
+  jerry_value_t args[3] = { 0 };
 
-  if (status == 0) {
+  if (status == 0 && res != NULL) {
     char ip[INET6_ADDRSTRLEN];
     int family;
     const char* addr;
+    struct addrinfo* info;
+
+    /* search for the first AF_INET entry */
+    for (info = res; info != NULL; info = info->ai_next) {
+      if (info->ai_family == AF_INET) {
+        break;
+      }
+    }
+
+    if (info == NULL) {
+      /* Did not find an AF_INET addr, using the first one */
+      info = res;
+    }
+
+    IOTJS_ASSERT(info != NULL);
 
-    // Only first address is used
-    if (res->ai_family == AF_INET) {
-      struct sockaddr_in* sockaddr = (struct sockaddr_in*)(res->ai_addr);
+    if (info->ai_family == AF_INET) {
+      struct sockaddr_in* sockaddr = (struct sockaddr_in*)(info->ai_addr);
       addr = (char*)(&(sockaddr->sin_addr));
       family = 4;
     } else {
-      struct sockaddr_in6* sockaddr = (struct sockaddr_in6*)(res->ai_addr);
+      struct sockaddr_in6* sockaddr = (struct sockaddr_in6*)(info->ai_addr);
       addr = (char*)(&(sockaddr->sin6_addr));
       family = 6;
     }
 
-    int err = uv_inet_ntop(res->ai_family, addr, ip, INET6_ADDRSTRLEN);
+    int err = uv_inet_ntop(info->ai_family, addr, ip, INET6_ADDRSTRLEN);
     if (err) {
       ip[0] = 0;
-      iotjs_jargs_append_error(&args,
-                               "EAFNOSUPPORT, DNS could not resolve hostname");
+      args[argc++] = iotjs_jval_create_error_without_error_flag(
+          "EAFNOSUPPORT, DNS could not resolve hostname");
     } else {
-      iotjs_jargs_append_null(&args);
+      args[argc++] = jerry_create_null();
     }
 
-    iotjs_jargs_append_string_raw(&args, ip);
-    iotjs_jargs_append_number(&args, family);
+    args[argc++] = jerry_create_string_from_utf8((const jerry_char_t*)ip);
+    args[argc++] = jerry_create_number(family);
   } else {
-    iotjs_jargs_append_error(&args, getaddrinfo_error_str(status));
+    args[argc++] = iotjs_jval_create_error_without_error_flag(
+        getaddrinfo_error_str(status));
   }
 
   uv_freeaddrinfo(res);
 
   // Make the callback into JavaScript
-  jerry_value_t jcallback = iotjs_getaddrinfo_reqwrap_jcallback(req_wrap);
-  iotjs_make_callback(jcallback, jerry_create_undefined(), &args);
+  jerry_value_t jcallback = *IOTJS_UV_REQUEST_JSCALLBACK(req);
+  iotjs_invoke_callback(jcallback, jerry_create_undefined(), args, argc);
 
-  iotjs_jargs_destroy(&args);
+  for (size_t i = 0; i < argc; i++) {
+    jerry_release_value(args[i]);
+  }
 
-  iotjs_getaddrinfo_reqwrap_dispatched(req_wrap);
+  iotjs_uv_request_destroy((uv_req_t*)req);
 }
 #endif
 
 
-JS_FUNCTION(GetAddrInfo) {
+JS_FUNCTION(GetAddressInfo) {
   DJS_CHECK_THIS();
   DJS_CHECK_ARGS(4, string, number, number, function);
 
@@ -175,8 +143,7 @@ JS_FUNCTION(GetAddrInfo) {
     return JS_CREATE_ERROR(TYPE, "bad address family");
   }
 
-#if defined(__NUTTX__) || defined(__TIZENRT__)
-  iotjs_jargs_t args = iotjs_jargs_create(3);
+#if defined(__NUTTX__)
   char ip[INET6_ADDRSTRLEN] = "";
   const char* hostname_data = iotjs_string_data(&hostname);
 
@@ -192,21 +159,27 @@ JS_FUNCTION(GetAddrInfo) {
     }
   }
 
+  size_t argc = 0;
+  jerry_value_t args[3] = { 0 };
+
   if (error) {
-    iotjs_jargs_append_error(&args, "EAFNOSUPPORT, could not resolve hostname");
+    args[argc++] = iotjs_jval_create_error_without_error_flag(
+        "EAFNOSUPPORT, could not resolve hostname");
   } else {
-    iotjs_jargs_append_null(&args);
+    args[argc++] = jerry_create_null();
   }
 
-  iotjs_jargs_append_string_raw(&args, ip);
-  iotjs_jargs_append_number(&args, option);
+  args[argc++] = jerry_create_string_from_utf8((const jerry_char_t*)ip);
+  args[argc++] = jerry_create_number(option);
 
-  iotjs_make_callback(jcallback, jerry_create_undefined(), &args);
-  iotjs_jargs_destroy(&args);
+  iotjs_invoke_callback(jcallback, jerry_create_undefined(), args, argc);
+  for (size_t i = 0; i < argc; i++) {
+    jerry_release_value(args[i]);
+  }
   IOTJS_UNUSED(flags);
 #else
-  iotjs_getaddrinfo_reqwrap_t* req_wrap =
-      iotjs_getaddrinfo_reqwrap_create(jcallback);
+  uv_req_t* req_addr =
+      iotjs_uv_request_create(sizeof(uv_getaddrinfo_t), jcallback, 0);
 
   static const struct addrinfo empty_hints;
   struct addrinfo hints = empty_hints;
@@ -215,11 +188,11 @@ JS_FUNCTION(GetAddrInfo) {
   hints.ai_flags = flags;
 
   error = uv_getaddrinfo(iotjs_environment_loop(iotjs_environment_get()),
-                         &req_wrap->req, AfterGetAddrInfo,
+                         (uv_getaddrinfo_t*)req_addr, AfterGetAddrInfo,
                          iotjs_string_data(&hostname), NULL, &hints);
 
   if (error) {
-    iotjs_getaddrinfo_reqwrap_dispatched(req_wrap);
+    iotjs_uv_request_destroy(req_addr);
   }
 #endif
 
@@ -239,7 +212,7 @@ JS_FUNCTION(GetAddrInfo) {
 jerry_value_t InitDns() {
   jerry_value_t dns = jerry_create_object();
 
-  iotjs_jval_set_method(dns, IOTJS_MAGIC_STRING_GETADDRINFO, GetAddrInfo);
+  iotjs_jval_set_method(dns, IOTJS_MAGIC_STRING_GETADDRINFO, GetAddressInfo);
   SET_CONSTANT(dns, AI_ADDRCONFIG);
   SET_CONSTANT(dns, AI_V4MAPPED);
 
diff --git a/src/modules/iotjs_module_dns.h b/src/modules/iotjs_module_dns.h
deleted file mode 100644 (file)
index 6496cee..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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 IOTJS_MODULE_DNS_H
-#define IOTJS_MODULE_DNS_H
-
-
-#include "iotjs_def.h"
-#include "iotjs_reqwrap.h"
-
-
-typedef struct {
-  iotjs_reqwrap_t reqwrap;
-  uv_getaddrinfo_t req;
-} iotjs_getaddrinfo_reqwrap_t;
-
-iotjs_getaddrinfo_reqwrap_t* iotjs_getaddrinfo_reqwrap_create(
-    const jerry_value_t jcallback);
-
-void iotjs_getaddrinfo_reqwrap_dispatched(
-    iotjs_getaddrinfo_reqwrap_t* getaddrinfo_reqwrap);
-
-jerry_value_t iotjs_getaddrinfo_reqwrap_jcallback(
-    iotjs_getaddrinfo_reqwrap_t* getaddrinfo_reqwrap);
-
-
-#endif /* IOTJS_MODULE_DNS_H */
index 8ed50325c0d3e12dcd252195cfd65b9d44beae1e..ceb3cd4d2817ebf597bf76c67b14c4f4456f31d6 100644 (file)
 #include "iotjs_def.h"
 
 #include "iotjs_module_buffer.h"
-#include "iotjs_reqwrap.h"
-
-
-typedef struct {
-  iotjs_reqwrap_t reqwrap;
-  uv_fs_t req;
-} iotjs_fs_reqwrap_t;
-
-
-iotjs_fs_reqwrap_t* iotjs_fs_reqwrap_create(const jerry_value_t jcallback) {
-  iotjs_fs_reqwrap_t* fs_reqwrap = IOTJS_ALLOC(iotjs_fs_reqwrap_t);
-  iotjs_reqwrap_initialize(&fs_reqwrap->reqwrap, jcallback,
-                           (uv_req_t*)&fs_reqwrap->req);
-  return fs_reqwrap;
-}
-
-
-static void iotjs_fs_reqwrap_destroy(iotjs_fs_reqwrap_t* fs_reqwrap) {
-  uv_fs_req_cleanup(&fs_reqwrap->req);
-  iotjs_reqwrap_destroy(&fs_reqwrap->reqwrap);
-  IOTJS_RELEASE(fs_reqwrap);
-}
+#include "iotjs_uv_request.h"
 
 jerry_value_t MakeStatObject(uv_stat_t* statbuf);
 
@@ -51,20 +30,16 @@ static jerry_value_t iotjs_create_uv_exception(int errorno,
 
 
 static void AfterAsync(uv_fs_t* req) {
-  iotjs_fs_reqwrap_t* req_wrap = (iotjs_fs_reqwrap_t*)(req->data);
-  IOTJS_ASSERT(req_wrap != NULL);
-  IOTJS_ASSERT(&req_wrap->req == req);
-
-  const jerry_value_t cb = iotjs_reqwrap_jcallback(&req_wrap->reqwrap);
+  const jerry_value_t cb = *IOTJS_UV_REQUEST_JSCALLBACK(req);
   IOTJS_ASSERT(jerry_value_is_function(cb));
 
-  iotjs_jargs_t jarg = iotjs_jargs_create(2);
+  jerry_value_t jargs[2] = { 0 };
+  size_t jargc = 0;
   if (req->result < 0) {
     jerry_value_t jerror = iotjs_create_uv_exception(req->result, "open");
-    iotjs_jargs_append_jval(&jarg, jerror);
-    jerry_release_value(jerror);
+    jargs[jargc++] = jerror;
   } else {
-    iotjs_jargs_append_null(&jarg);
+    jargs[jargc++] = jerry_create_null();
     switch (req->fs_type) {
       case UV_FS_CLOSE: {
         break;
@@ -72,52 +47,47 @@ static void AfterAsync(uv_fs_t* req) {
       case UV_FS_OPEN:
       case UV_FS_READ:
       case UV_FS_WRITE: {
-        iotjs_jargs_append_number(&jarg, (double)req->result);
+        jargs[jargc++] = jerry_create_number((double)req->result);
         break;
       }
       case UV_FS_SCANDIR: {
         int r;
         uv_dirent_t ent;
         uint32_t idx = 0;
-        jerry_value_t ret = jerry_create_array(0);
+        jargs[jargc++] = jerry_create_array(0);
         while ((r = uv_fs_scandir_next(req, &ent)) != UV_EOF) {
           jerry_value_t name =
               jerry_create_string((const jerry_char_t*)ent.name);
-          iotjs_jval_set_property_by_index(ret, idx, name);
+          iotjs_jval_set_property_by_index(jargs[1], idx, name);
           jerry_release_value(name);
           idx++;
         }
-        iotjs_jargs_append_jval(&jarg, ret);
-        jerry_release_value(ret);
         break;
       }
       case UV_FS_FSTAT:
       case UV_FS_STAT: {
         uv_stat_t s = (req->statbuf);
-        jerry_value_t ret = MakeStatObject(&s);
-        iotjs_jargs_append_jval(&jarg, ret);
-        jerry_release_value(ret);
-        break;
-      }
-      default: {
-        iotjs_jargs_append_null(&jarg);
+        jargs[jargc++] = MakeStatObject(&s);
         break;
       }
+      default: { break; }
     }
   }
 
-  iotjs_make_callback(cb, jerry_create_undefined(), &jarg);
+  iotjs_invoke_callback(cb, jerry_create_undefined(), jargs, jargc);
 
-  iotjs_jargs_destroy(&jarg);
-  iotjs_fs_reqwrap_destroy(req_wrap);
+  jerry_release_value(jargs[0]);
+  jerry_release_value(jargs[1]);
+  uv_fs_req_cleanup(req);
+  iotjs_uv_request_destroy((uv_req_t*)req);
 }
 
 
 static jerry_value_t AfterSync(uv_fs_t* req, int err,
                                const char* syscall_name) {
   if (err < 0) {
-    jerry_value_t jerror = iotjs_create_uv_exception(err, syscall_name);
-    jerry_value_set_error_flag(&jerror);
+    jerry_value_t jvalue = iotjs_create_uv_exception(err, syscall_name);
+    jerry_value_t jerror = jerry_create_error_from_value(jvalue, true);
     return jerror;
   }
 
@@ -169,8 +139,8 @@ static inline bool IsWithinBounds(size_t off, size_t len, size_t max) {
 
 
 #define FS_ASYNC(env, syscall, pcallback, ...)                                \
-  iotjs_fs_reqwrap_t* req_wrap = iotjs_fs_reqwrap_create(pcallback);          \
-  uv_fs_t* fs_req = &req_wrap->req;                                           \
+  uv_fs_t* fs_req =                                                           \
+      (uv_fs_t*)iotjs_uv_request_create(sizeof(uv_fs_t), pcallback, 0);       \
   int err = uv_fs_##syscall(iotjs_environment_loop(env), fs_req, __VA_ARGS__, \
                             AfterAsync);                                      \
   if (err < 0) {                                                              \
@@ -232,7 +202,13 @@ JS_FUNCTION(Open) {
 }
 
 
-JS_FUNCTION(Read) {
+typedef enum { IOTJS_FS_READ, IOTJS_FS_WRITE } iotjs_fs_op_t;
+
+jerry_value_t fs_do_read_or_write(const jerry_value_t jfunc,
+                                  const jerry_value_t jthis,
+                                  const jerry_value_t jargv[],
+                                  const jerry_length_t jargc,
+                                  const iotjs_fs_op_t fs_op) {
   DJS_CHECK_THIS();
   DJS_CHECK_ARGS(5, number, object, number, number, number);
   DJS_CHECK_ARG_IF_EXIST(5, function);
@@ -258,47 +234,30 @@ JS_FUNCTION(Read) {
   uv_buf_t uvbuf = uv_buf_init(data + offset, length);
 
   jerry_value_t ret_value;
-  if (!jerry_value_is_null(jcallback)) {
-    FS_ASYNC(env, read, jcallback, fd, &uvbuf, 1, position);
+  if (fs_op == IOTJS_FS_READ) {
+    if (!jerry_value_is_null(jcallback)) {
+      FS_ASYNC(env, read, jcallback, fd, &uvbuf, 1, position);
+    } else {
+      FS_SYNC(env, read, fd, &uvbuf, 1, position);
+    }
   } else {
-    FS_SYNC(env, read, fd, &uvbuf, 1, position);
+    if (!jerry_value_is_null(jcallback)) {
+      FS_ASYNC(env, write, jcallback, fd, &uvbuf, 1, position);
+    } else {
+      FS_SYNC(env, write, fd, &uvbuf, 1, position);
+    }
   }
   return ret_value;
 }
 
 
-JS_FUNCTION(Write) {
-  DJS_CHECK_THIS();
-  DJS_CHECK_ARGS(5, number, object, number, number, number);
-  DJS_CHECK_ARG_IF_EXIST(5, function);
-
-  const iotjs_environment_t* env = iotjs_environment_get();
-
-  int fd = JS_GET_ARG(0, number);
-  const jerry_value_t jbuffer = JS_GET_ARG(1, object);
-  size_t offset = JS_GET_ARG(2, number);
-  size_t length = JS_GET_ARG(3, number);
-  int position = JS_GET_ARG(4, number);
-  const jerry_value_t jcallback = JS_GET_ARG_IF_EXIST(5, function);
-
-  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(jbuffer);
-  char* data = buffer_wrap->buffer;
-  size_t data_length = iotjs_bufferwrap_length(buffer_wrap);
-  JS_CHECK(data != NULL && data_length > 0);
-
-  if (!IsWithinBounds(offset, length, data_length)) {
-    return JS_CREATE_ERROR(RANGE, "length out of bound");
-  }
+JS_FUNCTION(Read) {
+  return fs_do_read_or_write(jfunc, jthis, jargv, jargc, IOTJS_FS_READ);
+}
 
-  uv_buf_t uvbuf = uv_buf_init(data + offset, length);
 
-  jerry_value_t ret_value;
-  if (!jerry_value_is_null(jcallback)) {
-    FS_ASYNC(env, write, jcallback, fd, &uvbuf, 1, position);
-  } else {
-    FS_SYNC(env, write, fd, &uvbuf, 1, position);
-  }
-  return ret_value;
+JS_FUNCTION(Write) {
+  return fs_do_read_or_write(jfunc, jthis, jargv, jargc, IOTJS_FS_WRITE);
 }
 
 
index 37cf5bbd229de6bbea6f2854bee1df964c84443b..b05c0c23e3767cebb92bc8620ee71b64155f0061 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "iotjs_def.h"
 #include "iotjs_module_gpio.h"
+#include "iotjs_uv_request.h"
 
 
 IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(gpio);
@@ -27,23 +28,22 @@ static void iotjs_gpio_destroy(iotjs_gpio_t* gpio) {
 }
 
 static void gpio_worker(uv_work_t* work_req) {
-  iotjs_periph_reqwrap_t* req_wrap =
-      (iotjs_periph_reqwrap_t*)(iotjs_reqwrap_from_request(
-          (uv_req_t*)work_req));
-  iotjs_gpio_t* gpio = (iotjs_gpio_t*)req_wrap->data;
+  iotjs_periph_data_t* worker_data =
+      (iotjs_periph_data_t*)IOTJS_UV_REQUEST_EXTRA_DATA(work_req);
+  iotjs_gpio_t* gpio = (iotjs_gpio_t*)worker_data->data;
 
-  switch (req_wrap->op) {
+  switch (worker_data->op) {
     case kGpioOpOpen:
-      req_wrap->result = iotjs_gpio_open(gpio);
+      worker_data->result = iotjs_gpio_open(gpio);
       break;
     case kGpioOpWrite:
-      req_wrap->result = iotjs_gpio_write(gpio);
+      worker_data->result = iotjs_gpio_write(gpio);
       break;
     case kGpioOpRead:
-      req_wrap->result = iotjs_gpio_read(gpio);
+      worker_data->result = iotjs_gpio_read(gpio);
       break;
     case kGpioOpClose:
-      req_wrap->result = iotjs_gpio_close(gpio);
+      worker_data->result = iotjs_gpio_close(gpio);
       break;
     default:
       IOTJS_ASSERT(!"Invalid Operation");
@@ -54,7 +54,13 @@ static jerry_value_t gpio_set_configuration(iotjs_gpio_t* gpio,
                                             jerry_value_t jconfigurable) {
   jerry_value_t jpin =
       iotjs_jval_get_property(jconfigurable, IOTJS_MAGIC_STRING_PIN);
-  gpio->pin = iotjs_jval_as_number(jpin);
+
+  double pin = -1.0;
+  if (!jerry_value_is_number(jpin) || (pin = iotjs_jval_as_number(jpin)) < 0) {
+    jerry_release_value(jpin);
+    return JS_CREATE_ERROR(TYPE, "Bad arguments gpio.pin should be a number");
+  }
+  gpio->pin = (uint32_t)pin;
   jerry_release_value(jpin);
 
   // Direction
@@ -70,6 +76,7 @@ static jerry_value_t gpio_set_configuration(iotjs_gpio_t* gpio,
       gpio->direction = __kGpioDirectionMax;
     }
     if (gpio->direction >= __kGpioDirectionMax) {
+      jerry_release_value(jdirection);
       return JS_CREATE_ERROR(
           TYPE, "Bad arguments - gpio.direction should be DIRECTION.IN or OUT");
     }
@@ -124,6 +131,7 @@ static jerry_value_t gpio_set_configuration(iotjs_gpio_t* gpio,
       gpio->edge = __kGpioEdgeMax;
     }
     if (gpio->edge >= __kGpioEdgeMax) {
+      jerry_release_value(jedge);
       return JS_CREATE_ERROR(TYPE,
                              "Bad arguments - gpio.edge should be EDGE.NONE, "
                              "RISING, FALLING or BOTH");
@@ -145,7 +153,7 @@ JS_FUNCTION(GpioCons) {
 
   jerry_value_t config_res =
       gpio_set_configuration(gpio, JS_GET_ARG(0, object));
-  if (jerry_value_has_error_flag(config_res)) {
+  if (jerry_value_is_error(config_res)) {
     return config_res;
   }
   IOTJS_ASSERT(jerry_value_is_undefined(config_res));
@@ -183,7 +191,13 @@ JS_FUNCTION(CloseSync) {
   return jerry_create_undefined();
 }
 
-JS_FUNCTION(Write) {
+typedef enum { IOTJS_GPIO_WRITE, IOTJS_GPIO_WRITESYNC } iotjs_gpio_op_t;
+
+jerry_value_t gpio_do_write_or_writesync(const jerry_value_t jfunc,
+                                         const jerry_value_t jthis,
+                                         const jerry_value_t jargv[],
+                                         const jerry_length_t jargc,
+                                         const iotjs_gpio_op_t gpio_op) {
   JS_DECLARE_THIS_PTR(gpio, gpio);
 
   bool value;
@@ -192,39 +206,40 @@ JS_FUNCTION(Write) {
   } else if (jerry_value_is_boolean(jargv[0])) {
     value = jerry_get_boolean_value(jargv[0]);
   } else {
-    return JS_CREATE_ERROR(COMMON, iotjs_periph_error_str(kGpioOpWrite));
-  }
+    const jerry_value_t jcallback = JS_GET_ARG_IF_EXIST(1, function);
+    if (gpio_op == IOTJS_GPIO_WRITE && !jerry_value_is_null(jcallback)) {
+      const char* error_msg = iotjs_periph_error_str(kGpioOpWrite);
+      jerry_value_t error_str = jerry_create_string((jerry_char_t*)error_msg);
+      iotjs_invoke_callback(jcallback, jthis, &error_str, 1);
+      jerry_release_value(error_str);
+      return jerry_create_undefined();
+    }
 
-  DJS_CHECK_ARG_IF_EXIST(1, function);
+    return JS_CREATE_ERROR(TYPE, "GPIO WriteSync Error - Wrong argument type");
+  }
 
   gpio->value = value;
-
-  iotjs_periph_call_async(gpio, JS_GET_ARG_IF_EXIST(1, function), kGpioOpWrite,
-                          gpio_worker);
-
-  return jerry_create_undefined();
-}
-
-JS_FUNCTION(WriteSync) {
-  JS_DECLARE_THIS_PTR(gpio, gpio);
-
-  bool value;
-  if (jerry_value_is_number(jargv[0])) {
-    value = (bool)jerry_get_number_value(jargv[0]);
-  } else if (jerry_value_is_boolean(jargv[0])) {
-    value = jerry_get_boolean_value(jargv[0]);
+  if (gpio_op == IOTJS_GPIO_WRITE) {
+    DJS_CHECK_ARG_IF_EXIST(1, function);
+    iotjs_periph_call_async(gpio, JS_GET_ARG_IF_EXIST(1, function),
+                            kGpioOpWrite, gpio_worker);
   } else {
-    return JS_CREATE_ERROR(COMMON,
-                           "GPIO WriteSync Error - Wrong argument type");
+    if (!iotjs_gpio_write(gpio)) {
+      return JS_CREATE_ERROR(COMMON, iotjs_periph_error_str(kGpioOpWrite));
+    }
   }
 
-  gpio->value = value;
+  return jerry_create_undefined();
+}
 
-  if (!iotjs_gpio_write(gpio)) {
-    return JS_CREATE_ERROR(COMMON, iotjs_periph_error_str(kGpioOpWrite));
-  }
+JS_FUNCTION(Write) {
+  return gpio_do_write_or_writesync(jfunc, jthis, jargv, jargc,
+                                    IOTJS_GPIO_WRITE);
+}
 
-  return jerry_create_undefined();
+JS_FUNCTION(WriteSync) {
+  return gpio_do_write_or_writesync(jfunc, jthis, jargv, jargc,
+                                    IOTJS_GPIO_WRITESYNC);
 }
 
 JS_FUNCTION(Read) {
@@ -247,6 +262,26 @@ JS_FUNCTION(ReadSync) {
   return jerry_create_boolean(gpio->value);
 }
 
+JS_FUNCTION(SetDirectionSync) {
+  DJS_CHECK_ARGS(1, number);
+  JS_DECLARE_THIS_PTR(gpio, gpio);
+
+  int direction;
+  JS_GET_REQUIRED_ARG_VALUE(0, direction, IOTJS_MAGIC_STRING_DIRECTION, number);
+  if (direction >= __kGpioDirectionMax) {
+    return JS_CREATE_ERROR(
+        TYPE, "Bad arguments - gpio.direction should be DIRECTION.IN or OUT");
+  }
+  gpio->direction = direction;
+
+  if (!iotjs_gpio_set_direction(gpio)) {
+    return JS_CREATE_ERROR(
+        COMMON, "GPIO SetDirectionSync Error - Cannot set direction");
+  }
+
+  return jerry_create_undefined();
+}
+
 jerry_value_t InitGpio() {
   jerry_value_t jgpioConstructor = jerry_create_external_function(GpioCons);
 
@@ -258,6 +293,8 @@ jerry_value_t InitGpio() {
   iotjs_jval_set_method(jprototype, IOTJS_MAGIC_STRING_WRITESYNC, WriteSync);
   iotjs_jval_set_method(jprototype, IOTJS_MAGIC_STRING_READ, Read);
   iotjs_jval_set_method(jprototype, IOTJS_MAGIC_STRING_READSYNC, ReadSync);
+  iotjs_jval_set_method(jprototype, IOTJS_MAGIC_STRING_SETDIRECTIONSYNC,
+                        SetDirectionSync);
 
   iotjs_jval_set_property_jval(jgpioConstructor, IOTJS_MAGIC_STRING_PROTOTYPE,
                                jprototype);
index 3c78b598af3bebbfab0d517dbad9102a6bddb63c..d0557c7efb129d2b544b993c41e0d118fde41aeb 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "iotjs_def.h"
 #include "iotjs_module_periph_common.h"
-#include "iotjs_reqwrap.h"
 
 
 typedef enum {
@@ -65,6 +64,7 @@ bool iotjs_gpio_open(iotjs_gpio_t* gpio);
 bool iotjs_gpio_write(iotjs_gpio_t* gpio);
 bool iotjs_gpio_read(iotjs_gpio_t* gpio);
 bool iotjs_gpio_close(iotjs_gpio_t* gpio);
+bool iotjs_gpio_set_direction(iotjs_gpio_t* gpio);
 
 // Platform-related functions; they are implemented
 // by platform code (i.e.: linux, nuttx, tizen).
index e3f56e57aa0badb2b0afd00dee62906101caf4a6..b861dc79a516ed08be62b0ff25e6c5d7f32fb3af 100644 (file)
@@ -131,19 +131,21 @@ static void iotjs_http_parserwrap_flush(
       iotjs_jval_get_property(jobj, IOTJS_MAGIC_STRING_ONHEADERS);
   IOTJS_ASSERT(jerry_value_is_function(func));
 
-  iotjs_jargs_t argv = iotjs_jargs_create(2);
   jerry_value_t jheader = iotjs_http_parserwrap_make_header(http_parserwrap);
-  iotjs_jargs_append_jval(&argv, jheader);
-  jerry_release_value(jheader);
+  size_t argc = 1;
+  jerry_value_t argv[2] = { jheader, 0 };
+
   if (http_parserwrap->parser.type == HTTP_REQUEST &&
       !iotjs_string_is_empty(&http_parserwrap->url)) {
-    iotjs_jargs_append_string(&argv, &http_parserwrap->url);
+    argv[argc++] = iotjs_jval_create_string(&http_parserwrap->url);
   }
 
-  iotjs_make_callback(func, jobj, &argv);
+  iotjs_invoke_callback(func, jobj, argv, argc);
 
   iotjs_string_destroy(&http_parserwrap->url);
-  iotjs_jargs_destroy(&argv);
+  for (size_t i = 0; i < argc; i++) {
+    jerry_release_value(argv[i]);
+  }
   jerry_release_value(func);
   http_parserwrap->flushed = true;
 }
@@ -240,7 +242,6 @@ static int iotjs_http_parserwrap_on_headers_complete(http_parser* parser) {
   IOTJS_ASSERT(jerry_value_is_function(func));
 
   // URL
-  iotjs_jargs_t argv = iotjs_jargs_create(1);
   jerry_value_t info = jerry_create_object();
 
   if (http_parserwrap->flushed) {
@@ -286,21 +287,21 @@ static int iotjs_http_parserwrap_on_headers_complete(http_parser* parser) {
                                   http_should_keep_alive(
                                       &http_parserwrap->parser));
 
+  // http version number
+  iotjs_jval_set_property_number(info, IOTJS_MAGIC_STRING_HTTP_VERSION_MAJOR,
+                                 parser->http_major);
+  iotjs_jval_set_property_number(info, IOTJS_MAGIC_STRING_HTTP_VERSION_MINOR,
+                                 parser->http_minor);
 
-  iotjs_jargs_append_jval(&argv, info);
-
-  jerry_value_t res = iotjs_make_callback_with_result(func, jobj, &argv);
+  jerry_value_t res = iotjs_invoke_callback_with_result(func, jobj, &info, 1);
 
   int ret = 1;
   if (jerry_value_is_boolean(res)) {
     ret = iotjs_jval_as_boolean(res);
-  } else if (jerry_value_is_object(res)) {
-    // if exception throw occurs in iotjs_make_callback_with_result, then the
-    // result can be an object.
+  } else if (jerry_value_is_error(res)) {
     ret = 0;
   }
 
-  iotjs_jargs_destroy(&argv);
   jerry_release_value(func);
   jerry_release_value(res);
   jerry_release_value(info);
@@ -317,15 +318,14 @@ static int iotjs_http_parserwrap_on_body(http_parser* parser, const char* at,
   jerry_value_t func = iotjs_jval_get_property(jobj, IOTJS_MAGIC_STRING_ONBODY);
   IOTJS_ASSERT(jerry_value_is_function(func));
 
-  iotjs_jargs_t argv = iotjs_jargs_create(3);
-  iotjs_jargs_append_jval(&argv, http_parserwrap->cur_jbuf);
-  iotjs_jargs_append_number(&argv, at - http_parserwrap->cur_buf);
-  iotjs_jargs_append_number(&argv, length);
-
+  jerry_value_t argv[3] = { http_parserwrap->cur_jbuf,
+                            jerry_create_number(at - http_parserwrap->cur_buf),
+                            jerry_create_number(length) };
 
-  iotjs_make_callback(func, jobj, &argv);
+  iotjs_invoke_callback(func, jobj, argv, 3);
 
-  iotjs_jargs_destroy(&argv);
+  jerry_release_value(argv[1]);
+  jerry_release_value(argv[2]);
   jerry_release_value(func);
 
   return 0;
@@ -340,7 +340,7 @@ static int iotjs_http_parserwrap_on_message_complete(http_parser* parser) {
       iotjs_jval_get_property(jobj, IOTJS_MAGIC_STRING_ONMESSAGECOMPLETE);
   IOTJS_ASSERT(jerry_value_is_function(func));
 
-  iotjs_make_callback(func, jobj, iotjs_jargs_get_empty());
+  iotjs_invoke_callback(func, jobj, NULL, 0);
 
   jerry_release_value(func);
 
@@ -375,22 +375,6 @@ static jerry_value_t iotjs_http_parser_return_parserrror(
 }
 
 
-JS_FUNCTION(Reinitialize) {
-  JS_DECLARE_THIS_PTR(http_parserwrap, parser);
-  DJS_CHECK_ARGS(1, number);
-
-  http_parser_type httpparser_type = (http_parser_type)(JS_GET_ARG(0, number));
-
-  if (httpparser_type != HTTP_REQUEST && httpparser_type != HTTP_RESPONSE) {
-    return JS_CREATE_ERROR(TYPE, "Invalid type");
-  }
-
-  iotjs_http_parserwrap_initialize(parser, httpparser_type);
-
-  return jerry_create_undefined();
-}
-
-
 JS_FUNCTION(Finish) {
   JS_DECLARE_THIS_PTR(http_parserwrap, parser);
 
@@ -461,13 +445,31 @@ JS_FUNCTION(HTTPParserCons) {
   http_parser_type httpparser_type = (http_parser_type)(JS_GET_ARG(0, number));
 
   if (httpparser_type != HTTP_REQUEST && httpparser_type != HTTP_RESPONSE) {
-    return JS_CREATE_ERROR(TYPE, "Invalid type");
+    return JS_CREATE_ERROR(TYPE, "Invalid type of HTTP.");
   }
 
   iotjs_http_parserwrap_create(jparser, httpparser_type);
   return jerry_create_undefined();
 }
 
+static void http_parser_register_methods_object(jerry_value_t target) {
+  jerry_value_t methods = jerry_create_array(26);
+
+  jerry_value_t method_name;
+  uint32_t idx = 0;
+#define V(num, name, string)                                         \
+  do {                                                               \
+    method_name = jerry_create_string((const jerry_char_t*)#string); \
+    jerry_set_property_by_index(methods, idx++, method_name);        \
+    jerry_release_value(method_name);                                \
+  } while (0);
+
+  HTTP_METHOD_MAP(V)
+#undef V
+
+  iotjs_jval_set_property_jval(target, IOTJS_MAGIC_STRING_METHODS, methods);
+  jerry_release_value(methods);
+}
 
 jerry_value_t InitHttpParser() {
   jerry_value_t http_parser = jerry_create_object();
@@ -481,20 +483,11 @@ jerry_value_t InitHttpParser() {
   iotjs_jval_set_property_number(jParserCons, IOTJS_MAGIC_STRING_RESPONSE_U,
                                  HTTP_RESPONSE);
 
-  jerry_value_t methods = jerry_create_object();
-#define V(num, name, string) \
-  iotjs_jval_set_property_string_raw(methods, #num, #string);
-  HTTP_METHOD_MAP(V)
-#undef V
-
-  iotjs_jval_set_property_jval(jParserCons, IOTJS_MAGIC_STRING_METHODS,
-                               methods);
+  http_parser_register_methods_object(jParserCons);
 
   jerry_value_t prototype = jerry_create_object();
 
   iotjs_jval_set_method(prototype, IOTJS_MAGIC_STRING_EXECUTE, Execute);
-  iotjs_jval_set_method(prototype, IOTJS_MAGIC_STRING_REINITIALIZE,
-                        Reinitialize);
   iotjs_jval_set_method(prototype, IOTJS_MAGIC_STRING_FINISH, Finish);
   iotjs_jval_set_method(prototype, IOTJS_MAGIC_STRING_PAUSE, Pause);
   iotjs_jval_set_method(prototype, IOTJS_MAGIC_STRING_RESUME, Resume);
@@ -503,7 +496,6 @@ jerry_value_t InitHttpParser() {
                                prototype);
 
   jerry_release_value(jParserCons);
-  jerry_release_value(methods);
   jerry_release_value(prototype);
 
   return http_parser;
index d0e264c9fca47e6a8784a1226510d87746af8b85..06ae0af6047ed5ff1e90aba77eb3cf84543e0a36 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "iotjs_def.h"
 #include "iotjs_module_i2c.h"
+#include "iotjs_uv_request.h"
 
 
 IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(i2c);
@@ -28,23 +29,22 @@ static void iotjs_i2c_destroy(iotjs_i2c_t* i2c) {
 }
 
 static void i2c_worker(uv_work_t* work_req) {
-  iotjs_periph_reqwrap_t* req_wrap =
-      (iotjs_periph_reqwrap_t*)(iotjs_reqwrap_from_request(
-          (uv_req_t*)work_req));
-  iotjs_i2c_t* i2c = (iotjs_i2c_t*)req_wrap->data;
+  iotjs_periph_data_t* worker_data =
+      (iotjs_periph_data_t*)IOTJS_UV_REQUEST_EXTRA_DATA(work_req);
+  iotjs_i2c_t* i2c = (iotjs_i2c_t*)worker_data->data;
 
-  switch (req_wrap->op) {
+  switch (worker_data->op) {
     case kI2cOpOpen:
-      req_wrap->result = iotjs_i2c_open(i2c);
+      worker_data->result = iotjs_i2c_open(i2c);
       break;
     case kI2cOpWrite:
-      req_wrap->result = iotjs_i2c_write(i2c);
+      worker_data->result = iotjs_i2c_write(i2c);
       break;
     case kI2cOpRead:
-      req_wrap->result = iotjs_i2c_read(i2c);
+      worker_data->result = iotjs_i2c_read(i2c);
       break;
     case kI2cOpClose:
-      req_wrap->result = iotjs_i2c_close(i2c);
+      worker_data->result = iotjs_i2c_close(i2c);
       break;
     default:
       IOTJS_ASSERT(!"Invalid Operation");
@@ -64,7 +64,7 @@ JS_FUNCTION(I2cCons) {
   JS_GET_REQUIRED_ARG_VALUE(0, jconfig, IOTJS_MAGIC_STRING_CONFIG, object);
 
   jerry_value_t res = iotjs_i2c_set_platform_config(i2c, jconfig);
-  if (jerry_value_has_error_flag(res)) {
+  if (jerry_value_is_error(res)) {
     return res;
   }
 
@@ -114,6 +114,7 @@ static jerry_value_t i2c_write(iotjs_i2c_t* i2c, const jerry_value_t jargv[],
   i2c->buf_data = iotjs_buffer_allocate_from_number_array(i2c->buf_len, jarray);
 
   if (async) {
+    DJS_CHECK_ARG_IF_EXIST(1, function);
     iotjs_periph_call_async(i2c, JS_GET_ARG_IF_EXIST(1, function), kI2cOpWrite,
                             i2c_worker);
   } else {
@@ -125,19 +126,25 @@ static jerry_value_t i2c_write(iotjs_i2c_t* i2c, const jerry_value_t jargv[],
   return jerry_create_undefined();
 }
 
-JS_FUNCTION(Write) {
+typedef enum { IOTJS_I2C_WRITE, IOTJS_I2C_WRITESYNC } iotjs_i2c_op_t;
+
+jerry_value_t i2c_do_write_or_writesync(const jerry_value_t jfunc,
+                                        const jerry_value_t jthis,
+                                        const jerry_value_t jargv[],
+                                        const jerry_length_t jargc,
+                                        const iotjs_i2c_op_t i2c_op) {
   JS_DECLARE_THIS_PTR(i2c, i2c);
   DJS_CHECK_ARGS(1, array);
-  DJS_CHECK_ARG_IF_EXIST(1, function);
+  return i2c_write(i2c, jargv, jargc, i2c_op == IOTJS_I2C_WRITE);
+}
 
-  return i2c_write(i2c, jargv, jargc, true);
+JS_FUNCTION(Write) {
+  return i2c_do_write_or_writesync(jfunc, jthis, jargv, jargc, IOTJS_I2C_WRITE);
 }
 
 JS_FUNCTION(WriteSync) {
-  JS_DECLARE_THIS_PTR(i2c, i2c);
-  DJS_CHECK_ARGS(1, array);
-
-  return i2c_write(i2c, jargv, jargc, false);
+  return i2c_do_write_or_writesync(jfunc, jthis, jargv, jargc,
+                                   IOTJS_I2C_WRITESYNC);
 }
 
 JS_FUNCTION(Read) {
index c7516531e9f930e70293d4a38a1b97bff4ed0f9a..6844071d07defb752667de60f755c3e5811a4c3d 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "iotjs_def.h"
 #include "iotjs_module_periph_common.h"
-#include "iotjs_reqwrap.h"
 
 // Forward declaration of platform data. These are only used by platform code.
 // Generic I2C module never dereferences platform data pointer.
index 58d0ef93ba30d93897a5471b02187c7e0ed73911..21f4985c63a76c2510b725c959a0522f1dc376a3 100644 (file)
 #include "iotjs_module_mqtt.h"
 
 
-#include "iotjs_handlewrap.h"
-#include "iotjs_reqwrap.h"
+static void iotjs_mqttclient_destroy(iotjs_mqttclient_t *mqttclient) {
+  IOTJS_RELEASE(mqttclient->buffer);
+  IOTJS_RELEASE(mqttclient);
+}
 
+static const jerry_object_native_info_t mqttclient_native_info = {
+  .free_cb = (jerry_object_native_free_callback_t)iotjs_mqttclient_destroy
+};
 
-static jerry_value_t mqtt_client_connack_error(const unsigned char error_code) {
-  switch (error_code) {
-    case UNACCEPTABLE_PROTOCOL:
-      return JS_CREATE_ERROR(COMMON,
-                             "MQTT: Connection refused: unacceptable protocol");
-    case BAD_IDENTIFIER:
-      return JS_CREATE_ERROR(COMMON,
-                             "MQTT: Connection refused: bad client identifier");
-    case SERVER_UNAVIABLE:
-      return JS_CREATE_ERROR(COMMON,
-                             "MQTT: Connection refused: server unaviable");
-    case BAD_CREDENTIALS:
-      return JS_CREATE_ERROR(
-          COMMON, "MQTT: Connection refused: bad username or password");
-    case UNAUTHORISED:
-      return JS_CREATE_ERROR(COMMON, "MQTT: Connection refused: unauthorised");
-    default:
-      return JS_CREATE_ERROR(COMMON, "MQTT: Unknown error");
-  }
+
+iotjs_mqttclient_t *iotjs_mqttclient_create(const jerry_value_t jobject) {
+  iotjs_mqttclient_t *mqttclient = IOTJS_ALLOC(iotjs_mqttclient_t);
+
+  jerry_set_object_native_pointer(jobject, mqttclient, &mqttclient_native_info);
+  return mqttclient;
 }
 
 
@@ -74,24 +66,35 @@ static size_t get_remaining_length_size(uint32_t len) {
 }
 
 
-static uint32_t iotjs_decode_remaining_length(char *buffer, size_t *offset) {
-  unsigned char c;
-  uint32_t remaining_length = 0;
-  uint32_t length = 0;
-  uint32_t shift = 0;
+static uint32_t iotjs_decode_remaining_length(char *buffer,
+                                              uint32_t *out_length) {
+  // There must be at least 2 bytes to decode
+  uint32_t c = (uint32_t)(*buffer);
+  uint32_t decoded_length = (c & 0x7F);
+  uint32_t length = 1;
+  uint32_t shift = 7;
+
+  buffer++;
 
   do {
     if (++length > IOTJS_MODULE_MQTT_MAX_REMAINING_LENGTH_BYTES) {
-      return UINT32_MAX;
+      return 0;
     }
-    c = (unsigned char)buffer[*offset];
-    remaining_length += (uint32_t)(c & 0x7F) << shift;
+    c = (uint32_t)(*buffer);
+    decoded_length += (c & 0x7F) << shift;
+
     shift += 7;
+    buffer++;
+  } while ((c & 0x80) != 0);
 
-    (*offset)++;
-  } while ((c & 128) != 0);
+  if (c == 0) {
+    // The length must be encoded with the least amount of bytes.
+    // This rule is not fulfilled if the last byte is zero.
+    return 0;
+  }
 
-  return remaining_length;
+  *out_length = length;
+  return decoded_length;
 }
 
 
@@ -101,7 +104,7 @@ static uint16_t iotjs_mqtt_calculate_length(uint8_t msb, uint8_t lsb) {
 
 
 static uint8_t *iotjs_mqtt_string_serialize(uint8_t *dst_buffer,
-                                            iotjs_bufferwrap_t *src_buffer) {
+                                            iotjs_tmp_buffer_t *src_buffer) {
   uint16_t len = src_buffer->length;
   dst_buffer[0] = (uint8_t)(len >> 8);
   dst_buffer[1] = (uint8_t)(len & 0x00FF);
@@ -109,22 +112,37 @@ static uint8_t *iotjs_mqtt_string_serialize(uint8_t *dst_buffer,
   return (dst_buffer + 2 + src_buffer->length);
 }
 
-void iotjs_create_ack_callback(char *buffer, char *name, jerry_value_t jsref) {
-  uint8_t packet_identifier_MSB = (uint8_t)buffer[2];
-  uint8_t packet_identifier_LSB = (uint8_t)buffer[3];
-
+void iotjs_mqtt_ack(char *buffer, char *name, jerry_value_t jsref,
+                    char *error) {
   uint16_t package_id =
-      iotjs_mqtt_calculate_length(packet_identifier_MSB, packet_identifier_LSB);
+      iotjs_mqtt_calculate_length((uint8_t)buffer[0], (uint8_t)buffer[1]);
 
   // The callback takes the packet identifier as parameter.
-  iotjs_jargs_t args = iotjs_jargs_create(2);
-  iotjs_jargs_append_jval(&args, jsref);
-  iotjs_jargs_append_number(&args, package_id);
+  jerry_value_t args[2] = { jerry_create_number(package_id),
+                            jerry_create_undefined() };
+
+  if (error) {
+    args[1] = iotjs_jval_create_error_without_error_flag(error);
+  }
 
   jerry_value_t fn = iotjs_jval_get_property(jsref, name);
-  iotjs_make_callback(fn, jsref, &args);
+  iotjs_invoke_callback(fn, jsref, args, 2);
   jerry_release_value(fn);
-  iotjs_jargs_destroy(&args);
+  jerry_release_value(args[0]);
+  jerry_release_value(args[1]);
+}
+
+
+JS_FUNCTION(MqttInit) {
+  DJS_CHECK_THIS();
+
+  const jerry_value_t jmqtt = JS_GET_ARG(0, object);
+
+  iotjs_mqttclient_t *mqttclient = iotjs_mqttclient_create(jmqtt);
+  mqttclient->buffer = NULL;
+  mqttclient->buffer_length = 0;
+
+  return jerry_create_undefined();
 }
 
 
@@ -135,45 +153,57 @@ JS_FUNCTION(MqttConnect) {
 
   jerry_value_t joptions = JS_GET_ARG(0, object);
 
-  jerry_value_t jclient_id =
-      iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_CLIENTID);
-  jerry_value_t jusername =
-      iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_USERNAME);
-  jerry_value_t jpassword =
-      iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_PASSWORD);
+  iotjs_tmp_buffer_t client_id;
+  iotjs_jval_get_jproperty_as_tmp_buffer(joptions, IOTJS_MAGIC_STRING_CLIENTID,
+                                         &client_id);
+  iotjs_tmp_buffer_t username;
+  iotjs_jval_get_jproperty_as_tmp_buffer(joptions, IOTJS_MAGIC_STRING_USERNAME,
+                                         &username);
+  iotjs_tmp_buffer_t password;
+  iotjs_jval_get_jproperty_as_tmp_buffer(joptions, IOTJS_MAGIC_STRING_PASSWORD,
+                                         &password);
+  iotjs_tmp_buffer_t message;
+  iotjs_jval_get_jproperty_as_tmp_buffer(joptions, IOTJS_MAGIC_STRING_MESSAGE,
+                                         &message);
+  iotjs_tmp_buffer_t topic;
+  iotjs_jval_get_jproperty_as_tmp_buffer(joptions, IOTJS_MAGIC_STRING_TOPIC,
+                                         &topic);
+
+  if (client_id.buffer == NULL || client_id.length >= UINT16_MAX ||
+      username.length >= UINT16_MAX || password.length >= UINT16_MAX ||
+      message.length >= UINT16_MAX || topic.length >= UINT16_MAX) {
+    iotjs_free_tmp_buffer(&client_id);
+    iotjs_free_tmp_buffer(&username);
+    iotjs_free_tmp_buffer(&password);
+    iotjs_free_tmp_buffer(&message);
+    iotjs_free_tmp_buffer(&topic);
+    return JS_CREATE_ERROR(COMMON, "mqtt id too long (max: 65535)");
+  }
+
   jerry_value_t jkeepalive =
       iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_KEEPALIVE);
   jerry_value_t jwill =
       iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_WILL);
   jerry_value_t jqos =
       iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_QOS);
-  jerry_value_t jmessage =
-      iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_MESSAGE);
-  jerry_value_t jtopic =
-      iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_TOPIC);
   jerry_value_t jretain =
-      iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_TOPIC);
+      iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_RETAIN);
 
   uint8_t connect_flags = 0;
-  uint8_t keep_alive_msb = 0;
-  uint8_t keep_alive_lsb = 10;
   connect_flags |= MQTT_FLAG_CLEANSESSION;
-  iotjs_bufferwrap_t *username = NULL;
-  iotjs_bufferwrap_t *password = NULL;
-  iotjs_bufferwrap_t *message = NULL;
-  iotjs_bufferwrap_t *topic = NULL;
 
   uint8_t header_byte = 0;
   header_byte |= (CONNECT << 4);
 
-
   if (!jerry_value_is_undefined(jwill) && jerry_get_boolean_value(jwill)) {
     connect_flags |= MQTT_FLAG_WILL;
-    if (!jerry_value_is_undefined(jqos)) {
-      uint8_t qos = 0;
-      qos = jerry_get_number_value(qos);
-      if (qos) {
-        connect_flags |= (qos == 1) ? MQTT_FLAG_WILLQOS_1 : MQTT_FLAG_WILLQOS_2;
+    if (jerry_value_is_number(jqos)) {
+      double qos = jerry_get_number_value(jqos);
+
+      if (qos == 1.0) {
+        connect_flags |= MQTT_FLAG_WILLQOS_1;
+      } else if (qos == 2.0) {
+        connect_flags |= MQTT_FLAG_WILLQOS_2;
       }
     }
 
@@ -181,26 +211,24 @@ JS_FUNCTION(MqttConnect) {
         jerry_get_boolean_value(jretain)) {
       connect_flags |= MQTT_FLAG_WILLRETAIN;
     }
-    message = iotjs_bufferwrap_from_jbuffer(jmessage);
-    topic = iotjs_bufferwrap_from_jbuffer(jtopic);
   }
 
-  if (!jerry_value_is_undefined(jusername)) {
+  if (username.buffer != NULL) {
     connect_flags |= MQTT_FLAG_USERNAME;
-    username = iotjs_bufferwrap_from_jbuffer(jusername);
   }
-  if (!jerry_value_is_undefined(jpassword)) {
+  if (password.buffer != NULL) {
     connect_flags |= MQTT_FLAG_PASSWORD;
-    password = iotjs_bufferwrap_from_jbuffer(jpassword);
-  }
-  if (!jerry_value_is_undefined(jkeepalive)) {
-    uint16_t len = jerry_get_number_value(jkeepalive);
-    keep_alive_msb = (uint8_t)(len >> 8);
-    keep_alive_lsb = (uint8_t)(len & 0x00FF);
   }
 
+  uint16_t keepalive = 0;
+
+  if (jerry_value_is_number(jkeepalive)) {
+    keepalive = (uint16_t)jerry_get_number_value(jkeepalive);
+  }
 
-  iotjs_bufferwrap_t *client_id = iotjs_bufferwrap_from_jbuffer(jclient_id);
+  if (keepalive < 30) {
+    keepalive = 30;
+  }
 
   unsigned char variable_header_protocol[7];
   variable_header_protocol[0] = 0;
@@ -212,20 +240,21 @@ JS_FUNCTION(MqttConnect) {
   variable_header_protocol[6] = 4;
 
   size_t variable_header_len = sizeof(variable_header_protocol) +
-                               sizeof(connect_flags) + sizeof(keep_alive_lsb) +
-                               sizeof(keep_alive_msb);
+                               sizeof(connect_flags) + IOTJS_MQTT_LSB_MSB_SIZE;
+
+  size_t payload_len = IOTJS_MQTT_LSB_MSB_SIZE + client_id.length;
 
-  size_t payload_len = client_id->length + IOTJS_MQTT_LSB_MSB_SIZE;
   if (connect_flags & MQTT_FLAG_USERNAME) {
-    payload_len += IOTJS_MQTT_LSB_MSB_SIZE + username->length;
+    payload_len += IOTJS_MQTT_LSB_MSB_SIZE + username.length;
   }
   if (connect_flags & MQTT_FLAG_PASSWORD) {
-    payload_len += IOTJS_MQTT_LSB_MSB_SIZE + password->length;
+    payload_len += IOTJS_MQTT_LSB_MSB_SIZE + password.length;
   }
   if (connect_flags & MQTT_FLAG_WILL) {
-    payload_len += IOTJS_MQTT_LSB_MSB_SIZE + topic->length;
-    payload_len += IOTJS_MQTT_LSB_MSB_SIZE + message->length;
+    payload_len += IOTJS_MQTT_LSB_MSB_SIZE + topic.length;
+    payload_len += IOTJS_MQTT_LSB_MSB_SIZE + message.length;
   }
+
   uint32_t remaining_length = payload_len + variable_header_len;
   size_t full_len = sizeof(header_byte) +
                     get_remaining_length_size(remaining_length) +
@@ -242,32 +271,33 @@ JS_FUNCTION(MqttConnect) {
   memcpy(buff_ptr, variable_header_protocol, sizeof(variable_header_protocol));
   buff_ptr += sizeof(variable_header_protocol);
   *buff_ptr++ = connect_flags;
-  *buff_ptr++ = keep_alive_msb;
-  *buff_ptr++ = keep_alive_lsb;
+  *buff_ptr++ = (uint8_t)(keepalive >> 8);
+  *buff_ptr++ = (uint8_t)(keepalive & 0x00FF);
 
-  buff_ptr = iotjs_mqtt_string_serialize(buff_ptr, client_id);
+  buff_ptr = iotjs_mqtt_string_serialize(buff_ptr, &client_id);
 
   if (connect_flags & MQTT_FLAG_WILL) {
-    buff_ptr = iotjs_mqtt_string_serialize(buff_ptr, topic);
-    buff_ptr = iotjs_mqtt_string_serialize(buff_ptr, message);
+    buff_ptr = iotjs_mqtt_string_serialize(buff_ptr, &topic);
+    buff_ptr = iotjs_mqtt_string_serialize(buff_ptr, &message);
   }
 
   if (connect_flags & MQTT_FLAG_USERNAME) {
-    buff_ptr = iotjs_mqtt_string_serialize(buff_ptr, username);
+    buff_ptr = iotjs_mqtt_string_serialize(buff_ptr, &username);
   }
   if (connect_flags & MQTT_FLAG_PASSWORD) {
-    buff_ptr = iotjs_mqtt_string_serialize(buff_ptr, password);
+    buff_ptr = iotjs_mqtt_string_serialize(buff_ptr, &password);
   }
 
-  jerry_release_value(jretain);
-  jerry_release_value(jtopic);
-  jerry_release_value(jmessage);
-  jerry_release_value(jqos);
-  jerry_release_value(jwill);
+  iotjs_free_tmp_buffer(&client_id);
+  iotjs_free_tmp_buffer(&username);
+  iotjs_free_tmp_buffer(&password);
+  iotjs_free_tmp_buffer(&message);
+  iotjs_free_tmp_buffer(&topic);
+
   jerry_release_value(jkeepalive);
-  jerry_release_value(jclient_id);
-  jerry_release_value(jusername);
-  jerry_release_value(jpassword);
+  jerry_release_value(jwill);
+  jerry_release_value(jqos);
+  jerry_release_value(jretain);
 
   return jbuff;
 }
@@ -276,50 +306,45 @@ JS_FUNCTION(MqttConnect) {
 JS_FUNCTION(MqttPublish) {
   DJS_CHECK_THIS();
 
-  DJS_CHECK_ARGS(1, object);
+  DJS_CHECK_ARGS(3, any, any, number);
 
-  jerry_value_t joptions = JS_GET_ARG(0, object);
+  iotjs_tmp_buffer_t topic;
+  iotjs_jval_as_tmp_buffer(JS_GET_ARG(0, any), &topic);
 
-  jerry_value_t jmessage =
-      iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_MESSAGE);
-  jerry_value_t jtopic =
-      iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_TOPIC);
-  jerry_value_t jretain =
-      iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_RETAIN);
-  jerry_value_t jqos =
-      iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_QOS);
-  jerry_value_t jpacket_id =
-      iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_PACKETID);
+  if (jerry_value_is_error(topic.jval)) {
+    return topic.jval;
+  }
 
-  uint8_t qos = 0;
-  if (jerry_value_is_number(jqos)) {
-    qos = jerry_get_number_value(jqos);
+  if (topic.buffer == NULL || topic.length >= UINT16_MAX) {
+    iotjs_free_tmp_buffer(&topic);
+
+    return JS_CREATE_ERROR(COMMON, "Topic for PUBLISH is empty or too long.");
+  }
+
+  iotjs_tmp_buffer_t message;
+  iotjs_jval_as_tmp_buffer(JS_GET_ARG(1, any), &message);
+
+  if (jerry_value_is_error(message.jval)) {
+    iotjs_free_tmp_buffer(&topic);
+    return message.jval;
   }
 
-  bool dup = false;
+  // header bits: | 16 bit packet id | 4 bit PUBLISH header |
+  uint32_t header = (uint32_t)JS_GET_ARG(2, number);
+  uint32_t packet_identifier = (header >> 4);
 
   uint8_t header_byte = 0;
-  header_byte |= (PUBLISH << 4);
-  header_byte |= (dup << 3);
-  header_byte |= (qos << 1);
-  header_byte |= (jerry_get_boolean_value(jretain));
+  header_byte |= (PUBLISH << 4) | (header & 0xf);
 
-  iotjs_bufferwrap_t *message_payload = iotjs_bufferwrap_from_jbuffer(jmessage);
-  iotjs_bufferwrap_t *topic_payload = iotjs_bufferwrap_from_jbuffer(jtopic);
+  const uint8_t qos_mask = (0x3 << 1);
 
-  uint8_t packet_identifier_lsb = 0;
-  uint8_t packet_identifier_msb = 0;
+  size_t payload_len = message.length + IOTJS_MQTT_LSB_MSB_SIZE;
+  size_t variable_header_len = topic.length + IOTJS_MQTT_LSB_MSB_SIZE;
 
-  if (qos > 0 && jerry_value_is_number(jpacket_id)) {
-    uint16_t packet_identifier = jerry_get_number_value(jpacket_id);
-    packet_identifier_msb = (uint8_t)(packet_identifier >> 8);
-    packet_identifier_lsb = (uint8_t)(packet_identifier & 0x00FF);
+  if (header_byte & qos_mask) {
+    variable_header_len += IOTJS_MQTT_LSB_MSB_SIZE;
   }
 
-  size_t payload_len = message_payload->length + IOTJS_MQTT_LSB_MSB_SIZE;
-  size_t variable_header_len = topic_payload->length + IOTJS_MQTT_LSB_MSB_SIZE +
-                               sizeof(packet_identifier_msb) +
-                               sizeof(packet_identifier_lsb);
   uint32_t remaining_length = payload_len + variable_header_len;
   size_t full_len = sizeof(header_byte) +
                     get_remaining_length_size(remaining_length) +
@@ -332,58 +357,45 @@ JS_FUNCTION(MqttPublish) {
 
   *buff_ptr++ = header_byte;
   buff_ptr = iotjs_encode_remaining_length(buff_ptr, remaining_length);
-  buff_ptr = iotjs_mqtt_string_serialize(buff_ptr, topic_payload);
-  *buff_ptr++ = packet_identifier_msb;
-  *buff_ptr++ = packet_identifier_lsb;
+  buff_ptr = iotjs_mqtt_string_serialize(buff_ptr, &topic);
+
+  if (header_byte & qos_mask) {
+    // Packet id format is MSB / LSB.
+    *buff_ptr++ = (uint8_t)(packet_identifier >> 8);
+    *buff_ptr++ = (uint8_t)(packet_identifier & 0x00FF);
+  }
 
   // Don't need to put length before the payload, so we can't use the
   // iotjs_mqtt_string_serialize. The broker and the other clients calculate
   // the payload length from remaining length and the topic length.
-  memcpy(buff_ptr, message_payload->buffer, message_payload->length);
-
-  jerry_release_value(jmessage);
-  jerry_release_value(jtopic);
-  jerry_release_value(jretain);
+  memcpy(buff_ptr, message.buffer, message.length);
 
+  iotjs_free_tmp_buffer(&message);
+  iotjs_free_tmp_buffer(&topic);
   return jbuff;
 }
 
 
-JS_FUNCTION(MqttHandle) {
-  DJS_CHECK_THIS();
-  DJS_CHECK_ARGS(2, object, object);
-
-  jerry_value_t jsref = JS_GET_ARG(0, object);
-  jerry_value_t jparam = JS_GET_ARG(1, object);
-
-  iotjs_bufferwrap_t *buffer_wrap = iotjs_bufferwrap_from_jbuffer(jparam);
-  char *buffer = buffer_wrap->buffer;
-
-  char first_byte = buffer[0];
+static int iotjs_mqtt_handle(jerry_value_t jsref, char first_byte, char *buffer,
+                             uint32_t packet_size) {
   char packet_type = (first_byte >> 4) & 0x0F;
 
-  size_t offset = 1;
-  uint32_t remaining_length = iotjs_decode_remaining_length(buffer, &offset);
-
   switch (packet_type) {
     case CONNACK: {
-      if (remaining_length != 2) {
-        return JS_CREATE_ERROR(COMMON, "MQTT: CONNACK packet is corrupted");
+      if (packet_size != 2) {
+        return MQTT_ERR_CORRUPTED_PACKET;
       }
 
-      uint8_t return_code = (uint8_t)buffer[++offset];
+      uint8_t return_code = (uint8_t)buffer[1];
 
       if (return_code != 0) {
-        return mqtt_client_connack_error(return_code);
+        return return_code;
       }
 
       jerry_value_t fn =
-          iotjs_jval_get_property(jsref, IOTJS_MAGIC_STRING__ONCONNECT);
-      iotjs_jargs_t jargs = iotjs_jargs_create(1);
-      iotjs_jargs_append_jval(&jargs, jsref);
-      iotjs_make_callback(fn, jsref, &jargs);
+          iotjs_jval_get_property(jsref, IOTJS_MAGIC_STRING_ONCONNECTION);
+      iotjs_invoke_callback(fn, jsref, NULL, 0);
 
-      iotjs_jargs_destroy(&jargs);
       jerry_release_value(fn);
       break;
     }
@@ -394,41 +406,35 @@ JS_FUNCTION(MqttHandle) {
       header.bits.qos = (first_byte & 0x06) >> 1;
       header.bits.retain = first_byte & 0x01;
 
-      uint8_t topic_length_MSB = (uint8_t)buffer[offset];
-      offset += sizeof(topic_length_MSB);
-
-      uint8_t topic_length_LSB = (uint8_t)buffer[offset];
-      offset += sizeof(topic_length_LSB);
+      uint8_t topic_length_MSB = (uint8_t)buffer[0];
+      uint8_t topic_length_LSB = (uint8_t)buffer[1];
+      buffer += 2;
 
       uint16_t topic_length =
           iotjs_mqtt_calculate_length(topic_length_MSB, topic_length_LSB);
 
-      jerry_value_t jtopic = iotjs_bufferwrap_create_buffer(topic_length);
-      iotjs_bufferwrap_t *topic_wrap = iotjs_bufferwrap_from_jbuffer(jtopic);
+      if (!jerry_is_valid_utf8_string((const uint8_t *)buffer, topic_length)) {
+        return MQTT_ERR_CORRUPTED_PACKET;
+      }
 
-      memcpy(topic_wrap->buffer, buffer + offset, topic_length);
-      offset += topic_length;
+      const jerry_char_t *topic = (const jerry_char_t *)buffer;
+      jerry_value_t jtopic = jerry_create_string_sz(topic, topic_length);
+      buffer += topic_length;
 
       // The Packet Identifier field is only present in PUBLISH packets
       // where the QoS level is 1 or 2.
       uint16_t packet_identifier = 0;
       if (header.bits.qos > 0) {
-        uint8_t packet_identifier_MSB = 0;
-        uint8_t packet_identifier_LSB = 0;
-
-
-        memcpy(&packet_identifier_MSB, buffer + offset, sizeof(uint8_t));
-        offset += sizeof(packet_identifier_MSB);
-
-        memcpy(&packet_identifier_LSB, buffer + offset, sizeof(uint8_t));
-        offset += sizeof(packet_identifier_LSB);
+        uint8_t packet_identifier_MSB = (uint8_t)buffer[0];
+        uint8_t packet_identifier_LSB = (uint8_t)buffer[1];
+        buffer += 2;
 
         packet_identifier = iotjs_mqtt_calculate_length(packet_identifier_MSB,
                                                         packet_identifier_LSB);
       }
 
       size_t payload_length =
-          (size_t)remaining_length - topic_length - sizeof(topic_length);
+          (size_t)packet_size - topic_length - sizeof(topic_length);
 
       if (header.bits.qos > 0) {
         payload_length -= sizeof(packet_identifier);
@@ -437,127 +443,98 @@ JS_FUNCTION(MqttHandle) {
       jerry_value_t jmessage = iotjs_bufferwrap_create_buffer(payload_length);
       iotjs_bufferwrap_t *msg_wrap = iotjs_bufferwrap_from_jbuffer(jmessage);
 
-      IOTJS_ASSERT(jerry_is_valid_utf8_string((const uint8_t *)msg_wrap->buffer,
-                                              msg_wrap->length));
-
-      IOTJS_ASSERT(
-          jerry_is_valid_utf8_string((const uint8_t *)topic_wrap->buffer,
-                                     topic_wrap->length));
-
-      memcpy(msg_wrap->buffer, buffer + offset, payload_length);
-      offset += payload_length;
+      memcpy(msg_wrap->buffer, buffer, payload_length);
 
-      iotjs_jargs_t args = iotjs_jargs_create(5);
-      iotjs_jargs_append_jval(&args, jsref);
-      iotjs_jargs_append_string_raw(&args, msg_wrap->buffer);
-      iotjs_jargs_append_string_raw(&args, topic_wrap->buffer);
-      iotjs_jargs_append_number(&args, header.bits.qos);
-      iotjs_jargs_append_number(&args, packet_identifier);
+      jerry_value_t args[4] = { jmessage, jtopic,
+                                jerry_create_number(header.bits.qos),
+                                jerry_create_number(packet_identifier) };
 
       jerry_value_t fn =
-          iotjs_jval_get_property(jsref, IOTJS_MAGIC_STRING__ONMESSAGE);
-      iotjs_make_callback(fn, jsref, &args);
+          iotjs_jval_get_property(jsref, IOTJS_MAGIC_STRING_ONMESSAGE);
+      iotjs_invoke_callback(fn, jsref, args, 4);
       jerry_release_value(fn);
 
-      iotjs_jargs_destroy(&args);
-      jerry_release_value(jmessage);
-      jerry_release_value(jtopic);
+      for (uint8_t i = 0; i < 4; i++) {
+        jerry_release_value(args[i]);
+      }
 
       break;
     }
     case PUBACK: {
-      if (remaining_length != 2) {
-        return JS_CREATE_ERROR(COMMON, "MQTT: PUBACK packet is corrupted");
+      if (packet_size != 2 || (first_byte & 0x0F) != 0x0) {
+        return MQTT_ERR_CORRUPTED_PACKET;
       }
 
-      iotjs_create_ack_callback(buffer, IOTJS_MAGIC_STRING__ONPUBACK, jsref);
+      iotjs_mqtt_ack(buffer, IOTJS_MAGIC_STRING_ONACK, jsref, NULL);
       break;
     }
     case PUBREC: {
-      if (remaining_length != 2) {
-        return JS_CREATE_ERROR(COMMON, "MQTT: RUBREC packet is corrupted");
+      if (packet_size != 2 || (first_byte & 0x0F) != 0x0) {
+        return MQTT_ERR_CORRUPTED_PACKET;
       }
 
-      iotjs_create_ack_callback(buffer, IOTJS_MAGIC_STRING__ONPUBREC, jsref);
+      iotjs_mqtt_ack(buffer, IOTJS_MAGIC_STRING_ONPUBREC, jsref, NULL);
       break;
     }
     case PUBREL: {
-      if (remaining_length != 2) {
-        return JS_CREATE_ERROR(COMMON, "MQTT: PUBREL packet is corrupted");
-      }
-
-      char control_packet_reserved = first_byte & 0x0F;
-      if (control_packet_reserved != 2) {
-        return JS_CREATE_ERROR(COMMON, "MQTT: PUBREL packet is corrupted");
+      if (packet_size != 2 || (first_byte & 0x0F) != 0x2) {
+        return MQTT_ERR_CORRUPTED_PACKET;
       }
 
-      iotjs_create_ack_callback(buffer, IOTJS_MAGIC_STRING__ONPUBREL, jsref);
+      iotjs_mqtt_ack(buffer, IOTJS_MAGIC_STRING_ONPUBREL, jsref, NULL);
       break;
     }
     case PUBCOMP: {
-      if (remaining_length != 2) {
-        return JS_CREATE_ERROR(COMMON, "MQTT: PUBCOMP packet is corrupted");
+      if (packet_size != 2 || (first_byte & 0x0F) != 0x0) {
+        return MQTT_ERR_CORRUPTED_PACKET;
       }
 
-      iotjs_create_ack_callback(buffer, IOTJS_MAGIC_STRING__ONPUBCOMP, jsref);
+      iotjs_mqtt_ack(buffer, IOTJS_MAGIC_STRING_ONACK, jsref, NULL);
       break;
     }
     case SUBACK: {
       // We assume that only one topic was in the SUBSCRIBE packet.
-      if (remaining_length != 3) {
-        return JS_CREATE_ERROR(COMMON, "MQTT: SUBACK packet is corrupted");
+      if (packet_size != 3 || (first_byte & 0x0F) != 0x0) {
+        return MQTT_ERR_CORRUPTED_PACKET;
       }
 
-      uint8_t return_code = (uint8_t)buffer[4];
-      if (return_code == 128) {
-        return JS_CREATE_ERROR(COMMON, "MQTT: Subscription was unsuccessful");
-      }
+      char *error = NULL;
 
-      // The callback takes the granted QoS as parameter.
-      iotjs_jargs_t args = iotjs_jargs_create(2);
-      iotjs_jargs_append_jval(&args, jsref);
-      iotjs_jargs_append_number(&args, return_code);
+      if ((uint8_t)buffer[2] == 0x80) {
+        error = "Subscribe failed";
+      }
 
-      jerry_value_t sub_fn =
-          iotjs_jval_get_property(jsref, IOTJS_MAGIC_STRING__ONSUBACK);
-      iotjs_make_callback(sub_fn, jsref, &args);
-      jerry_release_value(sub_fn);
-      iotjs_jargs_destroy(&args);
+      iotjs_mqtt_ack(buffer, IOTJS_MAGIC_STRING_ONACK, jsref, error);
       break;
     }
     case UNSUBACK: {
-      if (remaining_length != 2) {
-        return JS_CREATE_ERROR(COMMON, "MQTT: UNSUBACK packet is corrupted");
+      if (packet_size != 2 || (first_byte & 0x0F) != 0x0) {
+        return MQTT_ERR_CORRUPTED_PACKET;
       }
 
-      iotjs_create_ack_callback(buffer, IOTJS_MAGIC_STRING__ONUNSUBACK, jsref);
+      iotjs_mqtt_ack(buffer, IOTJS_MAGIC_STRING_ONACK, jsref, NULL);
       break;
     }
     case PINGRESP: {
-      if (remaining_length != 0) {
-        return JS_CREATE_ERROR(COMMON, "MQTT: PingRESP packet is corrupted");
+      if (packet_size != 0 || (first_byte & 0x0F) != 0x0) {
+        return MQTT_ERR_CORRUPTED_PACKET;
       }
+
       jerry_value_t fn =
-          iotjs_jval_get_property(jsref, IOTJS_MAGIC_STRING__ONPINGRESP);
-      iotjs_jargs_t jargs = iotjs_jargs_create(1);
-      iotjs_jargs_append_jval(&jargs, jsref);
-      iotjs_make_callback(fn, jsref, &jargs);
+          iotjs_jval_get_property(jsref, IOTJS_MAGIC_STRING_ONPINGRESP);
+      iotjs_invoke_callback(fn, jsref, NULL, 0);
       jerry_release_value(fn);
-      iotjs_jargs_destroy(&jargs);
       break;
     }
     case DISCONNECT: {
-      iotjs_jargs_t jargs = iotjs_jargs_create(2);
-      iotjs_jargs_append_jval(&jargs, jsref);
-      jerry_value_t str_arg = jerry_create_string(
-          (jerry_char_t *)"The broker disconnected the client");
-      iotjs_jargs_append_jval(&jargs, str_arg);
+      if (packet_size != 0 || (first_byte & 0x0F) != 0x0) {
+        return MQTT_ERR_CORRUPTED_PACKET;
+      }
+
       jerry_value_t fn =
-          iotjs_jval_get_property(jsref, IOTJS_MAGIC_STRING__ONDISCONNECT);
-      iotjs_make_callback(fn, jsref, &jargs);
-      jerry_release_value(str_arg);
+          iotjs_jval_get_property(jsref, IOTJS_MAGIC_STRING_ONEND);
+      iotjs_invoke_callback(fn, jsref, NULL, 0);
       jerry_release_value(fn);
-      iotjs_jargs_destroy(&jargs);
       break;
     }
 
@@ -565,120 +542,199 @@ JS_FUNCTION(MqttHandle) {
     case SUBSCRIBE:
     case UNSUBSCRIBE:
     case PINGREQ:
-      return JS_CREATE_ERROR(
-          COMMON, "MQTT: Unallowed packet has arrived to the client");
+      return MQTT_ERR_UNALLOWED_PACKET;
   }
 
-  return jerry_create_undefined();
+  return 0;
 }
 
 
-JS_FUNCTION(MqttSubscribe) {
+static void iotjs_mqtt_concat_buffers(iotjs_mqttclient_t *mqttclient,
+                                      iotjs_bufferwrap_t *buff_recv) {
+  char *tmp_buf = mqttclient->buffer;
+  mqttclient->buffer =
+      IOTJS_CALLOC(mqttclient->buffer_length + buff_recv->length, char);
+  memcpy(mqttclient->buffer, tmp_buf, mqttclient->buffer_length);
+  memcpy(mqttclient->buffer + mqttclient->buffer_length, buff_recv->buffer,
+         buff_recv->length);
+  mqttclient->buffer_length += buff_recv->length;
+  IOTJS_RELEASE(tmp_buf);
+}
+
+
+static jerry_value_t iotjs_mqtt_handle_error(
+    iotjs_mqtt_packet_error_t error_code) {
+  switch (error_code) {
+    case MQTT_ERR_UNACCEPTABLE_PROTOCOL:
+      return JS_CREATE_ERROR(COMMON,
+                             "MQTT: Connection refused: unacceptable protocol");
+    case MQTT_ERR_BAD_IDENTIFIER:
+      return JS_CREATE_ERROR(COMMON,
+                             "MQTT: Connection refused: bad client identifier");
+    case MQTT_ERR_SERVER_UNAVIABLE:
+      return JS_CREATE_ERROR(COMMON,
+                             "MQTT: Connection refused: server unavailable");
+    case MQTT_ERR_BAD_CREDENTIALS:
+      return JS_CREATE_ERROR(
+          COMMON, "MQTT: Connection refused: bad username or password");
+    case MQTT_ERR_UNAUTHORISED:
+      return JS_CREATE_ERROR(COMMON, "MQTT: Connection refused: unauthorised");
+    case MQTT_ERR_CORRUPTED_PACKET:
+      return JS_CREATE_ERROR(COMMON, "MQTT: Corrupted packet");
+    case MQTT_ERR_UNALLOWED_PACKET:
+      return JS_CREATE_ERROR(COMMON, "MQTT: Broker sent an unallowed packet");
+    case MQTT_ERR_SUBSCRIPTION_FAILED:
+      return JS_CREATE_ERROR(COMMON, "MQTT: Subscription failed");
+    default:
+      return JS_CREATE_ERROR(COMMON, "MQTT: Unknown error");
+  }
+}
+
+
+JS_FUNCTION(MqttReceive) {
   DJS_CHECK_THIS();
-  DJS_CHECK_ARGS(1, object);
+  DJS_CHECK_ARGS(2, object, object);
 
-  jerry_value_t joptions = JS_GET_ARG(0, object);
+  jerry_value_t jnat = JS_GET_ARG(0, object);
 
-  jerry_value_t jtopic =
-      iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_TOPIC);
-  jerry_value_t jqos =
-      iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_QOS);
+  iotjs_mqttclient_t *mqttclient = (iotjs_mqttclient_t *)
+      iotjs_jval_get_object_native_handle(jnat, &mqttclient_native_info);
+  if (mqttclient == NULL) {
+    return JS_CREATE_ERROR(COMMON, "MQTT native pointer not available");
+  }
 
-  uint8_t qos = 0;
-  if (jerry_value_is_number(jqos)) {
-    qos = (uint8_t)jerry_get_number_value(jqos);
+  jerry_value_t jbuffer = JS_GET_ARG(1, object);
+  iotjs_bufferwrap_t *buff_recv = iotjs_bufferwrap_from_jbuffer(jbuffer);
+  if (buff_recv->length == 0) {
+    return jerry_create_undefined();
   }
 
-  bool dup = false;
-  bool retain = false;
+  char *current_buffer = buff_recv->buffer;
+  char *current_buffer_end = current_buffer + buff_recv->length;
 
-  uint8_t header_byte = 0;
-  header_byte |= (SUBSCRIBE << 4);
-  header_byte |= (dup << 3);
-  header_byte |= (1 << 1); // always 1
-  header_byte |= retain;
+  // Concat the buffers if we previously needed to
+  if (mqttclient->buffer_length > 0) {
+    iotjs_mqtt_concat_buffers(mqttclient, buff_recv);
+    current_buffer = mqttclient->buffer;
+    current_buffer_end = current_buffer + mqttclient->buffer_length;
+  }
 
-  iotjs_bufferwrap_t *topic_payload = iotjs_bufferwrap_from_jbuffer(jtopic);
+  // Keep on going, if data remains just continue looping
+  while (true) {
+    if (current_buffer >= current_buffer_end) {
+      if (mqttclient->buffer_length > 0) {
+        IOTJS_RELEASE(mqttclient->buffer);
+        mqttclient->buffer_length = 0;
+      }
+      return jerry_create_undefined();
+    }
 
-  uint8_t packet_identifier_lsb = 0;
-  uint8_t packet_identifier_msb = 0;
+    if (current_buffer + 2 > current_buffer_end) {
+      break;
+    }
 
-  size_t payload_len =
-      sizeof(qos) + topic_payload->length + IOTJS_MQTT_LSB_MSB_SIZE;
-  size_t variable_header_len =
-      sizeof(packet_identifier_msb) + sizeof(packet_identifier_lsb);
-  uint32_t remaining_length = payload_len + variable_header_len;
-  size_t full_len = sizeof(header_byte) +
-                    get_remaining_length_size(remaining_length) +
-                    variable_header_len + payload_len;
+    uint32_t packet_size;
+    uint32_t packet_size_length;
 
-  jerry_value_t jbuff = iotjs_bufferwrap_create_buffer(full_len);
-  iotjs_bufferwrap_t *buffer_wrap = iotjs_bufferwrap_from_jbuffer(jbuff);
+    if ((uint8_t)current_buffer[1] <= 0x7f) {
+      packet_size = (uint32_t)current_buffer[1];
+      packet_size_length = 1;
 
-  uint8_t *buff_ptr = (uint8_t *)buffer_wrap->buffer;
+      if (current_buffer + 2 + packet_size > current_buffer_end) {
+        break;
+      }
+    } else {
+      // At least 128 bytes arrived
+      if (current_buffer + 5 >= current_buffer_end) {
+        break;
+      }
 
-  *buff_ptr++ = header_byte;
+      packet_size = iotjs_decode_remaining_length(current_buffer + 1,
+                                                  &packet_size_length);
 
-  buff_ptr = iotjs_encode_remaining_length(buff_ptr, remaining_length);
+      if (packet_size == 0) {
+        return iotjs_mqtt_handle_error(MQTT_ERR_CORRUPTED_PACKET);
+      }
 
-  *buff_ptr++ = packet_identifier_msb;
-  *buff_ptr++ = packet_identifier_lsb;
+      if (current_buffer + 1 + packet_size_length + packet_size >
+          current_buffer_end) {
+        break;
+      }
+    }
 
-  buff_ptr = iotjs_mqtt_string_serialize(buff_ptr, topic_payload);
+    char first_byte = current_buffer[0];
+    current_buffer += 1 + packet_size_length;
 
-  buff_ptr[0] = qos;
+    int ret_val =
+        iotjs_mqtt_handle(jnat, first_byte, current_buffer, packet_size);
 
-  jerry_release_value(jtopic);
-  jerry_release_value(jqos);
+    if (ret_val != 0) {
+      return iotjs_mqtt_handle_error(ret_val);
+    }
 
-  return jbuff;
-}
+    current_buffer += packet_size;
+  }
 
+  if (current_buffer == mqttclient->buffer) {
+    return jerry_create_undefined();
+  }
 
-JS_FUNCTION(MqttPing) {
-  DJS_CHECK_THIS();
+  uint32_t remaining_size = (uint32_t)(current_buffer_end - current_buffer);
+  char *buffer = IOTJS_CALLOC(remaining_size, char);
+  memcpy(buffer, current_buffer, remaining_size);
 
-  uint8_t header_byte = 0;
-  header_byte |= (PINGREQ << 4);
+  if (mqttclient->buffer != NULL) {
+    IOTJS_RELEASE(mqttclient->buffer);
+  }
 
-  uint8_t remaining_length = 0;
-  size_t full_len = sizeof(header_byte) + sizeof(remaining_length);
+  mqttclient->buffer = buffer;
+  mqttclient->buffer_length = remaining_size;
 
-  jerry_value_t jbuff = iotjs_bufferwrap_create_buffer(full_len);
-  iotjs_bufferwrap_t *buffer_wrap = iotjs_bufferwrap_from_jbuffer(jbuff);
+  return jerry_create_undefined();
+}
 
-  uint8_t *buff_ptr = (uint8_t *)buffer_wrap->buffer;
+static jerry_value_t iotjs_mqtt_subscribe_handler(
+    const jerry_value_t jthis, const jerry_value_t jargv[],
+    const jerry_value_t jargc,
+    const iotjs_mqtt_control_packet_type packet_type) {
+  DJS_CHECK_THIS();
+  DJS_CHECK_ARGS(2, any, number);
 
-  buff_ptr[0] = header_byte;
-  buff_ptr[1] = remaining_length;
+  JS_CHECK(packet_type == SUBSCRIBE || packet_type == UNSUBSCRIBE);
 
-  return jbuff;
-}
+  iotjs_tmp_buffer_t topic;
+  iotjs_jval_as_tmp_buffer(JS_GET_ARG(0, any), &topic);
 
+  if (jerry_value_is_error(topic.jval)) {
+    return topic.jval;
+  }
 
-JS_FUNCTION(MqttUnsubscribe) {
-  DJS_CHECK_THIS();
-  DJS_CHECK_ARGS(1, object);
+  if (topic.buffer == NULL || topic.length >= UINT16_MAX) {
+    iotjs_free_tmp_buffer(&topic);
+
+    return JS_CREATE_ERROR(COMMON, "Topic for SUBSCRIBE is empty or too long.");
+  }
 
-  jerry_value_t jtopic = JS_GET_ARG(0, object);
+  // header bits: |2 bit qos | 16 bit packet id |
+  // qos is only available in case of subscribe
+  uint32_t header = (uint32_t)JS_GET_ARG(1, number);
+  uint32_t packet_identifier = (header & 0xFFFF);
 
-  iotjs_bufferwrap_t *topic_payload = iotjs_bufferwrap_from_jbuffer(jtopic);
+  // Low 4 bits must be 0,0,1,0
+  uint8_t header_byte = (packet_type << 4) | (1 << 1);
 
-  uint8_t header_byte = 0;
-  header_byte |= (UNSUBSCRIBE << 4);
-  // Reserved
-  header_byte |= (1 << 1);
+  size_t payload_len = topic.length + IOTJS_MQTT_LSB_MSB_SIZE;
 
-  uint8_t packet_identifier_msb = 0;
-  uint8_t packet_identifier_lsb = 0;
+  if (packet_type == SUBSCRIBE) {
+    // Add place for the SUBSCRIBE QoS data.
+    payload_len += sizeof(uint8_t);
+  }
 
-  size_t payload_len = topic_payload->length + IOTJS_MQTT_LSB_MSB_SIZE;
-  size_t variable_header_len =
-      sizeof(packet_identifier_msb) + sizeof(packet_identifier_lsb);
+  size_t variable_header_len = IOTJS_MQTT_LSB_MSB_SIZE;
   uint32_t remaining_length = payload_len + variable_header_len;
   size_t full_len = sizeof(header_byte) +
                     get_remaining_length_size(remaining_length) +
-                    variable_header_len + payload_len;
+                    remaining_length;
 
   jerry_value_t jbuff = iotjs_bufferwrap_create_buffer(full_len);
   iotjs_bufferwrap_t *buffer_wrap = iotjs_bufferwrap_from_jbuffer(jbuff);
@@ -689,10 +745,48 @@ JS_FUNCTION(MqttUnsubscribe) {
 
   buff_ptr = iotjs_encode_remaining_length(buff_ptr, remaining_length);
 
-  *buff_ptr++ = packet_identifier_msb;
-  *buff_ptr++ = packet_identifier_lsb;
+  // Packet id format is MSB / LSB.
+  *buff_ptr++ = (uint8_t)(packet_identifier >> 8);
+  *buff_ptr++ = (uint8_t)(packet_identifier & 0x00FF);
+
+  buff_ptr = iotjs_mqtt_string_serialize(buff_ptr, &topic);
 
-  buff_ptr = iotjs_mqtt_string_serialize(buff_ptr, topic_payload);
+  if (packet_type == SUBSCRIBE) {
+    uint8_t qos = ((header >> 16) & 0x3);
+    buff_ptr[0] = qos;
+  }
+
+  iotjs_free_tmp_buffer(&topic);
+  return jbuff;
+}
+
+
+JS_FUNCTION(MqttUnsubscribe) {
+  return iotjs_mqtt_subscribe_handler(jthis, jargv, jargc, UNSUBSCRIBE);
+}
+
+
+JS_FUNCTION(MqttSubscribe) {
+  return iotjs_mqtt_subscribe_handler(jthis, jargv, jargc, SUBSCRIBE);
+}
+
+
+JS_FUNCTION(MqttPing) {
+  DJS_CHECK_THIS();
+
+  uint8_t header_byte = 0;
+  header_byte |= (PINGREQ << 4);
+
+  uint8_t remaining_length = 0;
+  size_t full_len = sizeof(header_byte) + sizeof(remaining_length);
+
+  jerry_value_t jbuff = iotjs_bufferwrap_create_buffer(full_len);
+  iotjs_bufferwrap_t *buffer_wrap = iotjs_bufferwrap_from_jbuffer(jbuff);
+
+  uint8_t *buff_ptr = (uint8_t *)buffer_wrap->buffer;
+
+  buff_ptr[0] = header_byte;
+  buff_ptr[1] = remaining_length;
 
   return jbuff;
 }
@@ -720,52 +814,21 @@ JS_FUNCTION(MqttDisconnect) {
 
 JS_FUNCTION(MqttSendAck) {
   DJS_CHECK_THIS();
-  DJS_CHECK_ARGS(1, object);
+  DJS_CHECK_ARGS(2, number, number);
 
-  jerry_value_t joptions = JS_GET_ARG(0, object);
-  jerry_value_t jack_type =
-      iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_ACKTYPE);
-  jerry_value_t jpacket_id =
-      iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_PACKETID);
+  uint8_t ack_type = (uint8_t)JS_GET_ARG(0, number);
+  uint16_t packet_id = (uint16_t)JS_GET_ARG(1, number);
 
-  uint16_t packet_id = 0;
-  if (!jerry_value_is_undefined(jpacket_id)) {
-    packet_id = (uint16_t)jerry_get_number_value(jpacket_id);
-  }
-
-  uint8_t ack_type = 0;
-  if (!jerry_value_is_undefined(jack_type)) {
-    ack_type = (uint8_t)jerry_get_number_value(jack_type);
-  }
+  uint8_t header_byte = (ack_type << 4);
 
-  uint8_t header_byte = 0;
-  uint8_t remaining_length = 2;
-
-  switch (ack_type) {
-    case PUBACK: {
-      header_byte |= (PUBACK << 4);
-      break;
-    }
-    case PUBREC: {
-      header_byte |= (PUBREC << 4);
-      break;
-    }
-    case PUBREL: {
-      header_byte |= (PUBREL << 4);
-      header_byte |= 2;
-      break;
-    }
-    case PUBCOMP: {
-      header_byte |= (PUBCOMP << 4);
-      break;
-    }
+  if (ack_type == PUBREL) {
+    header_byte |= 0x2;
   }
 
   uint8_t packet_identifier_msb = (uint8_t)(packet_id >> 8);
   uint8_t packet_identifier_lsb = (uint8_t)(packet_id & 0x00FF);
 
-  size_t full_len =
-      sizeof(header_byte) + sizeof(remaining_length) + sizeof(packet_id);
+  size_t full_len = sizeof(uint8_t) * 2 + sizeof(packet_id);
 
   jerry_value_t jbuff = iotjs_bufferwrap_create_buffer(full_len);
   iotjs_bufferwrap_t *buffer_wrap = iotjs_bufferwrap_from_jbuffer(jbuff);
@@ -773,13 +836,10 @@ JS_FUNCTION(MqttSendAck) {
   uint8_t *buff_ptr = (uint8_t *)buffer_wrap->buffer;
 
   buff_ptr[0] = header_byte;
-  buff_ptr[1] = remaining_length;
+  buff_ptr[1] = 2; /* length */
   buff_ptr[2] = packet_identifier_msb;
   buff_ptr[3] = packet_identifier_lsb;
 
-  jerry_release_value(jpacket_id);
-  jerry_release_value(jack_type);
-
   return jbuff;
 }
 
@@ -787,9 +847,10 @@ jerry_value_t InitMQTT() {
   jerry_value_t jMQTT = jerry_create_object();
   iotjs_jval_set_method(jMQTT, IOTJS_MAGIC_STRING_CONNECT, MqttConnect);
   iotjs_jval_set_method(jMQTT, IOTJS_MAGIC_STRING_DISCONNECT, MqttDisconnect);
-  iotjs_jval_set_method(jMQTT, IOTJS_MAGIC_STRING_MQTTHANDLE, MqttHandle);
   iotjs_jval_set_method(jMQTT, IOTJS_MAGIC_STRING_PING, MqttPing);
   iotjs_jval_set_method(jMQTT, IOTJS_MAGIC_STRING_PUBLISH, MqttPublish);
+  iotjs_jval_set_method(jMQTT, IOTJS_MAGIC_STRING_MQTTINIT, MqttInit);
+  iotjs_jval_set_method(jMQTT, IOTJS_MAGIC_STRING_MQTTRECEIVE, MqttReceive);
   iotjs_jval_set_method(jMQTT, IOTJS_MAGIC_STRING_SENDACK, MqttSendAck);
   iotjs_jval_set_method(jMQTT, IOTJS_MAGIC_STRING_SUBSCRIBE, MqttSubscribe);
   iotjs_jval_set_method(jMQTT, IOTJS_MAGIC_STRING_UNSUBSCRIBE, MqttUnsubscribe);
index 4a1f8e2466685e59cac387f3b0157b1620ff9d08..8a58f411251b90d16672a18782d935a818fe8275 100644 (file)
@@ -25,7 +25,7 @@
  * The types of the control packet.
  * These values determine the aim of the message.
  */
-enum {
+typedef enum {
   CONNECT = 0x1,
   CONNACK = 0x2,
   PUBLISH = 0x3,
@@ -42,6 +42,18 @@ enum {
   DISCONNECT = 0xE
 } iotjs_mqtt_control_packet_type;
 
+// Packet error types
+typedef enum {
+  MQTT_ERR_UNACCEPTABLE_PROTOCOL = 1,
+  MQTT_ERR_BAD_IDENTIFIER = 2,
+  MQTT_ERR_SERVER_UNAVIABLE = 3,
+  MQTT_ERR_BAD_CREDENTIALS = 4,
+  MQTT_ERR_UNAUTHORISED = 5,
+  MQTT_ERR_CORRUPTED_PACKET = 6,
+  MQTT_ERR_UNALLOWED_PACKET = 7,
+  MQTT_ERR_SUBSCRIPTION_FAILED = 8,
+} iotjs_mqtt_packet_error_t;
+
 /*
  * The values of the Quality of Service.
  */
@@ -51,14 +63,6 @@ enum {
   QoS2 = 2  // Exactly once delivery.
 } iotjs_mqtt_quality_of_service;
 
-enum {
-  UNACCEPTABLE_PROTOCOL = 1,
-  BAD_IDENTIFIER = 2,
-  SERVER_UNAVIABLE = 3,
-  BAD_CREDENTIALS = 4,
-  UNAUTHORISED = 5
-} iotjs_mqtt_connection_error;
-
 /*
  * First byte of the message's fixed header.
  * Contains:
@@ -127,4 +131,9 @@ enum {
   MQTT_FLAG_USERNAME = 1 << 7
 } iotjs_mqtt_connect_flag_t;
 
+typedef struct {
+  char *buffer;
+  uint32_t buffer_length;
+} iotjs_mqttclient_t;
+
 #endif /* IOTJS_MODULE_MQTT_H */
index ec4dc5a8b66938315656d1cd8588882faed24435..90af5a2900f872e9e105cc6f60d93a116e308c43 100644 (file)
@@ -20,6 +20,7 @@
 #include "iotjs_module_pwm.h"
 #include "iotjs_module_spi.h"
 #include "iotjs_module_uart.h"
+#include "iotjs_uv_request.h"
 
 const char* iotjs_periph_error_str(uint8_t op) {
   switch (op) {
@@ -88,18 +89,21 @@ const char* iotjs_periph_error_str(uint8_t op) {
 }
 
 static void after_worker(uv_work_t* work_req, int status) {
-  iotjs_periph_reqwrap_t* reqwrap =
-      (iotjs_periph_reqwrap_t*)iotjs_reqwrap_from_request((uv_req_t*)work_req);
+  iotjs_periph_data_t* worker_data =
+      (iotjs_periph_data_t*)IOTJS_UV_REQUEST_EXTRA_DATA(work_req);
 
-  iotjs_jargs_t jargs = iotjs_jargs_create(2);
+  size_t jargc = 0;
+  jerry_value_t jargs[2] = { 0 };
 
   if (status) {
-    iotjs_jargs_append_error(&jargs, "System error");
+    jargs[jargc++] = iotjs_jval_create_error_without_error_flag("System error");
   } else {
-    if (!reqwrap->result) {
-      iotjs_jargs_append_error(&jargs, iotjs_periph_error_str(reqwrap->op));
+    if (!worker_data->result) {
+      jargs[jargc++] = iotjs_jval_create_error_without_error_flag(
+          iotjs_periph_error_str(worker_data->op));
     } else {
-      switch (reqwrap->op) {
+      jargs[jargc++] = jerry_create_null();
+      switch (worker_data->op) {
         case kAdcOpClose:
         case kAdcOpOpen:
         case kGpioOpClose:
@@ -119,37 +123,27 @@ static void after_worker(uv_work_t* work_req, int status) {
         case kUartOpClose:
         case kUartOpOpen:
         case kUartOpWrite: {
-          iotjs_jargs_append_null(&jargs);
           break;
         }
         case kAdcOpRead: {
 #if ENABLE_MODULE_ADC
-          iotjs_adc_t* adc = (iotjs_adc_t*)reqwrap->data;
-
-          iotjs_jargs_append_null(&jargs);
-          iotjs_jargs_append_number(&jargs, adc->value);
+          iotjs_adc_t* adc = (iotjs_adc_t*)worker_data->data;
+          jargs[jargc++] = jerry_create_number(adc->value);
 #endif /* ENABLE_MODULE_ADC */
           break;
         }
         case kGpioOpRead: {
 #if ENABLE_MODULE_GPIO
-          iotjs_gpio_t* gpio = (iotjs_gpio_t*)reqwrap->data;
-
-          iotjs_jargs_append_null(&jargs);
-          iotjs_jargs_append_bool(&jargs, gpio->value);
+          iotjs_gpio_t* gpio = (iotjs_gpio_t*)worker_data->data;
+          jargs[jargc++] = jerry_create_boolean(gpio->value);
 #endif /* ENABLE_MODULE_GPIO */
           break;
         }
         case kI2cOpRead: {
 #if ENABLE_MODULE_I2C
-          iotjs_i2c_t* i2c = (iotjs_i2c_t*)reqwrap->data;
-
-          iotjs_jargs_append_null(&jargs);
-          jerry_value_t result =
+          iotjs_i2c_t* i2c = (iotjs_i2c_t*)worker_data->data;
+          jargs[jargc++] =
               iotjs_jval_create_byte_array(i2c->buf_len, i2c->buf_data);
-          iotjs_jargs_append_jval(&jargs, result);
-          jerry_release_value(result);
-
           IOTJS_RELEASE(i2c->buf_data);
 #endif /* ENABLE_MODULE_I2C */
           break;
@@ -157,16 +151,10 @@ static void after_worker(uv_work_t* work_req, int status) {
         case kSpiOpTransferArray:
         case kSpiOpTransferBuffer: {
 #if ENABLE_MODULE_SPI
-          iotjs_spi_t* spi = (iotjs_spi_t*)reqwrap->data;
-
-          iotjs_jargs_append_null(&jargs);
-
+          iotjs_spi_t* spi = (iotjs_spi_t*)worker_data->data;
           // Append read data
-          jerry_value_t result =
+          jargs[jargc++] =
               iotjs_jval_create_byte_array(spi->buf_len, spi->rx_buf_data);
-          iotjs_jargs_append_jval(&jargs, result);
-          jerry_release_value(result);
-
           IOTJS_RELEASE(spi->rx_buf_data);
 #endif /* ENABLE_MODULE_SPI */
           break;
@@ -178,42 +166,42 @@ static void after_worker(uv_work_t* work_req, int status) {
       }
     }
 #if ENABLE_MODULE_SPI
-    if (reqwrap->op == kSpiOpTransferArray) {
-      iotjs_spi_t* spi = (iotjs_spi_t*)reqwrap->data;
+    if (worker_data->op == kSpiOpTransferArray) {
+      iotjs_spi_t* spi = (iotjs_spi_t*)worker_data->data;
       IOTJS_RELEASE(spi->tx_buf_data);
     }
 #endif /* ENABLE_MODULE_SPI */
 #if ENABLE_MODULE_UART
-    if (reqwrap->op == kUartOpWrite) {
-      iotjs_uart_t* uart = (iotjs_uart_t*)reqwrap->data;
+    if (worker_data->op == kUartOpWrite) {
+      iotjs_uart_t* uart = (iotjs_uart_t*)worker_data->data;
       iotjs_string_destroy(&uart->buf_data);
     }
 #endif /* ENABLE_MODULE_UART */
   }
 
-  jerry_value_t jcallback = iotjs_reqwrap_jcallback(&reqwrap->reqwrap);
+  jerry_value_t jcallback = *IOTJS_UV_REQUEST_JSCALLBACK(work_req);
   if (jerry_value_is_function(jcallback)) {
-    iotjs_make_callback(jcallback, jerry_create_undefined(), &jargs);
+    iotjs_invoke_callback(jcallback, jerry_create_undefined(), jargs, jargc);
   }
 
-  iotjs_jargs_destroy(&jargs);
-  iotjs_reqwrap_destroy(&reqwrap->reqwrap);
-  IOTJS_RELEASE(reqwrap);
-}
+  for (size_t i = 0; i < jargc; i++) {
+    jerry_release_value(jargs[i]);
+  }
 
-static iotjs_periph_reqwrap_t* reqwrap_create(const jerry_value_t jcallback,
-                                              void* data, uint8_t op) {
-  iotjs_periph_reqwrap_t* reqwrap = IOTJS_ALLOC(iotjs_periph_reqwrap_t);
-  iotjs_reqwrap_initialize((iotjs_reqwrap_t*)reqwrap, jcallback,
-                           (uv_req_t*)&reqwrap->req);
-  reqwrap->op = op;
-  reqwrap->data = data;
-  return (iotjs_periph_reqwrap_t*)reqwrap;
+  iotjs_uv_request_destroy((uv_req_t*)work_req);
 }
 
+
 void iotjs_periph_call_async(void* data, jerry_value_t jcallback, uint8_t op,
                              uv_work_cb worker) {
   uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get());
-  iotjs_periph_reqwrap_t* req_wrap = reqwrap_create(jcallback, data, op);
-  uv_queue_work(loop, &req_wrap->req, worker, after_worker);
+
+  uv_req_t* work_req = iotjs_uv_request_create(sizeof(uv_work_t), jcallback,
+                                               sizeof(iotjs_periph_data_t));
+  iotjs_periph_data_t* worker_data =
+      (iotjs_periph_data_t*)IOTJS_UV_REQUEST_EXTRA_DATA(work_req);
+  worker_data->op = op;
+  worker_data->data = data;
+
+  uv_queue_work(loop, (uv_work_t*)work_req, worker, after_worker);
 }
index 1f6fd3d2375cefa4357358fd5d70674385e4f78c..ec29ac6466434a4bf3c824cb3caec507da56bb92 100644 (file)
@@ -17,7 +17,6 @@
 #define IOTJS_MODULE_PERIPH_COMMON_H
 
 #include "iotjs_def.h"
-#include "iotjs_reqwrap.h"
 
 typedef enum {
   kAdcOpOpen,
@@ -47,12 +46,10 @@ typedef enum {
 } iotjs_periph_op_t;
 
 typedef struct {
-  iotjs_reqwrap_t reqwrap; /* Note: must be the first */
-  uv_work_t req;
   uint8_t op;
   bool result;
   void* data;
-} iotjs_periph_reqwrap_t;
+} iotjs_periph_data_t;
 
 const char* iotjs_periph_error_str(uint8_t op);
 void iotjs_periph_call_async(void* type_p, jerry_value_t jcallback, uint8_t op,
index 157fc3923dee7b82793309cdd4d7aff9e1f70ce1..6fe080325857546c3a032c85e2a7a192d06df7a1 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include "iotjs_def.h"
+#include "iotjs_compatibility.h"
 #include "iotjs_js.h"
 #include "jerryscript-debugger.h"
 
@@ -40,11 +41,13 @@ JS_FUNCTION(Compile) {
   iotjs_string_t source = JS_GET_ARG(1, string);
 
   const char* filename = iotjs_string_data(&file);
-  const iotjs_environment_t* env = iotjs_environment_get();
 
+#ifdef JERRY_DEBUGGER
+  const iotjs_environment_t* env = iotjs_environment_get();
   if (iotjs_environment_config(env)->debugger != NULL) {
     jerry_debugger_stop();
   }
+#endif
 
   jerry_value_t jres =
       WrapEval(filename, strlen(filename), iotjs_string_data(&source),
@@ -57,6 +60,7 @@ JS_FUNCTION(Compile) {
 }
 
 
+#ifdef JERRY_DEBUGGER
 // Callback function for DebuggerGetSource
 static jerry_value_t wait_for_source_callback(
     const jerry_char_t* resource_name_p, size_t resource_name_size,
@@ -102,6 +106,7 @@ JS_FUNCTION(DebuggerGetSource) {
 
   return ret_val;
 }
+#endif
 
 
 JS_FUNCTION(CompileModule) {
@@ -128,23 +133,25 @@ JS_FUNCTION(CompileModule) {
   }
 
   jerry_value_t native_module_jval = iotjs_module_get(name);
-  if (jerry_value_has_error_flag(native_module_jval)) {
+
+  if (jerry_value_is_error(native_module_jval)) {
+    iotjs_string_destroy(&id);
     return native_module_jval;
   }
 
-  jerry_value_t jexports = iotjs_jval_get_property(jmodule, "exports");
   jerry_value_t jres = jerry_create_undefined();
 
   if (js_modules[i].name != NULL) {
 #ifdef ENABLE_SNAPSHOT
-    jres = jerry_exec_snapshot((const void*)iotjs_js_modules_s,
-                               iotjs_js_modules_l, js_modules[i].idx, 0);
+    jres = jerry_exec_snapshot((const uint32_t*)iotjs_js_modules_s,
+                               iotjs_js_modules_l, js_modules[i].idx,
+                               JERRY_SNAPSHOT_EXEC_ALLOW_STATIC);
 #else
     jres = WrapEval(name, iotjs_string_size(&id),
                     (const char*)js_modules[i].code, js_modules[i].length);
 #endif
-
-    if (!jerry_value_has_error_flag(jres)) {
+    if (!jerry_value_is_error(jres)) {
+      jerry_value_t jexports = iotjs_jval_get_property(jmodule, "exports");
       jerry_value_t args[] = { jexports, jrequire, jmodule,
                                native_module_jval };
 
@@ -152,15 +159,16 @@ JS_FUNCTION(CompileModule) {
       jres = jerry_call_function(jfunc, jerry_create_undefined(), args,
                                  sizeof(args) / sizeof(jerry_value_t));
       jerry_release_value(jfunc);
+      jerry_release_value(jexports);
     }
   } else if (!jerry_value_is_undefined(native_module_jval)) {
     iotjs_jval_set_property_jval(jmodule, "exports", native_module_jval);
   } else {
-    jres = iotjs_jval_create_error_without_error_flag("Unknown native module");
+    jres = JS_CREATE_ERROR(COMMON, "Unknown native module");
   }
 
-  jerry_release_value(jexports);
   iotjs_string_destroy(&id);
+
   return jres;
 }
 
@@ -252,8 +260,10 @@ static void SetProcessEnv(jerry_value_t process) {
 
   iotjspath = getenv(IOTJS_MAGIC_STRING_IOTJS_PATH_U);
   if (iotjspath == NULL) {
-#if defined(__NUTTX__) || defined(__TIZENRT__)
+#if defined(__NUTTX__)
     iotjspath = "/mnt/sdcard";
+#elif defined(__TIZENRT__)
+    iotjspath = "/rom";
 #else
     iotjspath = "";
 #endif
@@ -336,6 +346,7 @@ static void SetProcessPrivate(jerry_value_t process, bool wait_source) {
                         CompileModule);
   iotjs_jval_set_method(private, IOTJS_MAGIC_STRING_READSOURCE, ReadSource);
 
+#ifdef JERRY_DEBUGGER
   // debugger
   iotjs_jval_set_method(private, IOTJS_MAGIC_STRING_DEBUGGERGETSOURCE,
                         DebuggerGetSource);
@@ -345,6 +356,8 @@ static void SetProcessPrivate(jerry_value_t process, bool wait_source) {
                                wait_source_val);
 
   jerry_release_value(wait_source_val);
+#endif
+
   jerry_release_value(private);
 }
 
@@ -379,10 +392,12 @@ jerry_value_t InitProcess() {
   // Set iotjs
   SetProcessIotjs(process);
   bool wait_source = false;
+#ifdef JERRY_DEBUGGER
   if (iotjs_environment_config(iotjs_environment_get())->debugger != NULL) {
     wait_source = iotjs_environment_config(iotjs_environment_get())
                       ->debugger->wait_source;
   }
+#endif
 
   if (!wait_source) {
     SetProcessArgv(process);
index 365f1ae89b1b9f710176485eb130cd5826fa893e..dc61daaac5886456985c6f545f53ad66b6ed05bd 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "iotjs_def.h"
 #include "iotjs_module_pwm.h"
+#include "iotjs_uv_request.h"
 
 
 IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(pwm);
@@ -28,27 +29,26 @@ static void iotjs_pwm_destroy(iotjs_pwm_t* pwm) {
 }
 
 static void pwm_worker(uv_work_t* work_req) {
-  iotjs_periph_reqwrap_t* req_wrap =
-      (iotjs_periph_reqwrap_t*)(iotjs_reqwrap_from_request(
-          (uv_req_t*)work_req));
-  iotjs_pwm_t* pwm = (iotjs_pwm_t*)req_wrap->data;
+  iotjs_periph_data_t* worker_data =
+      (iotjs_periph_data_t*)IOTJS_UV_REQUEST_EXTRA_DATA(work_req);
+  iotjs_pwm_t* pwm = (iotjs_pwm_t*)worker_data->data;
 
-  switch (req_wrap->op) {
+  switch (worker_data->op) {
     case kPwmOpClose:
-      req_wrap->result = iotjs_pwm_close(pwm);
+      worker_data->result = iotjs_pwm_close(pwm);
       break;
     case kPwmOpOpen:
-      req_wrap->result = iotjs_pwm_open(pwm);
+      worker_data->result = iotjs_pwm_open(pwm);
       break;
     case kPwmOpSetDutyCycle:
-      req_wrap->result = iotjs_pwm_set_dutycycle(pwm);
+      worker_data->result = iotjs_pwm_set_dutycycle(pwm);
       break;
     case kPwmOpSetEnable:
-      req_wrap->result = iotjs_pwm_set_enable(pwm);
+      worker_data->result = iotjs_pwm_set_enable(pwm);
       break;
     case kPwmOpSetFrequency: /* update the period */
     case kPwmOpSetPeriod:
-      req_wrap->result = iotjs_pwm_set_period(pwm);
+      worker_data->result = iotjs_pwm_set_period(pwm);
       break;
     default:
       IOTJS_ASSERT(!"Invalid Operation");
@@ -87,13 +87,13 @@ JS_FUNCTION(PwmCons) {
   JS_GET_REQUIRED_ARG_VALUE(0, jconfig, IOTJS_MAGIC_STRING_CONFIG, object);
 
   jerry_value_t res = iotjs_pwm_set_platform_config(pwm, jconfig);
-  if (jerry_value_has_error_flag(res)) {
+  if (jerry_value_is_error(res)) {
     return res;
   }
   IOTJS_ASSERT(jerry_value_is_undefined(res));
 
   res = pwm_set_configuration(pwm, jconfig);
-  if (jerry_value_has_error_flag(res)) {
+  if (jerry_value_is_error(res)) {
     return res;
   }
   IOTJS_ASSERT(jerry_value_is_undefined(res));
index f11fd6ec5d500b17012d4547cfb067204ddbeb93..728d1b9ab0599ee55b41ba68e16f589a9baba637 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "iotjs_def.h"
 #include "iotjs_module_periph_common.h"
-#include "iotjs_reqwrap.h"
 
 #if defined(__TIZENRT__)
 #include <iotbus_pwm.h>
index 4169a6f91a5cdf67362a1612f3a39a78b3faefb0..c7ad7392e0def2d80c2b5f60000629be0800eb80 100644 (file)
@@ -16,6 +16,7 @@
 #include "iotjs_def.h"
 #include "iotjs_module_spi.h"
 #include "iotjs_module_buffer.h"
+#include "iotjs_uv_request.h"
 
 
 IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(spi);
@@ -163,23 +164,22 @@ static jerry_value_t spi_set_configuration(iotjs_spi_t* spi,
  * SPI worker function
  */
 static void spi_worker(uv_work_t* work_req) {
-  iotjs_periph_reqwrap_t* req_wrap =
-      (iotjs_periph_reqwrap_t*)(iotjs_reqwrap_from_request(
-          (uv_req_t*)work_req));
-  iotjs_spi_t* spi = (iotjs_spi_t*)req_wrap->data;
+  iotjs_periph_data_t* worker_data =
+      (iotjs_periph_data_t*)IOTJS_UV_REQUEST_EXTRA_DATA(work_req);
+  iotjs_spi_t* spi = (iotjs_spi_t*)worker_data->data;
 
-  switch (req_wrap->op) {
+  switch (worker_data->op) {
     case kSpiOpClose: {
-      req_wrap->result = iotjs_spi_close(spi);
+      worker_data->result = iotjs_spi_close(spi);
       break;
     }
     case kSpiOpOpen: {
-      req_wrap->result = iotjs_spi_open(spi);
+      worker_data->result = iotjs_spi_open(spi);
       break;
     }
     case kSpiOpTransferArray:
     case kSpiOpTransferBuffer: {
-      req_wrap->result = iotjs_spi_transfer(spi);
+      worker_data->result = iotjs_spi_transfer(spi);
       break;
     }
     default:
@@ -201,13 +201,13 @@ JS_FUNCTION(SpiCons) {
   JS_GET_REQUIRED_ARG_VALUE(0, jconfig, IOTJS_MAGIC_STRING_CONFIG, object);
 
   jerry_value_t res = iotjs_spi_set_platform_config(spi, jconfig);
-  if (jerry_value_has_error_flag(res)) {
+  if (jerry_value_is_error(res)) {
     return res;
   }
   IOTJS_ASSERT(jerry_value_is_undefined(res));
 
   res = spi_set_configuration(spi, jconfig);
-  if (jerry_value_has_error_flag(res)) {
+  if (jerry_value_is_error(res)) {
     return res;
   }
   IOTJS_ASSERT(jerry_value_is_undefined(res));
index fb7e90a2e6c07cb09993d051f2d6e90b63c1c3b6..2eb2eb386766b5bfcd69bf4f65ce2cc06d848a5f 100644 (file)
@@ -20,7 +20,6 @@
 #include "iotjs_def.h"
 #include "iotjs_module_buffer.h"
 #include "iotjs_module_periph_common.h"
-#include "iotjs_reqwrap.h"
 
 
 typedef enum {
index 3b37b3a9d8193544b736b4449334d5f603f3b64c..48566b1de84a00507d2f037549d34a68f48c95be 100644 (file)
 #include "iotjs_def.h"
 #include "iotjs_module_tcp.h"
 
-#include "iotjs_handlewrap.h"
 #include "iotjs_module_buffer.h"
-#include "iotjs_reqwrap.h"
+#include "iotjs_uv_handle.h"
+#include "iotjs_uv_request.h"
 
+static const jerry_object_native_info_t this_module_native_info = { NULL };
 
-IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(tcpwrap);
 
-
-iotjs_tcpwrap_t* iotjs_tcpwrap_create(jerry_value_t jtcp) {
-  iotjs_tcpwrap_t* tcpwrap = IOTJS_ALLOC(iotjs_tcpwrap_t);
-
-  iotjs_handlewrap_initialize(&tcpwrap->handlewrap, jtcp,
-                              (uv_handle_t*)(&tcpwrap->handle),
-                              &this_module_native_info);
+void iotjs_tcp_object_init(jerry_value_t jtcp) {
+  // uv_tcp_t* can be handled as uv_handle_t* or even as uv_stream_t*
+  uv_handle_t* handle = iotjs_uv_handle_create(sizeof(uv_tcp_t), jtcp,
+                                               &this_module_native_info, 0);
 
   const iotjs_environment_t* env = iotjs_environment_get();
-  uv_tcp_init(iotjs_environment_loop(env), &tcpwrap->handle);
-
-  return tcpwrap;
-}
-
-
-static void iotjs_tcpwrap_destroy(iotjs_tcpwrap_t* tcpwrap) {
-  iotjs_handlewrap_destroy(&tcpwrap->handlewrap);
-  IOTJS_RELEASE(tcpwrap);
-}
-
-
-iotjs_tcpwrap_t* iotjs_tcpwrap_from_handle(uv_tcp_t* tcp_handle) {
-  uv_handle_t* handle = (uv_handle_t*)(tcp_handle);
-  iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_handle(handle);
-  iotjs_tcpwrap_t* tcpwrap = (iotjs_tcpwrap_t*)handlewrap;
-  IOTJS_ASSERT(iotjs_tcpwrap_tcp_handle(tcpwrap) == tcp_handle);
-  return tcpwrap;
-}
-
-
-iotjs_tcpwrap_t* iotjs_tcpwrap_from_jobject(jerry_value_t jtcp) {
-  iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_jobject(jtcp);
-  return (iotjs_tcpwrap_t*)handlewrap;
-}
-
-
-uv_tcp_t* iotjs_tcpwrap_tcp_handle(iotjs_tcpwrap_t* tcpwrap) {
-  uv_handle_t* handle = iotjs_handlewrap_get_uv_handle(&tcpwrap->handlewrap);
-  return (uv_tcp_t*)handle;
-}
-
-
-static void iotjs_connect_reqwrap_destroy(
-    iotjs_connect_reqwrap_t* connect_reqwrap);
-
-
-iotjs_connect_reqwrap_t* iotjs_connect_reqwrap_create(jerry_value_t jcallback) {
-  iotjs_connect_reqwrap_t* connect_reqwrap =
-      IOTJS_ALLOC(iotjs_connect_reqwrap_t);
-  iotjs_reqwrap_initialize(&connect_reqwrap->reqwrap, jcallback,
-                           (uv_req_t*)&connect_reqwrap->req);
-  return connect_reqwrap;
+  uv_tcp_init(iotjs_environment_loop(env), (uv_tcp_t*)handle);
 }
 
 
-static void iotjs_connect_reqwrap_destroy(
-    iotjs_connect_reqwrap_t* connect_reqwrap) {
-  iotjs_reqwrap_destroy(&connect_reqwrap->reqwrap);
-  IOTJS_RELEASE(connect_reqwrap);
-}
-
-
-static void iotjs_write_reqwrap_destroy(iotjs_write_reqwrap_t* write_reqwrap);
-
-
-iotjs_write_reqwrap_t* iotjs_write_reqwrap_create(jerry_value_t jcallback) {
-  iotjs_write_reqwrap_t* write_reqwrap = IOTJS_ALLOC(iotjs_write_reqwrap_t);
-  iotjs_reqwrap_initialize(&write_reqwrap->reqwrap, jcallback,
-                           (uv_req_t*)&write_reqwrap->req);
-  return write_reqwrap;
-}
-
-
-static void iotjs_write_reqwrap_destroy(iotjs_write_reqwrap_t* write_reqwrap) {
-  iotjs_reqwrap_destroy(&write_reqwrap->reqwrap);
-  IOTJS_RELEASE(write_reqwrap);
-}
-
-static void iotjs_shutdown_reqwrap_destroy(
-    iotjs_shutdown_reqwrap_t* shutdown_reqwrap);
+static void iotjs_tcp_report_req_result(uv_req_t* req, int status) {
+  IOTJS_ASSERT(req != NULL);
+  // Take callback function object.
+  jerry_value_t jcallback = *IOTJS_UV_REQUEST_JSCALLBACK(req);
 
+  // Only parameter is status code.
+  jerry_value_t jstatus = jerry_create_number(status);
 
-iotjs_shutdown_reqwrap_t* iotjs_shutdown_reqwrap_create(
-    jerry_value_t jcallback) {
-  iotjs_shutdown_reqwrap_t* shutdown_reqwrap =
-      IOTJS_ALLOC(iotjs_shutdown_reqwrap_t);
-  iotjs_reqwrap_initialize(&shutdown_reqwrap->reqwrap, jcallback,
-                           (uv_req_t*)&shutdown_reqwrap->req);
-  return shutdown_reqwrap;
-}
+  // Make callback.
+  iotjs_invoke_callback(jcallback, jerry_create_undefined(), &jstatus, 1);
 
+  // Destroy args
+  jerry_release_value(jstatus);
 
-static void iotjs_shutdown_reqwrap_destroy(
-    iotjs_shutdown_reqwrap_t* shutdown_reqwrap) {
-  iotjs_reqwrap_destroy(&shutdown_reqwrap->reqwrap);
-  IOTJS_RELEASE(shutdown_reqwrap);
+  // Release request.
+  iotjs_uv_request_destroy(req);
 }
 
 
@@ -127,24 +57,20 @@ JS_FUNCTION(TCP) {
   DJS_CHECK_THIS();
 
   jerry_value_t jtcp = JS_GET_THIS();
-  iotjs_tcpwrap_create(jtcp);
+  iotjs_tcp_object_init(jtcp);
   return jerry_create_undefined();
 }
 
 
 // Socket close result handler.
 void AfterClose(uv_handle_t* handle) {
-  iotjs_handlewrap_t* wrap = iotjs_handlewrap_from_handle(handle);
-
-  // tcp object.
-  jerry_value_t jtcp = iotjs_handlewrap_jobject(wrap);
+  jerry_value_t jtcp = IOTJS_UV_HANDLE_DATA(handle)->jobject;
 
   // callback function.
   jerry_value_t jcallback =
       iotjs_jval_get_property(jtcp, IOTJS_MAGIC_STRING_ONCLOSE);
   if (jerry_value_is_function(jcallback)) {
-    iotjs_make_callback(jcallback, jerry_create_undefined(),
-                        iotjs_jargs_get_empty());
+    iotjs_invoke_callback(jcallback, jerry_create_undefined(), NULL, 0);
   }
   jerry_release_value(jcallback);
 }
@@ -152,10 +78,9 @@ void AfterClose(uv_handle_t* handle) {
 
 // Close socket
 JS_FUNCTION(Close) {
-  JS_DECLARE_THIS_PTR(handlewrap, wrap);
+  JS_DECLARE_PTR(jthis, uv_handle_t, uv_handle);
 
-  // close uv handle, `AfterClose` will be called after socket closed.
-  iotjs_handlewrap_close(wrap, AfterClose);
+  iotjs_uv_handle_close(uv_handle, AfterClose);
   return jerry_create_undefined();
 }
 
@@ -165,7 +90,7 @@ JS_FUNCTION(Close) {
 // [0] address
 // [1] port
 JS_FUNCTION(Bind) {
-  JS_DECLARE_THIS_PTR(tcpwrap, tcp_wrap);
+  JS_DECLARE_PTR(jthis, uv_tcp_t, tcp_handle);
 
   DJS_CHECK_ARGS(2, string, number);
 
@@ -176,8 +101,7 @@ JS_FUNCTION(Bind) {
   int err = uv_ip4_addr(iotjs_string_data(&address), port, &addr);
 
   if (err == 0) {
-    err = uv_tcp_bind(iotjs_tcpwrap_tcp_handle(tcp_wrap),
-                      (const sockaddr*)(&addr), 0);
+    err = uv_tcp_bind(tcp_handle, (const sockaddr*)(&addr), 0);
   }
 
   iotjs_string_destroy(&address);
@@ -188,35 +112,15 @@ JS_FUNCTION(Bind) {
 
 // Connection request result handler.
 static void AfterConnect(uv_connect_t* req, int status) {
-  iotjs_connect_reqwrap_t* req_wrap = (iotjs_connect_reqwrap_t*)(req->data);
-  IOTJS_ASSERT(req_wrap != NULL);
-
-  // Take callback function object.
-  // function afterConnect(status)
-  jerry_value_t jcallback = iotjs_reqwrap_jcallback(&req_wrap->reqwrap);
-  IOTJS_ASSERT(jerry_value_is_function(jcallback));
-
-  // Only parameter is status code.
-  iotjs_jargs_t args = iotjs_jargs_create(1);
-  iotjs_jargs_append_number(&args, status);
-
-  // Make callback.
-  iotjs_make_callback(jcallback, jerry_create_undefined(), &args);
-
-  // Destroy args
-  iotjs_jargs_destroy(&args);
-
-  // Release request wrapper.
-  iotjs_connect_reqwrap_destroy(req_wrap);
+  iotjs_tcp_report_req_result((uv_req_t*)req, status);
 }
 
-
 // Create a connection using the socket.
 // [0] address
 // [1] port
 // [2] callback
 JS_FUNCTION(Connect) {
-  JS_DECLARE_THIS_PTR(tcpwrap, tcp_wrap);
+  JS_DECLARE_PTR(jthis, uv_tcp_t, tcp_handle);
 
   DJS_CHECK_ARGS(3, string, number, function);
 
@@ -228,15 +132,16 @@ JS_FUNCTION(Connect) {
   int err = uv_ip4_addr(iotjs_string_data(&address), port, &addr);
 
   if (err == 0) {
-    // Create connection request wrapper.
-    iotjs_connect_reqwrap_t* req_wrap = iotjs_connect_reqwrap_create(jcallback);
+    // Create connection request and configure request data.
+    uv_req_t* req_connect =
+        iotjs_uv_request_create(sizeof(uv_connect_t), jcallback, 0);
 
     // Create connection request.
-    err = uv_tcp_connect(&req_wrap->req, iotjs_tcpwrap_tcp_handle(tcp_wrap),
+    err = uv_tcp_connect((uv_connect_t*)req_connect, tcp_handle,
                          (const sockaddr*)(&addr), AfterConnect);
 
     if (err) {
-      iotjs_connect_reqwrap_destroy(req_wrap);
+      iotjs_uv_request_destroy(req_connect);
     }
   }
 
@@ -251,11 +156,7 @@ JS_FUNCTION(Connect) {
 //   * uv_stream_t* handle - server handle
 //   * int status - status code
 static void OnConnection(uv_stream_t* handle, int status) {
-  // Server tcp wrapper.
-  iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_handle((uv_tcp_t*)handle);
-
-  // Tcp object
-  jerry_value_t jtcp = iotjs_handlewrap_jobject(&tcp_wrap->handlewrap);
+  jerry_value_t jtcp = IOTJS_UV_HANDLE_DATA(handle)->jobject;
 
   // `onconnection` callback.
   jerry_value_t jonconnection =
@@ -265,8 +166,8 @@ static void OnConnection(uv_stream_t* handle, int status) {
   // The callback takes two parameter
   // [0] status
   // [1] client tcp object
-  iotjs_jargs_t args = iotjs_jargs_create(2);
-  iotjs_jargs_append_number(&args, status);
+  size_t argc = 1;
+  jerry_value_t args[2] = { jerry_create_number(status), 0 };
 
   if (status == 0) {
     // Create client socket handle wrapper.
@@ -275,74 +176,51 @@ static void OnConnection(uv_stream_t* handle, int status) {
     IOTJS_ASSERT(jerry_value_is_function(jcreate_tcp));
 
     jerry_value_t jclient_tcp =
-        iotjs_jhelper_call(jcreate_tcp, jerry_create_undefined(),
-                           iotjs_jargs_get_empty());
-    IOTJS_ASSERT(!jerry_value_has_error_flag(jclient_tcp));
+        jerry_call_function(jcreate_tcp, jerry_create_undefined(), NULL, 0);
+    IOTJS_ASSERT(!jerry_value_is_error(jclient_tcp));
     IOTJS_ASSERT(jerry_value_is_object(jclient_tcp));
 
-    iotjs_tcpwrap_t* tcp_wrap_client =
-        (iotjs_tcpwrap_t*)(iotjs_jval_get_object_native_handle(jclient_tcp));
+    uv_handle_t* client_handle = (uv_handle_t*)
+        iotjs_jval_get_object_native_handle(jclient_tcp,
+                                            &this_module_native_info);
 
-    uv_stream_t* client_handle =
-        (uv_stream_t*)(iotjs_tcpwrap_tcp_handle(tcp_wrap_client));
-
-    int err = uv_accept(handle, client_handle);
+    int err = uv_accept(handle, (uv_stream_t*)client_handle);
     if (err) {
-      iotjs_jargs_destroy(&args);
+      jerry_release_value(args[0]);
       return;
     }
 
-    iotjs_jargs_append_jval(&args, jclient_tcp);
+    args[argc++] = jclient_tcp;
     jerry_release_value(jcreate_tcp);
-    jerry_release_value(jclient_tcp);
   }
 
-  iotjs_make_callback(jonconnection, jtcp, &args);
+  iotjs_invoke_callback(jonconnection, jtcp, args, argc);
 
   jerry_release_value(jonconnection);
-  iotjs_jargs_destroy(&args);
+  for (size_t i = 0; i < argc; i++) {
+    jerry_release_value(args[i]);
+  }
 }
 
 
 JS_FUNCTION(Listen) {
-  JS_DECLARE_THIS_PTR(tcpwrap, tcp_wrap);
+  JS_DECLARE_PTR(jthis, uv_tcp_t, tcp_handle);
   DJS_CHECK_ARGS(1, number);
 
   int backlog = JS_GET_ARG(0, number);
-
-  int err = uv_listen((uv_stream_t*)(iotjs_tcpwrap_tcp_handle(tcp_wrap)),
-                      backlog, OnConnection);
+  int err = uv_listen((uv_stream_t*)tcp_handle, backlog, OnConnection);
 
   return jerry_create_number(err);
 }
 
 
 void AfterWrite(uv_write_t* req, int status) {
-  iotjs_write_reqwrap_t* req_wrap = (iotjs_write_reqwrap_t*)(req->data);
-  iotjs_tcpwrap_t* tcp_wrap = (iotjs_tcpwrap_t*)(req->handle->data);
-  IOTJS_ASSERT(req_wrap != NULL);
-  IOTJS_ASSERT(tcp_wrap != NULL);
-
-  // Take callback function object.
-  jerry_value_t jcallback = iotjs_reqwrap_jcallback(&req_wrap->reqwrap);
-
-  // Only parameter is status code.
-  iotjs_jargs_t args = iotjs_jargs_create(1);
-  iotjs_jargs_append_number(&args, status);
-
-  // Make callback.
-  iotjs_make_callback(jcallback, jerry_create_undefined(), &args);
-
-  // Destroy args
-  iotjs_jargs_destroy(&args);
-
-  // Release request wrapper.
-  iotjs_write_reqwrap_destroy(req_wrap);
+  iotjs_tcp_report_req_result((uv_req_t*)req, status);
 }
 
 
 JS_FUNCTION(Write) {
-  JS_DECLARE_THIS_PTR(tcpwrap, tcp_wrap);
+  JS_DECLARE_PTR(jthis, uv_stream_t, tcp_handle);
   DJS_CHECK_ARGS(2, object, function);
 
   const jerry_value_t jbuffer = JS_GET_ARG(0, object);
@@ -354,14 +232,12 @@ JS_FUNCTION(Write) {
   buf.len = len;
 
   jerry_value_t arg1 = JS_GET_ARG(1, object);
-  iotjs_write_reqwrap_t* req_wrap = iotjs_write_reqwrap_create(arg1);
+  uv_req_t* req_write = iotjs_uv_request_create(sizeof(uv_write_t), arg1, 0);
 
-  int err = uv_write(&req_wrap->req,
-                     (uv_stream_t*)(iotjs_tcpwrap_tcp_handle(tcp_wrap)), &buf,
-                     1, AfterWrite);
+  int err = uv_write((uv_write_t*)req_write, tcp_handle, &buf, 1, AfterWrite);
 
   if (err) {
-    iotjs_write_reqwrap_destroy(req_wrap);
+    iotjs_uv_request_destroy((uv_req_t*)req_write);
   }
 
   return jerry_create_number(err);
@@ -379,10 +255,7 @@ void OnAlloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
 
 
 void OnRead(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
-  iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_handle((uv_tcp_t*)handle);
-
-  // tcp handle
-  jerry_value_t jtcp = iotjs_handlewrap_jobject(&tcp_wrap->handlewrap);
+  jerry_value_t jtcp = IOTJS_UV_HANDLE_DATA(handle)->jobject;
 
   // socket object
   jerry_value_t jsocket =
@@ -394,20 +267,19 @@ void OnRead(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
       iotjs_jval_get_property(jtcp, IOTJS_MAGIC_STRING_ONREAD);
   IOTJS_ASSERT(jerry_value_is_function(jonread));
 
-  iotjs_jargs_t jargs = iotjs_jargs_create(4);
-  iotjs_jargs_append_jval(&jargs, jsocket);
-  iotjs_jargs_append_number(&jargs, nread);
-  iotjs_jargs_append_bool(&jargs, false);
+  size_t argc = 3;
+  jerry_value_t jargs[4] = { jsocket, jerry_create_number(nread),
+                             jerry_create_boolean(false), 0 };
 
   if (nread <= 0) {
     iotjs_buffer_release(buf->base);
 
     if (nread < 0) {
       if (nread == UV__EOF) {
-        iotjs_jargs_replace(&jargs, 2, jerry_create_boolean(true));
+        jargs[2] = jerry_create_boolean(true);
       }
 
-      iotjs_make_callback(jonread, jerry_create_undefined(), &jargs);
+      iotjs_invoke_callback(jonread, jerry_create_undefined(), jargs, argc);
     }
   } else {
     jerry_value_t jbuffer = iotjs_bufferwrap_create_buffer((size_t)nread);
@@ -415,64 +287,46 @@ void OnRead(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
 
     iotjs_bufferwrap_copy(buffer_wrap, buf->base, (size_t)nread);
 
-    iotjs_jargs_append_jval(&jargs, jbuffer);
-    iotjs_make_callback(jonread, jerry_create_undefined(), &jargs);
+    jargs[argc++] = jbuffer;
+    iotjs_invoke_callback(jonread, jerry_create_undefined(), jargs, argc);
 
-    jerry_release_value(jbuffer);
     iotjs_buffer_release(buf->base);
   }
 
-  iotjs_jargs_destroy(&jargs);
+  for (uint8_t i = 0; i < argc; i++) {
+    jerry_release_value(jargs[i]);
+  }
   jerry_release_value(jonread);
-  jerry_release_value(jsocket);
 }
 
 
 JS_FUNCTION(ReadStart) {
-  JS_DECLARE_THIS_PTR(tcpwrap, tcp_wrap);
+  JS_DECLARE_PTR(jthis, uv_stream_t, tcp_handle);
 
-  int err = uv_read_start((uv_stream_t*)(iotjs_tcpwrap_tcp_handle(tcp_wrap)),
-                          OnAlloc, OnRead);
+  int err = uv_read_start(tcp_handle, OnAlloc, OnRead);
 
   return jerry_create_number(err);
 }
 
 
 static void AfterShutdown(uv_shutdown_t* req, int status) {
-  iotjs_shutdown_reqwrap_t* req_wrap = (iotjs_shutdown_reqwrap_t*)(req->data);
-  iotjs_tcpwrap_t* tcp_wrap = (iotjs_tcpwrap_t*)(req->handle->data);
-  IOTJS_ASSERT(req_wrap != NULL);
-  IOTJS_ASSERT(tcp_wrap != NULL);
-
-  // function onShutdown(status)
-  jerry_value_t jonshutdown = iotjs_reqwrap_jcallback(&req_wrap->reqwrap);
-  IOTJS_ASSERT(jerry_value_is_function(jonshutdown));
-
-  iotjs_jargs_t args = iotjs_jargs_create(1);
-  iotjs_jargs_append_number(&args, status);
-
-  iotjs_make_callback(jonshutdown, jerry_create_undefined(), &args);
-
-  iotjs_jargs_destroy(&args);
-
-  iotjs_shutdown_reqwrap_destroy(req_wrap);
+  iotjs_tcp_report_req_result((uv_req_t*)req, status);
 }
 
 
 JS_FUNCTION(Shutdown) {
-  JS_DECLARE_THIS_PTR(tcpwrap, tcp_wrap);
+  JS_DECLARE_PTR(jthis, uv_stream_t, tcp_handle);
 
   DJS_CHECK_ARGS(1, function);
 
   jerry_value_t arg0 = JS_GET_ARG(0, object);
-  iotjs_shutdown_reqwrap_t* req_wrap = iotjs_shutdown_reqwrap_create(arg0);
+  uv_shutdown_t* req_shutdown =
+      (uv_shutdown_t*)iotjs_uv_request_create(sizeof(uv_shutdown_t), arg0, 0);
 
-  int err = uv_shutdown(&req_wrap->req,
-                        (uv_stream_t*)(iotjs_tcpwrap_tcp_handle(tcp_wrap)),
-                        AfterShutdown);
+  int err = uv_shutdown(req_shutdown, tcp_handle, AfterShutdown);
 
   if (err) {
-    iotjs_shutdown_reqwrap_destroy(req_wrap);
+    iotjs_uv_request_destroy((uv_req_t*)req_shutdown);
   }
 
   return jerry_create_number(err);
@@ -483,14 +337,14 @@ JS_FUNCTION(Shutdown) {
 // [0] enable
 // [1] delay
 JS_FUNCTION(SetKeepAlive) {
-  JS_DECLARE_THIS_PTR(tcpwrap, tcp_wrap);
+  JS_DECLARE_PTR(jthis, uv_tcp_t, tcp_handle);
 
   DJS_CHECK_ARGS(2, number, number);
 
   int enable = JS_GET_ARG(0, number);
   unsigned delay = JS_GET_ARG(1, number);
 
-  int err = uv_tcp_keepalive(iotjs_tcpwrap_tcp_handle(tcp_wrap), enable, delay);
+  int err = uv_tcp_keepalive(tcp_handle, enable, delay);
 
   return jerry_create_number(err);
 }
@@ -543,15 +397,14 @@ void AddressToJS(jerry_value_t obj, const sockaddr* addr) {
 
 
 JS_FUNCTION(GetSockeName) {
-  DJS_CHECK_ARGS(1, object);
+  JS_DECLARE_PTR(jthis, uv_tcp_t, tcp_handle);
 
-  iotjs_tcpwrap_t* wrap = iotjs_tcpwrap_from_jobject(JS_GET_THIS());
-  IOTJS_ASSERT(wrap != NULL);
+  DJS_CHECK_ARGS(1, object);
 
   sockaddr_storage storage;
   int addrlen = sizeof(storage);
   sockaddr* const addr = (sockaddr*)(&storage);
-  int err = uv_tcp_getsockname(iotjs_tcpwrap_tcp_handle(wrap), addr, &addrlen);
+  int err = uv_tcp_getsockname(tcp_handle, addr, &addrlen);
   if (err == 0)
     AddressToJS(JS_GET_ARG(0, object), addr);
   return jerry_create_number(err);
index d2b097e0693a965f4598412772f311eecae311bb..bb9dbb1d64d9ef62b339af0b74bdc4ea40c98c75 100644 (file)
@@ -19,8 +19,6 @@
 
 
 #include "iotjs_binding.h"
-#include "iotjs_handlewrap.h"
-#include "iotjs_reqwrap.h"
 
 
 typedef struct sockaddr sockaddr;
@@ -29,45 +27,6 @@ typedef struct sockaddr_in6 sockaddr_in6;
 typedef struct sockaddr_storage sockaddr_storage;
 
 
-typedef struct {
-  iotjs_handlewrap_t handlewrap;
-  uv_tcp_t handle;
-} iotjs_tcpwrap_t;
-
-
-iotjs_tcpwrap_t* iotjs_tcpwrap_create(jerry_value_t jtcp);
-
-iotjs_tcpwrap_t* iotjs_tcpwrap_from_handle(uv_tcp_t* handle);
-iotjs_tcpwrap_t* iotjs_tcpwrap_from_jobject(jerry_value_t jtcp);
-
-uv_tcp_t* iotjs_tcpwrap_tcp_handle(iotjs_tcpwrap_t* tcpwrap);
-
-
-typedef struct {
-  iotjs_reqwrap_t reqwrap;
-  uv_connect_t req;
-} iotjs_connect_reqwrap_t;
-
-iotjs_connect_reqwrap_t* iotjs_connect_reqwrap_create(jerry_value_t jcallback);
-
-
-typedef struct {
-  iotjs_reqwrap_t reqwrap;
-  uv_write_t req;
-} iotjs_write_reqwrap_t;
-
-iotjs_write_reqwrap_t* iotjs_write_reqwrap_create(jerry_value_t jcallback);
-
-
-typedef struct {
-  iotjs_reqwrap_t reqwrap;
-  uv_shutdown_t req;
-} iotjs_shutdown_reqwrap_t;
-
-iotjs_shutdown_reqwrap_t* iotjs_shutdown_reqwrap_create(
-    jerry_value_t jcallback);
-
-
 void AddressToJS(jerry_value_t obj, const sockaddr* addr);
 
 
index 54b3285a6f03a742e93df2c4de2f8f1656c7a13c..fca9b0391620d7575d71aab8e76cbd3cc93cc05b 100644 (file)
  */
 
 #include "iotjs_def.h"
-#include "iotjs_module_timer.h"
+#include "iotjs_uv_handle.h"
 
 
-static void iotjs_timerwrap_destroy(iotjs_timerwrap_t* timerwrap);
-static void iotjs_timerwrap_on_timeout(iotjs_timerwrap_t* timerwrap);
-IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(timerwrap);
+static const jerry_object_native_info_t this_module_native_info = { NULL };
 
 
-iotjs_timerwrap_t* iotjs_timerwrap_create(const jerry_value_t jtimer) {
-  iotjs_timerwrap_t* timerwrap = IOTJS_ALLOC(iotjs_timerwrap_t);
-  uv_timer_t* uv_timer = IOTJS_ALLOC(uv_timer_t);
+void iotjs_timer_object_init(jerry_value_t jtimer) {
+  uv_handle_t* handle = iotjs_uv_handle_create(sizeof(uv_timer_t), jtimer,
+                                               &this_module_native_info, 0);
 
-  iotjs_handlewrap_initialize(&timerwrap->handlewrap, jtimer,
-                              (uv_handle_t*)(uv_timer),
-                              &this_module_native_info);
-
-  // Initialize timer handler.
   const iotjs_environment_t* env = iotjs_environment_get();
-  uv_timer_init(iotjs_environment_loop(env), uv_timer);
-
-  return timerwrap;
+  uv_timer_init(iotjs_environment_loop(env), (uv_timer_t*)handle);
 }
 
 
-static void iotjs_timerwrap_destroy(iotjs_timerwrap_t* timerwrap) {
-  iotjs_handlewrap_destroy(&timerwrap->handlewrap);
-
-  IOTJS_RELEASE(timerwrap);
-}
-
-static void TimoutHandlerDestroy(uv_handle_t* handle) {
-  IOTJS_RELEASE(handle);
-}
-
-// This function is called from uv when timeout expires.
 static void TimeoutHandler(uv_timer_t* handle) {
-  // Find timer wrap from handle.
-  iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_from_handle(handle);
-
-  // Call the timeout handler.
-  iotjs_timerwrap_on_timeout(timer_wrap);
-}
-
-
-int iotjs_timerwrap_start(iotjs_timerwrap_t* timerwrap, uint64_t timeout,
-                          uint64_t repeat) {
-  // Start uv timer.
-  uv_timer_t* uv_timer =
-      (uv_timer_t*)iotjs_handlewrap_get_uv_handle(&timerwrap->handlewrap);
-  return uv_timer_start(uv_timer, TimeoutHandler, timeout, repeat);
-}
-
-
-int iotjs_timerwrap_stop(iotjs_timerwrap_t* timerwrap) {
-  if (!uv_is_closing(iotjs_handlewrap_get_uv_handle(&timerwrap->handlewrap))) {
-    iotjs_handlewrap_close(&timerwrap->handlewrap, TimoutHandlerDestroy);
-  }
-
-  return 0;
-}
-
+  IOTJS_ASSERT(handle != NULL);
 
-static void iotjs_timerwrap_on_timeout(iotjs_timerwrap_t* timerwrap) {
-  // Call javascript timeout handler function.
-  jerry_value_t jobject = iotjs_timerwrap_jobject(timerwrap);
+  jerry_value_t jobject = IOTJS_UV_HANDLE_DATA(handle)->jobject;
   jerry_value_t jcallback =
       iotjs_jval_get_property(jobject, IOTJS_MAGIC_STRING_HANDLETIMEOUT);
-  iotjs_make_callback(jcallback, jobject, iotjs_jargs_get_empty());
+  iotjs_invoke_callback(jcallback, jobject, NULL, 0);
   jerry_release_value(jcallback);
 }
 
 
-uv_timer_t* iotjs_timerwrap_handle(iotjs_timerwrap_t* timerwrap) {
-  return (uv_timer_t*)iotjs_handlewrap_get_uv_handle(&timerwrap->handlewrap);
-}
-
-
-jerry_value_t iotjs_timerwrap_jobject(iotjs_timerwrap_t* timerwrap) {
-  jerry_value_t jobject = iotjs_handlewrap_jobject(&timerwrap->handlewrap);
-  IOTJS_ASSERT(jerry_value_is_object(jobject));
-  return jobject;
-}
-
-
-iotjs_timerwrap_t* iotjs_timerwrap_from_handle(uv_timer_t* timer_handle) {
-  uv_handle_t* handle = (uv_handle_t*)(timer_handle);
-  iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_handle(handle);
-  iotjs_timerwrap_t* timerwrap = (iotjs_timerwrap_t*)handlewrap;
-  IOTJS_ASSERT(iotjs_timerwrap_handle(timerwrap) == timer_handle);
-  return timerwrap;
-}
-
-
-iotjs_timerwrap_t* iotjs_timerwrap_from_jobject(const jerry_value_t jtimer) {
-  iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_jobject(jtimer);
-  return (iotjs_timerwrap_t*)handlewrap;
-}
-
-
 JS_FUNCTION(Start) {
   // Check parameters.
-  JS_DECLARE_THIS_PTR(timerwrap, timer_wrap);
+  JS_DECLARE_PTR(jthis, uv_timer_t, timer_handle);
   DJS_CHECK_ARGS(2, number, number);
 
   // parameters.
@@ -123,18 +50,21 @@ JS_FUNCTION(Start) {
   uint64_t repeat = JS_GET_ARG(1, number);
 
   // Start timer.
-  int res = iotjs_timerwrap_start(timer_wrap, timeout, repeat);
+  int res = uv_timer_start(timer_handle, TimeoutHandler, timeout, repeat);
 
   return jerry_create_number(res);
 }
 
 
 JS_FUNCTION(Stop) {
-  JS_DECLARE_THIS_PTR(timerwrap, timer_wrap);
+  JS_DECLARE_PTR(jthis, uv_handle_t, timer_handle);
   // Stop timer.
-  int res = iotjs_timerwrap_stop(timer_wrap);
 
-  return jerry_create_number(res);
+  if (!uv_is_closing(timer_handle)) {
+    iotjs_uv_handle_close(timer_handle, NULL);
+  }
+
+  return jerry_create_number(0);
 }
 
 
@@ -143,12 +73,7 @@ JS_FUNCTION(Timer) {
 
   const jerry_value_t jtimer = JS_GET_THIS();
 
-  iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_create(jtimer);
-
-  jerry_value_t jobject = iotjs_timerwrap_jobject(timer_wrap);
-  IOTJS_ASSERT(jerry_value_is_object(jobject));
-  IOTJS_ASSERT(iotjs_jval_get_object_native_handle(jtimer) != 0);
-
+  iotjs_timer_object_init(jtimer);
   return jerry_create_undefined();
 }
 
diff --git a/src/modules/iotjs_module_timer.h b/src/modules/iotjs_module_timer.h
deleted file mode 100644 (file)
index 28e2214..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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 IOTJS_MODULE_TIMER_H
-#define IOTJS_MODULE_TIMER_H
-
-
-#include "iotjs_binding.h"
-#include "iotjs_handlewrap.h"
-
-
-typedef struct { iotjs_handlewrap_t handlewrap; } iotjs_timerwrap_t;
-
-
-iotjs_timerwrap_t* iotjs_timerwrap_create(const jerry_value_t jtimer);
-
-iotjs_timerwrap_t* iotjs_timerwrap_from_jobject(const jerry_value_t jtimer);
-iotjs_timerwrap_t* iotjs_timerwrap_from_handle(uv_timer_t* timer_handle);
-
-uv_timer_t* iotjs_timerwrap_handle(iotjs_timerwrap_t* timerwrap);
-jerry_value_t iotjs_timerwrap_jobject(iotjs_timerwrap_t* timerwrap);
-
-// Start timer.
-int iotjs_timerwrap_start(iotjs_timerwrap_t* timerwrap, uint64_t timeout,
-                          uint64_t repeat);
-// Stop & close timer.
-int iotjs_timerwrap_stop(iotjs_timerwrap_t* timerwrap);
-
-
-#endif /* IOTJS_MODULE_TIMER_H */
index 19825bc06ba0723e35f607241c2b0030999fbd59..61f1a01d47e41b01a574fc267194d7e08c69dc44 100644 (file)
@@ -205,35 +205,44 @@ JS_FUNCTION(TlsContext) {
 
   // User provided certificate
   int ret = 0;
+
   jerry_value_t jcert =
       iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_CERT);
   jerry_value_t jkey =
       iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_KEY);
 
-  if (jerry_value_is_string(jcert) && jerry_value_is_string(jkey)) {
-    iotjs_string_t cert = iotjs_jval_as_string(jcert);
-    const char *cert_chars = iotjs_string_data(&cert);
+  iotjs_string_t cert_string;
+  iotjs_string_t key_string;
+
+  if (iotjs_jbuffer_as_string(jcert, &cert_string)) {
+    const char *cert_chars = iotjs_string_data(&cert_string);
 
     ret = mbedtls_x509_crt_parse(&tls_context->own_cert,
                                  (const unsigned char *)cert_chars,
-                                 (size_t)iotjs_string_size(&cert) + 1);
+                                 (size_t)iotjs_string_size(&cert_string) + 1);
 
-    iotjs_string_destroy(&cert);
+    iotjs_string_destroy(&cert_string);
 
-    if (ret == 0) {
-      iotjs_string_t key = iotjs_jval_as_string(jkey);
-      const char *key_chars = iotjs_string_data(&key);
+    if (ret == 0 && iotjs_jbuffer_as_string(jkey, &key_string)) {
+      const char *key_chars = iotjs_string_data(&key_string);
 
       ret = mbedtls_pk_parse_key(&tls_context->pkey,
                                  (const unsigned char *)key_chars,
-                                 (size_t)iotjs_string_size(&key) + 1, NULL, 0);
+                                 (size_t)iotjs_string_size(&key_string) + 1,
+                                 NULL, 0);
 
-      iotjs_string_destroy(&key);
+      iotjs_string_destroy(&key_string);
 
       if (ret == 0) {
+        // Both own_cert and pkey must be valid for setting this flag.
         tls_context->context_flags |= SSL_CONTEXT_HAS_KEY;
       }
+    } else {
+      ret = -1;
     }
+  } else if (!jerry_value_is_undefined(jcert) ||
+             !jerry_value_is_undefined(jkey)) {
+    ret = -1;
   }
 
   jerry_release_value(jcert);
@@ -246,16 +255,19 @@ JS_FUNCTION(TlsContext) {
   // User provided trusted certificates
   jerry_value_t jcert_auth =
       iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_CA);
+  iotjs_string_t cert_auth_string;
 
-  if (jerry_value_is_string(jcert_auth)) {
-    iotjs_string_t cert_auth = iotjs_jval_as_string(jcert_auth);
-    const char *cert_auth_chars = iotjs_string_data(&cert_auth);
+  if (iotjs_jbuffer_as_string(jcert_auth, &cert_auth_string)) {
+    const char *cert_auth_chars = iotjs_string_data(&cert_auth_string);
 
     ret = mbedtls_x509_crt_parse(&tls_context->cert_auth,
                                  (const unsigned char *)cert_auth_chars,
-                                 (size_t)iotjs_string_size(&cert_auth) + 1);
+                                 (size_t)iotjs_string_size(&cert_auth_string) +
+                                     1);
 
-    iotjs_string_destroy(&cert_auth);
+    iotjs_string_destroy(&cert_auth_string);
+  } else if (!jerry_value_is_undefined(jcert_auth)) {
+    ret = -1;
   } else {
     // Parse the default certificate authority
     ret = mbedtls_x509_crt_parse(&tls_context->cert_auth,
@@ -281,18 +293,13 @@ JS_FUNCTION(TlsInit) {
 
   // Get context
   jerry_value_t jtls_context = JS_GET_ARG(2, object);
-
-  void *native_ptr;
-  const jerry_object_native_info_t *native_info;
-  bool tls_context_available =
-      jerry_get_object_native_pointer(jtls_context, &native_ptr, &native_info);
-
-  if (!tls_context_available || native_info != &tls_context_native_info) {
+  iotjs_tls_context_t *tls_context = (iotjs_tls_context_t *)
+      iotjs_jval_get_object_native_handle(jtls_context,
+                                          &tls_context_native_info);
+  if (tls_context == NULL) {
     return JS_CREATE_ERROR(COMMON, "secure context not available");
   }
 
-  iotjs_tls_context_t *tls_context = (iotjs_tls_context_t *)native_ptr;
-
   iotjs_tls_t *tls_data = iotjs_tls_create(jtls_socket, tls_context);
 
   // Check server
@@ -383,13 +390,10 @@ static void iotjs_tls_send_pending(iotjs_tls_t *tls_data) {
   jerry_value_t jthis = tls_data->jobject;
   jerry_value_t fn = iotjs_jval_get_property(jthis, IOTJS_MAGIC_STRING_ONWRITE);
 
-  iotjs_jargs_t jargv = iotjs_jargs_create(1);
-  iotjs_jargs_append_jval(&jargv, jbuffer);
-  iotjs_make_callback(fn, jthis, &jargv);
+  iotjs_invoke_callback(fn, jthis, &jbuffer, 1);
 
   jerry_release_value(fn);
   jerry_release_value(jbuffer);
-  iotjs_jargs_destroy(&jargv);
 }
 
 
@@ -401,13 +405,12 @@ static void iotjs_tls_notify_error(iotjs_tls_t *tls_data) {
   jerry_value_t jthis = tls_data->jobject;
   jerry_value_t fn = iotjs_jval_get_property(jthis, IOTJS_MAGIC_STRING_EMIT);
 
-  iotjs_jargs_t jargv = iotjs_jargs_create(2);
-  iotjs_jargs_append_jval(&jargv, jerror);
-  iotjs_jargs_append_jval(&jargv, jmessage);
-  iotjs_make_callback(fn, jthis, &jargv);
+  jerry_value_t jargv[2] = { jerror, jmessage };
+  iotjs_invoke_callback(fn, jthis, jargv, 2);
 
   jerry_release_value(fn);
-  iotjs_jargs_destroy(&jargv);
+  jerry_release_value(jargv[0]);
+  jerry_release_value(jargv[1]);
 }
 
 
@@ -445,7 +448,7 @@ JS_FUNCTION(Write) {
 
     if (ret_val > 0) {
       data += ret_val;
-      length -= ret_val;
+      length -= (size_t)ret_val;
     } else if (ret_val != MBEDTLS_ERR_SSL_WANT_WRITE) {
       tls_data->state = TLS_CLOSED;
       return jerry_create_null();
@@ -509,16 +512,16 @@ static void tls_handshake(iotjs_tls_t *tls_data, jerry_value_t jthis) {
   }
 
   // Result of certificate verification
-  iotjs_jargs_t jargv = iotjs_jargs_create(2);
-  iotjs_jargs_append_bool(&jargv, error);
-  iotjs_jargs_append_bool(&jargv, authorized);
+  jerry_value_t jargv[2] = { jerry_create_boolean(error),
+                             jerry_create_boolean(authorized) };
 
   jerry_value_t fn =
       iotjs_jval_get_property(jthis, IOTJS_MAGIC_STRING_ONHANDSHAKEDONE);
-  iotjs_make_callback(fn, jthis, &jargv);
+  iotjs_invoke_callback(fn, jthis, jargv, 2);
 
   jerry_release_value(fn);
-  iotjs_jargs_destroy(&jargv);
+  jerry_release_value(jargv[0]);
+  jerry_release_value(jargv[1]);
 }
 
 
@@ -548,7 +551,7 @@ JS_FUNCTION(Read) {
       copy_size = length;
     }
 
-    iotjs_bio_write(receive_bio, data, length);
+    iotjs_bio_write(receive_bio, data, copy_size);
     data += copy_size;
     length -= copy_size;
 
@@ -561,6 +564,10 @@ JS_FUNCTION(Read) {
         IOTJS_ASSERT(tls_data->state == TLS_HANDSHAKE_IN_PROGRESS ||
                      tls_data->state == TLS_CLOSED);
 
+        if (length > 0 && tls_data->state == TLS_HANDSHAKE_IN_PROGRESS) {
+          continue;
+        }
+
         bool result = (tls_data->state != TLS_CLOSED);
         return jerry_create_boolean(result);
       }
@@ -587,19 +594,15 @@ JS_FUNCTION(Read) {
 
         jerry_value_t fn =
             iotjs_jval_get_property(jthis, IOTJS_MAGIC_STRING_ONREAD);
-        iotjs_jargs_t jargv = iotjs_jargs_create(1);
-
-        iotjs_jargs_append_jval(&jargv, jbuffer);
-        iotjs_make_callback(fn, jthis, &jargv);
+        iotjs_invoke_callback(fn, jthis, &jbuffer, 1);
 
         jerry_release_value(jbuffer);
         jerry_release_value(fn);
-        iotjs_jargs_destroy(&jargv);
         continue;
       }
 
       if (ret_val == MBEDTLS_ERR_SSL_WANT_READ) {
-        return jerry_create_boolean(true);
+        break;
       }
 
       if (ret_val == MBEDTLS_ERR_SSL_WANT_WRITE) {
index aa59d8f1c3cd2702fc25f0208708dbee32f7c429..4446f05b2467810089466d8d5b8169f1dac6176c 100644 (file)
 #include <unistd.h>
 
 #include "iotjs_def.h"
+#include "iotjs_module_buffer.h"
 #include "iotjs_module_uart.h"
+#include "iotjs_uv_handle.h"
+#include "iotjs_uv_request.h"
 
 
-IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(uart);
+static void iotjs_uart_object_destroy(uv_handle_t* handle);
 
-static iotjs_uart_t* uart_create(const jerry_value_t juart) {
-  iotjs_uart_t* uart = IOTJS_ALLOC(iotjs_uart_t);
-  iotjs_uart_create_platform_data(uart);
+static const jerry_object_native_info_t this_module_native_info = {
+  .free_cb = (jerry_object_native_free_callback_t)iotjs_uart_object_destroy,
+};
 
-  iotjs_handlewrap_initialize(&uart->handlewrap, juart,
-                              (uv_handle_t*)(&uart->poll_handle),
-                              &this_module_native_info);
 
-  uart->device_fd = -1;
-  return uart;
-}
+void iotjs_uart_object_destroy(uv_handle_t* handle) {
+  iotjs_uart_t* uart = (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(handle);
 
-static void iotjs_uart_destroy(iotjs_uart_t* uart) {
-  iotjs_handlewrap_destroy(&uart->handlewrap);
   iotjs_uart_destroy_platform_data(uart->platform_data);
-  IOTJS_RELEASE(uart);
 }
 
+
 static void uart_worker(uv_work_t* work_req) {
-  iotjs_periph_reqwrap_t* req_wrap =
-      (iotjs_periph_reqwrap_t*)(iotjs_reqwrap_from_request(
-          (uv_req_t*)work_req));
-  iotjs_uart_t* uart = (iotjs_uart_t*)req_wrap->data;
+  iotjs_periph_data_t* worker_data =
+      (iotjs_periph_data_t*)IOTJS_UV_REQUEST_EXTRA_DATA(work_req);
+  uv_handle_t* uart_poll_handle = (uv_handle_t*)worker_data->data;
 
-  switch (req_wrap->op) {
+  switch (worker_data->op) {
     case kUartOpOpen:
-      req_wrap->result = iotjs_uart_open(uart);
+      worker_data->result = iotjs_uart_open(uart_poll_handle);
       break;
     case kUartOpWrite:
-      req_wrap->result = iotjs_uart_write(uart);
+      worker_data->result = iotjs_uart_write(uart_poll_handle);
       break;
     case kUartOpClose:
-      iotjs_handlewrap_close(&uart->handlewrap, iotjs_uart_handlewrap_close_cb);
-      req_wrap->result = true;
+      iotjs_uv_handle_close(uart_poll_handle, iotjs_uart_handle_close_cb);
+      worker_data->result = true;
       break;
     default:
       IOTJS_ASSERT(!"Invalid Operation");
@@ -67,37 +63,38 @@ static void iotjs_uart_read_cb(uv_poll_t* req, int status, int events) {
   int i = read(uart->device_fd, buf, UART_WRITE_BUFFER_SIZE - 1);
   if (i > 0) {
     buf[i] = '\0';
-    DDDLOG("%s - read data: %s", __func__, buf);
+    DDDLOG("%s - read length: %d", __func__, i);
+    jerry_value_t juart = IOTJS_UV_HANDLE_DATA(req)->jobject;
     jerry_value_t jemit =
-        iotjs_jval_get_property(iotjs_handlewrap_jobject(&uart->handlewrap),
-                                IOTJS_MAGIC_STRING_EMIT);
+        iotjs_jval_get_property(juart, IOTJS_MAGIC_STRING_EMIT);
     IOTJS_ASSERT(jerry_value_is_function(jemit));
 
-    iotjs_jargs_t jargs = iotjs_jargs_create(2);
     jerry_value_t str =
         jerry_create_string((const jerry_char_t*)IOTJS_MAGIC_STRING_DATA);
-    jerry_value_t data = jerry_create_string((const jerry_char_t*)buf);
-    iotjs_jargs_append_jval(&jargs, str);
-    iotjs_jargs_append_jval(&jargs, data);
+
+    jerry_value_t jbuf = iotjs_bufferwrap_create_buffer((size_t)i);
+    iotjs_bufferwrap_t* buf_wrap = iotjs_bufferwrap_from_jbuffer(jbuf);
+    iotjs_bufferwrap_copy(buf_wrap, buf, (size_t)i);
+
+    jerry_value_t jargs[] = { str, jbuf };
     jerry_value_t jres =
-        iotjs_jhelper_call(jemit, iotjs_handlewrap_jobject(&uart->handlewrap),
-                           &jargs);
-    IOTJS_ASSERT(!jerry_value_has_error_flag(jres));
+        jerry_call_function(jemit, IOTJS_UV_HANDLE_DATA(req)->jobject, jargs,
+                            2);
+    IOTJS_ASSERT(!jerry_value_is_error(jres));
 
     jerry_release_value(jres);
     jerry_release_value(str);
-    jerry_release_value(data);
-    iotjs_jargs_destroy(&jargs);
+    jerry_release_value(jbuf);
     jerry_release_value(jemit);
   }
 }
 
-void iotjs_uart_register_read_cb(iotjs_uart_t* uart) {
-  uv_poll_t* poll_handle = &uart->poll_handle;
+void iotjs_uart_register_read_cb(uv_poll_t* uart_poll_handle) {
+  iotjs_uart_t* uart =
+      (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(uart_poll_handle);
   uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get());
-  uv_poll_init(loop, poll_handle, uart->device_fd);
-  poll_handle->data = uart;
-  uv_poll_start(poll_handle, UV_READABLE, iotjs_uart_read_cb);
+  uv_poll_init(loop, uart_poll_handle, uart->device_fd);
+  uv_poll_start(uart_poll_handle, UV_READABLE, iotjs_uart_read_cb);
 }
 
 static jerry_value_t uart_set_configuration(iotjs_uart_t* uart,
@@ -154,19 +151,26 @@ JS_FUNCTION(UartCons) {
   DJS_CHECK_ARG_IF_EXIST(1, function);
 
   // Create UART object
-  jerry_value_t juart = JS_GET_THIS();
-  iotjs_uart_t* uart = uart_create(juart);
+  const jerry_value_t juart = JS_GET_THIS();
+  uv_handle_t* uart_poll_handle =
+      iotjs_uv_handle_create(sizeof(uv_poll_t), juart, &this_module_native_info,
+                             sizeof(iotjs_uart_t));
+  iotjs_uart_t* uart =
+      (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(uart_poll_handle);
+  // TODO: merge platform data allocation into the handle allocation.
+  iotjs_uart_create_platform_data(uart);
+  uart->device_fd = -1;
 
   jerry_value_t jconfig = JS_GET_ARG(0, object);
 
   // set configuration
   jerry_value_t res = iotjs_uart_set_platform_config(uart, jconfig);
-  if (jerry_value_has_error_flag(res)) {
+  if (jerry_value_is_error(res)) {
     return res;
   }
 
   res = uart_set_configuration(uart, jconfig);
-  if (jerry_value_has_error_flag(res)) {
+  if (jerry_value_is_error(res)) {
     return res;
   }
 
@@ -178,8 +182,9 @@ JS_FUNCTION(UartCons) {
   // If the callback doesn't exist, it is completed synchronously.
   // Otherwise, it will be executed asynchronously.
   if (!jerry_value_is_null(jcallback)) {
-    iotjs_periph_call_async(uart, jcallback, kUartOpOpen, uart_worker);
-  } else if (!iotjs_uart_open(uart)) {
+    iotjs_periph_call_async(uart_poll_handle, jcallback, kUartOpOpen,
+                            uart_worker);
+  } else if (!iotjs_uart_open(uart_poll_handle)) {
     return JS_CREATE_ERROR(COMMON, iotjs_periph_error_str(kUartOpOpen));
   }
 
@@ -187,27 +192,31 @@ JS_FUNCTION(UartCons) {
 }
 
 JS_FUNCTION(Write) {
-  JS_DECLARE_THIS_PTR(uart, uart);
+  JS_DECLARE_PTR(jthis, uv_poll_t, uart_poll_handle);
   DJS_CHECK_ARGS(1, string);
   DJS_CHECK_ARG_IF_EXIST(1, function);
 
+  iotjs_uart_t* uart =
+      (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(uart_poll_handle);
   uart->buf_data = JS_GET_ARG(0, string);
   uart->buf_len = iotjs_string_size(&uart->buf_data);
 
-  iotjs_periph_call_async(uart, JS_GET_ARG_IF_EXIST(1, function), kUartOpWrite,
-                          uart_worker);
+  iotjs_periph_call_async(uart_poll_handle, JS_GET_ARG_IF_EXIST(1, function),
+                          kUartOpWrite, uart_worker);
 
   return jerry_create_undefined();
 }
 
 JS_FUNCTION(WriteSync) {
-  JS_DECLARE_THIS_PTR(uart, uart);
+  JS_DECLARE_PTR(jthis, uv_handle_t, uart_poll_handle);
   DJS_CHECK_ARGS(1, string);
 
+  iotjs_uart_t* uart =
+      (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(uart_poll_handle);
   uart->buf_data = JS_GET_ARG(0, string);
   uart->buf_len = iotjs_string_size(&uart->buf_data);
 
-  bool result = iotjs_uart_write(uart);
+  bool result = iotjs_uart_write(uart_poll_handle);
   iotjs_string_destroy(&uart->buf_data);
 
   if (!result) {
@@ -218,19 +227,19 @@ JS_FUNCTION(WriteSync) {
 }
 
 JS_FUNCTION(Close) {
-  JS_DECLARE_THIS_PTR(uart, uart);
+  JS_DECLARE_PTR(jthis, uv_poll_t, uart_poll_handle);
   DJS_CHECK_ARG_IF_EXIST(0, function);
 
-  iotjs_periph_call_async(uart, JS_GET_ARG_IF_EXIST(0, function), kUartOpClose,
-                          uart_worker);
+  iotjs_periph_call_async(uart_poll_handle, JS_GET_ARG_IF_EXIST(0, function),
+                          kUartOpClose, uart_worker);
 
   return jerry_create_undefined();
 }
 
 JS_FUNCTION(CloseSync) {
-  JS_DECLARE_THIS_PTR(uart, uart);
+  JS_DECLARE_PTR(jthis, uv_handle_t, uart_poll_handle);
 
-  iotjs_handlewrap_close(&uart->handlewrap, iotjs_uart_handlewrap_close_cb);
+  iotjs_uv_handle_close(uart_poll_handle, iotjs_uart_handle_close_cb);
   return jerry_create_undefined();
 }
 
index 650fc58a6b68c1e32114bba1af36fd7b628ca537..1cec3bb8442130751603932f91db1aef6de42196 100644 (file)
@@ -18,9 +18,7 @@
 #define IOTJS_MODULE_UART_H
 
 #include "iotjs_def.h"
-#include "iotjs_handlewrap.h"
 #include "iotjs_module_periph_common.h"
-#include "iotjs_reqwrap.h"
 
 
 #define UART_WRITE_BUFFER_SIZE 512
 typedef struct iotjs_uart_platform_data_s iotjs_uart_platform_data_t;
 
 typedef struct {
-  iotjs_handlewrap_t handlewrap;
-  iotjs_uart_platform_data_t* platform_data;
   int device_fd;
   unsigned baud_rate;
   uint8_t data_bits;
   iotjs_string_t buf_data;
   unsigned buf_len;
-  uv_poll_t poll_handle;
-} iotjs_uart_t;
 
-jerry_value_t iotjs_uart_set_platform_config(iotjs_uart_t* uart,
-                                             const jerry_value_t jconfig);
+  iotjs_uart_platform_data_t* platform_data;
+} iotjs_uart_t;
 
-void iotjs_uart_register_read_cb(iotjs_uart_t* uart);
-bool iotjs_uart_open(iotjs_uart_t* uart);
-bool iotjs_uart_write(iotjs_uart_t* uart);
-void iotjs_uart_handlewrap_close_cb(uv_handle_t* handle);
+void iotjs_uart_handle_close_cb(uv_handle_t* handle);
+void iotjs_uart_register_read_cb(uv_poll_t* uart_poll_handle);
 
 void iotjs_uart_create_platform_data(iotjs_uart_t* uart);
+jerry_value_t iotjs_uart_set_platform_config(iotjs_uart_t* uart,
+                                             const jerry_value_t jconfig);
 void iotjs_uart_destroy_platform_data(iotjs_uart_platform_data_t* pdata);
 
+bool iotjs_uart_open(uv_handle_t* uart_poll_handle);
+bool iotjs_uart_write(uv_handle_t* uart_poll_handle);
+
 #endif /* IOTJS_MODULE_UART_H */
index 36b8ce61f99e9422fd63db0d035a175338d1950a..0340e89fe906d189ca309d0b799a0cbcacc2495e 100644 (file)
 
 #include "iotjs_def.h"
 
-#include "iotjs_module_udp.h"
-
-#include "iotjs_handlewrap.h"
 #include "iotjs_module_buffer.h"
 #include "iotjs_module_tcp.h"
-#include "iotjs_reqwrap.h"
-
+#include "iotjs_uv_handle.h"
+#include "iotjs_uv_request.h"
 
-IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(udpwrap);
 
+static const jerry_object_native_info_t this_module_native_info = { NULL };
 
-iotjs_udpwrap_t* iotjs_udpwrap_create(jerry_value_t judp) {
-  iotjs_udpwrap_t* udpwrap = IOTJS_ALLOC(iotjs_udpwrap_t);
 
-  iotjs_handlewrap_initialize(&udpwrap->handlewrap, judp,
-                              (uv_handle_t*)(&udpwrap->handle),
-                              &this_module_native_info);
+void iotjs_udp_object_init(jerry_value_t judp) {
+  uv_handle_t* handle = iotjs_uv_handle_create(sizeof(uv_udp_t), judp,
+                                               &this_module_native_info, 0);
 
   const iotjs_environment_t* env = iotjs_environment_get();
-  uv_udp_init(iotjs_environment_loop(env), &udpwrap->handle);
-
-  return udpwrap;
-}
-
-
-static void iotjs_udpwrap_destroy(iotjs_udpwrap_t* udpwrap) {
-  iotjs_handlewrap_destroy(&udpwrap->handlewrap);
-  IOTJS_RELEASE(udpwrap);
-}
-
-
-iotjs_udpwrap_t* iotjs_udpwrap_from_handle(uv_udp_t* udp_handle) {
-  uv_handle_t* handle = (uv_handle_t*)(udp_handle);
-  iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_handle(handle);
-  iotjs_udpwrap_t* udpwrap = (iotjs_udpwrap_t*)handlewrap;
-  IOTJS_ASSERT(iotjs_udpwrap_udp_handle(udpwrap) == udp_handle);
-  return udpwrap;
-}
-
-
-iotjs_udpwrap_t* iotjs_udpwrap_from_jobject(jerry_value_t judp) {
-  iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_jobject(judp);
-  return (iotjs_udpwrap_t*)handlewrap;
-}
-
-
-uv_udp_t* iotjs_udpwrap_udp_handle(iotjs_udpwrap_t* udpwrap) {
-  uv_handle_t* handle = iotjs_handlewrap_get_uv_handle(&udpwrap->handlewrap);
-  return (uv_udp_t*)handle;
-}
-
-
-iotjs_send_reqwrap_t* iotjs_send_reqwrap_create(jerry_value_t jcallback,
-                                                const size_t msg_size) {
-  iotjs_send_reqwrap_t* send_reqwrap = IOTJS_ALLOC(iotjs_send_reqwrap_t);
-
-  iotjs_reqwrap_initialize(&send_reqwrap->reqwrap, jcallback,
-                           (uv_req_t*)&send_reqwrap->req);
-  send_reqwrap->msg_size = msg_size;
-
-  return send_reqwrap;
-}
-
-
-static void iotjs_send_reqwrap_destroy(iotjs_send_reqwrap_t* send_reqwrap) {
-  iotjs_reqwrap_destroy(&send_reqwrap->reqwrap);
-  IOTJS_RELEASE(send_reqwrap);
+  uv_udp_init(iotjs_environment_loop(env), (uv_udp_t*)handle);
 }
 
 
@@ -89,14 +37,14 @@ JS_FUNCTION(UDP) {
   DJS_CHECK_THIS();
 
   jerry_value_t judp = JS_GET_THIS();
-  iotjs_udpwrap_create(judp);
+  iotjs_udp_object_init(judp);
 
   return jerry_create_undefined();
 }
 
 
 JS_FUNCTION(Bind) {
-  JS_DECLARE_THIS_PTR(udpwrap, udp_wrap);
+  JS_DECLARE_PTR(jthis, uv_udp_t, udp_handle);
   DJS_CHECK_ARGS(2, string, number);
 
   iotjs_string_t address = JS_GET_ARG(0, string);
@@ -117,8 +65,7 @@ JS_FUNCTION(Bind) {
       uv_ip4_addr(iotjs_string_data(&address), port, (sockaddr_in*)(&addr));
 
   if (err == 0) {
-    err = uv_udp_bind(iotjs_udpwrap_udp_handle(udp_wrap),
-                      (const sockaddr*)(&addr), flags);
+    err = uv_udp_bind(udp_handle, (const sockaddr*)(&addr), flags);
   }
 
   jerry_release_value(reuse_addr);
@@ -145,10 +92,8 @@ static void OnRecv(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf,
     return;
   }
 
-  iotjs_udpwrap_t* udp_wrap = iotjs_udpwrap_from_handle(handle);
-
   // udp handle
-  jerry_value_t judp = iotjs_handlewrap_jobject(&udp_wrap->handlewrap);
+  jerry_value_t judp = IOTJS_UV_HANDLE_DATA(handle)->jobject;
   IOTJS_ASSERT(jerry_value_is_object(judp));
 
   // onmessage callback
@@ -156,44 +101,41 @@ static void OnRecv(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf,
       iotjs_jval_get_property(judp, IOTJS_MAGIC_STRING_ONMESSAGE);
   IOTJS_ASSERT(jerry_value_is_function(jonmessage));
 
-  iotjs_jargs_t jargs = iotjs_jargs_create(4);
-  iotjs_jargs_append_number(&jargs, nread);
-  iotjs_jargs_append_jval(&jargs, judp);
+  jerry_value_t jargs[4] = { jerry_create_number(nread),
+                             jerry_acquire_value(judp), jerry_create_null(),
+                             jerry_create_object() };
 
   if (nread < 0) {
     iotjs_buffer_release(buf->base);
-    iotjs_make_callback(jonmessage, jerry_create_undefined(), &jargs);
+    iotjs_invoke_callback(jonmessage, jerry_create_undefined(), jargs, 2);
     jerry_release_value(jonmessage);
-    iotjs_jargs_destroy(&jargs);
+
+    for (int i = 0; i < 4; i++) {
+      jerry_release_value(jargs[i]);
+    }
     return;
   }
 
-  jerry_value_t jbuffer = iotjs_bufferwrap_create_buffer((size_t)nread);
-  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(jbuffer);
-
+  jargs[2] = iotjs_bufferwrap_create_buffer((size_t)nread);
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(jargs[2]);
   iotjs_bufferwrap_copy(buffer_wrap, buf->base, (size_t)nread);
+  AddressToJS(jargs[3], addr);
 
-  iotjs_jargs_append_jval(&jargs, jbuffer);
-
-  jerry_value_t rinfo = jerry_create_object();
-  AddressToJS(rinfo, addr);
-  iotjs_jargs_append_jval(&jargs, rinfo);
+  iotjs_invoke_callback(jonmessage, jerry_create_undefined(), jargs, 4);
 
-  iotjs_make_callback(jonmessage, jerry_create_undefined(), &jargs);
-
-  jerry_release_value(rinfo);
-  jerry_release_value(jbuffer);
   jerry_release_value(jonmessage);
   iotjs_buffer_release(buf->base);
-  iotjs_jargs_destroy(&jargs);
+
+  for (int i = 0; i < 4; i++) {
+    jerry_release_value(jargs[i]);
+  }
 }
 
 
 JS_FUNCTION(RecvStart) {
-  JS_DECLARE_THIS_PTR(udpwrap, udp_wrap);
+  JS_DECLARE_PTR(jthis, uv_udp_t, udp_handle);
 
-  int err =
-      uv_udp_recv_start(iotjs_udpwrap_udp_handle(udp_wrap), OnAlloc, OnRecv);
+  int err = uv_udp_recv_start(udp_handle, OnAlloc, OnRecv);
 
   // UV_EALREADY means that the socket is already bound but that's okay
   if (err == UV_EALREADY)
@@ -204,33 +146,31 @@ JS_FUNCTION(RecvStart) {
 
 
 JS_FUNCTION(RecvStop) {
-  JS_DECLARE_THIS_PTR(udpwrap, udp_wrap);
+  JS_DECLARE_PTR(jthis, uv_udp_t, udp_handle);
 
-  int r = uv_udp_recv_stop(iotjs_udpwrap_udp_handle(udp_wrap));
+  int r = uv_udp_recv_stop(udp_handle);
 
   return jerry_create_number(r);
 }
 
 
 static void OnSend(uv_udp_send_t* req, int status) {
-  iotjs_send_reqwrap_t* req_wrap = (iotjs_send_reqwrap_t*)(req->data);
-  IOTJS_ASSERT(req_wrap != NULL);
+  IOTJS_ASSERT(req != NULL);
 
   // Take callback function object.
-  jerry_value_t jcallback = iotjs_reqwrap_jcallback(&req_wrap->reqwrap);
+  jerry_value_t jcallback = *IOTJS_UV_REQUEST_JSCALLBACK(req);
 
   if (jerry_value_is_function(jcallback)) {
-    // Take callback function object.
+    size_t msg_size = *((size_t*)IOTJS_UV_REQUEST_EXTRA_DATA(req));
+    jerry_value_t jargs[2] = { jerry_create_number(status),
+                               jerry_create_number(msg_size) };
 
-    iotjs_jargs_t jargs = iotjs_jargs_create(2);
-    iotjs_jargs_append_number(&jargs, status);
-    iotjs_jargs_append_number(&jargs, req_wrap->msg_size);
-
-    iotjs_make_callback(jcallback, jerry_create_undefined(), &jargs);
-    iotjs_jargs_destroy(&jargs);
+    iotjs_invoke_callback(jcallback, jerry_create_undefined(), jargs, 2);
+    jerry_release_value(jargs[0]);
+    jerry_release_value(jargs[1]);
   }
 
-  iotjs_send_reqwrap_destroy(req_wrap);
+  iotjs_uv_request_destroy((uv_req_t*)req);
 }
 
 
@@ -240,7 +180,7 @@ static void OnSend(uv_udp_send_t* req, int status) {
 // [2] ip
 // [3] callback function
 JS_FUNCTION(Send) {
-  JS_DECLARE_THIS_PTR(udpwrap, udp_wrap);
+  JS_DECLARE_PTR(jthis, uv_udp_t, udp_handle);
   DJS_CHECK_ARGS(3, object, number, string);
   IOTJS_ASSERT(jerry_value_is_function(jargv[3]) ||
                jerry_value_is_undefined(jargv[3]));
@@ -253,7 +193,9 @@ JS_FUNCTION(Send) {
   iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(jbuffer);
   size_t len = iotjs_bufferwrap_length(buffer_wrap);
 
-  iotjs_send_reqwrap_t* req_wrap = iotjs_send_reqwrap_create(jcallback, len);
+  uv_req_t* req_send =
+      iotjs_uv_request_create(sizeof(uv_udp_send_t), jcallback, sizeof(len));
+  *((size_t*)IOTJS_UV_REQUEST_EXTRA_DATA(req_send)) = len;
 
   uv_buf_t buf;
   buf.base = buffer_wrap->buffer;
@@ -264,12 +206,12 @@ JS_FUNCTION(Send) {
       uv_ip4_addr(iotjs_string_data(&address), port, (sockaddr_in*)(&addr));
 
   if (err == 0) {
-    err = uv_udp_send(&req_wrap->req, iotjs_udpwrap_udp_handle(udp_wrap), &buf,
-                      1, (const sockaddr*)(&addr), OnSend);
+    err = uv_udp_send((uv_udp_send_t*)req_send, udp_handle, &buf, 1,
+                      (const sockaddr*)(&addr), OnSend);
   }
 
   if (err) {
-    iotjs_send_reqwrap_destroy(req_wrap);
+    iotjs_uv_request_destroy(req_send);
   }
 
   iotjs_string_destroy(&address);
@@ -280,91 +222,79 @@ JS_FUNCTION(Send) {
 
 // Close socket
 JS_FUNCTION(Close) {
-  JS_DECLARE_THIS_PTR(handlewrap, wrap);
+  JS_DECLARE_PTR(jthis, uv_handle_t, uv_handle);
 
-  iotjs_handlewrap_close(wrap, NULL);
+  iotjs_uv_handle_close(uv_handle, NULL);
 
   return jerry_create_undefined();
 }
 
 
 JS_FUNCTION(GetSockeName) {
+  JS_DECLARE_PTR(jthis, uv_udp_t, udp_handle);
   DJS_CHECK_ARGS(1, object);
-  iotjs_udpwrap_t* wrap = iotjs_udpwrap_from_jobject(JS_GET_THIS());
-  IOTJS_ASSERT(wrap != NULL);
 
   sockaddr_storage storage;
   int addrlen = sizeof(storage);
   sockaddr* const addr = (sockaddr*)(&storage);
-  int err = uv_udp_getsockname(iotjs_udpwrap_udp_handle(wrap), addr, &addrlen);
+  int err = uv_udp_getsockname(udp_handle, addr, &addrlen);
   if (err == 0)
     AddressToJS(JS_GET_ARG(0, object), addr);
   return jerry_create_number(err);
 }
 
 
-#define IOTJS_UV_SET_SOCKOPT(fn)                          \
-  JS_DECLARE_THIS_PTR(udpwrap, udp_wrap);                 \
-  DJS_CHECK_ARGS(1, number);                              \
-                                                          \
-  int flag = JS_GET_ARG(0, number);                       \
-  int err = fn(iotjs_udpwrap_udp_handle(udp_wrap), flag); \
-                                                          \
-  return jerry_create_number(err);
-
-
-JS_FUNCTION(SetBroadcast) {
-#if !defined(__NUTTX__)
-  IOTJS_UV_SET_SOCKOPT(uv_udp_set_broadcast);
-#else
-  IOTJS_ASSERT(!"Not implemented");
-
-  return jerry_create_null();
-#endif
-}
-
-
-JS_FUNCTION(SetTTL) {
-#if !defined(__NUTTX__)
-  IOTJS_UV_SET_SOCKOPT(uv_udp_set_ttl);
-#else
-  IOTJS_ASSERT(!"Not implemented");
-
-  return jerry_create_null();
-#endif
-}
-
-
-JS_FUNCTION(SetMulticastTTL) {
-#if !defined(__NUTTX__)
-  IOTJS_UV_SET_SOCKOPT(uv_udp_set_multicast_ttl);
-#else
-  IOTJS_ASSERT(!"Not implemented");
+// The order of these config types must match the order
+// in the dgram js module.
+enum config_type { BROADCAST, TTL, MULTICASTTTL, MULTICASTLOOPBACK };
 
-  return jerry_create_null();
-#endif
-}
+JS_FUNCTION(Configure) {
+  JS_DECLARE_PTR(jthis, uv_udp_t, udp_handle);
+  DJS_CHECK_ARGS(2, number, number);
 
+  jerry_value_t ret_value = jerry_create_null();
 
-JS_FUNCTION(SetMulticastLoopback) {
 #if !defined(__NUTTX__)
-  IOTJS_UV_SET_SOCKOPT(uv_udp_set_multicast_loop);
+  enum config_type type = JS_GET_ARG(0, number);
+  int flag = JS_GET_ARG(1, number);
+  int (*fn)(uv_udp_t*, int) = NULL;
+
+  switch (type) {
+    case BROADCAST: {
+      fn = &uv_udp_set_broadcast;
+      break;
+    }
+    case TTL: {
+      fn = &uv_udp_set_ttl;
+      break;
+    }
+    case MULTICASTTTL: {
+      fn = &uv_udp_set_multicast_ttl;
+      break;
+    }
+    case MULTICASTLOOPBACK: {
+      fn = &uv_udp_set_multicast_loop;
+      break;
+    }
+    default: {
+      IOTJS_ASSERT(!"Unknown config type");
+      return jerry_create_null();
+    }
+  }
+  ret_value = jerry_create_number(fn(udp_handle, flag));
 #else
   IOTJS_ASSERT(!"Not implemented");
-
-  return jerry_create_null();
 #endif
+  return ret_value;
 }
 
-#undef IOTJS_UV_SET_SOCKOPT
-
 
 static jerry_value_t SetMembership(const jerry_value_t jthis,
                                    const jerry_value_t* jargv,
                                    const jerry_length_t jargc,
                                    uv_membership membership) {
 #if !defined(__NUTTX__)
-  JS_DECLARE_THIS_PTR(udpwrap, udp_wrap);
+  JS_DECLARE_PTR(jthis, uv_udp_t, udp_handle);
   DJS_CHECK_ARGS(1, string);
 
   iotjs_string_t address = JS_GET_ARG(0, string);
@@ -380,9 +310,8 @@ static jerry_value_t SetMembership(const jerry_value_t jthis,
     iface_cstr = iotjs_string_data(&iface);
   }
 
-  int err = uv_udp_set_membership(iotjs_udpwrap_udp_handle(udp_wrap),
-                                  iotjs_string_data(&address), iface_cstr,
-                                  membership);
+  int err = uv_udp_set_membership(udp_handle, iotjs_string_data(&address),
+                                  iface_cstr, membership);
 
   if (!isUndefinedOrNull)
     iotjs_string_destroy(&iface);
@@ -434,13 +363,7 @@ jerry_value_t InitUdp() {
   iotjs_jval_set_method(prototype, IOTJS_MAGIC_STRING_CLOSE, Close);
   iotjs_jval_set_method(prototype, IOTJS_MAGIC_STRING_GETSOCKNAME,
                         GetSockeName);
-  iotjs_jval_set_method(prototype, IOTJS_MAGIC_STRING_SETBROADCAST,
-                        SetBroadcast);
-  iotjs_jval_set_method(prototype, IOTJS_MAGIC_STRING_SETTTL, SetTTL);
-  iotjs_jval_set_method(prototype, IOTJS_MAGIC_STRING_SETMULTICASTTTL,
-                        SetMulticastTTL);
-  iotjs_jval_set_method(prototype, IOTJS_MAGIC_STRING_SETMULTICASTLOOPBACK,
-                        SetMulticastLoopback);
+  iotjs_jval_set_method(prototype, IOTJS_MAGIC_STRING_CONFIGURE, Configure);
   iotjs_jval_set_method(prototype, IOTJS_MAGIC_STRING_ADDMEMBERSHIP,
                         AddMembership);
   iotjs_jval_set_method(prototype, IOTJS_MAGIC_STRING_DROPMEMBERSHIP,
diff --git a/src/modules/iotjs_module_udp.h b/src/modules/iotjs_module_udp.h
deleted file mode 100644 (file)
index 65f7800..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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 IOTJS_MODULE_UDP_H
-#define IOTJS_MODULE_UDP_H
-
-
-#include "iotjs_def.h"
-#include "iotjs_handlewrap.h"
-#include "iotjs_reqwrap.h"
-
-
-typedef struct {
-  iotjs_handlewrap_t handlewrap;
-  uv_udp_t handle;
-} iotjs_udpwrap_t;
-
-
-iotjs_udpwrap_t* iotjs_udpwrap_create(jerry_value_t judp);
-
-iotjs_udpwrap_t* iotjs_udpwrap_from_handle(uv_udp_t* handle);
-iotjs_udpwrap_t* iotjs_udpwrap_from_jobject(jerry_value_t judp);
-
-uv_udp_t* iotjs_udpwrap_udp_handle(iotjs_udpwrap_t* udpwrap);
-
-
-typedef struct {
-  iotjs_reqwrap_t reqwrap;
-  uv_udp_send_t req;
-  size_t msg_size;
-} iotjs_send_reqwrap_t;
-
-iotjs_send_reqwrap_t* iotjs_send_reqwrap_create(jerry_value_t jcallback,
-                                                const size_t msg_size);
-
-
-#endif /* IOTJS_MODULE_UDP_H */
diff --git a/src/modules/iotjs_module_websocket.c b/src/modules/iotjs_module_websocket.c
new file mode 100644 (file)
index 0000000..9e8e6e6
--- /dev/null
@@ -0,0 +1,796 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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 <stdlib.h>
+#include <time.h>
+
+#include "iotjs_def.h"
+#include "iotjs_module_buffer.h"
+#include "iotjs_module_crypto.h"
+#include "iotjs_module_websocket.h"
+
+
+static void iotjs_wsclient_destroy(iotjs_wsclient_t *wsclient) {
+  IOTJS_RELEASE(wsclient->tcp_buff.buffer);
+  IOTJS_RELEASE(wsclient->ws_buff.data);
+  IOTJS_RELEASE(wsclient->generated_key);
+  IOTJS_RELEASE(wsclient);
+}
+
+static const jerry_object_native_info_t wsclient_native_info = {
+  .free_cb = (jerry_object_native_free_callback_t)iotjs_wsclient_destroy
+};
+
+iotjs_wsclient_t *iotjs_wsclient_create(const jerry_value_t jobject) {
+  iotjs_wsclient_t *wsclient = IOTJS_ALLOC(iotjs_wsclient_t);
+
+  jerry_set_object_native_pointer(jobject, wsclient, &wsclient_native_info);
+  return wsclient;
+}
+
+static const char WS_GUID[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+
+/**
+ * The protocol is as follows:
+ * method + USER_ENDPOINT + protocol
+ * host + USER_HOST + line_end
+ * upgrade
+ * connection
+ * sec_websocket_key + line_end
+ * sec_websocket_ver
+ */
+static const char method[] = "GET ";
+static const char protocol[] = " HTTP/1.1\r\n";
+static const char host[] = "Host: ";
+static const char line_end[] = "\r\n";
+static const char upgrade[] = "Upgrade: websocket\r\n";
+static const char connection[] = "Connection: Upgrade\r\n";
+static const char sec_websocket_key[] = "Sec-WebSocket-Key: ";
+static const char sec_websocket_ver[] = "Sec-WebSocket-Version: 13\r\n\r\n";
+static const char handshake_response[] =
+    "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: "
+    "Upgrade\r\nSec-WebSocket-Accept: ";
+static size_t header_fixed_size =
+    sizeof(method) + sizeof(protocol) + sizeof(host) + sizeof(upgrade) +
+    sizeof(connection) + sizeof(sec_websocket_key) + sizeof(sec_websocket_ver) -
+    9; // 9 is for every \0
+
+
+void iotjs_websocket_create_callback(jerry_value_t jsref, jerry_value_t jmsg,
+                                     char *name, jerry_value_t client) {
+  jerry_value_t args[2];
+  args[0] = jmsg;
+  args[1] = client;
+  jerry_value_t fn = iotjs_jval_get_property(jsref, name);
+  iotjs_invoke_callback(fn, jsref, args, 2);
+
+  jerry_release_value(fn);
+}
+
+
+static unsigned char *ws_generate_key(jerry_value_t jsref, size_t *key_len) {
+  unsigned char *key = IOTJS_CALLOC(16, unsigned char);
+  for (int i = 0; i < 16; i++) {
+    key[i] = rand() % 256;
+  }
+
+  unsigned char *ret_val = NULL;
+
+  if (!(*key_len = iotjs_base64_encode(&ret_val, key, 16))) {
+    jerry_value_t ret_str =
+        jerry_create_string((jerry_char_t *)"mbedtls base64 encode failed");
+    iotjs_websocket_create_callback(jsref, ret_str, IOTJS_MAGIC_STRING_ONERROR,
+                                    ret_str);
+    jerry_release_value(ret_str);
+  }
+  IOTJS_RELEASE(key);
+
+  return ret_val;
+}
+
+
+static char *iotjs_ws_write_header(char *dst, const char *src) {
+  memcpy(dst, src, strlen(src));
+  return dst + strlen(src);
+}
+
+
+static char *iotjs_ws_write_data(char *buff, void *data, size_t size) {
+  memcpy(buff, data, size);
+  return buff + size;
+}
+
+
+static unsigned char *iotjs_make_handshake_key(char *client_key,
+                                               size_t *key_len) {
+  unsigned char *out_buff = NULL;
+
+  size_t ws_guid_size = strlen(WS_GUID);
+  size_t client_key_size = strnlen((char *)client_key, 24);
+  size_t concatenated_size = ws_guid_size + client_key_size;
+
+  unsigned char concatenated[concatenated_size + 1];
+  memcpy(concatenated, client_key, client_key_size);
+  memcpy(concatenated + client_key_size, WS_GUID, ws_guid_size);
+  concatenated[concatenated_size] = '\0';
+  size_t out_buff_size =
+      iotjs_sha1_encode(&out_buff, concatenated, concatenated_size);
+  unsigned char *key_out = NULL;
+  if (!(*key_len = iotjs_base64_encode(&key_out, out_buff, out_buff_size))) {
+    key_out = NULL;
+  }
+
+  IOTJS_RELEASE(out_buff);
+  return key_out;
+}
+
+static bool iotjs_check_handshake_key(char *server_key, jerry_value_t jsref) {
+  bool ret_val = true;
+  void *native_p;
+  JNativeInfoType *out_native_info;
+  bool has_p =
+      jerry_get_object_native_pointer(jsref, &native_p, &out_native_info);
+  if (!has_p || out_native_info != &wsclient_native_info) {
+    ret_val = false;
+  }
+
+  iotjs_wsclient_t *wsclient = (iotjs_wsclient_t *)native_p;
+  size_t key_len = 0;
+  unsigned char *key;
+  if (!(key = iotjs_make_handshake_key((char *)wsclient->generated_key,
+                                       &key_len))) {
+    ret_val = false;
+  }
+
+  if (strncmp(server_key, (const char *)key, key_len)) {
+    ret_val = false;
+  }
+
+  IOTJS_RELEASE(wsclient->generated_key);
+  IOTJS_RELEASE(key);
+
+  return ret_val;
+}
+
+
+static jerry_value_t iotjs_websocket_encode_frame(uint8_t opcode, bool mask,
+                                                  bool compress, char *payload,
+                                                  size_t payload_len) {
+  uint8_t header[2] = { 0 };
+
+  uint64_t buffer_size = payload_len + sizeof(header);
+
+  header[0] |= WS_FIN_BIT;
+  header[0] |= opcode;
+
+  if (compress) {
+    header[0] |= 0x40;
+  }
+
+  if (mask) {
+    header[1] |= WS_MASK_BIT;
+    buffer_size += 4; // mask key size is 32 bits
+  }
+
+  uint8_t extended_len_size = 0;
+  if (payload_len <= WS_ONE_BYTE_LENGTH) {
+    header[1] |= payload_len;
+  } else if (payload_len <= UINT16_MAX) {
+    header[1] |= WS_TWO_BYTES_LENGTH;
+    extended_len_size = 2;
+  } else {
+    header[1] |= WS_THREE_BYTES_LENGTH;
+    extended_len_size = 8;
+  }
+
+  buffer_size += extended_len_size;
+
+  jerry_value_t jframe = iotjs_bufferwrap_create_buffer(buffer_size);
+  iotjs_bufferwrap_t *frame_wrap = iotjs_bufferwrap_from_jbuffer(jframe);
+  char *buff_ptr = frame_wrap->buffer;
+
+  *buff_ptr++ = (char)header[0];
+  *buff_ptr++ = (char)header[1];
+
+  if (extended_len_size) {
+    if (extended_len_size == 2) {
+      uint16_t len = payload_len;
+      *buff_ptr++ = *((char *)&len + 1);
+      *buff_ptr++ = *((char *)&len);
+    } else {
+      uint64_t len = payload_len;
+      for (int8_t i = sizeof(uint64_t) - 1; i >= 0; i--) {
+        *buff_ptr++ = *((char *)&len + i);
+      }
+    }
+  }
+
+  if (payload != NULL) {
+    if (mask) {
+      uint8_t key[4];
+      for (uint8_t i = 0; i < sizeof(key); i++) {
+        key[i] = rand() % 256;
+      }
+
+      buff_ptr = iotjs_ws_write_data(buff_ptr, key, sizeof(key));
+
+      for (size_t i = 0; i < payload_len; i++) {
+        payload[i] ^= key[i % 4];
+      }
+    }
+
+    buff_ptr = iotjs_ws_write_data(buff_ptr, payload, payload_len);
+  }
+
+  return jframe;
+}
+
+
+static void iotjs_websocket_create_buffer_and_cb(char **buff_ptr,
+                                                 uint32_t payload_len,
+                                                 char *cb_type,
+                                                 jerry_value_t jsref,
+                                                 jerry_value_t client) {
+  if (payload_len > 0) {
+    jerry_value_t ret_buff = iotjs_bufferwrap_create_buffer(payload_len);
+    iotjs_bufferwrap_t *buff_wrap = iotjs_bufferwrap_from_jbuffer(ret_buff);
+    iotjs_ws_write_data(buff_wrap->buffer, *buff_ptr, payload_len);
+    *buff_ptr += payload_len;
+    iotjs_websocket_create_callback(jsref, ret_buff, cb_type, client);
+    jerry_release_value(ret_buff);
+
+    return;
+  }
+  iotjs_websocket_create_callback(jsref, jerry_create_undefined(), cb_type,
+                                  client);
+}
+
+
+static jerry_value_t iotjs_websocket_check_error(uint8_t code) {
+  switch (code) {
+    case WS_ERR_INVALID_UTF8: {
+      return JS_CREATE_ERROR(COMMON, "Invalid UTF8 string in UTF8 message");
+    }
+
+    case WS_ERR_INVALID_TERMINATE_CODE: {
+      return JS_CREATE_ERROR(COMMON, "Invalid terminate code received");
+    }
+
+    case WS_ERR_UNKNOWN_OPCODE: {
+      return JS_CREATE_ERROR(COMMON, "Uknown opcode received");
+    }
+
+    case WS_ERR_NATIVE_POINTER_ERR: {
+      return JS_CREATE_ERROR(COMMON, "WebSocket native pointer unavailable");
+    }
+
+    case WS_ERR_FRAME_SIZE_LIMIT: {
+      return JS_CREATE_ERROR(COMMON, "Frame size received exceeds limit");
+    }
+
+    default: { return jerry_create_undefined(); };
+  }
+}
+
+
+JS_FUNCTION(PrepareHandshakeRequest) {
+  DJS_CHECK_THIS();
+
+  jerry_value_t jsref = JS_GET_ARG(0, object);
+  jerry_value_t jhost = JS_GET_ARG(1, any);
+  jerry_value_t jendpoint = JS_GET_ARG(2, any);
+
+  iotjs_string_t l_host;
+  iotjs_string_t l_endpoint;
+  if (!(iotjs_jbuffer_as_string(jendpoint, &l_endpoint)) ||
+      !(iotjs_jbuffer_as_string(jhost, &l_host))) {
+    return JS_CREATE_ERROR(COMMON, "Invalid host and/or path arguments!");
+  };
+
+  iotjs_wsclient_t *wsclient = (iotjs_wsclient_t *)
+      iotjs_jval_get_object_native_handle(jsref, &wsclient_native_info);
+  if (wsclient == NULL) {
+    return iotjs_websocket_check_error(WS_ERR_NATIVE_POINTER_ERR);
+  }
+
+  size_t generated_key_len = 0;
+  wsclient->generated_key = ws_generate_key(jsref, &generated_key_len);
+
+  jerry_value_t jfinal = iotjs_bufferwrap_create_buffer(
+      header_fixed_size + iotjs_string_size(&l_endpoint) +
+      iotjs_string_size(&l_host) + (sizeof(line_end) * 2) + generated_key_len);
+
+  iotjs_bufferwrap_t *final_wrap = iotjs_bufferwrap_from_jbuffer(jfinal);
+
+  char *buff_ptr = final_wrap->buffer;
+  buff_ptr = iotjs_ws_write_header(buff_ptr, method);
+  memcpy(buff_ptr, iotjs_string_data(&l_endpoint),
+         iotjs_string_size(&l_endpoint));
+  buff_ptr += iotjs_string_size(&l_endpoint);
+  buff_ptr = iotjs_ws_write_header(buff_ptr, protocol);
+  buff_ptr = iotjs_ws_write_header(buff_ptr, host);
+  memcpy(buff_ptr, iotjs_string_data(&l_host), iotjs_string_size(&l_host));
+  buff_ptr += iotjs_string_size(&l_host);
+  buff_ptr = iotjs_ws_write_header(buff_ptr, line_end);
+  buff_ptr = iotjs_ws_write_header(buff_ptr, upgrade);
+  buff_ptr = iotjs_ws_write_header(buff_ptr, connection);
+  buff_ptr = iotjs_ws_write_header(buff_ptr, sec_websocket_key);
+  memcpy(buff_ptr, wsclient->generated_key, generated_key_len);
+  buff_ptr += generated_key_len;
+  buff_ptr = iotjs_ws_write_header(buff_ptr, line_end);
+  buff_ptr = iotjs_ws_write_header(buff_ptr, sec_websocket_ver);
+
+  iotjs_string_destroy(&l_endpoint);
+  iotjs_string_destroy(&l_host);
+
+  return jfinal;
+}
+
+
+/**
+ * HTTP/1.1 101 Switching Protocols
+ * Upgrade: websocket
+ * Connection: Upgrade
+ * Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
+ */
+JS_FUNCTION(ReceiveHandshakeData) {
+  DJS_CHECK_THIS();
+  DJS_CHECK_ARGS(1, string);
+
+  iotjs_string_t client_key = JS_GET_ARG(0, string);
+
+  size_t key_len = 0;
+  unsigned char *key;
+  if (!(key = iotjs_make_handshake_key((char *)iotjs_string_data(&client_key),
+                                       &key_len))) {
+    return JS_CREATE_ERROR(COMMON, "mbedtls base64 encode failed");
+  }
+
+  jerry_value_t jfinal = iotjs_bufferwrap_create_buffer(
+      sizeof(handshake_response) - 1 + key_len + sizeof(line_end) * 2);
+
+  iotjs_bufferwrap_t *final_wrap = iotjs_bufferwrap_from_jbuffer(jfinal);
+  char *buff_ptr = final_wrap->buffer;
+  buff_ptr = iotjs_ws_write_header(buff_ptr, handshake_response);
+  memcpy(buff_ptr, key, key_len);
+  buff_ptr += key_len;
+  buff_ptr = iotjs_ws_write_header(buff_ptr, line_end);
+  buff_ptr = iotjs_ws_write_header(buff_ptr, line_end);
+
+  iotjs_string_destroy(&client_key);
+  IOTJS_RELEASE(key);
+  return jfinal;
+}
+
+JS_FUNCTION(ParseHandshakeData) {
+  DJS_CHECK_THIS();
+  DJS_CHECK_ARGS(2, object, object);
+
+  jerry_value_t jbuffer = JS_GET_ARG(0, object);
+  iotjs_bufferwrap_t *buff_wrap = iotjs_bufferwrap_from_jbuffer(jbuffer);
+  if (buff_wrap->length < 12 || strncmp(buff_wrap->buffer + 9, "101", 3)) {
+    return JS_CREATE_ERROR(COMMON, "WebSocket connection failed");
+  }
+  jerry_value_t jsref = JS_GET_ARG(1, object);
+
+  char ws_accept[] = "Sec-WebSocket-Accept: ";
+  char *frame_end = strstr(buff_wrap->buffer, "\r\n\r\n");
+  char *key_pos = strstr(buff_wrap->buffer, ws_accept) + strlen(ws_accept);
+  char key[28] = { 0 };
+  memcpy(key, key_pos, 28);
+
+  frame_end += 4; // \r\n\r\n
+
+  if (!iotjs_check_handshake_key(key, jsref)) {
+    return JS_CREATE_ERROR(COMMON, "WebSocket handshake key comparison failed");
+  }
+
+  size_t header_size = (size_t)(frame_end - buff_wrap->buffer);
+  if (buff_wrap->length > header_size) {
+    size_t remaining_length = buff_wrap->length - header_size;
+    jerry_value_t jdata = iotjs_bufferwrap_create_buffer(remaining_length);
+    iotjs_bufferwrap_t *data_wrap = iotjs_bufferwrap_from_jbuffer(jdata);
+
+    memcpy(data_wrap->buffer, buff_wrap->buffer + header_size,
+           remaining_length);
+    data_wrap->length = remaining_length;
+
+    return jdata;
+  }
+
+  return jerry_create_undefined();
+}
+
+
+static void iotjs_websocket_concat_tcp_buffers(iotjs_wsclient_t *wsclient,
+                                               iotjs_bufferwrap_t *buff_recv) {
+  char *tmp_buf = wsclient->tcp_buff.buffer;
+  wsclient->tcp_buff.buffer =
+      IOTJS_CALLOC(wsclient->tcp_buff.length + buff_recv->length, char);
+  memcpy(wsclient->tcp_buff.buffer, tmp_buf, wsclient->tcp_buff.length);
+  memcpy(wsclient->tcp_buff.buffer + wsclient->tcp_buff.length,
+         buff_recv->buffer, buff_recv->length);
+  wsclient->tcp_buff.length += buff_recv->length;
+  IOTJS_RELEASE(tmp_buf);
+}
+
+
+static uint8_t iotjs_websocket_decode_frame(iotjs_wsclient_t *wsclient,
+                                            char *first_byte, char *buff_ptr,
+                                            uint32_t payload_len,
+                                            jerry_value_t jsref, bool mask,
+                                            jerry_value_t client) {
+  uint8_t fin_bit = (first_byte[0] >> 7) & 0x01;
+  uint8_t opcode = first_byte[0] & 0x0F;
+
+  uint32_t *mask_key = NULL;
+  if (mask) {
+    mask_key = (uint32_t *)buff_ptr;
+    buff_ptr += sizeof(uint32_t);
+
+    for (uint64_t i = 0; i < payload_len; i++) {
+      buff_ptr[i] ^= ((unsigned char *)(mask_key))[i % 4];
+    }
+  }
+
+  switch (opcode) {
+    case WS_OP_CONTINUE: {
+      if (wsclient->ws_buff.length == 0) {
+        wsclient->ws_buff.masked = mask;
+        wsclient->ws_buff.first_byte = first_byte[0];
+        wsclient->ws_buff.data = IOTJS_CALLOC(payload_len, char);
+        memcpy(wsclient->ws_buff.data, buff_ptr, payload_len);
+        wsclient->ws_buff.length = payload_len;
+        break;
+      }
+
+      char *tmp_ptr = wsclient->ws_buff.data;
+      uint32_t tmp_len = wsclient->ws_buff.length;
+      wsclient->ws_buff.data =
+          IOTJS_CALLOC(wsclient->ws_buff.length + payload_len, char);
+      memcpy(wsclient->ws_buff.data, tmp_ptr, tmp_len);
+      memcpy(wsclient->ws_buff.data + tmp_len, buff_ptr, payload_len);
+      wsclient->ws_buff.length += payload_len;
+      IOTJS_RELEASE(tmp_ptr);
+
+
+      if (fin_bit) {
+        uint8_t ret_val =
+            iotjs_websocket_decode_frame(wsclient,
+                                         &wsclient->ws_buff.first_byte,
+                                         wsclient->ws_buff.data,
+                                         wsclient->ws_buff.length, jsref,
+                                         wsclient->ws_buff.masked, client);
+
+        IOTJS_RELEASE(wsclient->ws_buff.data);
+        wsclient->ws_buff.length = 0;
+        wsclient->ws_buff.first_byte = 0;
+
+        return ret_val;
+      }
+      break;
+    }
+
+    case WS_OP_UTF8:
+    case WS_OP_BINARY: {
+      if (opcode == WS_OP_UTF8 &&
+          !jerry_is_valid_utf8_string((unsigned char *)buff_ptr, payload_len)) {
+        return WS_ERR_INVALID_UTF8;
+      }
+      iotjs_websocket_create_buffer_and_cb(&buff_ptr, payload_len,
+                                           IOTJS_MAGIC_STRING_ONMESSAGE, jsref,
+                                           client);
+      break;
+    }
+
+    case WS_OP_TERMINATE: {
+      if (payload_len > 0) {
+        uint16_t ret_code = (uint16_t)((unsigned char)buff_ptr[0] << 8 |
+                                       (unsigned char)buff_ptr[1]);
+        if (ret_code > 4999 || ret_code < 1000) {
+          return WS_ERR_INVALID_TERMINATE_CODE;
+        }
+
+        buff_ptr += 2;
+        payload_len -= 2;
+        uint8_t ret_code_str_size = 4;
+        char ret_code_str[ret_code_str_size + 1];
+        sprintf(ret_code_str, "%d", ret_code);
+        ret_code_str[ret_code_str_size] = '\0';
+
+        jerry_value_t ret_buff =
+            iotjs_bufferwrap_create_buffer(payload_len + ret_code_str_size);
+        iotjs_bufferwrap_t *ret_wrap = iotjs_bufferwrap_from_jbuffer(ret_buff);
+        char *local_ptr = ret_wrap->buffer;
+        local_ptr =
+            iotjs_ws_write_data(local_ptr, ret_code_str, ret_code_str_size);
+        local_ptr = iotjs_ws_write_data(local_ptr, buff_ptr, payload_len);
+        buff_ptr += payload_len;
+        iotjs_websocket_create_callback(jsref, ret_buff,
+                                        IOTJS_MAGIC_STRING_ONCLOSE, client);
+        jerry_release_value(ret_buff);
+        break;
+      }
+      iotjs_websocket_create_callback(jsref, jerry_create_undefined(),
+                                      IOTJS_MAGIC_STRING_ONCLOSE, client);
+      break;
+    }
+
+    case WS_OP_PING: {
+      iotjs_websocket_create_buffer_and_cb(&buff_ptr, payload_len,
+                                           IOTJS_MAGIC_STRING_PONG, jsref,
+                                           client);
+      break;
+    }
+
+    case WS_OP_PONG: {
+      iotjs_websocket_create_buffer_and_cb(&buff_ptr, payload_len,
+                                           IOTJS_MAGIC_STRING_ONPINGRESP, jsref,
+                                           client);
+      break;
+    }
+
+    default:
+      return WS_ERR_UNKNOWN_OPCODE;
+      break;
+  }
+
+  return 0;
+}
+
+
+JS_FUNCTION(WsReceive) {
+  DJS_CHECK_THIS();
+  DJS_CHECK_ARGS(3, object, object, object);
+
+  jerry_value_t jsref = JS_GET_ARG(0, object);
+
+  iotjs_wsclient_t *wsclient = (iotjs_wsclient_t *)
+      iotjs_jval_get_object_native_handle(jsref, &wsclient_native_info);
+  if (wsclient == NULL) {
+    return iotjs_websocket_check_error(WS_ERR_NATIVE_POINTER_ERR);
+  }
+
+  jerry_value_t jbuffer = JS_GET_ARG(1, object);
+  iotjs_bufferwrap_t *buffer_wrap = iotjs_bufferwrap_from_jbuffer(jbuffer);
+
+  jerry_value_t client = JS_GET_ARG(2, object);
+
+  if (buffer_wrap->length == 0) {
+    return jerry_create_undefined();
+  }
+
+  char *current_buffer = buffer_wrap->buffer;
+  char *current_buffer_end = current_buffer + buffer_wrap->length;
+
+  if (wsclient->tcp_buff.length > 0) {
+    iotjs_websocket_concat_tcp_buffers(wsclient, buffer_wrap);
+    current_buffer = wsclient->tcp_buff.buffer;
+    current_buffer_end = current_buffer + wsclient->tcp_buff.length;
+  }
+
+
+  while (true) {
+    if (current_buffer >= current_buffer_end) {
+      if (wsclient->tcp_buff.length > 0) {
+        IOTJS_RELEASE(wsclient->tcp_buff.buffer);
+        wsclient->tcp_buff.length = 0;
+      }
+      return jerry_create_undefined();
+    }
+
+    if (current_buffer + 2 > current_buffer_end) {
+      break;
+    }
+
+    char *first_byte = current_buffer;
+    uint8_t payload_byte = (current_buffer[1]) & WS_THREE_BYTES_LENGTH;
+    uint8_t mask = (first_byte[1] >> 7) & 0x01;
+
+    current_buffer += 2;
+
+    uint32_t payload_len;
+    if (!(payload_byte ^ WS_TWO_BYTES_LENGTH)) {
+      if (current_buffer + sizeof(uint16_t) > current_buffer_end) {
+        break;
+      }
+      payload_len = (uint16_t)(current_buffer[0] << 8 | current_buffer[1]);
+      current_buffer += sizeof(uint16_t);
+    } else if (!(payload_byte ^ WS_THREE_BYTES_LENGTH)) {
+      if (current_buffer + sizeof(uint64_t) > current_buffer_end) {
+        break;
+      }
+      if ((*(uint64_t *)current_buffer & UINT32_MAX) > UINT32_MAX) {
+        return WS_ERR_FRAME_SIZE_LIMIT;
+      }
+      for (uint8_t i = 0; i < sizeof(uint64_t); i++) {
+        memcpy((uint8_t *)&payload_len + i,
+               current_buffer + sizeof(uint64_t) - 1 - i, sizeof(uint8_t));
+      }
+      current_buffer += sizeof(uint64_t);
+    } else {
+      payload_len = payload_byte;
+    }
+
+    if (mask && ((current_buffer + 4 > current_buffer_end) ||
+                 (current_buffer + 4 + payload_len > current_buffer_end))) {
+      break;
+    } else if (!mask && (current_buffer + payload_len > current_buffer_end)) {
+      break;
+    }
+
+    uint8_t ret_val =
+        iotjs_websocket_decode_frame(wsclient, first_byte, current_buffer,
+                                     payload_len, jsref, mask, client);
+    if (ret_val) {
+      return iotjs_websocket_check_error(ret_val);
+    }
+
+    current_buffer += mask ? 4 : 0;
+    current_buffer += payload_len;
+  }
+
+  if (current_buffer == wsclient->tcp_buff.buffer) {
+    return jerry_create_undefined();
+  }
+
+  uint32_t remaining_size = (uint32_t)(current_buffer_end - current_buffer);
+  char *buffer = IOTJS_CALLOC(remaining_size, char);
+  memcpy(buffer, current_buffer, remaining_size);
+
+  if (wsclient->tcp_buff.buffer != NULL) {
+    IOTJS_RELEASE(wsclient->tcp_buff.buffer);
+  }
+
+  wsclient->tcp_buff.buffer = buffer;
+  wsclient->tcp_buff.length = remaining_size;
+
+  return jerry_create_undefined();
+}
+
+
+JS_FUNCTION(WsInit) {
+  DJS_CHECK_THIS();
+
+  const jerry_value_t jws = JS_GET_ARG(0, object);
+
+  iotjs_wsclient_t *wsclient = iotjs_wsclient_create(jws);
+  wsclient->tcp_buff.buffer = NULL;
+  wsclient->tcp_buff.length = 0;
+
+  wsclient->ws_buff.data = NULL;
+  wsclient->ws_buff.length = 0;
+
+  wsclient->generated_key = NULL;
+
+  return jerry_create_undefined();
+}
+
+
+JS_FUNCTION(WsClose) {
+  DJS_CHECK_THIS();
+
+  bool masked = false;
+  uint8_t opcode = WS_OP_TERMINATE;
+  iotjs_string_t payload = iotjs_string_create();
+
+
+  jerry_value_t jmsg = JS_GET_ARG(0, any);
+  jerry_value_t jcode = JS_GET_ARG(1, any);
+
+  iotjs_string_t msg = iotjs_string_create();
+  // Client side close frame must be ALWAYS masked
+  masked = iotjs_jbuffer_as_string(jmsg, &msg) || jerry_value_is_number(jcode);
+
+  if (jerry_value_is_number(jcode)) {
+    uint16_t code = jerry_get_number_value(jcode);
+    iotjs_string_append(&payload, (const char *)&code + 1, 1);
+    iotjs_string_append(&payload, (const char *)&code, 1);
+  }
+
+  if (!iotjs_string_is_empty(&msg)) {
+    // We have no status code, but do have msg, append the status code
+    if (iotjs_string_is_empty(&payload)) {
+      uint16_t code = 1000;
+      iotjs_string_append(&payload, (const char *)&code + 1, 1);
+      iotjs_string_append(&payload, (const char *)&code, 1);
+    }
+    iotjs_string_append(&payload, iotjs_string_data(&msg),
+                        iotjs_string_size(&msg));
+    iotjs_string_destroy(&msg);
+  }
+
+  jerry_value_t ret_val =
+      iotjs_websocket_encode_frame(opcode, masked, false,
+                                   (char *)iotjs_string_data(&payload),
+                                   iotjs_string_size(&payload));
+
+  if (payload.data != NULL) {
+    iotjs_string_destroy(&payload);
+  }
+
+  return ret_val;
+}
+
+
+JS_FUNCTION(WsSendData) {
+  DJS_CHECK_THIS();
+
+  jerry_value_t jmsg = JS_GET_ARG(0, any);
+  iotjs_string_t msg = iotjs_string_create();
+
+  if (!iotjs_jbuffer_as_string(jmsg, &msg)) {
+    return jerry_create_undefined();
+  }
+
+  bool binary = jerry_get_boolean_value(jargv[1]);
+  bool mask = jerry_get_boolean_value(jargv[2]);
+  bool compress = jerry_get_boolean_value(jargv[3]);
+
+  uint8_t opcode = binary ? WS_OP_BINARY : WS_OP_UTF8;
+
+  jerry_value_t ret_val =
+      iotjs_websocket_encode_frame(opcode, mask, compress,
+                                   (char *)iotjs_string_data(&msg),
+                                   iotjs_string_size(&msg));
+
+  iotjs_string_destroy(&msg);
+  return ret_val;
+}
+
+
+JS_FUNCTION(WsPingOrPong) {
+  DJS_CHECK_THIS();
+
+  uint8_t opcode =
+      jerry_get_boolean_value(JS_GET_ARG(0, any)) ? WS_OP_PING : WS_OP_PONG;
+  jerry_value_t jmsg = JS_GET_ARG(1, any);
+
+  iotjs_string_t msg = iotjs_string_create();
+
+  jerry_value_t ret_val;
+
+  if (iotjs_jbuffer_as_string(jmsg, &msg)) {
+    ret_val =
+        iotjs_websocket_encode_frame(opcode, jerry_get_boolean_value(
+                                                 JS_GET_ARG(2, any)),
+                                     false, (char *)iotjs_string_data(&msg),
+                                     iotjs_string_size(&msg));
+    iotjs_string_destroy(&msg);
+  } else {
+    ret_val = iotjs_websocket_encode_frame(opcode, false, false, NULL, 0);
+  }
+
+  return ret_val;
+}
+
+
+jerry_value_t InitWebsocket() {
+  IOTJS_UNUSED(WS_GUID);
+  jerry_value_t jws = jerry_create_object();
+  iotjs_jval_set_method(jws, IOTJS_MAGIC_STRING_CLOSE, WsClose);
+  iotjs_jval_set_method(jws, IOTJS_MAGIC_STRING_PARSEHANDSHAKEDATA,
+                        ParseHandshakeData);
+  iotjs_jval_set_method(jws, IOTJS_MAGIC_STRING_PING, WsPingOrPong);
+  iotjs_jval_set_method(jws, IOTJS_MAGIC_STRING_PREPAREHANDSHAKE,
+                        PrepareHandshakeRequest);
+  iotjs_jval_set_method(jws, IOTJS_MAGIC_STRING_SEND, WsSendData);
+  iotjs_jval_set_method(jws, IOTJS_MAGIC_STRING_WSINIT, WsInit);
+  iotjs_jval_set_method(jws, IOTJS_MAGIC_STRING_WSRECEIVE, WsReceive);
+  iotjs_jval_set_method(jws, IOTJS_MAGIC_STRING_WSRECEIVEHANDSHAKEDATA,
+                        ReceiveHandshakeData);
+
+  return jws;
+}
diff --git a/src/modules/iotjs_module_websocket.h b/src/modules/iotjs_module_websocket.h
new file mode 100644 (file)
index 0000000..b9237e7
--- /dev/null
@@ -0,0 +1,62 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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 IOTJS_MODULE_WEBSOCKET_H
+#define IOTJS_MODULE_WEBSOCKET_H
+
+enum {
+  WS_OP_CONTINUE = 0x00,
+  WS_OP_UTF8 = 0x01,
+  WS_OP_BINARY = 0x02,
+  WS_OP_TERMINATE = 0x08,
+  WS_OP_PING = 0x09,
+  WS_OP_PONG = 0x0a,
+} iotjs_websocket_opcodes;
+
+enum {
+  WS_FIN_BIT = 0x80,
+  WS_MASK_BIT = WS_FIN_BIT,
+} iotjs_websocket_header_bits;
+
+enum {
+  WS_ERR_INVALID_UTF8 = 1,
+  WS_ERR_INVALID_TERMINATE_CODE = 2,
+  WS_ERR_UNKNOWN_OPCODE = 3,
+  WS_ERR_NATIVE_POINTER_ERR = 4,
+  WS_ERR_FRAME_SIZE_LIMIT = 5,
+} iotjs_websocket_err_codes;
+
+enum {
+  WS_ONE_BYTE_LENGTH = 125,
+  WS_TWO_BYTES_LENGTH,
+  WS_THREE_BYTES_LENGTH,
+} iotjs_websocket_frame_len_types;
+
+
+typedef struct {
+  struct {
+    uint32_t length;
+    char *buffer;
+  } tcp_buff;
+
+  struct {
+    uint32_t length;
+    char *data;
+    char first_byte;
+    bool masked;
+  } ws_buff;
+  unsigned char *generated_key;
+} iotjs_wsclient_t;
+
+#endif /* IOTJS_MODULE_WEBSOCKET_H */
index b71ade0f387efde0112fa817aefa5896663b6004..237f35d1548476cc326383efaf569cce76998fba 100644 (file)
@@ -281,21 +281,18 @@ void iotjs_blehcisocket_poll(iotjs_blehcisocket_t* blehcisocket) {
     jerry_value_t jemit = iotjs_jval_get_property(jhcisocket, "emit");
     IOTJS_ASSERT(jerry_value_is_function(jemit));
 
-    iotjs_jargs_t jargs = iotjs_jargs_create(2);
     jerry_value_t str = jerry_create_string((const jerry_char_t*)"data");
     IOTJS_ASSERT(length >= 0);
     jerry_value_t jbuf = iotjs_bufferwrap_create_buffer((size_t)length);
     iotjs_bufferwrap_t* buf_wrap = iotjs_bufferwrap_from_jbuffer(jbuf);
     iotjs_bufferwrap_copy(buf_wrap, data, (size_t)length);
-    iotjs_jargs_append_jval(&jargs, str);
-    iotjs_jargs_append_jval(&jargs, jbuf);
-    jerry_value_t jres = iotjs_jhelper_call(jemit, jhcisocket, &jargs);
-    IOTJS_ASSERT(!jerry_value_has_error_flag(jres));
+    jerry_value_t jargs[2] = { str, jbuf };
+    jerry_value_t jres = jerry_call_function(jemit, jhcisocket, jargs, 2);
+    IOTJS_ASSERT(!jerry_value_is_error(jres));
 
     jerry_release_value(jres);
     jerry_release_value(str);
     jerry_release_value(jbuf);
-    iotjs_jargs_destroy(&jargs);
     jerry_release_value(jemit);
   }
 }
@@ -319,16 +316,16 @@ void iotjs_blehcisocket_emitErrnoError(iotjs_blehcisocket_t* blehcisocket) {
   jerry_value_t jemit = iotjs_jval_get_property(jhcisocket, "emit");
   IOTJS_ASSERT(jerry_value_is_function(jemit));
 
-  iotjs_jargs_t jargs = iotjs_jargs_create(2);
   jerry_value_t str = jerry_create_string((const jerry_char_t*)"error");
-  iotjs_jargs_append_jval(&jargs, str);
-  iotjs_jargs_append_error(&jargs, strerror(errno));
-  jerry_value_t jres = iotjs_jhelper_call(jemit, jhcisocket, &jargs);
-  IOTJS_ASSERT(!jerry_value_has_error_flag(jres));
+  jerry_value_t jerror =
+      iotjs_jval_create_error_without_error_flag(strerror(errno));
+  jerry_value_t jargs[2] = { str, jerror };
+  jerry_value_t jres = jerry_call_function(jemit, jhcisocket, jargs, 2);
+  IOTJS_ASSERT(!jerry_value_is_error(jres));
 
   jerry_release_value(jres);
   jerry_release_value(str);
-  iotjs_jargs_destroy(&jargs);
+  jerry_release_value(jerror);
   jerry_release_value(jemit);
 }
 
index 263d2db1678989cbf0ecec6360daec72b29adaee..60f703e3cd86806d071ea9058cfc46e75edb27bc 100644 (file)
@@ -78,9 +78,8 @@ static void gpio_emit_change_event(iotjs_gpio_t* gpio) {
   jerry_value_t jonChange = iotjs_jval_get_property(jgpio, "onChange");
   IOTJS_ASSERT(jerry_value_is_function(jonChange));
 
-  jerry_value_t jres =
-      iotjs_jhelper_call(jonChange, jgpio, iotjs_jargs_get_empty());
-  IOTJS_ASSERT(!jerry_value_has_error_flag(jres));
+  jerry_value_t jres = jerry_call_function(jonChange, jgpio, NULL, 0);
+  IOTJS_ASSERT(!jerry_value_is_error(jres));
 
   jerry_release_value(jres);
   jerry_release_value(jonChange);
@@ -283,3 +282,12 @@ bool iotjs_gpio_open(iotjs_gpio_t* gpio) {
 
   return true;
 }
+
+
+bool iotjs_gpio_set_direction(iotjs_gpio_t* gpio) {
+  if (!gpio_set_direction(gpio->pin, gpio->direction)) {
+    DLOG("%s, Cannot set direction.", __func__);
+    return false;
+  }
+  return true;
+}
index c2d3f457a575a07cbf2ea150bfe51d70a448c6f2..51f0888b929ca9d66b20d7ef0050bad43158a86f 100644 (file)
@@ -58,7 +58,7 @@ jerry_value_t iotjs_pwm_set_platform_config(iotjs_pwm_t* pwm,
   jerry_value_t jchip =
       iotjs_jval_get_property(jconfig, IOTJS_MAGIC_STRING_CHIP);
 
-  if (jerry_value_has_error_flag(jchip)) {
+  if (jerry_value_is_error(jchip)) {
     return jchip;
   }
 
index 7a33f1f29478322ded6a7b62c654752898d8f253..52fc13871d5e4186caed3dac997e0e12ea8434bf 100644 (file)
@@ -18,6 +18,7 @@
 #include <termios.h>
 #include <unistd.h>
 
+#include "iotjs_uv_handle.h"
 #include "modules/iotjs_module_uart.h"
 
 struct iotjs_uart_platform_data_s {
@@ -100,7 +101,9 @@ jerry_value_t iotjs_uart_set_platform_config(iotjs_uart_t* uart,
   return jerry_create_undefined();
 }
 
-bool iotjs_uart_open(iotjs_uart_t* uart) {
+bool iotjs_uart_open(uv_handle_t* uart_poll_handle) {
+  iotjs_uart_t* uart =
+      (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(uart_poll_handle);
   int fd = open(iotjs_string_data(&uart->platform_data->device_path),
                 O_RDWR | O_NOCTTY | O_NDELAY);
   if (fd < 0) {
@@ -119,12 +122,15 @@ bool iotjs_uart_open(iotjs_uart_t* uart) {
   tcsetattr(fd, TCSANOW, &options);
 
   uart->device_fd = fd;
-  iotjs_uart_register_read_cb(uart);
+  iotjs_uart_register_read_cb((uv_poll_t*)uart_poll_handle);
 
   return true;
 }
 
-bool iotjs_uart_write(iotjs_uart_t* uart) {
+bool iotjs_uart_write(uv_handle_t* uart_poll_handle) {
+  iotjs_uart_t* uart =
+      (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(uart_poll_handle);
+
   int bytesWritten = 0;
   unsigned offset = 0;
   int fd = uart->device_fd;
@@ -155,8 +161,9 @@ bool iotjs_uart_write(iotjs_uart_t* uart) {
   return true;
 }
 
-void iotjs_uart_handlewrap_close_cb(uv_handle_t* handle) {
-  iotjs_uart_t* uart = (iotjs_uart_t*)handle->data;
+void iotjs_uart_handle_close_cb(uv_handle_t* uart_poll_handle) {
+  iotjs_uart_t* uart =
+      (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(uart_poll_handle);
 
   if (close(uart->device_fd) < 0) {
     DLOG(iotjs_periph_error_str(kUartOpClose));
diff --git a/src/modules/mock/iotjs_module_gpio-mock.c b/src/modules/mock/iotjs_module_gpio-mock.c
new file mode 100644 (file)
index 0000000..04db0a8
--- /dev/null
@@ -0,0 +1,73 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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 <stdlib.h>
+
+#include "modules/iotjs_module_gpio.h"
+
+struct iotjs_gpio_platform_data_s {
+  bool is_open;
+  bool level;
+};
+
+
+void iotjs_gpio_create_platform_data(iotjs_gpio_t* gpio) {
+  gpio->platform_data = IOTJS_ALLOC(iotjs_gpio_platform_data_t);
+}
+
+
+void iotjs_gpio_destroy_platform_data(
+    iotjs_gpio_platform_data_t* platform_data) {
+  IOTJS_RELEASE(platform_data);
+}
+
+
+bool iotjs_gpio_open(iotjs_gpio_t* gpio) {
+  DDDLOG("%s - pin: %d, direction: %d, mode: %d", __func__, gpio->pin,
+         gpio->direction, gpio->mode);
+  if (gpio->platform_data->is_open) {
+    return false; // pin is open already
+  }
+
+  gpio->platform_data->is_open = true;
+  return true;
+}
+
+
+bool iotjs_gpio_write(iotjs_gpio_t* gpio) {
+  gpio->platform_data->level = gpio->value;
+  return true;
+}
+
+
+bool iotjs_gpio_read(iotjs_gpio_t* gpio) {
+  gpio->value = gpio->platform_data->level;
+  return true;
+}
+
+
+bool iotjs_gpio_close(iotjs_gpio_t* gpio) {
+  if (!gpio->platform_data->is_open) {
+    return false; // pin is not open
+  }
+
+  gpio->platform_data->is_open = false;
+  return true;
+}
+
+
+bool iotjs_gpio_set_direction(iotjs_gpio_t* gpio) {
+  return true;
+}
diff --git a/src/modules/mock/iotjs_module_i2c-mock.c b/src/modules/mock/iotjs_module_i2c-mock.c
new file mode 100644 (file)
index 0000000..f18af80
--- /dev/null
@@ -0,0 +1,54 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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 "modules/iotjs_module_i2c.h"
+
+struct iotjs_i2c_platform_data_s {
+  int bus;
+};
+
+
+void iotjs_i2c_create_platform_data(iotjs_i2c_t* i2c) {
+  i2c->platform_data = IOTJS_ALLOC(iotjs_i2c_platform_data_t);
+}
+
+
+void iotjs_i2c_destroy_platform_data(iotjs_i2c_platform_data_t* platform_data) {
+  IOTJS_ASSERT(platform_data);
+  IOTJS_RELEASE(platform_data);
+}
+
+jerry_value_t iotjs_i2c_set_platform_config(iotjs_i2c_t* i2c,
+                                            const jerry_value_t jconfig) {
+  return jerry_create_undefined();
+}
+
+bool iotjs_i2c_open(iotjs_i2c_t* i2c) {
+  return true;
+}
+
+bool iotjs_i2c_close(iotjs_i2c_t* i2c) {
+  return true;
+}
+
+bool iotjs_i2c_write(iotjs_i2c_t* i2c) {
+  IOTJS_RELEASE(i2c->buf_data);
+  return true;
+}
+
+bool iotjs_i2c_read(iotjs_i2c_t* i2c) {
+  i2c->buf_data = iotjs_buffer_allocate(i2c->buf_len);
+  return true;
+}
index dd271971f270ca28616dced2ddf380de7715f4bf..974083d8c25e6c4a23663de2dff18c7cee0402fb 100644 (file)
@@ -53,7 +53,9 @@ bool iotjs_gpio_write(iotjs_gpio_t* gpio) {
 
 bool iotjs_gpio_read(iotjs_gpio_t* gpio) {
   DDDLOG("%s - pin: %d", __func__, gpio->pin);
-  return stm32_gpioread(gpio->pin);
+
+  gpio->value = stm32_gpioread(gpio->pin);
+  return true;
 }
 
 
@@ -64,10 +66,7 @@ bool iotjs_gpio_close(iotjs_gpio_t* gpio) {
 }
 
 
-bool iotjs_gpio_open(iotjs_gpio_t* gpio) {
-  DDDLOG("%s - pin: %d, dir: %d, mode: %d", __func__, gpio->pin,
-         gpio->direction, gpio->mode);
-
+static bool gpio_set_config(iotjs_gpio_t* gpio) {
   uint32_t cfgset = 0;
 
   // Set pin direction and mode
@@ -79,3 +78,15 @@ bool iotjs_gpio_open(iotjs_gpio_t* gpio) {
 
   return true;
 }
+
+
+bool iotjs_gpio_open(iotjs_gpio_t* gpio) {
+  DDDLOG("%s - pin: %d, dir: %d, mode: %d", __func__, gpio->pin,
+         gpio->direction, gpio->mode);
+  return gpio_set_config(gpio);
+}
+
+
+bool iotjs_gpio_set_direction(iotjs_gpio_t* gpio) {
+  return gpio_set_config(gpio);
+}
index 5a3bf2f5dc1c1996caf97d6bcc7ce167222f73de..e7792a1c711f89ba1f23038f232674957bc2b966 100644 (file)
@@ -15,6 +15,8 @@
 
 #include "modules/iotjs_module_uart.h"
 
+#include "iotjs_uv_handle.h"
+
 struct iotjs_uart_platform_data_s {
   iotjs_string_t device_path;
 };
@@ -39,7 +41,9 @@ jerry_value_t iotjs_uart_set_platform_config(iotjs_uart_t* uart,
   return jerry_create_undefined();
 }
 
-bool iotjs_uart_open(iotjs_uart_t* uart) {
+bool iotjs_uart_open(uv_handle_t* uart_poll_handle) {
+  iotjs_uart_t* uart =
+      (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(uart_poll_handle);
   int fd = open(iotjs_string_data(&uart->platform_data->device_path),
                 O_RDWR | O_NOCTTY | O_NDELAY);
 
@@ -48,12 +52,14 @@ bool iotjs_uart_open(iotjs_uart_t* uart) {
   }
 
   uart->device_fd = fd;
-  iotjs_uart_register_read_cb(uart);
+  iotjs_uart_register_read_cb((uv_poll_t*)uart);
 
   return true;
 }
 
-bool iotjs_uart_write(iotjs_uart_t* uart) {
+bool iotjs_uart_write(uv_handle_t* uart_poll_handle) {
+  iotjs_uart_t* uart =
+      (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(uart_poll_handle);
   int bytesWritten = 0;
   unsigned offset = 0;
   int fd = uart->device_fd;
@@ -83,8 +89,9 @@ bool iotjs_uart_write(iotjs_uart_t* uart) {
   return true;
 }
 
-void iotjs_uart_handlewrap_close_cb(uv_handle_t* handle) {
-  iotjs_uart_t* uart = (iotjs_uart_t*)handle->data;
+void iotjs_uart_handle_close_cb(uv_handle_t* uart_poll_handle) {
+  iotjs_uart_t* uart =
+      (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(uart_poll_handle);
 
   if (close(uart->device_fd) < 0) {
     DLOG(iotjs_periph_error_str(kUartOpClose));
index 422a2d7da49f44d1f71aa514430be0012f13ebc5..e2834f74bbdbca69417ec165a676acacd12d9457 100644 (file)
@@ -70,7 +70,7 @@ bool iotjs_gpio_open(iotjs_gpio_t* gpio) {
   if (gpio->direction == kGpioDirectionIn) {
     _direction = PERIPHERAL_GPIO_DIRECTION_IN;
   } else {
-    _direction = PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_HIGH;
+    _direction = PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW;
   }
 
   retVal = peripheral_gpio_set_direction(_gpio, _direction);
@@ -104,3 +104,22 @@ bool iotjs_gpio_open(iotjs_gpio_t* gpio) {
 
   return true;
 }
+
+
+bool iotjs_gpio_set_direction(iotjs_gpio_t* gpio) {
+  peripheral_gpio_direction_e direction;
+  if (gpio->direction == kGpioDirectionIn) {
+    direction = PERIPHERAL_GPIO_DIRECTION_IN;
+  } else {
+    direction = PERIPHERAL_GPIO_DIRECTION_OUT_INITIALLY_LOW;
+  }
+
+  int ret = peripheral_gpio_set_direction(gpio->platform_data->peripheral_gpio,
+                                          direction);
+  if (ret != PERIPHERAL_ERROR_NONE) {
+    DLOG("%s, Cannot set direction(%d).", __func__, ret);
+    return false;
+  }
+
+  return true;
+}
index 9d00793fcd0d9004dec32f5b07dd822af6a57389..e4f7a840d6a232c97d8a1f7d1c499d5f8f5fea2b 100644 (file)
@@ -99,6 +99,17 @@ void iotjs_tizen_app_control_cb(app_control_h app_control, void* user_data) {
     return;
   }
 
+  const char* event_emitter_name = IOTJS_MAGIC_STRING_TIZEN;
+  const char* event_name = IOTJS_MAGIC_STRING_APP_CONTROL;
+
+  jerry_value_t tizen = iotjs_module_get(event_emitter_name);
+  jerry_value_t fn = iotjs_jval_get_property(tizen, IOTJS_MAGIC_STRING_EMIT);
+
+  if (jerry_value_is_function(fn) == false) {
+    DDDLOG("tizen module is not loaded");
+    goto exit;
+  }
+
   // parse app control
   char* json = NULL;
   bundle* b = NULL;
@@ -112,25 +123,20 @@ void iotjs_tizen_app_control_cb(app_control_h app_control, void* user_data) {
   }
   DDDLOG("JSON: %s", json);
 
-  // prepare emit
-  const char* event_emitter_name = IOTJS_MAGIC_STRING_TIZEN;
-  const char* event_name = IOTJS_MAGIC_STRING_APP_CONTROL;
-
-  jerry_value_t tizen = iotjs_module_get(event_emitter_name);
-  jerry_value_t fn = iotjs_jval_get_property(tizen, IOTJS_MAGIC_STRING_EMIT);
-
   // call emit
-  iotjs_jargs_t jargv = iotjs_jargs_create(2);
-  iotjs_jargs_append_string_raw(&jargv, event_name);
-  iotjs_jargs_append_string_raw(&jargv, json);
+  jerry_value_t jargv[2] = { jerry_create_string(
+                                 (const jerry_char_t*)event_name),
+                             jerry_create_string((const jerry_char_t*)json) };
 
-  iotjs_make_callback(fn, tizen, &jargv);
+  iotjs_invoke_callback(fn, tizen, jargv, 2);
+  jerry_release_value(jargv[0]);
+  jerry_release_value(jargv[1]);
 
   free(json);
   bundle_free(b);
 
+exit:
   jerry_release_value(fn);
-  iotjs_jargs_destroy(&jargv);
 }
 
 
@@ -144,7 +150,12 @@ void iotjs_tizen_func(const char* command, const char* message, void* handle) {
     if (app_res_path != NULL) {
       free(app_res_path);
     }
-
+  } else if (strncmp(command, "getDataPath", strlen("getDataPath")) == 0) {
+    char* app_data_path = app_get_data_path();
+    iotjs_bridge_set_msg(handle, app_data_path);
+    if (app_data_path != NULL) {
+      free(app_data_path);
+    }
   } else if (strncmp(command, "launchAppControl", strlen("launchAppControl")) ==
              0) {
     iotjs_error_t err = tizen_send_launch_request(message, handle);
@@ -190,9 +201,9 @@ static bool bridge_native_call(const char* module_name, const char* func_name,
     return result;
   }
 
-  iotjs_jargs_t jargv = iotjs_jargs_create(1);
-  iotjs_jargs_append_string_raw(&jargv, message);
-  jerry_value_t jres = iotjs_make_callback_with_result(jfunc, jmodule, &jargv);
+  jerry_value_t jval = jerry_create_string((const jerry_char_t*)message);
+  jerry_value_t jres =
+      iotjs_invoke_callback_with_result(jfunc, jmodule, &jval, 1);
 
   if (jerry_value_is_string(jres)) {
     IOTJS_ASSERT(output_str != NULL);
@@ -202,7 +213,7 @@ static bool bridge_native_call(const char* module_name, const char* func_name,
 
   jerry_release_value(jfunc);
   jerry_release_value(jres);
-  iotjs_jargs_destroy(&jargv);
+  jerry_release_value(jval);
   return result;
 }
 
index d7325eb02c8515d56c9131fda2826b207f27b54c..79b433a8136102c296a8594746d5d4e7fe5f98f5 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <peripheral_io.h>
 
+#include "iotjs_uv_handle.h"
 #include "modules/iotjs_module_uart.h"
 
 struct _peripheral_uart_s {
@@ -108,7 +109,9 @@ jerry_value_t iotjs_uart_set_platform_config(iotjs_uart_t* uart,
   return jerry_create_undefined();
 }
 
-bool iotjs_uart_open(iotjs_uart_t* uart) {
+bool iotjs_uart_open(uv_handle_t* uart_poll_handle) {
+  iotjs_uart_t* uart =
+      (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(uart_poll_handle);
   iotjs_uart_platform_data_t* platform_data = uart->platform_data;
   IOTJS_ASSERT(platform_data);
 
@@ -137,12 +140,14 @@ bool iotjs_uart_open(iotjs_uart_t* uart) {
   }
 
   uart->device_fd = platform_data->uart_h->fd;
-  iotjs_uart_register_read_cb(uart);
+  iotjs_uart_register_read_cb((uv_poll_t*)uart_poll_handle);
 
   return true;
 }
 
-bool iotjs_uart_write(iotjs_uart_t* uart) {
+bool iotjs_uart_write(uv_handle_t* uart_poll_handle) {
+  iotjs_uart_t* uart =
+      (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(uart_poll_handle);
   iotjs_uart_platform_data_t* platform_data = uart->platform_data;
   IOTJS_ASSERT(platform_data);
   if (!platform_data->uart_h) {
@@ -163,8 +168,9 @@ bool iotjs_uart_write(iotjs_uart_t* uart) {
   return true;
 }
 
-void iotjs_uart_handlewrap_close_cb(uv_handle_t* handle) {
-  iotjs_uart_t* uart = (iotjs_uart_t*)handle->data;
+void iotjs_uart_handle_close_cb(uv_handle_t* uart_poll_handle) {
+  iotjs_uart_t* uart =
+      (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(uart_poll_handle);
 
   if (peripheral_uart_close(uart->platform_data->uart_h) !=
       PERIPHERAL_ERROR_NONE) {
index ac14db93bb4b8893aa59033d06a0cb4feacd3e16..965ca847e422e2f49b35b4b2b047681fb2be6218 100644 (file)
@@ -75,9 +75,13 @@ bool iotjs_gpio_write(iotjs_gpio_t* gpio) {
 
 
 bool iotjs_gpio_read(iotjs_gpio_t* gpio) {
-  if (iotbus_gpio_read(gpio->platform_data->gpio_context) < 0) {
+  int ret = iotbus_gpio_read(gpio->platform_data->gpio_context);
+  if (ret < 0) {
+    DLOG("%s, Cannot read value(%d).", __func__, ret);
     return false;
   }
+
+  gpio->value = (bool)ret;
   return true;
 }
 
@@ -89,3 +93,22 @@ bool iotjs_gpio_close(iotjs_gpio_t* gpio) {
   }
   return true;
 }
+
+
+bool iotjs_gpio_set_direction(iotjs_gpio_t* gpio) {
+  iotbus_gpio_direction_e direction;
+  if (gpio->direction == kGpioDirectionIn) {
+    direction = IOTBUS_GPIO_DIRECTION_IN;
+  } else {
+    direction = IOTBUS_GPIO_DIRECTION_OUT;
+  }
+
+  int ret =
+      iotbus_gpio_set_direction(gpio->platform_data->gpio_context, direction);
+  if (ret != 0) {
+    DLOG("%s, Cannot set direction(%d).", __func__, ret);
+    return false;
+  }
+
+  return true;
+}
index c14f524c4b42fd5db259afce163521812dd9f06e..08b0c2c50f08208f42e02f44e0f0fdaf554220c1 100644 (file)
@@ -19,6 +19,8 @@
 
 #include "modules/iotjs_module_uart.h"
 
+#include "iotjs_uv_handle.h"
+
 struct iotjs_uart_platform_data_s {
   iotjs_string_t device_path;
 };
@@ -43,7 +45,9 @@ jerry_value_t iotjs_uart_set_platform_config(iotjs_uart_t* uart,
   return jerry_create_undefined();
 }
 
-bool iotjs_uart_open(iotjs_uart_t* uart) {
+bool iotjs_uart_open(uv_handle_t* uart_poll_handle) {
+  iotjs_uart_t* uart =
+      (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(uart_poll_handle);
   int fd = open(iotjs_string_data(&uart->platform_data->device_path),
                 O_RDWR | O_NOCTTY | O_NDELAY);
 
@@ -52,12 +56,14 @@ bool iotjs_uart_open(iotjs_uart_t* uart) {
   }
 
   uart->device_fd = fd;
-  iotjs_uart_register_read_cb(uart);
+  iotjs_uart_register_read_cb((uv_poll_t*)uart_poll_handle);
 
   return true;
 }
 
-bool iotjs_uart_write(iotjs_uart_t* uart) {
+bool iotjs_uart_write(uv_handle_t* uart_poll_handle) {
+  iotjs_uart_t* uart =
+      (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(uart_poll_handle);
   int bytesWritten = 0;
   unsigned offset = 0;
   int fd = uart->device_fd;
@@ -87,8 +93,9 @@ bool iotjs_uart_write(iotjs_uart_t* uart) {
   return true;
 }
 
-void iotjs_uart_handlewrap_close_cb(uv_handle_t* handle) {
-  iotjs_uart_t* uart = (iotjs_uart_t*)handle->data;
+void iotjs_uart_handle_close_cb(uv_handle_t* uart_poll_handle) {
+  iotjs_uart_t* uart =
+      (iotjs_uart_t*)IOTJS_UV_HANDLE_EXTRA_DATA(uart_poll_handle);
 
   if (close(uart->device_fd) < 0) {
     DLOG(iotjs_periph_error_str(kUartOpClose));
index e6a05fb4097e779cb048f918d5279631809906fc..029a6761b5df34f67a8d70ad659176430e1330c6 100644 (file)
@@ -147,18 +147,14 @@ bool iotjs_systemio_device_open(const char* export_path, uint32_t value,
   int count_limit = created_files_length * 10;
   char buffer[DEVICE_IO_PIN_BUFFER_SIZE];
   char path[DEVICE_IO_PATH_BUFFER_SIZE] = { 0 };
-  char check_format[DEVICE_IO_PATH_BUFFER_SIZE] = { 0 };
 
   while (!iotjs_systemio_check_path(exported_path) && count < count_limit) {
     usleep(100 * 1000); // sleep 100 miliseconds.
     count++;
   }
 
-  strcat(check_format, exported_path);
-  strcat(check_format, "%s");
-
   for (int i = 0; i < created_files_length; i++) {
-    snprintf(path, DEVICE_IO_PATH_BUFFER_SIZE - 1, check_format,
+    snprintf(path, DEVICE_IO_PATH_BUFFER_SIZE - 1, "%s%s", exported_path,
              created_files[i]);
 
     DDDLOG("%s - created file: %s", __func__, path);
index 7024e48b3bb661fc0cfd138c9e6a9c19be41552d..7be1656e5fde26565e4215c12af78fbd0b5081d3 100644 (file)
@@ -56,7 +56,7 @@ static gboolean gmain_loop_dispatch(GSource* source, GSourceFunc callback,
   more |= iotjs_process_next_tick();
 
   jerry_value_t ret_val = jerry_run_all_enqueued_jobs();
-  if (jerry_value_has_error_flag(ret_val)) {
+  if (jerry_value_is_error(ret_val)) {
     DLOG("jerry_run_all_enqueued_jobs() failed");
   }
 
@@ -86,7 +86,6 @@ static void loop_method_init_cb(int argc, char** argv, void* data) {
 
   if (!iotjs_environment_parse_command_line_arguments(env, (uint32_t)iotjs_argc,
                                                       iotjs_argv)) {
-    DLOG("iotjs_environment_parse_command_line_arguments failed");
     service_app_exit();
     return;
   }
index bcf024377b6137be9dce7961351909afac50bc20..9423550b90a9c144fc331139915da6b4d58b5874 100644 (file)
 #include <tinyara/arch.h>
 #include <tinyara/config.h>
 
-#include <setjmp.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifdef JERRY_DEBUGGER
+#include <time.h>
+#endif /* JERRY_DEBUGGER */
 
 #include "jerryscript-port.h"
 #include "jerryscript.h"
@@ -48,25 +50,30 @@ void jerry_port_log(jerry_log_level_t level, /**< log level */
 } /* jerry_port_log */
 
 /**
- * Dummy function to get the time zone.
- *
- * @return true
+ * Dummy function to get local time zone adjustment, in milliseconds,
+ * for the given timestamp.
  */
-bool jerry_port_get_time_zone(jerry_time_zone_t *tz_p) {
-  /* We live in UTC. */
-  tz_p->offset = 0;
-  tz_p->daylight_saving_time = 0;
-
-  return true;
-} /* jerry_port_get_time_zone */
+double jerry_port_get_local_time_zone_adjustment(double unix_ms, bool is_utc) {
+  (void)unix_ms;
+  (void)is_utc;
+  return 0.0;
+} /* jerry_port_get_local_time_zone_adjustment */
 
 /**
- * Dummy function to get the current time.
+ * Get system time
  *
- * @return 0
+ * @return milliseconds since Unix epoch
  */
 double jerry_port_get_current_time(void) {
-  return 0;
+  struct timespec ts;
+
+  /* Get the current time */
+  int ret = clock_gettime(CLOCK_REALTIME, &ts);
+  if (ret < 0) {
+    return 0.0;
+  }
+
+  return ((double)ts.tv_sec) * 1000.0 + ((double)ts.tv_nsec) / 1000000.0;
 } /* jerry_port_get_current_time */
 
 /**
@@ -77,29 +84,16 @@ void jerryx_port_handler_print_char(char c) { /**< the character to print */
   // printf("%c", c);
 } /* jerryx_port_handler_print_char */
 
-
-/**
- * Compiler built-in setjmp function.
- *
- * @return 0 when called the first time
- *         1 when returns from a longjmp call
- */
-
-int setjmp(jmp_buf buf) {
-  return __builtin_setjmp(buf);
-} /* setjmp */
-
-/**
- * Compiler built-in longjmp function.
- *
- * Note:
- *   ignores value argument
- */
-
-void longjmp(jmp_buf buf, int value) {
-  /* Must be called with 1. */
-  __builtin_longjmp(buf, 1);
-} /* longjmp */
+#ifdef JERRY_DEBUGGER
+void jerry_port_sleep(uint32_t sleep_time) {
+  nanosleep(
+      &(const struct timespec){
+          (time_t)sleep_time / 1000,
+          ((long int)sleep_time % 1000) * 1000000L /* Seconds, nanoseconds */
+      },
+      NULL);
+} /* jerry_port_sleep */
+#endif /* JERRY_DEBUGGER */
 
 int iotjs_entry(int argc, char **argv);
 int tuv_cleanup(void);
index 7821553a4230f59c666dbf7b582a68cf162b6546..f27c39ae25ea40f8e226ca8fd733a84a83ad5b0a 100644 (file)
@@ -17,7 +17,7 @@
 # only requires the iotjs and jerry header file(s).
 #
 cmake_minimum_required(VERSION 2.8)
-set(NAME test-dynamicmodule)
+set(NAME dynamicmodule)
 
 # Currently only Linux and Tizen targets are supported
 if(("${TARGET_OS}" STREQUAL "LINUX") OR ("${TARGET_OS}" STREQUAL "TIZEN"))
@@ -26,13 +26,17 @@ if(("${TARGET_OS}" STREQUAL "LINUX") OR ("${TARGET_OS}" STREQUAL "TIZEN"))
     message(FATAL_ERROR "No 'IOTJS_INCLUDE_DIR' or 'JERRY_INCLUDE_DIR'")
   endif()
 
+  string(TOLOWER ${TARGET_OS} TARGET_OS_NAME)
+
   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
+  set(OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/build/${TARGET_OS_NAME}")
 
   add_library(${NAME} SHARED
               src/module_entry.c)
   target_include_directories(${NAME}
                              PRIVATE ${IOTJS_INCLUDE_DIR} ${JERRY_INCLUDE_DIR})
   set_target_properties(${NAME} PROPERTIES
+                        LIBRARY_OUTPUT_DIRECTORY ${OUTPUT_DIRECTORY}
                         PREFIX ""
                         SUFFIX ".iotjs")
 endif()
index e3aa286af0b5c2deb5d890d0eb9d63b6949ae36c..d5109b74de7a321a29d68305f16a9041d39d45fd 100644 (file)
@@ -57,6 +57,7 @@ exports.isLinuxPPCBE = (process.platform === 'linux') &&
 exports.isSunOS = process.platform === 'sunos';
 exports.isFreeBSD = process.platform === 'freebsd';
 exports.isLinux = process.platform === 'linux';
+exports.isNuttX = process.platform === 'nuttx';
 exports.isTizen = process.platform === 'tizen';
 exports.isOSX = process.platform === 'darwin';
 
index 56336f8bd658116d3396aa314c2ae8980a658986..4c4fcec3427e5c3d4d08eda8d7000c8d8b511065 100644 (file)
@@ -46,9 +46,11 @@ server1.listen(0, '127.0.0.1', common.mustCall(function() {
   var server2 = net.createServer(common.fail);
 
   server2.on('error', common.mustCall(function(e) {
-    // EADDRINUSE have different value on OSX.
+    // EADDRINUSE has different values on OSX and NuttX.
     if (common.isOSX) {
       assert.strictEqual(e, -48);
+    } else if (common.isNuttX) {
+      assert.strictEqual(e, -112);
     } else {
       assert.strictEqual(e, -98);
     }
index 68135c5f7cbc34fc3190a416eb353a751f13c4dc..b98be49b6a1d6dbf0f5fc4a49243b9bb75f640b4 100644 (file)
@@ -2,10 +2,14 @@ ENABLE_MODULE_IOTJS_BASIC_MODULES
 ENABLE_MODULE_IOTJS_CORE_MODULES
 ENABLE_MODULE_ADC
 ENABLE_MODULE_BLE
+ENABLE_MODULE_CRYPTO
 ENABLE_MODULE_DGRAM
 ENABLE_MODULE_GPIO
+ENABLE_MODULE_HTTP_SIGNATURE
 ENABLE_MODULE_HTTPS
 ENABLE_MODULE_I2C
+ENABLE_MODULE_MQTT
 ENABLE_MODULE_PWM
 ENABLE_MODULE_SPI
 ENABLE_MODULE_UART
+ENABLE_MODULE_WEBSOCKET
diff --git a/test/profiles/mock-linux.profile b/test/profiles/mock-linux.profile
new file mode 100644 (file)
index 0000000..9670685
--- /dev/null
@@ -0,0 +1,4 @@
+ENABLE_MODULE_IOTJS_BASIC_MODULES
+ENABLE_MODULE_IOTJS_CORE_MODULES
+ENABLE_MODULE_GPIO
+ENABLE_MODULE_I2C
index 21a0519dc8ce7611a0eb065f1fb90316efc3d89d..2bca36d7be25001dec511a72cac9648be304b6b6 100644 (file)
@@ -1,6 +1,7 @@
 ENABLE_MODULE_IOTJS_BASIC_MODULES
 ENABLE_MODULE_IOTJS_CORE_MODULES
 ENABLE_MODULE_ADC
+ENABLE_MODULE_CRYPTO
 ENABLE_MODULE_DGRAM
 ENABLE_MODULE_GPIO
 ENABLE_MODULE_I2C
index 8ed4b594ca0793a89803a3e8f4ac23a6561349cd..8aa0719ba4d8d9d2319311ee1d588e3a1b12c38e 100644 (file)
@@ -1,10 +1,14 @@
 ENABLE_MODULE_IOTJS_BASIC_MODULES
 ENABLE_MODULE_IOTJS_CORE_MODULES
 ENABLE_MODULE_BLE
+ENABLE_MODULE_CRYPTO
 ENABLE_MODULE_DGRAM
 ENABLE_MODULE_GPIO
+ENABLE_MODULE_HTTP_SIGNATURE
 ENABLE_MODULE_HTTPS
+ENABLE_MODULE_MQTT
 ENABLE_MODULE_I2C
 ENABLE_MODULE_PWM
 ENABLE_MODULE_SPI
 ENABLE_MODULE_UART
+ENABLE_MODULE_WEBSOCKET
diff --git a/test/profiles/tizen-jerry.profile b/test/profiles/tizen-jerry.profile
new file mode 100644 (file)
index 0000000..af04018
--- /dev/null
@@ -0,0 +1,3 @@
+CONFIG_DISABLE_ES2015_BUILTIN
+CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
+CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
index bf9c925855ea9064e4d03bd2c2a494754f257f13..507b8bec1cb39a47404f3e1e18397b3abb07033b 100644 (file)
@@ -1,11 +1,15 @@
 ENABLE_MODULE_IOTJS_BASIC_MODULES
 ENABLE_MODULE_IOTJS_CORE_MODULES
 ENABLE_MODULE_BRIDGE
+ENABLE_MODULE_CRYPTO
 ENABLE_MODULE_DGRAM
 ENABLE_MODULE_GPIO
+ENABLE_MODULE_HTTP_SIGNATURE
 ENABLE_MODULE_HTTPS
+ENABLE_MODULE_MQTT
 ENABLE_MODULE_I2C
 ENABLE_MODULE_PWM
 ENABLE_MODULE_SPI
 ENABLE_MODULE_TIZEN
 ENABLE_MODULE_UART
+ENABLE_MODULE_WEBSOCKET
index d6f288a888a05437f9df8f62cd29fd037ac48ca3..dd7cbd893df83ca2d81fd33293f326c93af5d741 100644 (file)
@@ -1,9 +1,14 @@
 ENABLE_MODULE_IOTJS_BASIC_MODULES
 ENABLE_MODULE_IOTJS_CORE_MODULES
 ENABLE_MODULE_ADC
+ENABLE_MODULE_CRYPTO
 ENABLE_MODULE_DGRAM
 ENABLE_MODULE_GPIO
+ENABLE_MODULE_HTTP_SIGNATURE
+ENABLE_MODULE_HTTPS
+ENABLE_MODULE_MQTT
 ENABLE_MODULE_I2C
 ENABLE_MODULE_PWM
 ENABLE_MODULE_SPI
 ENABLE_MODULE_UART
+ENABLE_MODULE_WEBSOCKET
diff --git a/test/resources/crypto_public.pem b/test/resources/crypto_public.pem
new file mode 100644 (file)
index 0000000..1d549e1
--- /dev/null
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsHbJBfgc4tPdH0bkuVoL
+AAhN6rxk7RaD73thMVP1KtlyomXdydWT9CEBR/MBepyQaokHHYt430tqbOYeeYss
++SJUp2mU0C+XCcuD27T5lcwbUOFhN8pkerUKvuqM8u+ndYwgEbn8XHXSM+x62qWd
+wM6CO/kJx5CtzQaJ+2jPfdPnUYB3BpZvRL4ymzvGa3lUpwmtns3jfyZjJMz7Bd3A
+kH9gJTREhTLM3A4LNocgvIFLJNadlTbB5OgMMHxH3EEmXn1Wq+LeC57E4f2PuhmX
+vSRLbT85NpGC1U1AmuG2IVitwFkw1Hx23lZG8Zld/ZeV3kLBwJ2o002U3rs+H1aP
+8QIDAQAB
+-----END PUBLIC KEY-----
diff --git a/test/resources/http_signature_key.key b/test/resources/http_signature_key.key
new file mode 100644 (file)
index 0000000..8805940
--- /dev/null
@@ -0,0 +1,8 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv5B5QBJx+XGoK8xbY2Q9L5pJyv0Ddlzx
+pwWSz6q049b/+7YzVsFLt7S+O7soW7upfwTxFkCcpWWTKIoRac6vCYY14lTmWK/M1cntho8BiFoL
+cvDAx7dXgH2OfIsr6VgJMFl4DZebcN2fvhsZBo2lTyhJt8lSw8esTDHFZ8App6ilvVXJ4p6uKWJp
+1bzJQxvwHuNa4itN6GKyMR5kqklDwTa359JXXZf5LO7kFwO7ULCrtliaCUEUvG4xTgZfctD4gKMb
+WScMzx2U4ksSFhlmGyxcED2FH+fUn98Qo5KFflu01RaHScodXUZo6VMV5oY466Yq7y7z2R4KdpL4
+vC4v4wIDAQAB
+-----END PUBLIC KEY-----
diff --git a/test/resources/my_ca.crt b/test/resources/my_ca.crt
new file mode 100644 (file)
index 0000000..2f2fb1b
--- /dev/null
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDuzCCAqOgAwIBAgIJAMeGQlu8r9jlMA0GCSqGSIb3DQEBCwUAMHQxCzAJBgNV
+BAYTAkhVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ8wDQYDVQQHDAZTemVnZWQxDjAM
+BgNVBAoMBU15IENBMREwDwYDVQQDDAhteWNhLm9yZzEcMBoGCSqGSIb3DQEJARYN
+bXljYUBteWNhLm9yZzAeFw0xODA2MjgxMDQzMThaFw0yODA2MjUxMDQzMThaMHQx
+CzAJBgNVBAYTAkhVMRMwEQYDVQQIDApTb21lLVN0YXRlMQ8wDQYDVQQHDAZTemVn
+ZWQxDjAMBgNVBAoMBU15IENBMREwDwYDVQQDDAhteWNhLm9yZzEcMBoGCSqGSIb3
+DQEJARYNbXljYUBteWNhLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBALCPKzrZoSVHjswF0W/5pn0ElmAjO3GmYH1rHbTdSfQ9fXWiXWHREcGXeGXJ
+Vs/OIr6hxrghuPehYxERW2RhZESosOZgtifLC5hpg5guHzls0p8ix1gZ/olNBhzV
+/1qO5J7MSxx87DldDvoVTNyUzp/FEL5U45N4B8ECrY5+41BN1SPgAs5xc+LJLiag
+JjrsUxrpzngqsfpf15zcFsXcknB3VZKLQStkbmZB2RNWJm2dulSwr1tdXeZhBs1M
+seKh7MZ86ay/8/LJPedBUNUnIm/ZlinFYC5dxRpfA4RFL7Q91PZbAIRMphpXfE2x
+SSeOnkB2InXXwaPi+PlQnDzzSIMCAwEAAaNQME4wHQYDVR0OBBYEFNm9NQ9P2i35
+oCIFHQmft53GXlCNMB8GA1UdIwQYMBaAFNm9NQ9P2i35oCIFHQmft53GXlCNMAwG
+A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAIurYWyw/AkMlNeW7PIu7zsh
+6mknQ0RCI8h05CgJ6SlSlVQSB6Tu9BiLT0DNc0PTIQxHoqgVofATndLLn7a6G0Lc
+iy8mcYDbfAEcXiXFlo58gyWCa+/azJ/hslOVKvCs66BieHOiDhaBVzqWwUYaVMYA
+EocmusQmx44qrSsMfNPqq4b15b9sn0WximHtc76Czibnj35Nkhr/x2Cd07vnoU/2
+5fpiu8PfrSAjOw6oaAINwP6pXskl1+wtJ9NpqvEJVl4aEUWpSJoGtIJGOtM0zbNF
+/IPITiGuLri8FzYqfvYBxRR2Wuq94Vcmwh8r2mysuPC1dHtjg5l1hm8vqiBW3p4=
+-----END CERTIFICATE-----
diff --git a/test/resources/my_ca.key b/test/resources/my_ca.key
new file mode 100644 (file)
index 0000000..7927a53
--- /dev/null
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAsI8rOtmhJUeOzAXRb/mmfQSWYCM7caZgfWsdtN1J9D19daJd
+YdERwZd4ZclWz84ivqHGuCG496FjERFbZGFkRKiw5mC2J8sLmGmDmC4fOWzSnyLH
+WBn+iU0GHNX/Wo7knsxLHHzsOV0O+hVM3JTOn8UQvlTjk3gHwQKtjn7jUE3VI+AC
+znFz4skuJqAmOuxTGunOeCqx+l/XnNwWxdyScHdVkotBK2RuZkHZE1YmbZ26VLCv
+W11d5mEGzUyx4qHsxnzprL/z8sk950FQ1Scib9mWKcVgLl3FGl8DhEUvtD3U9lsA
+hEymGld8TbFJJ46eQHYiddfBo+L4+VCcPPNIgwIDAQABAoIBAGeShOyP8B07XgRH
+QXYrgEQEZeZdpKhlzmKkbJfF3HU/gRJ5vcf86iqjnYgwVRGwPeeQZU9s0OHLNZ80
+jGVVUImKX8O1ZgXv8YxmEUE7hSudr+yUbVY8YXnPyk8uJg7MlkalV0aN7dE0yu1f
+g2g+jvtgkhLlH19J4VqTJJbbzqMzG+2m9htQqG2vM2spkYtSw3DbsmJS4zklkr/n
+g6VvIzLDzGq6KdIqE0LWvSiPm4pYTXQFk4j+J7UjY+ZmTXZIKedmk3a4vTpppiYu
+HAy1I8a5tZtgPYEOnRaZ2sPGuLcOgcBWa9iPx8JelRDcVB/51KcICsYZU/EOzoDc
+QHtqswECgYEA1ifEjpF4fTdAnXdrmj5ln3wIBjLd/YNAaOJW6ZWCFJ5Rcper7QYK
+2hUG9TvkJ/oq3m4v8X0gdxnOASpHZ5k04JMS58M85ptc4st0wvOvX36qdU9juRz4
+ClnCZDDndc1E7JMkqHl1uJHvDYWLFUYogkk042HIvkTwddNbp1tJL4ECgYEA0w7Q
+Dq6YIc+AHUisE0uVtli8kHZu/pQHv2XFZ3zRkwsYOLB5xwJU5uoXRZJcc6yF2EF+
+/kulJDLTwKi2b9UO491Fl071VqlGW086+gPmSDao0RzTGbfhqc3dAtn6fGHp1Vgf
+xpsxYTWpoiiexljHfa3NkDIYmgZtElRRR4iUugMCgYEAtol9E5xRHEHdNJsWv4lR
+64e3+zieWTjnzL6oID+MefCcMdWv+L8+vrZPkPY0uhKVObSn7umdo4b+PaYA6QAA
+vy79XUjf/xwMJ1AOPSGiqP35YzaBJMbZcVEizW2VzKZjila9V1D4E5NoNJlQfJip
+bKvjhbDSf8OZRoUaSWMY1YECgYApQqAR/rfnBDW7g9WAACrIdxiF9WFFi5LoK/En
+hhNCd8zIaFemPCJ08haSl0ZTpsqTuFonRIqIRRd4doMT4ccDbOKJ7fmwc285soeJ
+EPIX8/eUydnLEVOgaopmYE7DujCIcK3lmblRk7gR53cCt6BoRW4GXoTIt7DjAHDT
+VzQcGQKBgQDIsplosD3lXeRKA2agTozOROlUbJjYFlPLfztiXVPk3+QvGN1s4NIZ
+IzoJX/sufinHYzajRFK+IyAyusmnwHkwZz7WUmgJk0L6K+/T93nQhhwjSue6NMZK
+egpitIY58FY1J6Y67MR4+3h0/o4LCYQN5vOcrCAkczsNtAuVO0OnWA==
+-----END RSA PRIVATE KEY-----
diff --git a/test/resources/my_ca.srl b/test/resources/my_ca.srl
new file mode 100644 (file)
index 0000000..28d02ef
--- /dev/null
@@ -0,0 +1 @@
+94825A52EA8A27F1
diff --git a/test/resources/my_crt.crt b/test/resources/my_crt.crt
new file mode 100644 (file)
index 0000000..af3d56c
--- /dev/null
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEazCCA1MCCQCUglpS6oon8TANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJI
+VTETMBEGA1UECAwKU29tZS1TdGF0ZTEPMA0GA1UEBwwGU3plZ2VkMQ4wDAYDVQQK
+DAVNeSBDQTERMA8GA1UEAwwIbXljYS5vcmcxHDAaBgkqhkiG9w0BCQEWDW15Y2FA
+bXljYS5vcmcwHhcNMTgwNjI4MTA0NjA3WhcNMjgwNjI1MTA0NjA3WjB7MQswCQYD
+VQQGEwJIVTETMBEGA1UECAwKU29tZS1TdGF0ZTEPMA0GA1UEBwwGU3plZ2VkMRAw
+DgYDVQQKDAdUcnVzdGVkMRIwEAYDVQQDDAlsb2NhbGhvc3QxIDAeBgkqhkiG9w0B
+CQEWEXRydXN0ZWRAbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
+CgKCAgEApd/5D3T9EWTLcJLTk8ayjc+GdSZBiRNYo4JSACf4LSrTBOif4UN/3PZi
+02wmPesPFyPY86cqJGi/7IVxaXX2stKLBRa+ZE7Pp7T9tIjkxx/Rw1GMEHLSjJM4
+JMBUJ2Vb6a0jLPAvNqO9jiXeaw6XJVtvXJrE71zVOj0R1Ttq0b3VQ10oQgZVfaRy
+xjMFD2sTMFo7ADkGw+XUqvp0ZMleeOk2yKuflvQkr/BUHzncepBtsMdxGb8Xm58Z
+QbVodLlbCD+NAoRpTnVphVxSpGsYRfLNfEHWYA8CD+1J3nPTAYU9t7AxZYPsqcHW
+GHc2A6badnwLsg4jNbUGx4bOS2Jwtf5uVQxPLHobI4lMFAZXBBHHuySP3O9WTPB8
+m/SHRFP2TBLARJX4DCpisaeZ2f0kshdUCZaxKCKoiiQ0Eo826iRJItiAOx+Uo3E4
+VP9+qkphOjPW23ERw8EDY5Cm///Pp4q/vlGICTn3peoxDnYcy+FDPvbw+dakQPtK
+IxurQC80RqV3f+W6LhVx3uZQYN2FkfOhQaMbfdq+jB6dcrXbh1FUPwa00eaPdfXz
+Fq1xWpfzE6GrjThijC0HkGrUT6ThQVG0nrHDhzbKw+27FUDkhwnOrNtCJy1GgS9m
+TUD1CvoDfdRSvqP4N1zrxNK4PNnYuN8m/xcycn8i7aMroQFEGSECAwEAATANBgkq
+hkiG9w0BAQsFAAOCAQEAd5MuhS49EtJo/dYnLS6MdHQ9Afwc5dlE7375hx1++cDg
+rV2XD1RuMovZpwCi58RPTsD+lp9QB/60SkW/85Dvbh7Xmh/u5Cr6J0/drVQpBj7U
+++9dVFPs0nHmxkYxC7ZYM+NX1cwbcfLYf9dpjA88tIcVatnFjVoGqaJpZzyd7vRv
+UESF9EG1rLAtla36absMwg/rGxH+Rl0If662lCiHHu7jN+lu2uBP8tQ4tWlIxybp
+wcEpJqpqN7WnMwFuuriUL3p8zcglsWwIqccKi3M/lYS2uLvHBhF/44W06RM0zwxg
+oFr+K2SlC17Xr+A29kL+OmtFdgrVIQAhVZX02v3IkA==
+-----END CERTIFICATE-----
diff --git a/test/resources/my_crt.pem b/test/resources/my_crt.pem
deleted file mode 100644 (file)
index 798292d..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFQDCCAyigAwIBAgIBATANBgkqhkiG9w0BAQsFADA5MREwDwYDVQQDEwhteXNl
-cnZlcjEXMBUGA1UEChMObXlvcmdhbmlzYXRpb24xCzAJBgNVBAYTAk5MMB4XDTEz
-MDEwMTAwMDAwMFoXDTE5MTIzMTIzNTk1OVowOTERMA8GA1UEAxMIbXlzZXJ2ZXIx
-FzAVBgNVBAoTDm15b3JnYW5pc2F0aW9uMQswCQYDVQQGEwJOTDCCAiIwDQYJKoZI
-hvcNAQEBBQADggIPADCCAgoCggIBAKXf+Q90/RFky3CS05PGso3PhnUmQYkTWKOC
-UgAn+C0q0wTon+FDf9z2YtNsJj3rDxcj2POnKiRov+yFcWl19rLSiwUWvmROz6e0
-/bSI5Mcf0cNRjBBy0oyTOCTAVCdlW+mtIyzwLzajvY4l3msOlyVbb1yaxO9c1To9
-EdU7atG91UNdKEIGVX2kcsYzBQ9rEzBaOwA5BsPl1Kr6dGTJXnjpNsirn5b0JK/w
-VB853HqQbbDHcRm/F5ufGUG1aHS5Wwg/jQKEaU51aYVcUqRrGEXyzXxB1mAPAg/t
-Sd5z0wGFPbewMWWD7KnB1hh3NgOm2nZ8C7IOIzW1BseGzkticLX+blUMTyx6GyOJ
-TBQGVwQRx7skj9zvVkzwfJv0h0RT9kwSwESV+AwqYrGnmdn9JLIXVAmWsSgiqIok
-NBKPNuokSSLYgDsflKNxOFT/fqpKYToz1ttxEcPBA2OQpv//z6eKv75RiAk596Xq
-MQ52HMvhQz728PnWpED7SiMbq0AvNEald3/lui4Vcd7mUGDdhZHzoUGjG33avowe
-nXK124dRVD8GtNHmj3X18xatcVqX8xOhq404YowtB5Bq1E+k4UFRtJ6xw4c2ysPt
-uxVA5IcJzqzbQictRoEvZk1A9Qr6A33UUr6j+Ddc68TSuDzZ2LjfJv8XMnJ/Iu2j
-K6EBRBkhAgMBAAGjUzBRMA8GA1UdEwQIMAYBAf8CAQAwHQYDVR0OBBYEFDq9Z6I3
-rL5uuud2JuA1G9V4QP2sMB8GA1UdIwQYMBaAFDq9Z6I3rL5uuud2JuA1G9V4QP2s
-MA0GCSqGSIb3DQEBCwUAA4ICAQBVibU3yI7w3181J/QWp5QXO7Z8Ew1xdhp5thX4
-HWD/cW7Q7SR5hFkRViMvcFsF3K6bYZa8MJHdhURPKZe+jWYwDlPQ47Bk0eoPn28V
-edhwMEqTeIaAvZFIAP9fx0388p0+1ZPsH+B6jcbO89ViLbTrEXOmv+LppqYHpyq1
-NSlLong+S8qX9ILdLfeINP8a3OklEPkoqIoOt5SU3t1q6op+5fY+7KELVxGFa5c/
-rUrxjSGc1IrboMO8pMtUytbytWakZ2YdSfg7Nk8k/vsgymKD+7oN6IapA52MPTjZ
-G2lw8U98GCCsToaF95ctfCVjz6AcFhGLxtDgi1dlw6jChBOR8HhjBFptwloCucq5
-2TTvIO/UAkMp+CHLpz3lM8aK818SCiHqoyS7IS4mh5b6Vchb+qjiM68Jva9KZn8O
-5WjWj87VMGQ9k7t08zvHt9UmCteSnAJB81HxMIg8z3718tPqY/Ila5y0fgU18+9M
-uc1nCI4hAHorlkZh8jeVQRWQ6X1MF4IJOpVMjADeWjPOBOboRgpEB5EEKE0LrajW
-8UZZmuLOIXhrM+H4HYqVSiExqVyfqwHhGunPc2UKCo+Z5LWDHUfqNFhswjpa3o2J
-yc/Gu+aoHsXJ0fjtfEjA1b8ZxWOjLmALAX7Bl4fCl7IS87GytE9MwRlBfa0Jg1E8
-RB15XA==
------END CERTIFICATE-----
diff --git a/test/resources/my_csr.csr b/test/resources/my_csr.csr
new file mode 100644 (file)
index 0000000..9835e10
--- /dev/null
@@ -0,0 +1,28 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIEwDCCAqgCAQAwezELMAkGA1UEBhMCSFUxEzARBgNVBAgMClNvbWUtU3RhdGUx
+DzANBgNVBAcMBlN6ZWdlZDEQMA4GA1UECgwHVHJ1c3RlZDESMBAGA1UEAwwJbG9j
+YWxob3N0MSAwHgYJKoZIhvcNAQkBFhF0cnVzdGVkQGxvY2FsaG9zdDCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXf+Q90/RFky3CS05PGso3PhnUmQYkT
+WKOCUgAn+C0q0wTon+FDf9z2YtNsJj3rDxcj2POnKiRov+yFcWl19rLSiwUWvmRO
+z6e0/bSI5Mcf0cNRjBBy0oyTOCTAVCdlW+mtIyzwLzajvY4l3msOlyVbb1yaxO9c
+1To9EdU7atG91UNdKEIGVX2kcsYzBQ9rEzBaOwA5BsPl1Kr6dGTJXnjpNsirn5b0
+JK/wVB853HqQbbDHcRm/F5ufGUG1aHS5Wwg/jQKEaU51aYVcUqRrGEXyzXxB1mAP
+Ag/tSd5z0wGFPbewMWWD7KnB1hh3NgOm2nZ8C7IOIzW1BseGzkticLX+blUMTyx6
+GyOJTBQGVwQRx7skj9zvVkzwfJv0h0RT9kwSwESV+AwqYrGnmdn9JLIXVAmWsSgi
+qIokNBKPNuokSSLYgDsflKNxOFT/fqpKYToz1ttxEcPBA2OQpv//z6eKv75RiAk5
+96XqMQ52HMvhQz728PnWpED7SiMbq0AvNEald3/lui4Vcd7mUGDdhZHzoUGjG33a
+vowenXK124dRVD8GtNHmj3X18xatcVqX8xOhq404YowtB5Bq1E+k4UFRtJ6xw4c2
+ysPtuxVA5IcJzqzbQictRoEvZk1A9Qr6A33UUr6j+Ddc68TSuDzZ2LjfJv8XMnJ/
+Iu2jK6EBRBkhAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAgEAd88r+jJGHsPmBfhy
+ucNhCIK9VOh+kjlbfSnX0m6VJkNoqxJFx8mZ/fWlwUUW7Ff3WsmeDWEs/s5N6A3+
+NRAwPsuBrFImN/CeCbq0u4SU4+KJObZjmJjWhbXBgzYZQrtG/LvwOUceesDzgSj1
+qKfwSpafEYNeGtRWMcv02ypG7+h9Hbpqr2RpEe0Jgi3LAgW11wJzve/rLpDU3PKP
+DsZzx7GvkcWAuqxv3jTH68vJOEmHxUKNSybnvCGHCDcA/f5k0bROOO7RSJ1TQOKr
+dYLEMssil69gd/n2GpmXHmYjWx2LRlwuJp7Hm4GOjdmketu6bLotWH+R8lwBFuvH
+kDRGaBA2uHmFhtgokKult5zpCiIDw4FHfbC43dg63jGD3k6LrzrxbGbxZUb7tpFZ
+z9XJxdFPgzI6eOiiHD3SJikZoeox5AmUDCZOmsrF6Ex2iiTXxbIWfSqaImK8xZp4
+fUx6fDKy24SU+rrGqX8oxABOootPwdT/lsCVB4b/IdtzAugPf1dRDIHYWteohlc8
+4CVebKr0QyaQxH7fBRcTQmVNlJhzYfE6GcXa49G1AzXpEs6Eb3iPPRKRTNTssmZv
+ycHkTmWjoWLK1b1wEKK7jY17EXuIbxozIYCVoMXTEeUJtcB8lwt2gBDlASxfQYtB
+J8BmS9FN25iWTk5xW52UnpniwDk=
+-----END CERTIFICATE REQUEST-----
diff --git a/test/resources/my_key.key b/test/resources/my_key.key
new file mode 100644 (file)
index 0000000..c7e28e6
--- /dev/null
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJJwIBAAKCAgEApd/5D3T9EWTLcJLTk8ayjc+GdSZBiRNYo4JSACf4LSrTBOif
+4UN/3PZi02wmPesPFyPY86cqJGi/7IVxaXX2stKLBRa+ZE7Pp7T9tIjkxx/Rw1GM
+EHLSjJM4JMBUJ2Vb6a0jLPAvNqO9jiXeaw6XJVtvXJrE71zVOj0R1Ttq0b3VQ10o
+QgZVfaRyxjMFD2sTMFo7ADkGw+XUqvp0ZMleeOk2yKuflvQkr/BUHzncepBtsMdx
+Gb8Xm58ZQbVodLlbCD+NAoRpTnVphVxSpGsYRfLNfEHWYA8CD+1J3nPTAYU9t7Ax
+ZYPsqcHWGHc2A6badnwLsg4jNbUGx4bOS2Jwtf5uVQxPLHobI4lMFAZXBBHHuySP
+3O9WTPB8m/SHRFP2TBLARJX4DCpisaeZ2f0kshdUCZaxKCKoiiQ0Eo826iRJItiA
+Ox+Uo3E4VP9+qkphOjPW23ERw8EDY5Cm///Pp4q/vlGICTn3peoxDnYcy+FDPvbw
++dakQPtKIxurQC80RqV3f+W6LhVx3uZQYN2FkfOhQaMbfdq+jB6dcrXbh1FUPwa0
+0eaPdfXzFq1xWpfzE6GrjThijC0HkGrUT6ThQVG0nrHDhzbKw+27FUDkhwnOrNtC
+Jy1GgS9mTUD1CvoDfdRSvqP4N1zrxNK4PNnYuN8m/xcycn8i7aMroQFEGSECAwEA
+AQKCAgBU1Z3dx+l+MdzScGWBWMgNOyv7UluGLbzRs18Y8Vg+UX6nLgpG/Wyxp9mX
+Y+KTHFsVbKISy1YEVQaDgyQj2c8YWhH7wkwRpTUTAsAWy0SmiqGPkW9fIjqI5up5
+8VuY4oAFnSU2YIjlGw1hXADLJCUtV/w2knlSKlprdLxgIAlbyAkAcO6cBf1HSwng
+UEuwPQUNX7h5PrE1E6CW6Y0J1utYT35TV2NBow/4Y6PCbKdUj/VpyjcQAemjD9Wt
+A4iu2fWy3D3UIcBx/h6/tB4YNSWu8KUjfdCURFi7qJJ1ESvDxU9xWM2Kq9QoZhiH
+XsDjUTy+CGc643wihbk35rwvVeNqfN2GfkrrdyTzqIszJAqKtImoXv8BuEf+kgeX
+0s9Wtl8BF4Hv6jAZ28NI1DwXXjEFkuqG6Z1yn5UTAxcmKqAudZFVoI5dgeGu8c6x
+LVkudR7QOkeSuHTrn4ILYiWMsuP8No/qmnQBCHbfJT4xp2dBHdZ0vDml7LFZjzg1
+If1ZGStOBB7uZqDXyx4wdYdMdV05dvUelWwJqI0KLWF8doX6fr+Huh1Q3owYoOQ5
+MZOoXbHMegu5fOrkDFfaYeATTnCeE1RjoYjT9zf4rYjX3IOryj66b0DadXpYdNhk
+5vSAA+NRj3fLGFScdCFxwJjwPbw1Xsn0uSwRHHEQnF9H5hmsoQKCAQEA5poLkJ1s
+1ZeEWVr5CDU0js8QsEbeRGpXsm+Aj9X9gf4+D3HQ573lnXO8wiB+PoikETWp45Jf
+yq1XK2dcbygcxrSo6Zr+GtzE6grCztn8jE4omkqduJhViAr4hdg59R4UdNG1Qpgg
+Z9cFBYwnI/IWMJJBTiqKIVwD3RKQM75WKDT/ccDtUp2MxxNjUKAsVHpmOHW2ZC4T
+A2vwbqp+egQ5SfSUBcGkD034PjG2uOJGmHXcKnnG4Dm+9SeutvTF9JZwMJmg3WlG
+5AdVUnl4qN2g4t3TYasV4Y8i00EJPcQW5v4UV9sq4dAQ0GXfu/r/TXwMKkQp/cN1
+95I+xXsBjKQDdQKCAQEAuCTqVZJMZ5uovPzyPmnMOBqdtac5Hd7/eglN945sAK7n
+ssg3X1hRsHCf8Dx1X95lxCDVn97ac9C2uIEeiLy/+JDFQcOxcgj1vDeF6IaGzaFh
+Dc9qIDo4b0bhhD1kMxtowOAkI4YR/+iSIuGOJXq7wu71a6+dIm4meb+4d3L+O5Jq
+sOsOBLClL7Ymv1iZ3fol0XPQsuSv1eGoDqDdiNNXOBJHgKy0zMEXs4hpjL2vCGDN
+m8MbtqpMg4jCuesy/zh/b+CCkrX0AdW/fkw/euZ/ZTMEageqH5RfitX9CGOw2CuS
++78XmWeFqbr2YVbAZFo09I8Ytv40yO1ZyVQkyKSlfQKCAQA1ooCsGyF0MHCVA+bG
+NPHLgXfFOEZ8LSvGkc6aJdB3yrWOjA9lxzI/w+qUUFBspQVcB1pDVwk2r8iFjN3f
+8Ll4sg5Tfzw47T5TnTsgN21ZCNjCwjYa+Dt0j/Cr2NXqIBvr69a37YAkBsvhNW7p
+GmZ015+e2aAVEDzJz4aAsnWBlooPYCsSuxhCOU0xNH/7Chj6as6IUHsVoaZjZv5R
+zOeyPtOq3xYUhTMG7DMun1qCHW+e5YIPJv82MAuf/CCKue7QLvtOZC0b3mTG8P/S
+bvH7slJ29f753nvgHNFUb2ZQRapfoNdBfE5c2kUGiOOWlxKRRhdqMWsfsQEul2SN
+3Jv9AoIBAASuW46lU2/m0xlKzNWtVtWuR4gQojESNChkCClc43349EblNBMmaZ00
+n7w5rTosqyWbOBMCVUdQbPSvw5jyQ2cMNxd+5AnkFGsedjb9BHxBt/fj5+y9ziV2
+BdGYxe1OqxEMIZ8Nj3OT8/MTDMwDHLbN4EtGgZYYer3pk8TllXTqOfAZaZfQ7cIS
+vVVr6S1taHy0lv+VNKsZO25zxG3wAW2ZeVvaCBaUagfUVeqP/90UqOVmxlOUbLGD
+Tn/vbLJ0Ozka2fbkzTkmt+F8CrkTFvX5oAkZ/MckvHEJE4+dCSfVo7zmlLD/orQ3
+3n+G9wkWCfaVlKlCORFKh1fI3c6D8PkCggEAI/zEfC6+CndqrmehoCGgHZMP7B+a
+rytCeG3Qyoqjta0sKGC8/LUe85PSWDR9xHrrWgEriRF9gHvYxF8YCBXhfInIHDd+
+pdcsWEaoUWlvBqhbKaPhVF/0difpjogWH388sdVXT6PefHEO5maYii9EaPjWckKf
+314Eh0KW/oUiSo5rwAgdnu1J84qBOxXqMI2eDZaKLphueytHjt7QRnZW91zeYwrP
+3E7MbkKVJPaViIm3MvXUUsL8Gpqji9MY0wHjZAq1PXtZ5WP+K3wHUOte6OGkBcSQ
+7oUxhOoMlN0VC4FGtSHu1LLTvmWeYrHk9J6mpfNAj1/TfA/VvVKpNQVlaw==
+-----END RSA PRIVATE KEY-----
diff --git a/test/resources/my_key.pem b/test/resources/my_key.pem
deleted file mode 100644 (file)
index c7e28e6..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJJwIBAAKCAgEApd/5D3T9EWTLcJLTk8ayjc+GdSZBiRNYo4JSACf4LSrTBOif
-4UN/3PZi02wmPesPFyPY86cqJGi/7IVxaXX2stKLBRa+ZE7Pp7T9tIjkxx/Rw1GM
-EHLSjJM4JMBUJ2Vb6a0jLPAvNqO9jiXeaw6XJVtvXJrE71zVOj0R1Ttq0b3VQ10o
-QgZVfaRyxjMFD2sTMFo7ADkGw+XUqvp0ZMleeOk2yKuflvQkr/BUHzncepBtsMdx
-Gb8Xm58ZQbVodLlbCD+NAoRpTnVphVxSpGsYRfLNfEHWYA8CD+1J3nPTAYU9t7Ax
-ZYPsqcHWGHc2A6badnwLsg4jNbUGx4bOS2Jwtf5uVQxPLHobI4lMFAZXBBHHuySP
-3O9WTPB8m/SHRFP2TBLARJX4DCpisaeZ2f0kshdUCZaxKCKoiiQ0Eo826iRJItiA
-Ox+Uo3E4VP9+qkphOjPW23ERw8EDY5Cm///Pp4q/vlGICTn3peoxDnYcy+FDPvbw
-+dakQPtKIxurQC80RqV3f+W6LhVx3uZQYN2FkfOhQaMbfdq+jB6dcrXbh1FUPwa0
-0eaPdfXzFq1xWpfzE6GrjThijC0HkGrUT6ThQVG0nrHDhzbKw+27FUDkhwnOrNtC
-Jy1GgS9mTUD1CvoDfdRSvqP4N1zrxNK4PNnYuN8m/xcycn8i7aMroQFEGSECAwEA
-AQKCAgBU1Z3dx+l+MdzScGWBWMgNOyv7UluGLbzRs18Y8Vg+UX6nLgpG/Wyxp9mX
-Y+KTHFsVbKISy1YEVQaDgyQj2c8YWhH7wkwRpTUTAsAWy0SmiqGPkW9fIjqI5up5
-8VuY4oAFnSU2YIjlGw1hXADLJCUtV/w2knlSKlprdLxgIAlbyAkAcO6cBf1HSwng
-UEuwPQUNX7h5PrE1E6CW6Y0J1utYT35TV2NBow/4Y6PCbKdUj/VpyjcQAemjD9Wt
-A4iu2fWy3D3UIcBx/h6/tB4YNSWu8KUjfdCURFi7qJJ1ESvDxU9xWM2Kq9QoZhiH
-XsDjUTy+CGc643wihbk35rwvVeNqfN2GfkrrdyTzqIszJAqKtImoXv8BuEf+kgeX
-0s9Wtl8BF4Hv6jAZ28NI1DwXXjEFkuqG6Z1yn5UTAxcmKqAudZFVoI5dgeGu8c6x
-LVkudR7QOkeSuHTrn4ILYiWMsuP8No/qmnQBCHbfJT4xp2dBHdZ0vDml7LFZjzg1
-If1ZGStOBB7uZqDXyx4wdYdMdV05dvUelWwJqI0KLWF8doX6fr+Huh1Q3owYoOQ5
-MZOoXbHMegu5fOrkDFfaYeATTnCeE1RjoYjT9zf4rYjX3IOryj66b0DadXpYdNhk
-5vSAA+NRj3fLGFScdCFxwJjwPbw1Xsn0uSwRHHEQnF9H5hmsoQKCAQEA5poLkJ1s
-1ZeEWVr5CDU0js8QsEbeRGpXsm+Aj9X9gf4+D3HQ573lnXO8wiB+PoikETWp45Jf
-yq1XK2dcbygcxrSo6Zr+GtzE6grCztn8jE4omkqduJhViAr4hdg59R4UdNG1Qpgg
-Z9cFBYwnI/IWMJJBTiqKIVwD3RKQM75WKDT/ccDtUp2MxxNjUKAsVHpmOHW2ZC4T
-A2vwbqp+egQ5SfSUBcGkD034PjG2uOJGmHXcKnnG4Dm+9SeutvTF9JZwMJmg3WlG
-5AdVUnl4qN2g4t3TYasV4Y8i00EJPcQW5v4UV9sq4dAQ0GXfu/r/TXwMKkQp/cN1
-95I+xXsBjKQDdQKCAQEAuCTqVZJMZ5uovPzyPmnMOBqdtac5Hd7/eglN945sAK7n
-ssg3X1hRsHCf8Dx1X95lxCDVn97ac9C2uIEeiLy/+JDFQcOxcgj1vDeF6IaGzaFh
-Dc9qIDo4b0bhhD1kMxtowOAkI4YR/+iSIuGOJXq7wu71a6+dIm4meb+4d3L+O5Jq
-sOsOBLClL7Ymv1iZ3fol0XPQsuSv1eGoDqDdiNNXOBJHgKy0zMEXs4hpjL2vCGDN
-m8MbtqpMg4jCuesy/zh/b+CCkrX0AdW/fkw/euZ/ZTMEageqH5RfitX9CGOw2CuS
-+78XmWeFqbr2YVbAZFo09I8Ytv40yO1ZyVQkyKSlfQKCAQA1ooCsGyF0MHCVA+bG
-NPHLgXfFOEZ8LSvGkc6aJdB3yrWOjA9lxzI/w+qUUFBspQVcB1pDVwk2r8iFjN3f
-8Ll4sg5Tfzw47T5TnTsgN21ZCNjCwjYa+Dt0j/Cr2NXqIBvr69a37YAkBsvhNW7p
-GmZ015+e2aAVEDzJz4aAsnWBlooPYCsSuxhCOU0xNH/7Chj6as6IUHsVoaZjZv5R
-zOeyPtOq3xYUhTMG7DMun1qCHW+e5YIPJv82MAuf/CCKue7QLvtOZC0b3mTG8P/S
-bvH7slJ29f753nvgHNFUb2ZQRapfoNdBfE5c2kUGiOOWlxKRRhdqMWsfsQEul2SN
-3Jv9AoIBAASuW46lU2/m0xlKzNWtVtWuR4gQojESNChkCClc43349EblNBMmaZ00
-n7w5rTosqyWbOBMCVUdQbPSvw5jyQ2cMNxd+5AnkFGsedjb9BHxBt/fj5+y9ziV2
-BdGYxe1OqxEMIZ8Nj3OT8/MTDMwDHLbN4EtGgZYYer3pk8TllXTqOfAZaZfQ7cIS
-vVVr6S1taHy0lv+VNKsZO25zxG3wAW2ZeVvaCBaUagfUVeqP/90UqOVmxlOUbLGD
-Tn/vbLJ0Ozka2fbkzTkmt+F8CrkTFvX5oAkZ/MckvHEJE4+dCSfVo7zmlLD/orQ3
-3n+G9wkWCfaVlKlCORFKh1fI3c6D8PkCggEAI/zEfC6+CndqrmehoCGgHZMP7B+a
-rytCeG3Qyoqjta0sKGC8/LUe85PSWDR9xHrrWgEriRF9gHvYxF8YCBXhfInIHDd+
-pdcsWEaoUWlvBqhbKaPhVF/0difpjogWH388sdVXT6PefHEO5maYii9EaPjWckKf
-314Eh0KW/oUiSo5rwAgdnu1J84qBOxXqMI2eDZaKLphueytHjt7QRnZW91zeYwrP
-3E7MbkKVJPaViIm3MvXUUsL8Gpqji9MY0wHjZAq1PXtZ5WP+K3wHUOte6OGkBcSQ
-7oUxhOoMlN0VC4FGtSHu1LLTvmWeYrHk9J6mpfNAj1/TfA/VvVKpNQVlaw==
------END RSA PRIVATE KEY-----
diff --git a/test/run_fail/test-issue-1570.js b/test/run_fail/test-issue-1570.js
new file mode 100644 (file)
index 0000000..b94ca26
--- /dev/null
@@ -0,0 +1,17 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+Object.freeze(process);
+throw new Error("Some error");
diff --git a/test/run_pass/issue/issue-1463.js b/test/run_pass/issue/issue-1463.js
new file mode 100644 (file)
index 0000000..e64471d
--- /dev/null
@@ -0,0 +1,31 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+
+function readfile(fileName) {
+  return new Promise(function(resolve, reject) {
+    throw function() {}(), Buffer;
+  });
+};
+
+try {
+  readfile(readfile).then(function(value) {
+    loadfi([], 0);
+  }).prototype(function(e) {});
+  assert(false);
+} catch (ex) {
+  assert(ex instanceof TypeError);
+}
diff --git a/test/run_pass/test_buffer_from.js b/test/run_pass/test_buffer_from.js
new file mode 100644 (file)
index 0000000..18a2008
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+
+var array_src = [65, 66, 67];
+var buff = Buffer.from(array_src, 0, 3);
+assert.equal(buff.toString(), "ABC");
+var buff2 = Buffer.from(array_src, 0, -3);
+// Buffer.from(string, encoding)
+var string_utf = "ABC";
+var buff3 = Buffer.from(string_utf, 'utf8');
+assert.equal(buff3.toString(), "ABC");
+
+var string_hex = "414243";
+var buff4 = Buffer.from(string_hex, 'hex');
+assert.equal(buff4.toString(), "ABC");
+
+// Buffer.from(Buffer)
+var buffer_src = new Buffer([0x41, 0x42, 0x43]);
+var buff5 = Buffer.from(buffer_src);
+assert.equal(buff5.toString(), "ABC");
+
+var buff_undef = new Buffer(10);
+var buff6 = Buffer.from(buff_undef);
+assert.equal(buff6.toString(), buff_undef.toString());
+
+// Corner case tests
+var obj = {};
+var num = 5;
+assert.throws(function() { var buffer = Buffer.from(obj); },
+              TypeError);
+assert.throws(function() { var buffer = Buffer.from(num); },
+              TypeError);
diff --git a/test/run_pass/test_buffer_from_arraybuffer.js b/test/run_pass/test_buffer_from_arraybuffer.js
new file mode 100644 (file)
index 0000000..f6918f2
--- /dev/null
@@ -0,0 +1,81 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+
+var source = new ArrayBuffer(10);
+
+//creation tests
+var buff1 = Buffer.from(source, 0, 10);
+assert.equal(buff1.length, 10);
+var buff2 = Buffer.from(source, 3, 7);
+assert.throws(function() { var buffer = buffer.from(source, 3, 10) })
+assert.equal(buff2.length, 7);
+var buff3 = Buffer.from(source, 10, 0);
+assert.equal(buff3.length, 0);
+var buff4 = Buffer.from(source, 0, 0);
+assert.equal(buff4.length, 0);
+assert.throws(function() { var buffer = Buffer.from(source, 0, 1000); },
+              RangeError);
+assert.throws(function() { var buffer = Buffer.from(source, 1000, 9); },
+              RangeError);
+assert.throws(function() { var buffer = Buffer.from(source, 1000, 1000); },
+              RangeError);
+
+var buff5 = Buffer.from(source, undefined, 10);
+assert.equal(buff5.length, 10);
+var buff6 = Buffer.from(source, undefined, 0);
+assert.equal(buff6.length, 0);
+
+var buff7 = Buffer.from(source, undefined, -10);
+assert.equal(buff7.length, 0);
+var buff8 = Buffer.from(source, 0, undefined);
+assert.equal(buff8.length, 10);
+var buff9 = Buffer.from(source, 10, undefined);
+assert.equal(buff9.length, 0);
+assert.throws(function() {var buffer = Buffer.from(source, -10, undefined); },
+              RangeError);
+var buff10 = Buffer.from(source, undefined, undefined);
+assert.equal(buff10.length, 10);
+
+var buff11 = Buffer.from(source, NaN, 10);
+assert.equal(buff11.length, 10);
+var buff12 = Buffer.from(source, NaN, 0);
+assert.equal(buff12.length, 0);
+var buff13 = Buffer.from(source, NaN, -10);
+assert.equal(buff13.length, 0);
+
+var buff14 = Buffer.from(source, 0, NaN);
+assert.equal(buff14.length, 0);
+
+var buff15 = Buffer.from(source, 10, NaN);
+assert.equal(buff15.length, 0);
+assert.throws(function() { var buffer = Buffer.from(source, -10, NaN); },
+              RangeError);
+
+//value checks
+var typed_source1 = new Uint8Array([65, 66]);
+var arr_buff = Buffer.from(typed_source1.buffer, 0, 2);
+assert.equal(arr_buff.toString('utf-8'), 'AB');
+
+var typed_source2 = new Uint16Array([65, 66]);
+var arr_buff2 = Buffer.from(typed_source2.buffer, 0, 1);
+var arr_buff3 = Buffer.from(typed_source2.buffer, 2, 1);
+assert.equal(arr_buff2.toString(), 'A');
+assert.equal(arr_buff3.toString(), 'B');
+
+var typed_source3 = new Uint8Array([42, 43]);
+var arr_buff4 = Buffer.from(typed_source3.buffer, 0, 2);
+assert.equal(arr_buff4.toString('hex'), '2a2b');
diff --git a/test/run_pass/test_buffer_inmutability_creation.js b/test/run_pass/test_buffer_inmutability_creation.js
new file mode 100644 (file)
index 0000000..94dcfb1
--- /dev/null
@@ -0,0 +1,41 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+/* Related issue: https://github.com/Samsung/iotjs/issues/1379 */
+
+var assert = require('assert');
+
+/* The global Buffer by default is a function */
+assert.strictEqual(typeof(Buffer), "function");
+
+var backup_buffer = Buffer;
+
+/* Modify the global Buffer */
+Buffer++;
+
+/**
+ * The ++ operation will change the value of the "Buffer" variable.
+ * Thus the type shouldn't be a function now.
+ */
+assert.notStrictEqual(typeof(Buffer), "function");
+
+/**
+ * Still the creation of buffer should work.
+ * Using an already saved buffer reference
+ */
+var new_buffer = backup_buffer("OK");
+
+assert.equal(new_buffer.length, 2);
+assert.equal(new_buffer.toString(), "OK");
diff --git a/test/run_pass/test_crypto.js b/test/run_pass/test_crypto.js
new file mode 100644 (file)
index 0000000..4782240
--- /dev/null
@@ -0,0 +1,32 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var crypto = require('crypto');
+var assert = require('assert');
+
+var hash = crypto.createHash('sha1');
+
+assert.throws(function() { var err_hash = crypto.createHash('sadf'); });
+
+hash.update('Hello IoT.js');
+
+assert.equal(hash.digest('hex'), '4f5cf1945efb60f400c23172edb4e36b47f5a25e');
+assert.throws(function() { hash.digest('hex'); });
+
+var hash2 = crypto.createHash('sha1');
+hash2.update('Hello IoT.js');
+hash2.update(' v2');
+
+assert.equal(hash2.digest('base64'), 'DBnLTkxZ70AgUzCjZ7FTv91AWZw=');
diff --git a/test/run_pass/test_crypto_tls.js b/test/run_pass/test_crypto_tls.js
new file mode 100644 (file)
index 0000000..2f11f65
--- /dev/null
@@ -0,0 +1,66 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+var crypto = require('crypto');
+var fs = require('fs');
+
+var hash = crypto.createHash('sha256');
+hash.update('Hello IoT.js');
+
+assert.equal(hash.digest('hex'),
+             '23a1b938002c83a74b887d0a447c990' +
+             '5e83bab00459bcfd0bad548623b942e20');
+
+/*
+  This test requires a key file, which can be generated using the following
+  steps:
+  openssl genrsa -aes128 -passout pass:<passphrase> -out private.pem 2048
+  openssl rsa -in private.pem -passin pass:<passphrase> -pubout -out public.pem
+
+  Recreating this test with your own data requires you to have (a) key file(s)
+  with a public and a private key in them. The private key is used to sign the
+  data.
+  The public key is used to verify that the signature was done with the
+  appropriate private key.
+
+  To generate the rsa-sha256 signature you need to execute these lines:
+  Creating an sha256 signature
+  openssl dgst -sha256 -sign <privatekeyfile> -out <signed.sha256> <inputfile>
+  Creating a base64 encoded signature
+  openssl base64 -in <signed.sha256> -out <signature.sha256>
+
+  To verify the signature, you need:
+    - The <signature.sha256> file,
+    - The public key, most likely from the public.pem file,
+    - The <inputfile> which contains the data, or you can just copy and paste,
+      the data and give it to the `verify.update()` function.
+
+  Having created the `verify` object, just call the `.verify(pubkey, signature)`
+  on it, and you are ready to go.
+*/
+
+var pubKey = fs.readFileSync(process.cwd() + '/resources/crypto_public.pem');
+var verify = crypto.createVerify('sha256');
+verify.update('Hello IoT.js\n');
+var res = verify.verify(pubKey, 'JkFnOrBQGXYlpmlcMuS5EwyJ44WY/kW5sFwb8DRgAoo7' +
+                                'RmxYPKgyo/OrZ0YAcY5xpxbVZzS7ftxz7N4q+Ouufg6s' +
+                                'NSzmIimBPLV+afX4Qb8jOV0edCmeBKZaHQrMWpisWXF/' +
+                                'bZKS1yiMij2NGSJYXWhjRzreIeVNVv/b0phHHeK2r2tT' +
+                                '9T+XA+rdgHlIOb+r/FT/VWopr+vd+8I0fjxpP/S8lZ5u' +
+                                'HSF9jZ5TFdIEYMWchKit4Eyw7/VAWRlJNNKVxTmuM337' +
+                                '+rP9oLKiFUeoM6jrE10LxGnIpelvyNV+MHfo11I1GAMK' +
+                                'jsOuye9JZ8/hQPg+KLWH/l/xZlUD2fZNNg==');
+assert.equal(res, true);
index cb9c71733e8b968760353ebdc2793fd8def7ad00..d5a4ac0ad52fd952a6e6f250fa411b288e655a94 100644 (file)
@@ -58,7 +58,14 @@ dns.lookup('invalid', 4, function(err, ip, family) {
 
 // Test with empty hostname.
 dns.lookup('', 4, function(err, ip, family) {
-  assert.notEqual(err, null);
+  if (process.platform === "windows") {
+    /* On windows the empty dns name can be resolved. */
+    assert.equal(err, null);
+    assert.notEqual(ip, null);
+    assert.notEqual(family, null);
+  } else {
+    assert.notEqual(err, null);
+  }
 });
 
 // Test with non string hostname.
diff --git a/test/run_pass/test_fs_read_stream.js b/test/run_pass/test_fs_read_stream.js
new file mode 100644 (file)
index 0000000..5e43e67
--- /dev/null
@@ -0,0 +1,70 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+var fs = require('fs');
+var assert = require('assert');
+
+if (fs.createReadStream === undefined || fs.createWriteStream === undefined) {
+  process.exit(0);
+}
+
+var inputFile = process.cwd() + '/resources/tobeornottobe.txt';
+
+var res;
+var expected =
+  "To be, or not to be, that is the Question:\n" +
+  "Whether ’tis Nobler in the mind to ſuffer\n" +
+  "The Slings and Arrows of outragious Fortune,\n" +
+  "Or to take Armes against a Sea of troubles,\n" +
+  "And by opposing end them: to dye, to ſleepe\n" +
+  "No more; and by a sleep, to say we end\n" +
+  "The Heart-ake, and the thouſand Naturall ſhockes\n" +
+  'That Flesh is there too? "Tis a consummation\n' +
+  "Deuoutly to be wiſh'd. To dye to sleepe,\n" +
+  "To sleep, perchance to Dream; I, there's the rub,\n" +
+  "For in that sleep of death, what dreams may come,\n" +
+  "When we haue ſhufflel’d off this mortall coile,\n" +
+  "Muſt giue us pause. There's the respect\n" +
+  "That makes Calamity of long life:\n" +
+  "For who would beare the Whips and Scornes of time,\n" +
+  "The Oppreſſors wrong, the poore mans Contumely,\n" +
+  "The pangs of diſpriz’d Loue, the Lawes delay,\n" +
+  "The inſolence of Office, and the Spurnes\n" +
+  "That patient merit of the vnworthy takes,\n" +
+  "When he himſelfe might his Quietus make\n" +
+  "With a bare Bodkin? Who would theſe Fardles beare\n" +
+  "To grunt and ſweat vnder a weary life,\n" +
+  "But that the dread of ſomething after death,\n" +
+  "The vndiſcouered Countrey, from whoſe Borne\n" +
+  "No Traueller returnes, Puzels the will,\n" +
+  "And makes vs rather beare those illes we haue,\n" +
+  "Then flye to others that we know not of.\n" +
+  "Thus Conſcience does make Cowards of vs all,\n" +
+  "And thus the Natiue hew of Resolution\n" +
+  "Is ſicklied o’re, with the pale caſt of Thought,\n" +
+  "And enterprizes of great pith and moment,\n" +
+  "With this regard their Currants turne away,\n" +
+  "And looſe the name of Action. Soft you now,\n" +
+  "The faire Ophelia? Nimph, in thy Orizons\n" +
+  "Be all my ſinnes remembred.";
+
+var readableFileStream = fs.createReadStream(inputFile);
+
+readableFileStream.on('data', function(data) {
+  res = data;
+});
+
+process.on('exit', function() {
+  assert.equal(res, expected);
+});
diff --git a/test/run_pass/test_fs_stream_pipe.js b/test/run_pass/test_fs_stream_pipe.js
new file mode 100644 (file)
index 0000000..9a5890b
--- /dev/null
@@ -0,0 +1,83 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var fs = require('fs');
+var assert = require('assert');
+
+if (fs.createReadStream === undefined || fs.createWriteStream === undefined) {
+  process.exit(0);
+}
+
+var inputFileName = process.cwd() + '/resources/tobeornottobe.txt';
+var outputFileName = process.cwd() + '/tmp/test_fs4.txt';
+
+var buff1 = new Buffer(2048);
+var buff2 = new Buffer(2048);
+
+// Get the correct content of the input for later checking.
+fs.open(inputFileName, 'r', 0666, function(err, fd) {
+  if (err) {
+    throw err;
+  }
+
+  fs.read(fd, buff1, 0, buff1.length, 0, function(err, bytesRead, buffer) {
+    if (err) {
+      throw err;
+    }
+
+    fs.close(fd, onclose);
+  });
+});
+
+function onclose(err) {
+  if (err) {
+    throw err;
+  }
+
+  var readableFileStream = fs.createReadStream(inputFileName);
+  var writableFileStream = fs.createWriteStream(outputFileName);
+
+  writableFileStream.on('ready', function() {
+    readableFileStream.pipe(writableFileStream);
+  });
+
+  writableFileStream.on('close', check_output);
+}
+
+function check_output() {
+  // Read the output for checking.
+  fs.open(outputFileName, 'r', function(err, fd) {
+    if (err) {
+      throw err;
+    }
+
+    fs.read(fd, buff2, 0, buff2.length, 0, function(err, bytesRead, buffer) {
+      if (err) {
+        throw err;
+      }
+
+      fs.close(fd, function(err) {
+        if (err) {
+          throw err;
+        }
+      })
+    });
+  });
+}
+
+process.on('exit', function() {
+  assert.equal(buff1.toString(), buff2.toString(),
+               'File contents do not match');
+});
diff --git a/test/run_pass/test_fs_write_stream.js b/test/run_pass/test_fs_write_stream.js
new file mode 100644 (file)
index 0000000..398f1ae
--- /dev/null
@@ -0,0 +1,55 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var fs = require('fs');
+var assert = require('assert');
+
+if (fs.createReadStream === undefined || fs.createWriteStream === undefined) {
+  process.exit(0);
+}
+
+var dir = (process.platform === 'tizenrt') ? '/mnt/' : process.cwd() + '/tmp/';
+var outputFile = dir + 'test_fs5.txt';
+var testData = 'WriteStream test';
+
+var writableFileStream = fs.createWriteStream(outputFile);
+
+writableFileStream.on('ready', function() {
+  writableFileStream.write(testData);
+});
+
+var buff = new Buffer(64);
+writableFileStream.on('close', function() {
+  // Check output correctness
+  fs.open(outputFile, 'r', 0666, function(err, fd) {
+    if (err) {
+      throw err;
+    }
+
+    fs.read(fd, buff, 0, buff.length, 0, function(err, bytesRead, buffer) {
+      if (err) {
+        throw err;
+      }
+
+      assert.equal(buff.toString(), testData, 'Incorrect data in output file');
+
+      fs.close(fd, function(err) {
+        if (err) {
+          throw err;
+        }
+      });
+    });
+  })
+});
diff --git a/test/run_pass/test_gpio_api.js b/test/run_pass/test_gpio_api.js
new file mode 100644 (file)
index 0000000..b3e06b5
--- /dev/null
@@ -0,0 +1,317 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+var gpio = require('gpio');
+
+// ------ Test API existance
+assert.assert(gpio.DIRECTION,
+              'gpio module does not provide \'DIRECTION\' property');
+assert.notEqual(gpio.DIRECTION.IN, undefined);
+assert.notEqual(gpio.DIRECTION.OUT, undefined);
+
+assert.assert(gpio.EDGE,
+              'gpio module does not provide \'EDGE\' property');
+assert.notEqual(gpio.EDGE.NONE, undefined);
+assert.notEqual(gpio.EDGE.RISING, undefined);
+assert.notEqual(gpio.EDGE.FALLING, undefined);
+assert.notEqual(gpio.EDGE.BOTH, undefined);
+
+assert.assert(gpio.MODE,
+              'gpio module does not provide \'MODE\' property');
+assert.notEqual(gpio.MODE.NONE, undefined);
+if (process.platform === 'nuttx') {
+  assert.notEqual(gpio.MODE.PULLUP, undefined);
+  assert.notEqual(gpio.MODE.PULLDOWN, undefined);
+  assert.notEqual(gpio.MODE.FLOAT, undefined);
+  assert.notEqual(gpio.MODE.PUSHPULL, undefined);
+  assert.notEqual(gpio.MODE.OPENDRAIN, undefined);
+}
+
+assert.equal(typeof gpio.open, 'function',
+             'gpio does not provide \'open\' function');
+assert.equal(typeof gpio.openSync, 'function',
+             'gpio does not provide \'openSync\' function');
+
+
+function check_gpiopin(gpiopin) {
+  assert.equal(typeof pin.setDirectionSync, 'function',
+               '\'gpiopin\' does not provide \'setDirectionSync\' function');
+  assert.equal(typeof pin.write, 'function',
+               '\'gpiopin\' does not provide \'write\' function');
+  assert.equal(typeof pin.writeSync, 'function',
+               '\'gpiopin\' does not provide \'writeSync\' function');
+  assert.equal(typeof pin.read, 'function',
+               '\'gpiopin\' does not provide \'read\' function');
+  assert.equal(typeof pin.readSync, 'function',
+               '\'gpiopin\' does not provide \'readSync\' function');
+  assert.equal(typeof pin.close, 'function',
+               '\'gpiopin\' does not provide \'close\' function');
+  assert.equal(typeof pin.closeSync, 'function',
+               '\'gpiopin\' does not provide \'closeSync\' function');
+}
+
+// ------ Test synchronous GPIO pin opening
+assert.throws(
+  function() {
+    gpio.openSync({pin: 0, direction: 123});
+  },
+  TypeError
+);
+
+assert.throws(
+  function() {
+    gpio.openSync({pin: 0, direction: {}});
+  },
+  TypeError
+);
+
+assert.throws(
+  function() {
+    gpio.openSync({pin: 0, direction: 'out'});
+  },
+  TypeError
+);
+
+assert.throws(
+  function() {
+    gpio.openSync({pin: 0, edge: 123});
+  },
+  TypeError
+);
+
+assert.throws(
+  function() {
+    gpio.openSync({pin: 0, edge: {}});
+  },
+  TypeError
+);
+
+assert.throws(
+  function() {
+    gpio.openSync({pin: 0, edge: 'rising'});
+  },
+  TypeError
+);
+
+assert.throws(
+  function() {
+    gpio.openSync({pin: '12'});
+  },
+  TypeError
+);
+
+assert.throws(
+  function() {
+    gpio.openSync({pin: {}});
+  },
+  TypeError
+);
+
+assert.throws(
+  function() {
+    gpio.openSync({pin: -12});
+  },
+  TypeError
+);
+
+var pin = gpio.openSync({pin: 0, direction: gpio.DIRECTION.OUT});
+check_gpiopin(pin);
+pin.closeSync();
+
+assert.throws( // close twice
+  function() {
+    pin.closeSync();
+  },
+  Error
+);
+
+pin = gpio.openSync({pin: 0, direction: gpio.DIRECTION.IN});
+check_gpiopin(pin);
+pin.closeSync();
+
+pin = gpio.openSync({pin: 0});
+check_gpiopin(pin);
+
+assert.doesNotThrow(function() {
+  pin.setDirectionSync(gpio.DIRECTION.OUT)
+});
+
+assert.throws(
+  function() {
+    pin.setDirectionSync(123);
+  },
+  TypeError
+);
+
+assert.throws(
+  function() {
+    pin.setDirectionSync('out');
+  },
+  Error
+);
+
+assert.throws(
+  function() {
+    pin.setDirectionSync({});
+  },
+  Error
+);
+
+assert.doesNotThrow(
+  function() {
+    pin.writeSync(true);
+    pin.writeSync(false);
+    pin.writeSync(0);
+    pin.writeSync(1);
+    pin.writeSync(123);
+    pin.writeSync(-123);
+  }
+);
+
+assert.doesNotThrow(
+  function() {
+    pin.write(true, function(err) {
+      assert.assert(err === null, 'gpio.write failed: ' + err);
+      write_cb1 = true;
+    });
+    pin.write(false, function(err) {
+      assert.assert(err === null, 'gpio.write failed: ' + err);
+      write_cb2 = true;
+    });
+    pin.write(0, function(err) {
+      assert.assert(err === null, 'gpio.write failed: ' + err);
+      write_cb3 = true;
+    });
+    pin.write(1, function(err) {
+      assert.assert(err === null, 'gpio.write failed: ' + err);
+      write_cb4 = true;
+    });
+    pin.write(123, function(err) {
+      assert.assert(err === null, 'gpio.write failed: ' + err);
+      write_cb5 = true;
+    });
+    pin.write(-123, function(err) {
+      assert.assert(err === null, 'gpio.write failed: ' + err);
+      write_cb6 = true;
+    });
+  }
+);
+
+assert.throws(
+  function() {
+    pin.writeSync('true');
+  },
+  Error
+);
+
+assert.throws(
+  function() {
+    pin.writeSync({});
+  },
+  Error
+);
+
+assert.throws(
+  function() {
+    gpio.write({});
+  },
+  Error
+);
+
+assert.throws(
+  function() {
+    gpio.write('true');
+  },
+  Error
+);
+
+pin.write('true', function(err) {
+  assert.assert(err, 'gpio.write did not fail as expected');
+});
+
+pin.write({}, function(err) {
+  assert.assert(err, 'gpio.write did not fail as expected');
+});
+
+// ------ Test asynchronous GPIO pin opening
+
+var async_pin1 = gpio.open(
+  {
+    pin: 0,
+    direction: gpio.DIRECTION.OUT
+  },
+  function(err, async_pin2) {
+    open_cb1 = true;
+    assert.assert(err === null, 'gpio.open failed: ' + err);
+    assert.assert(async_pin1);
+    assert.assert(async_pin2);
+    assert.assert(async_pin1 === async_pin2,
+                  'return value and callback parameters are not equal');
+    check_gpiopin(async_pin2);
+    async_pin2.close(function(err) {
+      close_cb1 = true;
+      assert.assert(err === null, 'gpio.close failed: ' + err);
+    });
+  }
+);
+
+gpio.open(
+  {
+    pin: 0,
+    direction: gpio.DIRECTION.IN
+  },
+  function(err, async_pin) {
+    open_cb2 = true;
+    assert.assert(err === null, 'gpio.open failed: ' + err);
+    check_gpiopin(async_pin);
+    async_pin.close(function(err) {
+      close_cb2 = true;
+      assert.assert(err === null, 'gpio.close failed: ' + err);
+    });
+  }
+);
+
+gpio.open(
+  { pin: 0 },
+  function(err, async_pin) {
+    open_cb3 = true;
+    assert.assert(err === null, 'gpio.open failed: ' + err);
+    check_gpiopin(async_pin);
+    async_pin.close(function(err) {
+      close_cb3 = true;
+      assert.assert(err === null, 'gpio.close failed: ' + err);
+    });
+  }
+);
+
+process.on('exit', function(code) {
+  if (code === 0) {
+    assert.assert(open_cb1, 'callback of \'gpio.open\' was not called');
+    assert.assert(close_cb1, 'callback of \'gpio.close\' was not called');
+    assert.assert(open_cb2, 'callback of \'gpio.open\' was not called');
+    assert.assert(close_cb2, 'callback of \'gpio.close\' was not called');
+    assert.assert(open_cb3, 'callback of \'gpio.open\' was not called');
+    assert.assert(close_cb3, 'callback of \'gpio.close\' was not called');
+
+    assert.assert(write_cb1, 'callback of \'gpio.write\' was not called');
+    assert.assert(write_cb2, 'callback of \'gpio.write\' was not called');
+    assert.assert(write_cb3, 'callback of \'gpio.write\' was not called');
+    assert.assert(write_cb4, 'callback of \'gpio.write\' was not called');
+    assert.assert(write_cb5, 'callback of \'gpio.write\' was not called');
+    assert.assert(write_cb6, 'callback of \'gpio.write\' was not called');
+  }
+  pin.closeSync();
+});
diff --git a/test/run_pass/test_gpio_direction.js b/test/run_pass/test_gpio_direction.js
new file mode 100644 (file)
index 0000000..52c4688
--- /dev/null
@@ -0,0 +1,41 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var gpio = require('gpio');
+var pin = require('tools/systemio_common').pin;
+
+var gpioPin = gpio.openSync({
+  pin: pin.led,
+  direction: gpio.DIRECTION.OUT,
+});
+
+console.log('GPIO input test. Press the button.');
+gpioPin.setDirectionSync(gpio.DIRECTION.IN);
+var loop = setInterval(function() {
+  var value = gpioPin.readSync();
+  console.log('GpioPin value:', value);
+}, 500);
+
+setTimeout(function() {
+  clearInterval(loop);
+
+  console.log('GPIO output test. Led is on for 5000ms.');
+  gpioPin.setDirectionSync(gpio.DIRECTION.OUT);
+  gpioPin.writeSync(1);
+  setTimeout(function() {
+    gpioPin.writeSync(0);
+  }, 5000);
+}, 5000);
+
diff --git a/test/run_pass/test_http_signature.js b/test/run_pass/test_http_signature.js
new file mode 100644 (file)
index 0000000..3479bca
--- /dev/null
@@ -0,0 +1,54 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var fs = require('fs');
+var http_sign = require('http_signature');
+var assert = require('assert');
+
+var key = fs.readFileSync(process.cwd() + '/resources/http_signature_key.key');
+
+// This is an example request of a Samsung C2C demo
+var sampleRequest = { "headers": {
+              "Content-Type":"application/json",
+              "Accept":"application/json",
+              "Authorization":"Signature keyId=\"http_signature_key\"," +
+              "signature=\"mJUG2ceYWCGww2tXrVJywQUqQvaWbkWpAx4xSfqZD9Gr" +
+              "G12N8pVysa/nl18kEKe2Sbd00c50qyF/xH5hKtxFyyUYBxY5cOrdt+7W" +
+              "1EmctaGGIDOnZA/qZcXcnTBZsp8k68XI/6HxwIxHVUntAd2vxJvqzibB" +
+              "TZLHAhTRVCoAqHzjHe0kybv5oebbMASaNEhZTLslQYQUOYqVzE+4Ecen" +
+              "Vxrlk2wpjjFjnBdxd/Ek34FTOcWMoPKjpj1ja+hfet2Em8YzF+aeHrBR" +
+              "t7FTt7r/GkYfuwm9M0XYSY1JvnvCKxIU20YXKbZ+KINBaUXDwEKapUvm" +
+              "bDFuLi3arJcDigWIOA==\",headers=\"(request-target) digest" +
+              " date\",algorithm=\"rsa-sha256\"",
+              "Date":"Tue, 28 Aug 2018 15:28:59 UTC",
+              "Digest":"SHA-256=52eIrPP0TxhlUVwnChuVLj6qFmbl5dYdMIvUr+DlZ0A=",
+              "X-ST-CORRELATION":"b7891162-2084-da6e-da84-401be50cd534",
+              "X-B3-TraceId":"fb04fc10f3088f10",
+              "X-B3-SpanId":"c6245b1a3c934a0d",
+              "X-B3-ParentSpanId":"989731b1f545e7d1",
+              "X-B3-Sampled":"1",
+              "content-length":"344",
+              "host":"example.host.com",
+              "user-agent":"AHC/2.1",
+              "X-Forwarded-Proto":"https",
+              "X-Forwarded-For":"52.14.6.245" },
+            "method": "POST",
+            "url": "/",
+            "httpVersion": "1.1",
+          };
+
+
+var parsedRequest = http_sign.parseRequest(sampleRequest);
+assert.equal(http_sign.verifySignature(parsedRequest, key), true);
diff --git a/test/run_pass/test_i2c_api.js b/test/run_pass/test_i2c_api.js
new file mode 100644 (file)
index 0000000..48b6ee8
--- /dev/null
@@ -0,0 +1,165 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+var i2c = require('i2c');
+
+// ------ Test API existance
+assert.equal(typeof i2c.open, 'function',
+             'i2c does not provide \'open\' function');
+assert.equal(typeof i2c.openSync, 'function',
+             'i2c does not provide \'openSync\' function');
+
+function check_i2cbus(i2cbus) {
+  assert.equal(typeof i2cbus.write, 'function',
+               '\'i2cpin\' does not provide \'write\' function');
+  assert.equal(typeof i2cbus.writeSync, 'function',
+               '\'i2cpin\' does not provide \'writeSync\' function');
+  assert.equal(typeof i2cbus.read, 'function',
+               '\'i2cpin\' does not provide \'read\' function');
+  assert.equal(typeof i2cbus.readSync, 'function',
+               '\'i2cpin\' does not provide \'readSync\' function');
+  assert.equal(typeof i2cbus.close, 'function',
+               '\'i2cpin\' does not provide \'close\' function');
+  assert.equal(typeof i2cbus.closeSync, 'function',
+               '\'i2cpin\' does not provide \'closeSync\' function');
+}
+
+// ------ Test synchronous I2C Bus opening
+assert.throws(
+  function() {
+    i2c.openSync({address: '0x0'});
+  },
+  TypeError
+);
+
+assert.throws(
+  function() {
+    i2c.openSync('0x0');
+  },
+  Error
+);
+
+assert.throws(
+  function() {
+    i2c.openSync({});
+  },
+  TypeError
+);
+
+var bus = i2c.openSync({address: 0x23});
+check_i2cbus(bus);
+
+assert.doesNotThrow(
+  function() {
+    bus.writeSync([0x10, 123, -12]);
+    read_result = bus.readSync(5);
+  }
+);
+
+assert.throws(
+  function() {
+    bus.writeSync(0x23);
+  },
+  Error
+);
+
+assert.throws(
+  function() {
+    bus.writeSync(null);
+  },
+  Error
+);
+
+assert.throws(
+  function() {
+    bus.readSync('5');
+  },
+  Error
+);
+
+assert.throws(
+  function() {
+    bus.readSync(null);
+  },
+  Error
+);
+
+assert.throws(
+  function() {
+    bus.readSync([5]);
+  },
+  Error
+);
+
+assert.throws(
+  function() {
+    bus.readSync({});
+  },
+  Error
+);
+
+assert.assert(Array.isArray(read_result));
+assert.strictEqual(read_result.length, 5);
+
+bus.closeSync();
+
+// ------ Test asynchronous I2C Bus opening
+i2c.open({address: 0x0}, function(open_err, async_bus) {
+  assert.equal(open_err, null);
+  open_cb1 = true;
+
+  assert.throws(
+    function() {
+      async_bus.read(null);
+    },
+    Error
+  );
+
+  assert.throws(
+    function() {
+      async_bus.write(null);
+    },
+    Error
+  );
+
+  async_bus.write([0x10, 123, -12], function(write_err) {
+    assert.equal(write_err, null);
+    write_cb1 = true;
+
+    async_bus.read(5, function(read_err, res) {
+      assert.equal(read_err, null);
+      read_cb1 = true;
+      assert.assert(Array.isArray(res));
+      assert.strictEqual(res.length, 5);
+
+      async_bus.close(function(close_err) {
+        assert.equal(close_err, null);
+        close_cb1 = true;
+      });
+    });
+  });
+});
+
+process.on('exit', function(code) {
+  if (code === 0) {
+    assert.assert(open_cb1, 'callback of \'i2c.open\' was not called');
+    assert.assert(close_cb1, 'callback of \'i2c.close\' was not called');
+
+    assert.assert(read_cb1, 'callback of \'i2cbus.read\' was not called');
+    assert.assert(write_cb1, 'callback of \'i2cbus.write\' was not called');
+  }
+});
+
index 1aa072f54d7077570fe675ecc2f15b13218b2ef7..33a3744fa6ba9f95f76912d667caffb574a2261b 100644 (file)
 var assert = require('assert');
 var fs = require('fs');
 
-var iotjs_path = process.env["IOTJS_PATH"]
-/* Currenlty it is expected tha the loadable test module is at a given path. */
-var dynamicmodule_dir = iotjs_path + "/../test/dynamicmodule/"
-var dynamicmodule_name = "test-dynamicmodule"
+var dynamicmodule_dir = "dynamicmodule/build/" + process.platform + "/";
+var dynamicmodule_name = "dynamicmodule";
 var dynamicmodule_path = dynamicmodule_dir + dynamicmodule_name + ".iotjs";
 
 assert.assert(fs.existsSync(dynamicmodule_path),
diff --git a/test/run_pass/test_mqtt.js b/test/run_pass/test_mqtt.js
new file mode 100644 (file)
index 0000000..eb40b6f
--- /dev/null
@@ -0,0 +1,103 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var mqtt = require('mqtt');
+var assert = require('assert');
+
+var connected = false;
+var subscribed = false;
+
+// The number of the variable is the qos level (0-2)
+
+var msg0 = 'hello iotjs 1';
+var msg1 = 'hello iotjs 2';
+var msg2 = 'hello iotjs 3';
+
+var published0 = false;
+var published1 = false;
+var published2 = false;
+
+var received0 = false;
+var received1 = false;
+var received2 = false;
+
+var subClientOpts = {
+  clientId: 'iotjs-mqtt-test-sub',
+  host: 'test.mosquitto.org',
+  port: 1883,
+  keepalive: 30,
+};
+
+var pubClientOpts = {
+  clientId: 'iotjs-mqtt-test-pub',
+  port: 1883,
+  keepalive: 30
+};
+
+var pubClient;
+
+var subClient = mqtt.connect(subClientOpts, function() {
+  connected = true;
+
+  subClient.subscribe('iotjs-test-topic', { qos:2 }, function() {
+    subscribed = true;
+
+    pubClient = mqtt.connect('test.mosquitto.org', pubClientOpts, function() {
+      pubClient.publish('iotjs-test-topic', msg0, { qos:0 }, function() {
+        published0 = true;
+      });
+
+      pubClient.publish('iotjs-test-topic', msg1, { qos:1 }, function() {
+        published1 = true;
+      });
+
+      pubClient.publish('iotjs-test-topic', msg2, { qos:2 }, function() {
+        published2 = true;
+      });
+    });
+  });
+
+  subClient.on('message', function(data) {
+    var str = data.message.toString();
+
+    if (str == msg0) {
+      received0 = true;
+    }
+
+    if (str == msg1) {
+      received1 = true;
+    }
+
+    if (str == msg2) {
+      received2 = true;
+    }
+
+    if (received0 && received1 && received2) {
+      subClient.end();
+      pubClient.end();
+    }
+  });
+});
+
+process.on('exit', function() {
+  assert.equal(connected, true);
+  assert.equal(subscribed, true);
+  assert.equal(published0, true);
+  assert.equal(published1, true);
+  assert.equal(published2, true);
+  assert.equal(received0, true);
+  assert.equal(received1, true);
+  assert.equal(received2, true);
+});
diff --git a/test/run_pass/test_mqtt_frags.js b/test/run_pass/test_mqtt_frags.js
new file mode 100644 (file)
index 0000000..27a119a
--- /dev/null
@@ -0,0 +1,144 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var stream = require('stream');
+var mqtt = require('mqtt');
+var assert = require('assert');
+var fs = require('fs');
+
+var duplex = new stream.Duplex();
+
+var connect_state = 0;
+var recv_count = 0;
+var fragment_index = 0;
+
+// Message we send is always the same, but it is fragmented in different ways
+var fragments = [
+  // Basic message:
+  '3014000d67656e6572616c2f746f70696368656c6c6f',
+
+  // One message in three fragments
+  '30',
+  '14',
+  '000d67656e6572616c2f746f70696368656c6c6f',
+
+  // One message in four fragments
+  '30',
+  '14',
+  '00',
+  '0d67656e6572616c2f746f70696368656c6c6f',
+
+  // One message in five fragments
+  '30',
+  '14',
+  '00',
+  '0d67656e6572616c2f746f70696368656c6c',
+  '6f',
+
+  // Two connected messages
+  '3014000d67656e6572616c2f746f70696368656c6c6f' +
+  '3014000d67656e6572616c2f746f70696368656c6c6f',
+
+  // Two messages in three fragments
+  '3014000d67656e6572616c2f74',
+  '6f70696368656c6c6f3014000d67656e65',
+  '72616c2f746f70696368656c6c6f',
+
+  // Two messages in three fragments
+  '3014000d67656e6572616c2f746f70696368656c6c6f30',
+  '14',
+  '000d67656e6572616c2f746f70696368656c6c6f',
+
+  // A 132 byte long message
+  '30',
+  '87',
+  '01',
+  '000d67656e6572616c2f746f706963',
+  '68656c6c6f68656c6c6f68656c6c6f68656c6c6f',
+  '68656c6c6f68656c6c6f68656c6c6f68656c6c6f' +
+  '68656c6c6f68656c6c6f68656c6c6f68656c6c6f' +
+  '68656c6c6f68656c6c6f68656c6c6f68656c6c6f',
+  '68656c6c6f68656c6c6f68656c6c6f68656c6c6f' +
+  '68656c6c6f68656c6c6f68656c6c6f68656c6c6f'
+];
+
+function send_fragment() {
+  duplex.push(new Buffer(fragments[fragment_index], 'hex'));
+
+  if (++fragment_index < fragments.length) {
+    process.nextTick(send_fragment);
+  } else {
+    duplex.end();
+  }
+}
+
+duplex._write = function(chunk, callback, onwrite) {
+  onwrite();
+
+  switch (connect_state) {
+  case 0:
+    assert.equal(chunk.toString('hex'),
+                 '100f00044d5154540402001e0003636c69');
+
+    process.nextTick(function() {
+      duplex.push(new Buffer('20020000', 'hex'));
+    });
+    break;
+
+  case 1:
+    assert.equal(chunk.toString('hex'),
+                 '82120000000d67656e6572616c2f746f70696300');
+
+    process.nextTick(function() {
+      duplex.push(new Buffer('9003000002', 'hex'));
+      process.nextTick(send_fragment);
+    });
+    break;
+
+  default:
+    throw new RangeError("Unknown connection state")
+    break;
+  }
+
+  connect_state++;
+};
+
+duplex._readyToWrite();
+
+var mqtt_client = mqtt.connect({
+  clientId: 'cli',
+  keepalive: 30,
+  socket: duplex,
+}, function() {
+  /* Just subscribe a random topic. */
+  mqtt_client.subscribe('general/topic');
+});
+
+mqtt_client.on('message', function(data) {
+  if (recv_count < 10) {
+    assert.equal(data.message.toString(), 'hello');
+  } else {
+    var str = '';
+    for (var i = 0; i < 24; i++)
+        str += 'hello';
+    assert.equal(data.message.toString(), str);
+  }
+
+  recv_count++;
+});
+
+mqtt_client.on('finish', function(data) {
+  assert.equal(recv_count, 11);
+});
index 66538221f4de7914041af494f4e51de2eda3de4a..798dc474be5bfd2be4fc3374349d34d8173de8a2 100644 (file)
@@ -53,6 +53,8 @@ var server = http.createServer(function (req, res) {
       res.setHeader('h' + (5 + i), 'h' + (5 + i));
     }
 
+    res.setHeader('content-length', 0);
+
     res.end(function(){
       server.close();
     });
@@ -79,6 +81,7 @@ var postResponseHandler = function (res) {
   assert.equal(res.headers['h1'], 'h1');
   assert.equal(res.headers['h2'], undefined);
   assert.equal(res.headers['h3'], 'h3prime');
+  assert.equal(res.headers['content-length'], 0);
 
   var endHandler = function(){
     checkReqFinish = true;
diff --git a/test/run_pass/test_net_http_methods.js b/test/run_pass/test_net_http_methods.js
new file mode 100644 (file)
index 0000000..57dc81a
--- /dev/null
@@ -0,0 +1,33 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+var http = require('http');
+
+assert(http.METHODS instanceof Array, 'http.METHODS should be an array');
+
+for (var idx in http.METHODS) {
+  assert(typeof(http.METHODS[idx]) === 'string',
+         'Elements of the http.METHODS should be strings. ' +
+         'Found an invalid element, index: ' + idx);
+}
+
+/* Test if at least the basic HTTP methods should be supported */
+var main_methods = ['GET', 'POST', 'PUT', 'DELETE', 'HEAD'];
+for (var idx in main_methods) {
+  var method_name = main_methods[idx];
+  assert.notEqual(http.METHODS.indexOf(method_name), -1,
+                 'http.METHODS is missing the value: ' + method_name);
+}
diff --git a/test/run_pass/test_net_http_modified_req_resp.js b/test/run_pass/test_net_http_modified_req_resp.js
new file mode 100644 (file)
index 0000000..f7f285f
--- /dev/null
@@ -0,0 +1,113 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+var http = require('http');
+
+var response_message = 'DATA';
+var response_got = 'NOT THIS';
+
+/*
+ * Test if 'subclassing' the IncomingMessage
+ * and ServerResponse is correctly propagated.
+ */
+function newIncomingMessage() {
+  http.IncomingMessage.apply(this, arguments);
+};
+newIncomingMessage.prototype = Object.create(http.IncomingMessage.prototype);
+newIncomingMessage.prototype.extra_field = 'found';
+newIncomingMessage.prototype.waitForBody = function() {
+  var chunks = [];
+  this.on('data', function(chunk) {
+    chunks.push(chunk);
+  });
+  this.on('end', function() {
+    this.emit('full_body', Buffer.concat(chunks));
+  });
+};
+
+
+function newServerResponse() {
+  http.ServerResponse.apply(this, arguments);
+};
+newServerResponse.prototype = Object.create(http.ServerResponse.prototype);
+newServerResponse.prototype.sendJSON = function (obj) {
+  var message_body = JSON.stringify(obj);
+  this.setHeader('Content-Length', message_body.length);
+  this.setHeader('Content-Type', 'application/json');
+  this.writeHead(200);
+  this.end(message_body);
+};
+
+var serveropts = {
+  IncomingMessage: newIncomingMessage,
+  ServerResponse: newServerResponse,
+};
+
+var server = http.createServer(serveropts, function (req, res) {
+  assert.equal(req.method, 'POST', 'Incorrect request method detected');
+  assert.equal(req.url, '/put_msg', 'Incorrect request url detected');
+  assert.assert(req instanceof http.IncomingMessage,
+                'Request is not instance of http.IncomingMessage');
+  assert.assert(req instanceof newIncomingMessage,
+                'Request is not instance of the new Request object');
+  assert.equal(req.extra_field, 'found',
+               'No "extra_field" property on the request instance');
+
+  req.waitForBody();
+  req.on('full_body', function(body) {
+    assert.assert(body instanceof Buffer);
+    assert.equal(body.toString(), 'DEMO');
+
+    res.sendJSON({message: response_message});
+  });
+});
+
+server.listen(3001);
+
+var demo_msg = 'DEMO';
+var options = {
+  method : 'POST',
+  port : 3001,
+  path : '/put_msg',
+  headers: {
+    'Content-Length': demo_msg.length,
+  },
+};
+var req = http.request(options, function (response){
+  var content_type =
+    response.headers['Content-Type'] || response.headers['content-type']
+  assert.equal(content_type, 'application/json',
+               'Incorrect content type returned by the server');
+
+  var chunks = []
+  response.on('data', function(chunk) {
+    chunks.push(chunk);
+  });
+  response.on('end', function() {
+    var body = JSON.parse(Buffer.concat(chunks).toString());
+    assert.assert('message' in body, 'No "message" key in response JSON');
+    response_got = body.message;
+
+    server.close();
+  });
+});
+
+req.end(demo_msg);
+
+process.on('exit', function() {
+  assert.equal(response_got, response_message,
+               'Invalid response returned from the demo server');
+});
diff --git a/test/run_pass/test_net_http_modified_request.js b/test/run_pass/test_net_http_modified_request.js
new file mode 100644 (file)
index 0000000..6bad6ea
--- /dev/null
@@ -0,0 +1,104 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+var http = require('http');
+
+var response_message = 'DATA';
+var response_got = 'NOT THIS';
+
+/*
+ * Test if 'subclassing' the IncomingMessage
+ * and ServerResponse is propagated correctly.
+ */
+function newIncomingMessage() {
+  http.IncomingMessage.apply(this, arguments);
+};
+newIncomingMessage.prototype = Object.create(http.IncomingMessage.prototype);
+newIncomingMessage.prototype.extra_field = 'found';
+newIncomingMessage.prototype.waitForBody = function() {
+  var chunks = [];
+  this.on('data', function(chunk) {
+    chunks.push(chunk);
+  });
+  this.on('end', function() {
+    this.emit('full_body', Buffer.concat(chunks));
+  });
+};
+
+
+var serveropts = {
+  IncomingMessage: newIncomingMessage,
+};
+
+var server = http.createServer(serveropts, function (req, res) {
+  assert.equal(req.method, 'POST', 'Incorrect request method detected');
+  assert.equal(req.url, '/put_msg', 'Incorrect request url detected');
+  assert.assert(req instanceof http.IncomingMessage,
+                'Request is not instance of http.IncomingMessage');
+  assert.assert(req instanceof newIncomingMessage,
+                'Request is not instance of the new Request object');
+  assert.equal(req.extra_field, 'found',
+               'No "extra_field" property on the request instance');
+
+  req.waitForBody();
+  req.on('full_body', function(body) {
+    assert.assert(body instanceof Buffer);
+    assert.equal(body.toString(), 'DEMO');
+
+    var message_body = JSON.stringify({message: response_message});
+    res.setHeader('Content-Length', message_body.length);
+    res.setHeader('Content-Type', 'application/json');
+    res.writeHead(200);
+    res.end(message_body);
+  });
+});
+
+server.listen(3001);
+
+var demo_msg = 'DEMO';
+var options = {
+  method : 'POST',
+  port : 3001,
+  path : '/put_msg',
+  headers: {
+    'Content-Length': demo_msg.length,
+  },
+};
+var req = http.request(options, function (response){
+  var content_type =
+    response.headers['Content-Type'] || response.headers['content-type']
+  assert.equal(content_type, 'application/json',
+               'Incorrect content type returned by the server');
+
+  var chunks = []
+  response.on('data', function(chunk) {
+    chunks.push(chunk);
+  });
+  response.on('end', function() {
+    var body = JSON.parse(Buffer.concat(chunks).toString());
+    assert.assert('message' in body, 'No "message" key in response JSON');
+    response_got = body.message;
+
+    server.close();
+  });
+});
+
+req.end(demo_msg);
+
+process.on('exit', function() {
+  assert.equal(response_got, response_message,
+               'Invalid response returned from the demo server');
+});
diff --git a/test/run_pass/test_net_http_modified_response.js b/test/run_pass/test_net_http_modified_response.js
new file mode 100644 (file)
index 0000000..ec7ca6c
--- /dev/null
@@ -0,0 +1,94 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+var http = require('http');
+
+var response_message = 'DATA';
+var response_got = 'NOT THIS';
+
+/*
+ * Test if 'subclassing' the ServerResponse is propagated correctly.
+ */
+function newServerResponse() {
+  http.ServerResponse.apply(this, arguments);
+};
+newServerResponse.prototype = Object.create(http.ServerResponse.prototype);
+newServerResponse.prototype.sendJSON = function (obj) {
+  var message_body = JSON.stringify(obj);
+  this.setHeader('Content-Length', message_body.length);
+  this.setHeader('Content-Type', 'application/json');
+  this.writeHead(200);
+  this.end(message_body);
+};
+
+var serveropts = {
+  ServerResponse: newServerResponse,
+};
+
+var server = http.createServer(serveropts, function (req, res) {
+  assert.equal(req.method, 'POST', 'Incorrect request method detected');
+  assert.equal(req.url, '/put_msg', 'Incorrect request url detected');
+  assert.assert(req instanceof http.IncomingMessage,
+                'Request is not instance of http.IncomingMessage');
+
+  var chunks = [];
+  req.on('data', function(chunk) {
+    chunks.push(chunk);
+  });
+  req.on('end', function() {
+    var body = Buffer.concat(chunks);
+    assert.equal(body.toString(), 'DEMO');
+
+    res.sendJSON({message: response_message});
+  });
+});
+
+server.listen(3001);
+
+var demo_msg = 'DEMO';
+var options = {
+  method : 'POST',
+  port : 3001,
+  path : '/put_msg',
+  headers: {
+    'Content-Length': demo_msg.length,
+  },
+};
+var req = http.request(options, function (response){
+  var content_type =
+    response.headers['Content-Type'] || response.headers['content-type']
+  assert.equal(content_type, 'application/json',
+               'Incorrect content type returned by the server');
+
+  var chunks = []
+  response.on('data', function(chunk) {
+    chunks.push(chunk);
+  });
+  response.on('end', function() {
+    var body = JSON.parse(Buffer.concat(chunks).toString());
+    assert.assert('message' in body, 'No "message" key in response JSON');
+    response_got = body.message;
+
+    server.close();
+  });
+});
+
+req.end(demo_msg);
+
+process.on('exit', function() {
+  assert.equal(response_got, response_message,
+               'Invalid response returned from the demo server');
+});
diff --git a/test/run_pass/test_net_http_outgoing_buffer.js b/test/run_pass/test_net_http_outgoing_buffer.js
new file mode 100644 (file)
index 0000000..c6adb73
--- /dev/null
@@ -0,0 +1,60 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var http = require('http');
+var assert = require('assert');
+
+var clientMessage = new Buffer([0xE6, 0x7F, 0x3, 0x6, 0x7]);
+var serverMessage = new Buffer([0x3, 0x7F, 0x6, 0x7, 0xE6]);
+var serverReceived;
+var clientReceived;
+
+var server = http.createServer(function(req, res) {
+  var received = [];
+  req.on('data', function(data) {
+    received.push(data);
+  });
+  req.on('end', function() {
+    serverReceived = Buffer.concat(received);
+    res.end(serverMessage);
+  });
+}).listen(8383, 5);
+
+var reqOpts = {
+  method: 'POST',
+  port: 8383,
+  path: '/',
+  headers: {'Content-Length': clientMessage.length},
+};
+
+var clientReq = http.request(reqOpts, function(res) {
+  var response = [];
+
+  res.on('data', function(data) {
+    response.push(data);
+  });
+
+  res.on('end', function() {
+    clientReceived = Buffer.concat(response);
+    server.close();
+  });
+});
+
+clientReq.end(clientMessage);
+
+process.on('exit', function() {
+  assert.equal(serverReceived.compare(clientMessage), 0);
+  assert.equal(clientReceived.compare(serverMessage), 0);
+});
diff --git a/test/run_pass/test_net_http_request_http_version.js b/test/run_pass/test_net_http_request_http_version.js
new file mode 100644 (file)
index 0000000..318d32e
--- /dev/null
@@ -0,0 +1,40 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+var http = require('http');
+
+var server = http.createServer(function(request, response) {
+  // the http version in IoT.js is hardcoded to 1.1
+  assert.equal(request.httpVersion, "1.1",
+               "incorrect http version returned via the http request object");
+
+  response.writeHead(200);
+  response.end();
+});
+server.listen(3008, 5);
+
+var request = http.request({
+  method: 'HEAD',
+  port: 3008,
+  path: '/'
+}, function(response) {
+  assert.equal(response.statusCode, 200);
+
+  response.on('end', function() {
+    server.close();
+  });
+})
+request.end();
diff --git a/test/run_pass/test_net_https_modified_req_resp.js b/test/run_pass/test_net_https_modified_req_resp.js
new file mode 100644 (file)
index 0000000..5d2d3f9
--- /dev/null
@@ -0,0 +1,119 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+var fs = require('fs');
+var http = require('http');
+var https = require('https');
+
+var response_message = 'DATA';
+var response_got = 'NOT THIS';
+
+/*
+ * Test if 'subclassing' the IncomingMessage
+ * and ServerResponse is correctly propagated.
+ */
+function newIncomingMessage() {
+  http.IncomingMessage.apply(this, arguments);
+};
+newIncomingMessage.prototype = Object.create(http.IncomingMessage.prototype);
+newIncomingMessage.prototype.extra_field = 'found';
+newIncomingMessage.prototype.waitForBody = function() {
+  var chunks = [];
+  this.on('data', function(chunk) {
+    chunks.push(chunk);
+  });
+  this.on('end', function() {
+    this.emit('full_body', Buffer.concat(chunks));
+  });
+};
+
+
+function newServerResponse() {
+  http.ServerResponse.apply(this, arguments);
+};
+newServerResponse.prototype = Object.create(http.ServerResponse.prototype);
+newServerResponse.prototype.sendJSON = function (obj) {
+  var message_body = JSON.stringify(obj);
+  this.setHeader('Content-Length', message_body.length);
+  this.setHeader('Content-Type', 'application/json');
+  this.writeHead(200);
+  this.end(message_body);
+};
+
+var serveropts = {
+  IncomingMessage: newIncomingMessage,
+  ServerResponse: newServerResponse,
+
+  key: fs.readFileSync(process.cwd() + '/resources/my_key.key'),
+  cert: fs.readFileSync(process.cwd() + '/resources/my_crt.crt')
+};
+
+var server = https.createServer(serveropts, function (req, res) {
+  assert.equal(req.method, 'POST', 'Incorrect request method detected');
+  assert.equal(req.url, '/put_msg', 'Incorrect request url detected');
+  assert.assert(req instanceof http.IncomingMessage,
+                'Request is not instance of http.IncomingMessage');
+  assert.assert(req instanceof newIncomingMessage,
+                'Request is not instance of the new Request object');
+  assert.equal(req.extra_field, 'found',
+               'No "extra_field" property on the request instance');
+
+  req.waitForBody();
+  req.on('full_body', function(body) {
+    assert.assert(body instanceof Buffer);
+    assert.equal(body.toString(), 'DEMO');
+
+    res.sendJSON({message: response_message});
+  });
+});
+
+server.listen(3001);
+
+var demo_msg = 'DEMO';
+var options = {
+  method : 'POST',
+  port : 3001,
+  path : '/put_msg',
+  headers: {
+    'Content-Length': demo_msg.length,
+  },
+  rejectUnauthorized: false
+};
+var req = https.request(options, function (response){
+  var content_type =
+    response.headers['Content-Type'] || response.headers['content-type']
+  assert.equal(content_type, 'application/json',
+               'Incorrect content type returned by the server');
+
+  var chunks = []
+  response.on('data', function(chunk) {
+    chunks.push(chunk);
+  });
+  response.on('end', function() {
+    var body = JSON.parse(Buffer.concat(chunks).toString());
+    assert.assert('message' in body, 'No "message" key in response JSON');
+    response_got = body.message;
+
+    server.close();
+  });
+});
+
+req.end(demo_msg);
+
+process.on('exit', function() {
+  assert.equal(response_got, response_message,
+               'Invalid response returned from the demo server');
+});
index aaad8dc4c735eeb930d0da895f9622cc7b414b4a..d1120088e9bd079b41ced0bbd55159886fb86e69 100644 (file)
@@ -18,8 +18,8 @@ var https = require('https');
 var fs = require('fs');
 
 var server_options = {
-  key: fs.readFileSync('resources/my_key.pem').toString(),
-  cert: fs.readFileSync('resources/my_crt.pem').toString()
+  key: fs.readFileSync(process.cwd() + '/resources/my_key.key').toString(),
+  cert: fs.readFileSync(process.cwd() + '/resources/my_crt.crt').toString()
 };
 
 var server = https.createServer(server_options, function(req, res) {
index bd8b6f0441b3fdace6711e9717746f28e075d0d8..ca534b4de287185fabb220f97a65fd4849760f34 100644 (file)
@@ -22,6 +22,12 @@ try {
   console.log('invalid path');
 }
 
-assert.equal(process.cwd(), '/');
+var newPath = process.cwd();
+if (process.platform === "windows") {
+  /* check if the path is in format: <Drive Letter>:\ */
+  assert.equal(newPath.substr(1), ':\\');
+} else {
+  assert.equal(newPath, '/');
+}
 
 process.chdir(currentPath);
diff --git a/test/run_pass/test_stream_pipe.js b/test/run_pass/test_stream_pipe.js
new file mode 100644 (file)
index 0000000..bc98059
--- /dev/null
@@ -0,0 +1,206 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+var net = require('net');
+var stream = require('stream');
+var Duplex = stream.Duplex;
+var Readable = stream.Readable;
+var Writable = stream.Writable;
+
+var readable = new Readable();
+
+var msg = [];
+var resp = [];
+
+// Test case 1: basic data correctness.
+var dest1 = new Writable();
+
+msg.push('Hello');
+
+dest1._write = function(chunk, callback, onwrite) {
+  resp.push(chunk.toString());
+}
+
+dest1._readyToWrite();
+
+readable.pipe(dest1);
+readable.push(msg[0]);
+readable.unpipe(dest1);
+
+// Test case 2: serial piping.
+var dest2 = new Duplex();
+var dest3 = new Duplex();
+var dest4 = new Duplex();
+
+msg.push('data');
+
+dest2._write = function(chunk, callback, onwrite) {
+  this.push(chunk);
+  resp.push(chunk.toString());
+}
+
+dest3._write = function(chunk, callback, onwrite) {
+  this.push(chunk);
+  resp.push(chunk.toString());
+}
+
+dest4._write = function(chunk, callback, onwrite) {
+  resp.push(chunk.toString());
+}
+
+dest2._readyToWrite();
+dest3._readyToWrite();
+dest4._readyToWrite();
+
+readable.pipe(dest2).pipe(dest3).pipe(dest4);
+readable.push(msg[1]);
+readable.unpipe(dest2);
+dest2.unpipe(dest3);
+dest3.unpipe(dest4);
+
+// Test case 3: unpipe test.
+var dest5 = new Writable();
+
+var dest5_write_called = false;
+dest5._write = function(chunk, callback, onwrite) {
+  dest5_write_called = true;
+}
+
+dest5._readyToWrite();
+
+readable.pipe(dest5);
+readable.unpipe(dest5);
+readable.push('foo');
+
+// Test case 4: pushing data to the readable stream
+// before piping it.
+var readable2 = new Readable();
+var dest6 = new Writable();
+msg.push('data before pipe');
+
+dest6._write = function(chunk, callback, onwrite) {
+  resp.push(chunk.toString());
+}
+
+dest6._readyToWrite();
+
+readable2.push(msg[2]);
+readable2.pipe(dest6);
+readable2.unpipe(dest6);
+
+// Test case 5: piping multiple destinations to a single Readable
+var readable3 = new Readable();
+msg.push('Multiple pipe test');
+
+var dest7 = new Writable();
+var dest8 = new Duplex();
+
+dest7._write = function(chunk, callback, onwrite) {
+  resp.push(chunk.toString());
+}
+
+dest8._write = function(chunk, callback, onwrite) {
+  resp.push(chunk.toString());
+}
+
+dest7._readyToWrite();
+dest8._readyToWrite();
+
+readable.pipe(dest7);
+readable.pipe(dest8);
+readable.push(msg[3]);
+readable.unpipe(dest7);
+readable.unpipe(dest8);
+
+// Test case 6: piping with net.Socket source
+msg.push('Hello from the server');
+
+var server = net.createServer({}, function(socket) {
+  socket.write(msg[4]);
+});
+server.listen(8080);
+
+var dest9 = new Duplex();
+
+dest9._write = function(chunk, callback, onwrite) {
+  resp.push(chunk.toString());
+  this.emit('_write_done');
+}
+
+// This is needed to make sure that the order of the results in the resp
+// array is correct.
+dest9.on('_write_done', testCase7);
+
+dest9._readyToWrite();
+
+var socket = new net.Socket();
+socket.pipe(dest9);
+
+socket.on('data', function(data) {
+  socket.end();
+});
+
+socket.on('end', function() {
+  socket.unpipe(dest9);
+  server.close();
+});
+
+socket.connect({'port': 8080});
+
+// Test case 7: piping with net.Socket destination
+function testCase7() {
+ msg.push('Hello from the socket');
+
+  var server2 = net.createServer({}, function(socket) {
+    socket.on('data', function(data) {
+      resp.push(data.toString());
+      socket.end();
+    });
+  });
+  server2.listen(8081);
+
+  var socket2 = new net.Socket();
+
+  socket2.on('data', function(data) {
+    socket2.write(data);
+  });
+
+  socket2.on('end', function() {
+    server2.close();
+  });
+
+  var readable4 = new Readable();
+  readable4.pipe(socket2);
+  socket2.connect({'port': 8081});
+  readable4.push(msg[5]);
+  readable4.unpipe(socket2);
+  socket2.end();
+}
+
+// checking the results
+process.on('exit', function() {
+  assert.equal(msg[0], resp[0], 'Basic data correctness test failed');
+  assert.equal(msg[1], resp[1], 'Serial pipe test failed');
+  assert.equal(msg[1], resp[2], 'Serial pipe test failed');
+  assert.equal(msg[1], resp[3], 'Serial pipe test failed');
+  assert.equal(dest5_write_called, false, 'Unpipe test failed');
+  assert.equal(msg[2], resp[4], 'Incorrect data when pushing to the ' +
+                                'readable stream before piping');
+  assert.equal(msg[3], resp[5], 'Multiple piping test failed');
+  assert.equal(msg[3], resp[6], 'Multiple piping test failed');
+  assert.equal(msg[4], resp[7], 'net.Socket source piping test failed');
+  assert.equal(msg[5], resp[8], 'net.Socket destination piping test failed');
+});
diff --git a/test/run_pass/test_tls.js b/test/run_pass/test_tls.js
deleted file mode 100644 (file)
index 70193bb..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
- var tls = require('tls');
- var assert = require('assert');
- var fs = require('fs');
-
- var port = 8080;
-
- var server_closed = false;
- var expected_client_msg = 'Client hello';
- var expected_server_msg = 'Server hello';
- var client_message = '';
- var server_message = '';
- var server_handshake_done = false;
- var tlsClientError_caught = false;
- var socket_handshake_error_caught = false;
-
- var options = {
-   key: fs.readFileSync('resources/my_key.pem').toString(),
-   cert: fs.readFileSync('resources/my_crt.pem').toString(),
-   rejectUnauthorized: false,
-   isServer: true,
- };
-
- var server = tls.createServer(options, function(socket) {
-     socket.write('Server hello');
-
-     socket.on('data', function(data) {
-       client_message += data.toString();
-     });
-
- }).listen(port, function() { });
-
- server.on('secureConnection', function() {
-   server_handshake_done = true;
- });
-
- server.on('close', function() {
-   server_closed = true;
- });
-
- var error_caught = false;
- var handshake_done = false;
-
- var sockOpts = {
-   host: '127.0.0.1',
-   port: 8080,
-   rejectUnauthorized: false,
- }
-
- var socket = tls.connect(sockOpts, function() {
- });
-
- socket.on('secureConnect', function(){
-   handshake_done = true;
- });
-
- socket.on('end', function() {
-   server.close();
- });
-
- socket.on('data', function(data) {
-   server_message += data.toString();
-   socket.write('Client hello');
-   socket.end();
- });
-
- var socket2 = tls.connect({host: '127.123.123.123', port: 444}, function() {
-   socket2.end();
- });
-
- socket2.on('error', function(err) {
-   error_caught = true;
- });
-
-
-var nocert_options = {
-  rejectUnauthorized: false,
-  isServer: true,
-}
-
-var server2_port = 8081;
-
-sockOpts = {
-  host: '127.0.0.1',
-  port: server2_port,
-  rejectUnauthorized: false,
-}
-
-var server2 = tls.createServer(nocert_options, function(socket) {
-}).listen(server2_port, function() { });
-
-server2.on('tlsClientError', function(error) {
-  tlsClientError_caught = error instanceof Error;
-  server2.close();
-});
-
-var socket3 = tls.connect(sockOpts, function() { });
-
-socket3.on('error', function(error) {
-  socket_handshake_error_caught = error instanceof Error;
-});
-
-var server3 = tls.createServer(options, function(socket) {
-   socket.write('Server hello');
-
-   socket.on('data', function(data) {
-     client_message = data.toString();
-   });
-
-}).listen(9090, function() { });
-
-server3.on('secureConnection', function() {
- server_handshake_done = true;
-});
-
-server3.on('close', function() {
- server_closed = true;
-});
-
-var opt = {
-   rejectUnauthorized: false,
-}
-
-var socket4 = tls.connect(9090);
-
-socket4.on('secureConnect', function(){
-  handshake_done = true;
-});
-
-socket4.on('data', function(data) {
-  server_message = data.toString();
-  socket4.write('Client hello');
-  socket4.end();
-});
-
-var socket5 = tls.connect(9090, 'localhost');
-
-socket5.on('secureConnect', function(){
-  handshake_done = true;
-});
-
-socket5.on('data', function(data) {
-  server_message = data.toString();
-  socket5.write('Client hello');
-  socket5.end();
-});
-
-var socket6 = tls.connect(9090, 'localhost', opt);
-
-socket6.on('secureConnect', function(){
-  handshake_done = true;
-});
-
-socket6.on('data', function(data) {
-  server_message = data.toString();
-  socket6.write('Client hello');
-  socket6.end();
-});
-
-var socket7 = tls.connect(9090, 'localhost', opt, function() {
-});
-
-socket7.on('secureConnect', function(){
-  handshake_done = true;
-});
-
-socket7.on('data', function(data) {
-  server_message = data.toString();
-  socket7.write('Client hello');
-  socket7.end();
-});
-
-var socket8 = tls.connect(9090, 'localhost', function() {
-});
-
-socket8.on('secureConnect', function(){
- handshake_done = true;
-});
-
-socket8.on('data', function(data) {
- server_message = data.toString();
- socket8.write('Client hello');
- socket8.end();
-});
-
-var socket9 = tls.connect(9090, function() {
-});
-
-socket9.on('secureConnect', function(){
- handshake_done = true;
-});
-
-socket9.on('end', function() {
- server3.close();
-});
-
-socket9.on('data', function(data) {
- server_message = data.toString();
- socket9.write('Client hello');
- socket9.end();
-});
-
-process.on('exit', function() {
-  assert.equal(error_caught, true);
-  assert.equal(handshake_done, true);
-  assert.equal(server_handshake_done, true);
-  assert.equal(client_message === expected_client_msg, true);
-  assert.equal(server_message === expected_server_msg, true);
-  assert.equal(server_closed, true);
-  assert.equal(tlsClientError_caught, true);
-  assert.equal(socket_handshake_error_caught, true);
-});
diff --git a/test/run_pass/test_tls_1.js b/test/run_pass/test_tls_1.js
new file mode 100644 (file)
index 0000000..6e2063d
--- /dev/null
@@ -0,0 +1,64 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+var fs = require('fs');
+var tls = require('tls');
+
+var tlsClientError_caught = false;
+var socket_handshake_error_caught = false;
+
+var port = 8080;
+
+var server_options = {
+  rejectUnauthorized: false,
+  isServer: true
+}
+
+var server = tls.createServer(server_options, function(socket) {
+}).listen(port, function() {});
+
+server.on('tlsClientError', function(error) {
+  tlsClientError_caught = error instanceof Error;
+  server.close();
+});
+
+var socket_options = {
+  host: '127.0.0.1',
+  port: port,
+  rejectUnauthorized: false
+}
+
+var socket = tls.connect(socket_options, function() {});
+
+socket.on('error', function(error) {
+  socket_handshake_error_caught = error instanceof Error;
+});
+
+function createServerFailed(server_options) {
+  assert.throws(function() {
+    return tls.createServer(server_options);
+  });
+}
+
+createServerFailed({key: 0});
+createServerFailed({cert: null});
+createServerFailed({key: false, cert: 7});
+createServerFailed({ca: true});
+
+process.on('exit', function() {
+  assert.equal(tlsClientError_caught, true);
+  assert.equal(socket_handshake_error_caught, true);
+});
diff --git a/test/run_pass/test_tls_2.js b/test/run_pass/test_tls_2.js
new file mode 100644 (file)
index 0000000..d4dcf4e
--- /dev/null
@@ -0,0 +1,92 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+var fs = require('fs');
+var tls = require('tls');
+
+var expected_client_msg = 'Client hello';
+var expected_server_msg = 'Server hello';
+var client_message = '';
+var server_message = '';
+var server_closed = false;
+var server_handshake_done = false;
+var error_caught = false;
+var handshake_done = false;
+
+var port = 8080;
+
+var server_options = {
+  key: fs.readFileSync(process.cwd() + '/resources/my_key.key').toString(),
+  cert: fs.readFileSync(process.cwd() + '/resources/my_crt.crt'),
+  rejectUnauthorized: false,
+  isServer: true
+};
+
+var server = tls.createServer(server_options, function(socket1) {
+  socket1.write('Server hello');
+
+  socket1.on('data', function(data) {
+    client_message += data.toString();
+  });
+
+}).listen(port, function() {});
+
+server.on('secureConnection', function() {
+  server_handshake_done = true;
+});
+
+server.on('close', function() {
+  server_closed = true;
+});
+
+var socket_options = {
+  host: '127.0.0.1',
+  port: port,
+  rejectUnauthorized: false
+}
+
+var socket1 = tls.connect(socket_options, function() {});
+
+socket1.on('secureConnect', function() {
+  handshake_done = true;
+});
+
+socket1.on('end', function() {
+  server.close();
+});
+
+socket1.on('data', function(data) {
+  server_message += data.toString();
+  socket1.write('Client hello');
+  socket1.end();
+});
+
+var socket2 = tls.connect({host: '127.123.123.123', port: 444}, function() {
+  socket2.end();
+});
+
+socket2.on('error', function(err) {
+  error_caught = true;
+});
+
+process.on('exit', function() {
+  assert.equal(error_caught, true);
+  assert.equal(handshake_done, true);
+  assert.equal(server_handshake_done, true);
+  assert.equal(client_message === expected_client_msg, true);
+  assert.equal(server_message === expected_server_msg, true);
+  assert.equal(server_closed, true);
+});
diff --git a/test/run_pass/test_tls_3.js b/test/run_pass/test_tls_3.js
new file mode 100644 (file)
index 0000000..f96768a
--- /dev/null
@@ -0,0 +1,100 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+var fs = require('fs');
+var tls = require('tls');
+
+var expected_client_msg = 'Client hello';
+var expected_server_msg = 'Server hello';
+var client_message = '';
+var server_message = '';
+var server_closed = false;
+var server_handshake_done = false;
+var handshake_done = false;
+
+var port = 8080;
+
+var server_options = {
+  key: fs.readFileSync(process.cwd() + '/resources/my_key.key').toString(),
+  cert: fs.readFileSync(process.cwd() + '/resources/my_crt.crt'),
+  rejectUnauthorized: false,
+  isServer: true
+};
+
+var server = tls.createServer(server_options, function(socket) {
+  socket.write('Server hello');
+
+  socket.on('data', function(data) {
+    client_message = data.toString();
+  });
+
+}).listen(port, function() {});
+
+server.on('secureConnection', function() {
+  server_handshake_done = true;
+});
+
+server.on('close', function() {
+  server_closed = true;
+});
+
+var socket1 = tls.connect(port);
+
+socket1.on('secureConnect', function() {
+  handshake_done = true;
+});
+
+socket1.on('data', function(data) {
+  server_message = data.toString();
+  socket1.write('Client hello');
+  socket1.end();
+});
+
+var socket2 = tls.connect(port, 'localhost');
+
+socket2.on('secureConnect', function() {
+  handshake_done = true;
+});
+
+socket2.on('data', function(data) {
+  server_message = data.toString();
+  socket2.write('Client hello');
+  socket2.end();
+});
+
+var socket3 = tls.connect(port, function() {});
+
+socket3.on('secureConnect', function() {
+  handshake_done = true;
+});
+
+socket3.on('data', function(data) {
+  server_message = data.toString();
+  socket3.write('Client hello');
+  socket3.end();
+});
+
+socket3.on('end', function() {
+  server.close();
+});
+
+process.on('exit', function() {
+  assert.equal(handshake_done, true);
+  assert.equal(server_handshake_done, true);
+  assert.equal(client_message === expected_client_msg, true);
+  assert.equal(server_message === expected_server_msg, true);
+  assert.equal(server_closed, true);
+});
diff --git a/test/run_pass/test_tls_4.js b/test/run_pass/test_tls_4.js
new file mode 100644 (file)
index 0000000..18e7df3
--- /dev/null
@@ -0,0 +1,104 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var assert = require('assert');
+var fs = require('fs');
+var tls = require('tls');
+
+var expected_client_msg = 'Client hello';
+var expected_server_msg = 'Server hello';
+var client_message = '';
+var server_message = '';
+var server_closed = false;
+var server_handshake_done = false;
+var handshake_done = false;
+
+var port = 8080;
+
+var server_options = {
+  key: fs.readFileSync(process.cwd() + '/resources/my_key.key').toString(),
+  cert: fs.readFileSync(process.cwd() + '/resources/my_crt.crt'),
+  rejectUnauthorized: false,
+  isServer: true
+};
+
+var server = tls.createServer(server_options, function(socket) {
+  socket.write('Server hello');
+
+  socket.on('data', function(data) {
+    client_message = data.toString();
+  });
+
+}).listen(port, function() { });
+
+server.on('secureConnection', function() {
+  server_handshake_done = true;
+});
+
+server.on('close', function() {
+  server_closed = true;
+});
+
+var socket_options = {
+   rejectUnauthorized: false,
+}
+
+var socket1 = tls.connect(port, 'localhost', socket_options);
+
+socket1.on('secureConnect', function() {
+  handshake_done = true;
+});
+
+socket1.on('data', function(data) {
+  server_message = data.toString();
+  socket1.write('Client hello');
+  socket1.end();
+});
+
+var socket2 = tls.connect(port, 'localhost', socket_options, function() {});
+
+socket1.on('secureConnect', function() {
+  handshake_done = true;
+});
+
+socket2.on('data', function(data) {
+  server_message = data.toString();
+  socket2.write('Client hello');
+  socket2.end();
+});
+
+var socket3 = tls.connect(port, 'localhost', function() {});
+
+socket3.on('secureConnect', function(){
+  handshake_done = true;
+});
+
+socket3.on('data', function(data) {
+  server_message = data.toString();
+  socket3.write('Client hello');
+  socket3.end();
+});
+
+socket3.on('end', function() {
+  server.close();
+});
+
+process.on('exit', function() {
+  assert.equal(handshake_done, true);
+  assert.equal(server_handshake_done, true);
+  assert.equal(client_message === expected_client_msg, true);
+  assert.equal(server_message === expected_server_msg, true);
+  assert.equal(server_closed, true);
+});
diff --git a/test/run_pass/test_tls_ca.js b/test/run_pass/test_tls_ca.js
new file mode 100644 (file)
index 0000000..337b605
--- /dev/null
@@ -0,0 +1,114 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+/*
+  For this test, we created a certificate authority, and signed
+  a certificate request with it. Here are the steps taken:
+
+  1) created a secret rsa key for ourselves
+
+    openssl genrsa -out my_key.key 2048
+
+    Verify (dump): openssl rsa -in my_key.key -noout -text
+
+  2) created a secret rsa key for our certificate authority (CA)
+
+    openssl genrsa -out my_ca.key 2048
+
+    Verify (dump): openssl rsa -in my_ca.key -noout -text
+
+  3) created a certificate signing request (CSR),
+     which is signed by the CA later
+
+    openssl req -new -key my_key.pem -out my_csr.csr
+
+    Country Name (2 letter code) [AU]:HU
+    State or Province Name (full name) [Some-State]:
+    Locality Name (eg, city) []:Szeged
+    Organization Name (eg, company) [Internet Widgits Pty Ltd]:Trusted
+    Organizational Unit Name (eg, section) []:
+    Common Name (e.g. server FQDN or YOUR name) []:localhost
+    Email Address []:trusted@localhost
+
+    Please enter the following 'extra' attributes
+    to be sent with your certificate request
+    A challenge password []:ch+llenGe
+    An optional company name []:
+
+    Verify (dump): openssl req -in my_csr.csr -noout -text
+
+  4) created a self-signed certificate for the CA
+
+    openssl req -new -x509 -key my_ca.key -out my_ca.crt
+
+    Country Name (2 letter code) [AU]:HU
+    State or Province Name (full name) [Some-State]:
+    Locality Name (eg, city) []:Szeged
+    Organization Name (eg, company) [Internet Widgits Pty Ltd]:My CA
+    Organizational Unit Name (eg, section) []:
+    Common Name (e.g. server FQDN or YOUR name) []:myca.org
+    Email Address []:myca@myca.org
+
+    Verify (dump): openssl x509 -in my_ca.crt -noout -text
+
+  5) sign our certificate signing request
+
+    openssl x509 -req -in my_csr.csr -CA my_ca.crt -CAkey my_ca.key \
+        -CAcreateserial -out my_crt.crt
+
+    Note: A my_ca.srl file is also created to record the already
+          issued serial numbers. This file is needed for future
+          certificate signings.
+
+    Verify (dump): openssl x509 -in my_crt.crt -noout -text
+*/
+
+var tls = require('tls');
+var assert = require('assert');
+var fs = require('fs');
+
+var port = 8080;
+
+var server_message = '';
+
+var options = {
+  key: fs.readFileSync(process.cwd() + '/resources/my_key.key').toString(),
+  cert: fs.readFileSync(process.cwd() + '/resources/my_crt.crt')
+};
+
+var server = tls.createServer(options, function(socket) {
+  socket.write('Server hello');
+}).listen(port);
+
+var sockOpts = {
+  // The my_crt.crt certificate was issued for localhost as server FQDN
+  // Anything else here (e.g. 127.0.0.1) makes the handshake failed
+  host: 'localhost',
+  port: port,
+  rejectUnauthorized: true,
+  ca: fs.readFileSync(process.cwd() + '/resources/my_ca.crt')
+}
+
+var socket = tls.connect(sockOpts, function() {
+  socket.on('data', function(data) {
+    server_message += data.toString();
+    socket.end();
+    server.close();
+  });
+});
+
+process.on('exit', function() {
+  assert.equal(server_message, 'Server hello');
+});
diff --git a/test/run_pass/test_tls_stream_duplex.js b/test/run_pass/test_tls_stream_duplex.js
new file mode 100644 (file)
index 0000000..40b43ee
--- /dev/null
@@ -0,0 +1,105 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var stream = require('stream');
+var tls = require('tls');
+var assert = require('assert');
+var fs = require('fs');
+
+var tls1_message = 'Hello, this is tls1';
+var tls1_expected_message = tls1_message;
+var tls2_message = 'Hello, this is tls2';
+var tls2_expected_message = tls2_message;
+var tls1_received_message = '';
+var tls2_received_message = '';
+var tls1_received_encrypted = '';
+var tls2_received_encrypted = '';
+
+var handshake_done = false;
+var tls1_ended = false;
+var tls2_ended = false;
+
+var duplex1 = new stream.Duplex();
+var duplex2 = new stream.Duplex();
+
+duplex1._write = function(chunk, callback, onwrite) {
+  duplex2.push(chunk);
+  onwrite();
+};
+
+duplex2._write = function(chunk, callback, onwrite) {
+  duplex1.push(chunk);
+  onwrite();
+};
+
+duplex1._readyToWrite();
+duplex2._readyToWrite();
+
+var server_opts = {
+  key: fs.readFileSync(process.cwd() + '/resources/my_key.key').toString(),
+  cert: fs.readFileSync(process.cwd() + '/resources/my_crt.crt').toString(),
+  isServer: true,
+  rejectUnauthorized: false,
+};
+
+var client_opts = {
+  rejectUnauthorized: false,
+};
+
+var tls1 = new tls.TLSSocket(duplex1, server_opts);
+var tls2 = new tls.TLSSocket(duplex2, client_opts);
+
+tls2.on('secureConnect', function() {
+  handshake_done = true;
+});
+
+tls1.on('data', function(data) {
+  tls1_received_message += data.toString();
+  tls1.end();
+});
+
+tls1._socket.on('data', function(data) {
+  tls1_received_encrypted += data.toString('hex');
+});
+
+tls2.on('data', function(data) {
+  tls2_received_message += data.toString();
+  tls2.write(tls2_message);
+});
+
+tls2._socket.on('data', function(data) {
+  tls2_received_encrypted += data.toString('hex');
+});
+
+tls1.on('end', function() {
+  tls1_ended = true;
+  tls2.end();
+});
+
+tls2.on('end', function() {
+  tls2_ended = true;
+});
+
+tls1.write(tls1_message);
+
+process.on('exit', function() {
+  assert.equal(tls1_received_message === tls2_expected_message, true);
+  assert.equal(tls2_received_message === tls1_expected_message, true);
+  assert.equal(tls1_received_encrypted === tls2_message, false);
+  assert.equal(tls2_received_encrypted === tls1_message, false);
+  assert.equal(handshake_done === true, true);
+  assert.equal(tls1_ended === true, true);
+  assert.equal(tls2_ended === true, true);
+});
diff --git a/test/run_pass/test_websocket.js b/test/run_pass/test_websocket.js
new file mode 100644 (file)
index 0000000..8027e50
--- /dev/null
@@ -0,0 +1,53 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var ws = require('websocket');
+var assert = require('assert');
+
+var websocket = new ws.Websocket();
+
+var connected = false;
+var message_sent = 'Hello IoT.js WebSocket';
+var message_received = null;
+var ping_sent = 'IoT.js ping message';
+var ping_received = null;
+var close_string = 'Connection successfully closed';
+
+websocket.connect('ws://echo.websocket.org', 80, '/', function() {
+  connected = true;
+
+  this.on('message', function(msg){
+    message_received = msg.toString();
+  });
+
+  this.ping(ping_sent, true, function(msg) {
+    ping_received = msg.toString();
+  });
+
+  this.on('close', function(msg) {
+    assert.equal(msg.code, '1000');
+    assert.equal(msg.reason, close_string);
+  });
+
+  this.send(message_sent, {mask: true, binary: false})
+  this.close(close_string, 1000);
+});
+
+
+process.on('exit', function() {
+  assert.equal(connected, true);
+  assert.equal(message_received, message_sent);
+  assert.equal(ping_sent, ping_received);
+});
diff --git a/test/run_pass/test_websocket_server.js b/test/run_pass/test_websocket_server.js
new file mode 100644 (file)
index 0000000..836d2a3
--- /dev/null
@@ -0,0 +1,126 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var websocket = require('websocket');
+var assert = require('assert');
+var http = require('http');
+
+var client = new websocket.Websocket();
+var client2 = new websocket.Websocket();
+var client3 = new websocket.Websocket();
+var message_sent = 'Hello IoT.js WebSocket';
+var ping_sent = 'IoT.js ping message';
+var close_string = 'Connection successfully closed';
+var close_code = 1000;
+
+function listener(ws) {
+  ws.on('message', function(msg) {
+    assert.equal(message_sent, msg.toString(),
+                 'Message received by the Server');
+    // echo
+    ws.send(msg.toString(), {mask: true, binary: false});
+  });
+  ws.on('ping', function(msg) {
+    assert.equal(ping_sent, msg.toString(),
+                 'Ping received by the Server');
+  });
+}
+
+
+// Test two clients connection
+var options = {
+  port: 8081,
+};
+
+var wss = new websocket.Server(options, listener);
+var address = wss.address();
+
+wss.on('close', function(msg) {
+  assert.equal(close_string, msg.reason,
+               'Close reason received by the Server1');
+  assert.equal(close_code, msg.code,
+               'Close code received by the Server1');
+  assert.equal(address.address, '0.0.0.0', 'Address of Server1');
+  assert.equal(address.family, 'IPv4', 'Ip family of Server1');
+  assert.equal(address.port, '8081', 'Port of Server1');
+});
+
+client.connect('ws://localhost', 8081, '/', function() {
+  this.on('message', function(msg) {
+    assert.equal(message_sent, msg.toString(),
+                 'Message received by the Client1');
+  });
+
+  this.ping(ping_sent, true, function(msg) {
+    assert.equal(ping_sent, msg.toString(),
+                 'Ping received by the Client1');
+  });
+
+  this.on('close', function(msg) {
+    assert.equal(close_string, msg.reason,
+                 'Close reason received by the Client1');
+    assert.equal(close_code, msg.code,
+                 'Close code received by the Client1');
+  });
+
+  // Client2 connect
+  client2.connect('ws://localhost', 8081, '/');
+  client2.on('open', function() {
+    // Broadcast then terminate all clients and close the server
+    wss.broadcast(message_sent);
+    wss.close();
+  });
+
+  this.send(message_sent, {mask: true, binary: false});
+});
+
+
+// Test http server upgrade to websocket
+var httpServer = http.createServer().listen(8082);
+
+options = {
+  server: httpServer,
+};
+
+var wss2 = new websocket.Server(options, listener);
+
+wss2.on('close', function(msg) {
+  assert.equal(close_string, msg.reason,
+               'Close reason received by the Server2');
+  assert.equal(close_code, msg.code,
+               'Close code received by the Server2');
+});
+
+client3.connect('ws://localhost', 8082, '/', function() {
+  this.on('message', function(msg) {
+    assert.equal(message_sent, msg.toString(),
+                 'Message received by the Client3');
+    wss2.close();
+  });
+
+  this.ping(ping_sent, true, function(msg) {
+    assert.equal(ping_sent, msg.toString(),
+                 'Ping received by the Client3');
+  });
+
+  this.on('close', function(msg) {
+    assert.equal(close_string, msg.reason,
+                 'Close reason received by the Client3');
+    assert.equal(close_code, msg.code,
+                 'Close code received by the Client3');
+  });
+
+  this.send(message_sent, {mask: true, binary: false});
+});
diff --git a/test/run_pass/test_websocket_server_secure.js b/test/run_pass/test_websocket_server_secure.js
new file mode 100644 (file)
index 0000000..1a737a7
--- /dev/null
@@ -0,0 +1,140 @@
+/* Copyright 2018-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+var websocket = require('websocket');
+var assert = require('assert');
+var fs = require('fs');
+var tls = require('tls');
+var key = fs.readFileSync(process.cwd() +
+    '/resources/my_key.key').toString();
+var cert = fs.readFileSync(process.cwd() +
+    '/resources/my_crt.crt');
+
+var client = new websocket.Websocket();
+var client2 = new websocket.Websocket();
+var client3 = new websocket.Websocket();
+var message_sent = 'Hello IoT.js WebSocket';
+var ping_sent = 'IoT.js ping message';
+var close_string = 'Connection successfully closed';
+var close_code = 1000;
+
+function listener(ws) {
+  ws.on('message', function(msg) {
+    assert.equal(message_sent, msg.toString(),
+                 'Message received by the Server');
+    // echo
+    ws.send(msg.toString(), {mask: true, binary: false});
+  });
+  ws.on('ping', function(msg) {
+    assert.equal(ping_sent, msg.toString(),
+                 'Ping received by the Server');
+  });
+}
+
+
+// Test two clients connection
+var options = {
+  port: 8081,
+  secure: true,
+  key: key,
+  cert: cert,
+};
+
+var wss = new websocket.Server(options, listener);
+var address = wss.address();
+
+wss.on('close', function(msg) {
+  assert.equal(close_string, msg.reason,
+               'Close reason received by the Server1');
+  assert.equal(close_code, msg.code,
+               'Close code received by the Server1');
+  assert.equal(address.address, '0.0.0.0', 'Address of Server1');
+  assert.equal(address.family, 'IPv4', 'Ip family of Server1');
+  assert.equal(address.port, '8081', 'Port of Server1');
+});
+
+client.connect('wss://localhost', 8081, '/', function() {
+  this.on('message', function(msg) {
+    assert.equal(message_sent, msg.toString(),
+                 'Message received by the Client1');
+  });
+
+  this.ping(ping_sent, true, function(msg) {
+    assert.equal(ping_sent, msg.toString(),
+                 'Ping received by the Client1');
+  });
+
+  this.on('close', function(msg) {
+    assert.equal(close_string, msg.reason,
+                 'Close reason received by the Client1');
+    assert.equal(close_code, msg.code,
+                 'Close code received by the Client1');
+  });
+
+  // Client2 connect
+  client2.connect('wss://localhost', 8081, '/');
+  client2.on('open', function() {
+    // Broadcast then terminate all clients and close the server
+    wss.broadcast(message_sent);
+    wss.close();
+  });
+
+  this.send(message_sent, {mask: true, binary: false});
+});
+
+
+// Test tls server upgrade to websocket
+var tlsOptions = {
+  key: key,
+  cert: cert,
+  isServer: true,
+};
+
+var tlsServer = tls.createServer(tlsOptions).listen(8082);
+
+options = {
+  server: tlsServer,
+};
+
+var wss2 = new websocket.Server(options, listener);
+
+wss2.on('close', function(msg) {
+  assert.equal(close_string, msg.reason,
+               'Close reason received by the Server2');
+  assert.equal(close_code, msg.code,
+               'Close code received by the Server2');
+});
+
+client3.connect('wss://localhost', 8082, '/', function() {
+  this.on('message', function(msg) {
+    assert.equal(message_sent, msg.toString(),
+                 'Message received by the Client3');
+    wss2.close();
+  });
+
+  this.ping(ping_sent, true, function(msg) {
+    assert.equal(ping_sent, msg.toString(),
+                 'Ping received by the Client3');
+  });
+
+  this.on('close', function(msg) {
+    assert.equal(close_string, msg.reason,
+                 'Close reason received by the Client3');
+    assert.equal(close_code, msg.code,
+                 'Close code received by the Client3');
+  });
+
+  this.send(message_sent, {mask: true, binary: false});
+});
diff --git a/test/testsets-es2015.json b/test/testsets-es2015.json
deleted file mode 100644 (file)
index b3449fd..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "run_pass":  [
-    { "name": "test_iotjs_promise.js" },
-    { "name": "test_iotjs_promise_chain_calls.js" }
-  ]
-}
diff --git a/test/testsets-external-modules.json b/test/testsets-external-modules.json
deleted file mode 100644 (file)
index d5e3d8a..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "external_modules":  [
-    { "name": "test-external-module1.js" },
-    { "name": "test-external-module2.js" }
-  ]
-}
diff --git a/test/testsets-host-darwin.json b/test/testsets-host-darwin.json
deleted file mode 100644 (file)
index da9f345..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "run_pass":  [
-    { "name": "test_net_https_get.js", "timeout": 10 },
-    { "name": "test_net_https_post_status_codes.js", "timeout": 10 },
-    { "name": "test_net_https_request_response.js", "timeout": 10 },
-    { "name": "test_net_https_timeout.js", "timeout": 10 },
-    { "name": "test_net_https_server.js", "timeout": 10 },
-    { "name": "test_tls.js" }
-  ]
-}
diff --git a/test/testsets-host-linux.json b/test/testsets-host-linux.json
deleted file mode 100644 (file)
index da9f345..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "run_pass":  [
-    { "name": "test_net_https_get.js", "timeout": 10 },
-    { "name": "test_net_https_post_status_codes.js", "timeout": 10 },
-    { "name": "test_net_https_request_response.js", "timeout": 10 },
-    { "name": "test_net_https_timeout.js", "timeout": 10 },
-    { "name": "test_net_https_server.js", "timeout": 10 },
-    { "name": "test_tls.js" }
-  ]
-}
diff --git a/test/testsets-minimal.json b/test/testsets-minimal.json
deleted file mode 100644 (file)
index 1cee36c..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "run_pass/issue": [
-    { "name": "issue-223.js", "skip": ["all"], "reason": "unsupported module by iotjs build" },
-    { "name": "issue-266.js", "skip": ["all"], "reason": "unsupported module by iotjs build" }
-  ],
-  "node/parallel": [
-    { "name": "test-assert.js", "skip": ["all"], "reason": "unsupported module by iotjs build" },
-    { "name": "test-http-catch-uncaughtexception.js", "skip": ["all"], "reason": "unsupported module by iotjs build" },
-    { "name": "test-http-status-message.js", "skip": ["all"], "reason": "unsupported module by iotjs build" },
-    { "name": "test-http-write-head.js", "skip": ["all"], "reason": "unsupported module by iotjs build" },
-    { "name": "test-net-bind-twice.js", "skip": ["all"], "reason": "unsupported module by iotjs build" },
-    { "name": "test-net-end-without-connect.js", "skip": ["all"], "reason": "unsupported module by iotjs build" },
-    { "name": "test-net-keepalive.js", "skip": ["all"], "reason": "unsupported module by iotjs build" },
-    { "name": "test-timers-clear-null-does-not-throw-error.js", "skip": ["all"], "reason": "unsupported module by iotjs build" }
-  ]
-}
index dd0ee23c0b1b8453786db19cf97c3f57f2b05e0a..e1ad6020e4ca69200d47da6b7a80f4214cdacefb 100644 (file)
 {
-  "run_pass":  [
-    { "name": "test_adc.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "test_assert.js" },
-    { "name": "test_ble_advertisement.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "test_ble_setservices.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "test_ble_setservices_central.js", "skip": ["all"], "reason": "run it with nodejs after running test_ble_setservices.js" },
-    { "name": "test_buffer.js" },
-    { "name": "test_buffer_str_conv.js" },
-    { "name": "test_console.js" },
-    { "name": "test_dgram_1_server_1_client.js" },
-    { "name": "test_dgram_1_server_n_clients.js", "skip": ["linux"], "reason": "[linux]: flaky on Travis" },
-    { "name": "test_dgram_address.js", "skip": ["nuttx"], "reason": "[nuttx]: not implemented for nuttx" },
-    { "name": "test_dgram_broadcast.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "test_dgram_multicast_membership.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "test_dgram_multicast_set_multicast_loop.js", "skip": ["nuttx"], "reason": "[nuttx]: not implemented for nuttx" },
-    { "name": "test_dgram_setttl_client.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "test_dgram_setttl_server.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "test_dns.js" },
-    { "name": "test_dns_lookup.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
-    { "name": "test_events.js" },
-    { "name": "test_events_assert_emit_error.js" },
-    { "name": "test_events_uncaught_error.js" },
-    { "name": "test_fs_exists.js" },
-    { "name": "test_fs_exists_sync.js" },
-    { "name": "test_fs_fstat.js", "skip": ["nuttx", "tizenrt"], "reason": "not implemented for nuttx/TizenRT" },
-    { "name": "test_fs_fstat_sync.js", "skip": ["nuttx", "tizenrt"], "reason": "not implemented for nuttx/TizenRT" },
-    { "name": "test_fs_mkdir_rmdir.js", "skip": ["nuttx"], "reason": "[nuttx]: implemented, run manually in default configuration" },
-    { "name": "test_fs_open_close.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
-    { "name": "test_fs_readdir.js" },
-    { "name": "test_fs_readfile.js" },
-    { "name": "test_fs_readfile_sync.js" },
-    { "name": "test_fs_rename.js", "skip": ["nuttx"], "reason": "depends on the type of the memory (testrunner uses Read Only Memory)" },
-    { "name": "test_fs_rename_sync.js", "skip": ["nuttx"], "reason": "depends on the type of the memory (testrunner uses Read Only Memory)" },
-    { "name": "test_fs_stat.js" },
-    { "name": "test_fs_write.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
-    { "name": "test_fs_writefile.js", "skip": ["nuttx"], "reason": "depends on the type of the memory (testrunner uses Read Only Memory)" },
-    { "name": "test_fs_writefile_sync.js", "skip": ["nuttx"], "reason": "depends on the type of the memory (testrunner uses Read Only Memory)" },
-    { "name": "test_fs_writefile_unlink.js", "skip": ["nuttx"], "reason": "depends on the type of the memory (testrunner uses Read Only Memory)" },
-    { "name": "test_fs_writefile_unlink_sync.js", "skip": ["nuttx"], "reason": "depends on the type of the memory (testrunner uses Read Only Memory)" },
-    { "name": "test_fs_event.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
-    { "name": "test_fs_open_read.js" },
-    { "name": "test_fs_open_read_sync_1.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
-    { "name": "test_fs_open_read_sync_2.js" },
-    { "name": "test_fs_open_read_sync_3.js" },
-    { "name": "test_gpio_input.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "test_gpio_output.js", "skip": ["all"], "reason": "need to setup test environment"},
-    { "name": "test_i2c_gy30.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "test_iotjs_promise.js", "skip": ["all"], "reason": "es2015 is off by default" },
-    { "name": "test_iotjs_promise_chain_calls.js", "skip": ["all"], "reason": "es2015 is off by default" },
-    { "name": "test_module_cache.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
-    { "name": "test_module_json.js" },
-    { "name": "test_module_require.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
-    { "name": "test_module_dynamicload.js", "skip": ["darwin", "nuttx", "tizenrt"], "reason": "embedded and macos does not support dynamic loading" },
-    { "name": "test_net_1.js" },
-    { "name": "test_net_2.js" },
-    { "name": "test_net_3.js", "skip": ["nuttx"], "reason": "[nuttx]: requires too many socket descriptors and too large buffers" },
-    { "name": "test_net_4.js" },
-    { "name": "test_net_5.js" },
-    { "name": "test_net_6.js" },
-    { "name": "test_net_7.js", "skip": ["nuttx"], "reason": "requires too many socket descriptors" },
-    { "name": "test_net_8.js" },
-    { "name": "test_net_9.js" },
-    { "name": "test_net_10.js" },
-    { "name": "test_net_connect.js" },
-    { "name": "test_net_headers.js" },
-    { "name": "test_net_http_get.js" },
-    { "name": "test_net_http_response_twice.js" },
-    { "name": "test_net_http_request_response.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
-    { "name": "test_net_http_status_codes.js", "skip": ["nuttx"], "reason": "[nuttx]: not implemented" },
-    { "name": "test_net_httpclient_error.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
-    { "name": "test_net_httpclient_parse_error.js" },
-    { "name": "test_net_httpclient_timeout_1.js" },
-    { "name": "test_net_httpclient_timeout_2.js" },
-    { "name": "test_net_http_server_timeout.js" },
-    { "name": "test_net_http_server.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
-    { "name": "test_net_https_get.js", "timeout": 10, "skip": ["all"], "reason": "HTTPS module is not enabled by default" },
-    { "name": "test_net_https_post_status_codes.js", "timeout": 10, "skip": ["all"], "reason": "HTTPS module is not enabled by default" },
-    { "name": "test_net_https_request_response.js", "timeout": 10, "skip": ["all"], "reason": "HTTPS module is not enabled by default" },
-    { "name": "test_net_https_timeout.js", "timeout": 10, "skip": ["all"], "reason": "HTTPS module is not enabled by default" },
-    { "name": "test_net_https_server.js", "timeout": 10, "skip": ["all"], "reason": "HTTPS module is not enabled by default" },
-    { "name": "test_process.js" },
-    { "name": "test_process_chdir.js" },
-    { "name": "test_process_cwd.js" },
-    { "name": "test_process_exit.js" },
-    { "name": "test_process_experimental_off.js", "skip": ["experimental"], "reason": "needed if testing stablity is set with stable" },
-    { "name": "test_process_experimental_on.js", "skip": ["stable"], "reason": "needed if testing stablity is set with experimental" },
-    { "name": "test_process_next_tick.js" },
-    { "name": "test_process_uncaught_order.js" },
-    { "name": "test_process_uncaught_simple.js" },
-    { "name": "test_pwm_async.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "test_pwm_sync.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "test_spi.js", "skip": ["linux"], "reason": "Different env on Linux desktop/travis/rpi" },
-    { "name": "test_spi_buffer_async.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "test_spi_buffer_sync.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "test_spi_mcp3008.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "test_stream.js" },
-    { "name": "test_stream_duplex.js" },
-    { "name": "test_timers_arguments.js" },
-    { "name": "test_timers_error.js" },
-    { "name": "test_timers_simple.js", "timeout": 10 },
-    { "name": "test_tizen_app_control.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "test_tls.js", "skip": ["all"], "reason": "TLS module is not enabled by default" },
-    { "name": "test_uart.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "test_uart_api.js" },
-    { "name": "test_util.js" }
+  "run_pass": [
+    {
+      "name": "test_adc.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "adc"
+      ]
+    },
+    {
+      "name": "test_assert.js"
+    },
+    {
+      "name": "test_ble_advertisement.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "ble"
+      ]
+    },
+    {
+      "name": "test_ble_setservices.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "ble"
+      ]
+    },
+    {
+      "name": "test_ble_setservices_central.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "run it with nodejs after running test_ble_setservices.js"
+    },
+    {
+      "name": "test_buffer.js"
+    },
+    {
+      "name": "test_buffer_from.js"
+    },
+    {
+      "name": "test_buffer_from_arraybuffer.js",
+      "required-features": [
+        "ArrayBuffer"
+      ]
+    },
+    {
+      "name": "test_buffer_str_conv.js"
+    },
+    {
+      "name": "test_buffer_inmutability_creation.js"
+    },
+    {
+      "name": "test_console.js",
+      "required-modules": [
+        "console"
+      ]
+    },
+    {
+      "name": "test_crypto.js",
+      "required-modules": [
+        "crypto"
+      ]
+    },
+    {
+      "name": "test_crypto_tls.js",
+      "required-modules": [
+        "crypto",
+        "fs",
+        "tls"
+      ]
+    },
+    {
+      "name": "test_dgram_1_server_1_client.js",
+      "required-modules": [
+        "dgram"
+      ]
+    },
+    {
+      "name": "test_dgram_1_server_n_clients.js",
+      "skip": [
+        "linux"
+      ],
+      "reason": "[linux]: flaky on Travis",
+      "required-modules": [
+        "dgram"
+      ]
+    },
+    {
+      "name": "test_dgram_address.js",
+      "required-modules": [
+        "dgram"
+      ]
+    },
+    {
+      "name": "test_dgram_broadcast.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "dgram"
+      ]
+    },
+    {
+      "name": "test_dgram_multicast_membership.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "dgram"
+      ]
+    },
+    {
+      "name": "test_dgram_multicast_set_multicast_loop.js",
+      "required-modules": [
+        "dgram"
+      ]
+    },
+    {
+      "name": "test_dgram_setttl_client.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "dgram"
+      ]
+    },
+    {
+      "name": "test_dgram_setttl_server.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "dgram"
+      ]
+    },
+    {
+      "name": "test_dns.js",
+      "required-modules": [
+        "net"
+      ]
+    },
+    {
+      "name": "test_dns_lookup.js",
+      "required-modules": [
+        "dns"
+      ]
+    },
+    {
+      "name": "test_events.js",
+      "required-modules": [
+        "events"
+      ]
+    },
+    {
+      "name": "test_events_assert_emit_error.js",
+      "required-modules": [
+        "events"
+      ]
+    },
+    {
+      "name": "test_events_uncaught_error.js",
+      "required-modules": [
+        "events"
+      ]
+    },
+    {
+      "name": "test_fs_exists.js",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_exists_sync.js",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_fstat.js",
+      "skip": [
+        "nuttx",
+        "tizenrt"
+      ],
+      "reason": "not implemented for nuttx/TizenRT",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_fstat_sync.js",
+      "skip": [
+        "nuttx",
+        "tizenrt"
+      ],
+      "reason": "not implemented for nuttx/TizenRT",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_mkdir_rmdir.js",
+      "skip": [
+        "nuttx"
+      ],
+      "reason": "[nuttx]: implemented, run manually in default configuration",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_open_close.js",
+      "skip": [
+        "nuttx"
+      ],
+      "reason": "not implemented for nuttx",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_read_stream.js",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_readdir.js",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_readfile.js",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_readfile_sync.js",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_rename.js",
+      "skip": [
+        "nuttx"
+      ],
+      "reason": "depends on the type of the memory (testrunner uses Read Only Memory)",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_rename_sync.js",
+      "skip": [
+        "nuttx"
+      ],
+      "reason": "depends on the type of the memory (testrunner uses Read Only Memory)",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_stat.js",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_stream_pipe.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "flaky on Travis",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_write.js",
+      "skip": [
+        "nuttx"
+      ],
+      "reason": "not implemented for nuttx",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_write_stream.js",
+      "skip": [
+        "nuttx"
+      ],
+      "reason": "depends on the type of the memory (testrunner uses Read Only Memory)",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_writefile.js",
+      "skip": [
+        "nuttx"
+      ],
+      "reason": "depends on the type of the memory (testrunner uses Read Only Memory)",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_writefile_sync.js",
+      "skip": [
+        "nuttx"
+      ],
+      "reason": "depends on the type of the memory (testrunner uses Read Only Memory)",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_writefile_unlink.js",
+      "skip": [
+        "nuttx"
+      ],
+      "reason": "depends on the type of the memory (testrunner uses Read Only Memory)",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_writefile_unlink_sync.js",
+      "skip": [
+        "nuttx"
+      ],
+      "reason": "depends on the type of the memory (testrunner uses Read Only Memory)",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_event.js",
+      "skip": [
+        "nuttx"
+      ],
+      "reason": "not implemented for nuttx",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_open_read.js",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_open_read_sync_1.js",
+      "skip": [
+        "nuttx"
+      ],
+      "reason": "not implemented for nuttx",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_open_read_sync_2.js",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_fs_open_read_sync_3.js",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_gpio_api.js",
+      "skip": [
+        "linux", "nuttx", "tizen", "tizenrt"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "gpio"
+      ]
+    },
+    {
+      "name": "test_gpio_direction.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "gpio"
+      ]
+    },
+    {
+      "name": "test_gpio_input.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "gpio"
+      ]
+    },
+    {
+      "name": "test_gpio_output.js",
+      "skip": [
+        "linux", "nuttx", "tizen", "tizenrt"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "gpio"
+      ]
+    },
+    {
+      "name": "test_http_signature.js",
+      "required-modules": [
+        "http_signature"
+      ]
+    },
+    {
+      "name": "test_i2c_api.js",
+      "skip": [
+        "linux", "nuttx", "tizen", "tizenrt"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "i2c"
+      ]
+    },
+    {
+      "name": "test_i2c_gy30.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "i2c"
+      ]
+    },
+    {
+      "name": "test_iotjs_promise.js",
+      "required-features": [
+        "Promise"
+      ]
+    },
+    {
+      "name": "test_iotjs_promise_chain_calls.js",
+      "required-modules": [
+        "fs"
+      ],
+      "required-features": [
+        "Promise"
+      ]
+    },
+    {
+      "name": "test_module_cache.js"
+    },
+    {
+      "name": "test_module_json.js"
+    },
+    {
+      "name": "test_module_require.js"
+    },
+    {
+      "name": "test_module_dynamicload.js",
+      "skip": [
+        "darwin",
+        "mock",
+        "nuttx",
+        "tizenrt",
+        "windows"
+      ],
+      "reason": "embedded, macos, and windows does not support dynamic loading",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_mqtt.js",
+      "required-modules": [
+        "mqtt"
+      ]
+    },
+    {
+      "name": "test_mqtt_frags.js",
+      "required-modules": [
+        "mqtt"
+      ]
+    },
+    {
+      "name": "test_net_1.js",
+      "required-modules": [
+        "net"
+      ]
+    },
+    {
+      "name": "test_net_2.js",
+      "required-modules": [
+        "net"
+      ]
+    },
+    {
+      "name": "test_net_3.js",
+      "skip": [
+        "nuttx"
+      ],
+      "reason": "[nuttx]: requires too many socket descriptors and too large buffers",
+      "required-modules": [
+        "net"
+      ]
+    },
+    {
+      "name": "test_net_4.js",
+      "required-modules": [
+        "net",
+        "timers"
+      ]
+    },
+    {
+      "name": "test_net_5.js",
+      "required-modules": [
+        "net",
+        "timers"
+      ]
+    },
+    {
+      "name": "test_net_6.js",
+      "required-modules": [
+        "net",
+        "timers"
+      ]
+    },
+    {
+      "name": "test_net_7.js",
+      "skip": [
+        "nuttx"
+      ],
+      "reason": "requires too many socket descriptors",
+      "required-modules": [
+        "net",
+        "timers"
+      ]
+    },
+    {
+      "name": "test_net_8.js",
+      "required-modules": [
+        "net",
+        "timers"
+      ]
+    },
+    {
+      "name": "test_net_9.js",
+      "required-modules": [
+        "net"
+      ]
+    },
+    {
+      "name": "test_net_10.js",
+      "required-modules": [
+        "net"
+      ]
+    },
+    {
+      "name": "test_net_connect.js",
+      "required-modules": [
+        "net"
+      ]
+    },
+    {
+      "name": "test_net_headers.js",
+      "required-modules": [
+        "http"
+      ]
+    },
+    {
+      "name": "test_net_http_get.js",
+      "required-modules": [
+        "http"
+      ]
+    },
+    {
+      "name": "test_net_http_outgoing_buffer.js",
+      "required-modules": [
+        "http"
+      ]
+    },
+    {
+      "name": "test_net_http_methods.js",
+      "required-modules": [
+        "http"
+      ]
+    },
+    {
+      "name": "test_net_http_response_twice.js",
+      "required-modules": [
+        "http",
+        "net"
+      ]
+    },
+    {
+      "name": "test_net_http_request_response.js",
+      "skip": [
+        "nuttx"
+      ],
+      "reason": "not implemented for nuttx",
+      "required-modules": [
+        "http",
+        "net"
+      ]
+    },
+    {
+      "name": "test_net_http_request_http_version.js",
+      "required-modules": [
+        "http"
+      ]
+    },
+    {
+      "name": "test_net_http_status_codes.js",
+      "required-modules": [
+        "http"
+      ]
+    },
+    {
+      "name": "test_net_http_modified_request.js",
+      "required-modules": [
+        "http"
+      ]
+    },
+    {
+      "name": "test_net_http_modified_response.js",
+      "required-modules": [
+        "http"
+      ]
+    },
+    {
+      "name": "test_net_http_modified_req_resp.js",
+      "required-modules": [
+        "http"
+      ]
+    },
+    {
+      "name": "test_net_httpclient_error.js",
+      "required-modules": [
+        "http"
+      ]
+    },
+    {
+      "name": "test_net_httpclient_parse_error.js",
+      "required-modules": [
+        "http",
+        "net"
+      ]
+    },
+    {
+      "name": "test_net_httpclient_timeout_1.js",
+      "required-modules": [
+        "http",
+        "net"
+      ]
+    },
+    {
+      "name": "test_net_httpclient_timeout_2.js",
+      "required-modules": [
+        "http"
+      ]
+    },
+    {
+      "name": "test_net_http_server_timeout.js",
+      "required-modules": [
+        "http"
+      ]
+    },
+    {
+      "name": "test_net_http_server.js",
+      "required-modules": [
+        "http"
+      ]
+    },
+    {
+      "name": "test_net_https_get.js",
+      "timeout": 10,
+      "required-modules": [
+        "https"
+      ]
+    },
+    {
+      "name": "test_net_https_post_status_codes.js",
+      "timeout": 10,
+      "required-modules": [
+        "https"
+      ]
+    },
+    {
+      "name": "test_net_https_request_response.js",
+      "timeout": 10,
+      "required-modules": [
+        "https",
+        "http",
+        "net"
+      ]
+    },
+    {
+      "name": "test_net_https_modified_req_resp.js",
+      "required-modules": [
+        "https",
+        "http",
+        "net"
+      ]
+    },
+    {
+      "name": "test_net_https_timeout.js",
+      "timeout": 10,
+      "required-modules": [
+        "https"
+      ]
+    },
+    {
+      "name": "test_net_https_server.js",
+      "timeout": 10,
+      "required-modules": [
+        "https",
+        "fs"
+      ]
+    },
+    {
+      "name": "test_process.js"
+    },
+    {
+      "name": "test_process_chdir.js"
+    },
+    {
+      "name": "test_process_cwd.js"
+    },
+    {
+      "name": "test_process_exit.js"
+    },
+    {
+      "name": "test_process_experimental_off.js",
+      "skip": [
+        "experimental"
+      ],
+      "reason": "needed if testing stablity is set with stable"
+    },
+    {
+      "name": "test_process_experimental_on.js",
+      "skip": [
+        "stable"
+      ],
+      "reason": "needed if testing stablity is set with experimental"
+    },
+    {
+      "name": "test_process_next_tick.js"
+    },
+    {
+      "name": "test_process_uncaught_order.js"
+    },
+    {
+      "name": "test_process_uncaught_simple.js"
+    },
+    {
+      "name": "test_pwm_async.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "pwm"
+      ]
+    },
+    {
+      "name": "test_pwm_sync.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "pwm"
+      ]
+    },
+    {
+      "name": "test_spi.js",
+      "skip": [
+        "linux"
+      ],
+      "reason": "Different env on Linux desktop/travis/rpi",
+      "required-modules": [
+        "spi"
+      ]
+    },
+    {
+      "name": "test_spi_buffer_async.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "spi"
+      ]
+    },
+    {
+      "name": "test_spi_buffer_sync.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "spi"
+      ]
+    },
+    {
+      "name": "test_spi_mcp3008.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "spi"
+      ]
+    },
+    {
+      "name": "test_stream.js",
+      "required-modules": [
+        "stream"
+      ]
+    },
+    {
+      "name": "test_stream_duplex.js",
+      "required-modules": [
+        "stream"
+      ]
+    },
+    {
+      "name": "test_stream_pipe.js",
+      "required-modules": [
+        "stream"
+      ]
+    },
+    {
+      "name": "test_timers_arguments.js"
+    },
+    {
+      "name": "test_timers_error.js"
+    },
+    {
+      "name": "test_timers_simple.js",
+      "timeout": 10
+    },
+    {
+      "name": "test_tizen_app_control.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "tizen"
+      ]
+    },
+    {
+      "name": "test_tls_1.js",
+      "required-modules": [
+        "tls",
+        "fs"
+      ]
+    },
+    {
+      "name": "test_tls_2.js",
+      "required-modules": [
+        "tls",
+        "fs"
+      ]
+    },
+    {
+      "name": "test_tls_3.js",
+      "required-modules": [
+        "tls",
+        "fs"
+      ]
+    },
+    {
+      "name": "test_tls_4.js",
+      "required-modules": [
+        "tls",
+        "fs"
+      ]
+    },
+    {
+      "name": "test_tls_ca.js",
+      "required-modules": [
+        "tls",
+        "fs"
+      ]
+    },
+    {
+      "name": "test_tls_stream_duplex.js",
+      "required-modules": [
+        "tls",
+        "fs",
+        "stream"
+      ]
+    },
+    {
+      "name": "test_uart.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "uart"
+      ]
+    },
+    {
+      "name": "test_uart_api.js",
+      "required-modules": [
+        "uart"
+      ]
+    },
+    {
+      "name": "test_util.js",
+      "required-modules": [
+        "util"
+      ]
+    },
+    {
+      "name": "test_websocket.js",
+      "required-modules": [
+        "websocket"
+      ]
+    },
+    {
+      "name": "test_websocket_server.js",
+      "required-modules": [
+        "websocket"
+      ]
+    },
+    {
+      "name": "test_websocket_server_secure.js",
+      "required-modules": [
+        "websocket",
+        "tls"
+      ]
+    }
   ],
   "run_pass/issue": [
-    { "name": "issue-133.js" },
-    { "name": "issue-137.js" },
-    { "name": "issue-198.js" },
-    { "name": "issue-223.js" },
-    { "name": "issue-266.js" },
-    { "name": "issue-323.js" },
-    { "name": "issue-816.js" },
-    { "name": "issue-1046.js" },
-    { "name": "issue-1077.js" },
-    { "name": "issue-1101.js", "skip": ["all"], "reason": "need to setup test environment" },
-    { "name": "issue-1348.js" },
-    { "name": "issue-1485.js" },
-    { "name": "issue-1507.js" },
-    { "name": "issue-1557.js" }
+    {
+      "name": "issue-133.js"
+    },
+    {
+      "name": "issue-137.js"
+    },
+    {
+      "name": "issue-198.js"
+    },
+    {
+      "name": "issue-223.js",
+      "required-modules": [
+        "net"
+      ]
+    },
+    {
+      "name": "issue-266.js",
+      "required-modules": [
+        "net"
+      ]
+    },
+    {
+      "name": "issue-323.js",
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "issue-816.js",
+      "required-modules": [
+        "buffer"
+      ]
+    },
+    {
+      "name": "issue-1046.js",
+      "required-modules": [
+        "buffer"
+      ]
+    },
+    {
+      "name": "issue-1077.js"
+    },
+    {
+      "name": "issue-1101.js",
+      "skip": [
+        "all"
+      ],
+      "reason": "need to setup test environment",
+      "required-modules": [
+        "uart"
+      ]
+    },
+    {
+      "name": "issue-1348.js"
+    },
+    {
+      "name": "issue-1463.js",
+      "required-features": [
+        "Promise"
+      ]
+    },
+    {
+      "name": "issue-1485.js"
+    },
+    {
+      "name": "issue-1507.js",
+      "required-modules": [
+        "console"
+      ]
+    },
+    {
+      "name": "issue-1557.js"
+    }
   ],
-  "run_fail":  [
-    { "name": "test_assert_equal.js", "expected-failure": true },
-    { "name": "test_assert_fail.js", "expected-failure": true },
-    { "name": "test_assert_notequal.js", "expected-failure": true },
-    { "name": "test_events_emit_error.js", "expected-failure": true },
-    { "name": "test_fs_callbacks_called.js", "expected-failure": true },
-    { "name": "test_iotjs_runtime_error.js", "expected-failure": true },
-    { "name": "test_iotjs_syntax_error.js", "expected-failure": true },
-    { "name": "test-issue-1349.js", "expected-failure": true},
-    { "name": "test-issue-1360.js", "expected-failure": true},
-    { "name": "test_module_require_invalid_file.js", "expected-failure": true },
-    { "name": "test_module_require_path_below_root.js", "expected-failure": true },
-    { "name": "test_process_exitcode_arg.js", "expected-failure": true },
-    { "name": "test_process_exitcode_var.js", "expected-failure": true },
-    { "name": "test_process_explicit_exit.js", "expected-failure": true },
-    { "name": "test_process_implicit_exit.js", "expected-failure": true },
-    { "name": "test_timers_issue_1353.js", "expected-failure": true }
+  "run_fail": [
+    {
+      "name": "test_assert_equal.js",
+      "expected-failure": true
+    },
+    {
+      "name": "test_assert_fail.js",
+      "expected-failure": true
+    },
+    {
+      "name": "test_assert_notequal.js",
+      "expected-failure": true
+    },
+    {
+      "name": "test_events_emit_error.js",
+      "expected-failure": true,
+      "required-modules": [
+        "events"
+      ]
+    },
+    {
+      "name": "test_fs_callbacks_called.js",
+      "expected-failure": true,
+      "required-modules": [
+        "fs"
+      ]
+    },
+    {
+      "name": "test_iotjs_runtime_error.js",
+      "expected-failure": true
+    },
+    {
+      "name": "test_iotjs_syntax_error.js",
+      "expected-failure": true
+    },
+    {
+      "name": "test-issue-1349.js",
+      "expected-failure": true,
+      "required-modules": [
+        "dns"
+      ]
+    },
+    {
+      "name": "test-issue-1360.js",
+      "expected-failure": true
+    },
+    {
+      "name": "test-issue-1570.js",
+      "expected-failure": true
+    },
+    {
+      "name": "test_module_require_invalid_file.js",
+      "expected-failure": true
+    },
+    {
+      "name": "test_module_require_path_below_root.js",
+      "expected-failure": true
+    },
+    {
+      "name": "test_process_exitcode_arg.js",
+      "expected-failure": true
+    },
+    {
+      "name": "test_process_exitcode_var.js",
+      "expected-failure": true
+    },
+    {
+      "name": "test_process_explicit_exit.js",
+      "expected-failure": true
+    },
+    {
+      "name": "test_process_implicit_exit.js",
+      "expected-failure": true
+    },
+    {
+      "name": "test_timers_issue_1353.js",
+      "expected-failure": true
+    }
   ],
   "node/parallel": [
-    { "name": "test-assert.js" },
-    { "name": "test-module-circular.js" },
-    { "name": "test-http-catch-uncaughtexception.js" },
-    { "name": "test-http-status-message.js" },
-    { "name": "test-http-write-head.js" },
-    { "name": "test-net-bind-twice.js" },
-    { "name": "test-net-end-without-connect.js" },
-    { "name": "test-net-keepalive.js" },
-    { "name": "test-timers-clear-null-does-not-throw-error.js" }
+    {
+      "name": "test-assert.js",
+      "required-modules": [
+        "fs",
+        "stream"
+      ]
+    },
+    {
+      "name": "test-module-circular.js",
+      "required-modules": [
+        "fs",
+        "stream"
+      ]
+    },
+    {
+      "name": "test-http-catch-uncaughtexception.js",
+      "required-modules": [
+        "http",
+        "fs",
+        "stream"
+      ]
+    },
+    {
+      "name": "test-http-status-message.js",
+      "required-modules": [
+        "http",
+        "net",
+        "fs",
+        "stream"
+      ]
+    },
+    {
+      "name": "test-http-write-head.js",
+      "required-modules": [
+        "http",
+        "fs",
+        "stream"
+      ]
+    },
+    {
+      "name": "test-net-bind-twice.js",
+      "required-modules": [
+        "net",
+        "fs",
+        "stream"
+      ]
+    },
+    {
+      "name": "test-net-end-without-connect.js",
+      "required-modules": [
+        "net",
+        "fs",
+        "stream"
+      ]
+    },
+    {
+      "name": "test-net-keepalive.js",
+      "required-modules": [
+        "net",
+        "fs",
+        "stream"
+      ]
+    },
+    {
+      "name": "test-timers-clear-null-does-not-throw-error.js",
+      "required-modules": [
+        "fs",
+        "stream"
+      ]
+    }
+  ],
+  "external_modules": [
+    {
+      "name": "test-external-module1.js",
+      "required-modules": [
+        "mymodule1"
+      ]
+    },
+    {
+      "name": "test-external-module2.js",
+      "required-modules": [
+        "mymodule2"
+      ]
+    }
   ]
 }
diff --git a/test/tools/iotjs_build_info.js b/test/tools/iotjs_build_info.js
new file mode 100644 (file)
index 0000000..e222147
--- /dev/null
@@ -0,0 +1,76 @@
+/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
+ *
+ * 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.
+ */
+
+/* Just for the testrunner to get runtime information about the build. */
+var builtins = process.builtin_modules;
+
+if (process.env.IOTJS_ENV.indexOf("experimental") > -1)
+    stability = "experimental"
+else
+    stability = "stable"
+
+/* Check if certain es2015 features are available */
+function hasFeatures(object, features) {
+  supported = true;
+
+  for (feature in features) {
+    supported = supported && object.hasOwnProperty(features[feature]);
+  }
+
+  return supported;
+}
+
+function hasArrowFunction() {
+  try {
+    eval("a => {}");
+    return true;
+  } catch(e) {}
+
+  return false;
+}
+
+var features = {};
+
+var typedArrayFeatures = [
+  'Int8Array',
+  'Uint8Array',
+  'Uint8ClampedArray',
+  'Int168Array',
+  'Uint16Array',
+  'Int32Array',
+  'Uint32Array',
+  'Float32Array',
+  'Float64Array'
+];
+
+if (hasFeatures(global, ['Promise']))
+  features.Promise = true;
+
+if (hasFeatures(global, ['ArrayBuffer']))
+  features.ArrayBuffer = true;
+
+if (hasFeatures(global, typedArrayFeatures))
+  features.TypedArray = true;
+
+if (hasArrowFunction())
+  features.ArrowFunction = true;
+
+result = {
+    'builtins': builtins,
+    'features': features,
+    'stability': stability
+}
+
+console.log(JSON.stringify(result))
index e7045d7a7a81e08a1ef7c62d6695787f12284fa6..b0dab17bdc4c67ec381d2a5114029da9734e74cc 100755 (executable)
@@ -16,4 +16,4 @@
 
 sudo apt-get update -q
 sudo apt-get install -q -y \
-    cmake gcc valgrind clang-format-3.8
+    cmake gcc valgrind clang-format-3.9
index b30bf61197132cbb66e17800d38773df10469a32..48fed97cd70630b1bb16e0be221ea2d3a631ebc8 100755 (executable)
@@ -30,6 +30,7 @@ import os
 from common_py import path
 from common_py.system.filesystem import FileSystem as fs
 from common_py.system.executor import Executor as ex
+from common_py.system.executor import Terminal
 from common_py.system.platform import Platform
 
 platform = Platform()
@@ -147,12 +148,10 @@ def init_options():
         choices=[None, 'artik10', 'stm32f4dis', 'rpi2', 'rpi3', 'artik05x'],
         default=None, help='Specify the target board (default: %(default)s).')
     iotjs_group.add_argument('--target-os',
-        choices=['linux', 'darwin', 'osx', 'nuttx', 'tizen', 'tizenrt',
-                 'openwrt'],
+        choices=['linux', 'darwin', 'osx', 'mock', 'nuttx', 'tizen', 'tizenrt',
+                 'openwrt', 'windows'],
         default=platform.os(),
         help='Specify the target OS (default: %(default)s).')
-    iotjs_group.add_argument('--testsets',
-        help='Specify the additional testsets file for IoT.js')
 
 
     jerry_group = parser.add_argument_group('Arguments of JerryScript',
@@ -184,14 +183,15 @@ def init_options():
         action='store_true', default=False,
         help='Enable JerryScript heap statistics')
     jerry_group.add_argument('--jerry-profile',
-        choices=['es5.1', 'es2015-subset'], default='es5.1',
-        help='Specify the profile for JerryScript (default: %(default)s).')
+        metavar='FILE', action='store', default='es5.1',
+        help='Specify the profile for JerryScript (default: %(default)s). '
+             'Possible values are "es5.1", "es2015-subset" or an absolute '
+             'path to a custom JerryScript profile file.')
     jerry_group.add_argument('--js-backtrace',
         choices=['ON', 'OFF'], type=str.upper,
         help='Enable/disable backtrace information of JavaScript code '
              '(default: ON in debug and OFF in release build)')
 
-
     options = parser.parse_args(argv)
     options.config = build_config
 
@@ -203,7 +203,7 @@ def adjust_options(options):
     if options.target_os in ['nuttx', 'tizenrt']:
         options.buildlib = True
         if not options.sysroot:
-            ex.fail('--sysroot needed for nuttx target')
+            ex.fail('--sysroot needed for %s target' % options.target_os)
 
         options.sysroot = fs.abspath(options.sysroot)
         if not fs.exists(options.sysroot):
@@ -217,6 +217,11 @@ def adjust_options(options):
     if options.target_os == 'darwin':
         options.no_check_valgrind = True
 
+    # Switch to no-snapshot mode on windows for now.
+    # TODO: After Jerry update this could be removed.
+    if options.target_os == 'windows':
+        options.no_snapshot = True
+
     if options.target_board in ['rpi2', 'rpi3', 'artik10', 'artik05x']:
         options.no_check_valgrind = True
 
@@ -235,9 +240,12 @@ def adjust_options(options):
     cmake_path = fs.join(path.PROJECT_ROOT, 'cmake', 'config', '%s.cmake')
     options.cmake_toolchain_file = cmake_path % options.target_tuple
 
-    # Specify the file of JerryScript profile.
-    options.jerry_profile = fs.join(path.JERRY_PROFILE_ROOT,
-                                    options.jerry_profile + '.profile')
+    # Set the default value of '--js-backtrace' if it is not defined.
+    if not options.js_backtrace:
+        if options.buildtype == 'debug':
+            options.js_backtrace = "ON"
+        else:
+            options.js_backtrace = "OFF"
 
 
 def print_progress(msg):
@@ -275,6 +283,8 @@ def build_cmake_args(options):
 
     if options.target_os == 'tizenrt':
         include_dirs.append('%s/../framework/include/iotbus' % options.sysroot)
+    elif options.target_os == 'windows':
+        cmake_args.append("-GVisual Studio 15 2017")
 
     include_dirs.extend(options.external_include_dir)
     cmake_args.append("-DEXTERNAL_INCLUDE_DIR='%s'" % (' '.join(include_dirs)))
@@ -305,12 +315,11 @@ def build_iotjs(options):
     cmake_opt = [
         '-B%s' % options.build_root,
         '-H%s' % path.PROJECT_ROOT,
-        "-DCMAKE_TOOLCHAIN_FILE='%s'" % options.cmake_toolchain_file,
+        "-DCMAKE_TOOLCHAIN_FILE=%s" % options.cmake_toolchain_file,
         '-DCMAKE_BUILD_TYPE=%s' % options.buildtype.capitalize(),
         '-DTARGET_ARCH=%s' % options.target_arch,
         '-DTARGET_OS=%s' % options.target_os,
         '-DTARGET_BOARD=%s' % options.target_board,
-        '-DPLATFORM_DESCRIPTOR=%s' % options.target_tuple,
         '-DENABLE_LTO=%s' % get_on_off(options.jerry_lto), # --jerry-lto
         '-DENABLE_SNAPSHOT=%s' % get_on_off(not options.no_snapshot),
         '-DBUILD_LIB_ONLY=%s' % get_on_off(options.buildlib), # --buildlib
@@ -332,6 +341,9 @@ def build_iotjs(options):
     # --jerry-heaplimit
     if options.jerry_heaplimit:
         cmake_opt.append('-DMEM_HEAP_SIZE_KB=%d' % options.jerry_heaplimit)
+        if options.jerry_heaplimit > 512:
+            cmake_opt.append("-DEXTRA_JERRY_CMAKE_PARAMS='%s'" %
+                             "-DFEATURE_CPOINTER_32_BIT=ON")
 
     # --jerry-heap-section
     if options.jerry_heap_section:
@@ -343,11 +355,6 @@ def build_iotjs(options):
         cmake_opt.append("-DFEATURE_DEBUGGER=ON")
 
     # --js-backtrace
-    if not options.js_backtrace:
-        if options.buildtype == 'debug':
-            options.js_backtrace = "ON"
-        else:
-            options.js_backtrace = "OFF"
     cmake_opt.append("-DFEATURE_JS_BACKTRACE=%s" %
                      options.js_backtrace)
 
@@ -377,7 +384,10 @@ def build_iotjs(options):
     # Run cmake.
     ex.check_run_cmd('cmake', cmake_opt)
 
-    run_make(options, options.build_root)
+    if options.target_os == 'windows':
+        print("\nPlease open the iot.js solution file in Visual Studio!")
+    else:
+        run_make(options, options.build_root)
 
 
 def run_checktest(options):
@@ -385,11 +395,7 @@ def run_checktest(options):
     iotjs = fs.join(options.build_root, 'bin', 'iotjs')
 
     cmd = fs.join(path.TOOLS_ROOT, 'testrunner.py')
-    args = [iotjs]
-
-    # testsets
-    if options.testsets:
-        args.append('--testsets=' + options.testsets);
+    args = [iotjs, "--platform=%s" % options.target_os]
 
     if options.run_test == "quiet":
         args.append('--quiet')
@@ -411,7 +417,12 @@ if __name__ == '__main__':
     adjust_options(options)
 
     if options.clean:
-        print_progress('Clear build directory')
+        print_progress('Clear build directories')
+        test_build_root = fs.join(path.TEST_ROOT,
+                                  'dynamicmodule',
+                                  'build',
+                                  options.target_os)
+        fs.rmtree(test_build_root)
         fs.rmtree(options.build_root)
 
     # Perform init-submodule.
@@ -421,7 +432,7 @@ if __name__ == '__main__':
 
     build_iotjs(options)
 
-    print("\n%sIoT.js Build Succeeded!!%s\n" % (ex._TERM_GREEN, ex._TERM_EMPTY))
+    Terminal.pprint("\nIoT.js Build Succeeded!!\n", Terminal.green)
 
     # Run tests.
     if options.run_test:
@@ -430,13 +441,15 @@ if __name__ == '__main__':
             print("Skip unit tests - build target is library\n")
         elif (options.host_tuple == options.target_tuple or
               (options.host_tuple == 'x86_64-linux' and
-               options.target_tuple == 'i686-linux')):
+               options.target_tuple == 'i686-linux') or
+              (options.host_tuple == 'x86_64-linux' and
+               options.target_tuple == 'x86_64-mock')):
              run_checktest(options)
         else:
             print("Skip unit tests - target-host pair is not allowed\n")
     else:
-        print("\n%sTo run tests use '--run-test' "
-              "or one of the folowing commands:%s"
-              % (ex._TERM_BLUE, ex._TERM_EMPTY))
+        Terminal.pprint("\nTo run tests use '--run-test' "
+                        "or one of the folowing commands:",
+                        Terminal.blue)
         print("\n    tools/testrunner.py %s/%s/%s/bin/iotjs\n"
               % (options.builddir, options.target_tuple, options.buildtype))
index 977dff80c8bb7e76064fa8c83d22f97a2219ef79..4122d11b09764741371c9ccffbd793039cf69423 100755 (executable)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-if [[ -n "${TRAVIS_PULL_REQUEST_SLUG}" &&
-         "${TRAVIS_PULL_REQUEST_SLUG}" != "${TRAVIS_REPO_SLUG}" ]]; then
-  echo "Skip: The pull request from ${TRAVIS_PULL_REQUEST_SLUG} is an \
-  external one. It's not supported yet in Travis-CI";
+if [[ "${TRAVIS_REPO_SLUG}" == "Samsung/iotjs"
+          && ${TRAVIS_BRANCH} == "master"
+          && ${TRAVIS_EVENT_TYPE} == "push" ]]
+then
+  git fetch --unshallow
+  build-wrapper-linux-x86-64 --out-dir bw-output ./tools/build.py
+  sonar-scanner
 else
-  git fetch --unshallow;
-  build-wrapper-linux-x86-64 --out-dir bw-output ./tools/build.py;
-  sonar-scanner;
+  echo "Skip: The pull request from ${TRAVIS_PULL_REQUEST_SLUG} is an \
+  external one. It's not supported yet in Travis-CI"
 fi
index 98524881d077e70d1d93ee9527f603e3fa6004a8..e5386f993821e5abc9c249b4246308e507d28fbe 100755 (executable)
@@ -29,6 +29,7 @@ from distutils import spawn
 from check_license import CheckLicenser
 from common_py.system.filesystem import FileSystem as fs
 from common_py.system.executor import Executor as ex
+from common_py.system.executor import Terminal
 
 
 def parse_option():
@@ -102,7 +103,7 @@ class ClangFormat(object):
         self._extensions = extensions
         self._skip_files = skip_files
         self._options = options
-        self._check_clang_format("clang-format-3.8")
+        self._check_clang_format("clang-format-3.9")
 
     def _check_clang_format(self, base):
         clang_format = spawn.find_executable(base)
@@ -110,11 +111,12 @@ class ClangFormat(object):
         if not clang_format:
             clang_format = spawn.find_executable("clang-format")
             if clang_format:
-                print("%sUsing %s instead of %s%s"
-                      % (ex._TERM_YELLOW, clang_format, base, ex._TERM_EMPTY))
+                Terminal.pprint(
+                    "Using %s instead of %s" % (clang_format, base),
+                    Terminal.yellow)
             else:
-                print("%sNo %s found, skipping checks!%s"
-                      % (ex._TERM_RED, base, ex._TERM_EMPTY))
+                Terminal.pprint("No %s found, skipping checks!" % base,
+                    Terminal.red)
 
         self._clang_format = clang_format
 
@@ -161,16 +163,14 @@ class EslintChecker(object):
     def _check_eslint(self):
         self._node = spawn.find_executable('node')
         if not self._node:
-            print('%sNo node found.%s'
-                    % (ex._TERM_RED, ex._TERM_EMPTY))
+            Terminal.pprint('No node found,', Terminal.red)
             return
 
         self._eslint = spawn.find_executable('node_modules/.bin/eslint')
         if not self._eslint:
             self._eslint = spawn.find_executable('eslint')
             if not self._eslint:
-                print('%sNo eslint found.%s'
-                        % (ex._TERM_RED, ex._TERM_EMPTY))
+                Terminal.pprint('No eslint found.', Terminal.red)
 
     def check(self):
         self.error_count = 0
@@ -264,8 +264,8 @@ def check_tidy(src_dir, options=None):
     print("* clang-format errors: %d" % clang.error_count)
     print("* eslint errors: %d" % eslint.error_count)
 
-    msg_color = ex._TERM_RED if total_errors > 0 else ex._TERM_GREEN
-    print("%s* total errors: %d%s" % (msg_color, total_errors, ex._TERM_EMPTY))
+    msg_color = Terminal.red if total_errors > 0 else Terminal.green
+    Terminal.pprint("* total errors: %d" % (total_errors), msg_color)
     print()
 
     if total_errors:
diff --git a/tools/common_js/logger.js b/tools/common_js/logger.js
deleted file mode 100644 (file)
index 043eb31..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-var fs = require('fs');
-
-function Logger(path) {
-  this.text_colors = {
-    red: "\033[1;31m",
-    yellow: "\033[1;33m",
-    green: "\033[1;32m",
-    blue: "\033[1;34m",
-    empty: "\033[0m",
-  };
-  this.status = {
-    pass: "pass",
-    skip: "skip",
-    fail: "fail",
-    timeout: "timeout",
-    summary: "summary"
-  }
-  this.path = path;
-
-  return this;
-}
-
-Logger.prototype.message = function (msg, status) {
-  if (this.path) {
-    // FIXME : After fs.appendFile is implemented, it should be replaced.
-    var data = fs.readFileSync(this.path);
-    var newData = data + msg + "\n";
-    fs.writeFileSync(this.path, new Buffer(newData));
-  }
-  if (status == this.status.pass) {
-    console.log(this.text_colors.green + msg + this.text_colors.empty);
-  } else if (status == this.status.skip) {
-    console.log(this.text_colors.yellow + msg + this.text_colors.empty);
-  } else if (status == this.status.fail || status == this.status.timeout){
-    console.log(this.text_colors.red + msg + this.text_colors.empty);
-  } else if (status == this.status.summary){
-    console.log(this.text_colors.blue + msg + this.text_colors.empty);
-  } else {
-    console.log(msg);
-  }
-}
-
-module.exports.Logger = Logger;
diff --git a/tools/common_js/module/console.js b/tools/common_js/module/console.js
deleted file mode 100644 (file)
index 4aac72a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-var fs = require('fs');
-
-function Console() {
-  return this;
-}
-
-Console.prototype.log =
-Console.prototype.info =
-Console.prototype.warn =
-Console.prototype.error = function() {
-  /* Do Nothing */
-};
-
-module.exports = new Console();
diff --git a/tools/common_js/option_parser.js b/tools/common_js/option_parser.js
deleted file mode 100644 (file)
index ca0935b..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-var util = require('util');
-
-function Option(arg, value, default_value, help) {
-  this.arg = arg;
-  this.value = value;
-  this.default_value = default_value;
-  this.help = help;
-
-  return this;
-}
-
-Option.prototype.printHelp = function() {
-  console.log("\t" + this.arg + "=[" + this.value + "](default: " +
-              this.default_value + ") : " + this.help);
-}
-
-function OptionParser() {
-  this.options = [];
-  return this;
-}
-
-OptionParser.prototype.addOption = function(arg, value, default_value, help) {
-  var option  = new Option(arg, value, default_value, help);
-  this.options.push(option);
-}
-
-OptionParser.prototype.parse = function() {
-  var options = {};
-
-  for (var idx in this.options) {
-    var option = this.options[idx];
-    var default_value = option.default_value;
-    if (default_value !== "") {
-      options[option.arg] = default_value;
-    }
-  }
-
-  for (var aIdx = 2; aIdx < process.argv.length; aIdx++) {
-    var option = process.argv[aIdx];
-    var arg_val = option.split("=");
-
-    if (arg_val.length != 2 || !arg_val[0] || !arg_val[1]) {
-      return null;
-    }
-
-    var arg = arg_val[0];
-    var val = arg_val[1];
-    var found = false;
-
-    if (arg === "default-timeout") {
-      // Transform to number, or use default value.
-      val = util.stringToNumber(val, options[arg]);
-    }
-
-    for (var oIdx in this.options) {
-      if (arg == this.options[oIdx].arg) {
-        options[arg] = val;
-        found = true;
-        break;
-      }
-    }
-
-    if (!found)
-      return null;
-  }
-
-  return options;
-}
-
-OptionParser.prototype.printHelp = function() {
-  console.log(process.argv[1]);
-  console.log("\noptional arguments");
-  for (var idx in this.options) {
-    this.options[idx].printHelp();
-  }
-}
-
-
-module.exports.OptionParser = OptionParser;
diff --git a/tools/common_js/util.js b/tools/common_js/util.js
deleted file mode 100644 (file)
index dee234b..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-function absolutePath(path) {
-  // FIXME: On NuttX side, when dealing with file, path should be absolute.
-  // So workaround this problem, test driver converts relative path
-  // to absolute one.
-  return process.cwd() + '/' + path;
-}
-
-function join() {
-  var path = Array.prototype.join.call(arguments, '/');
-  return path;
-}
-
-function Watch() {
-  this.reset();
-}
-
-Watch.prototype.reset = function() {
-  this.startTime = 0;
-  this.elapsedTime = 0;
-}
-
-Watch.prototype.delta = function() {
-  if (this.startTime) {
-    this.elapsedTime = (Date.now() - this.startTime) / 1000;
-  }
-
-  this.startTime = Date.now();
-
-  return this.elapsedTime;
-}
-
-module.exports.absolutePath = absolutePath;
-module.exports.join = join;
-module.exports.Watch = Watch;
index ed7d145548ca96f355331f9fb16643f1921c2ba5..8d4a44bd7cbb56866f592b9308cf55b76d0c60ba 100644 (file)
@@ -56,4 +56,4 @@ HTTPPARSER_ROOT = fs.join(DEPS_ROOT, 'http-parser')
 BUILD_CONFIG_PATH = fs.join(PROJECT_ROOT, 'build.config')
 
 # IoT.js build information.
-BUILD_INFO_PATH = fs.join(TOOLS_ROOT, 'iotjs_build_info.js')
+BUILD_INFO_PATH = fs.join(TEST_ROOT, 'tools', 'iotjs_build_info.js')
index f372d5451f1a44b9b1b76befe43dbd0f5ed06242..3d8ccd41df98f57bd914e06350636a59db51ede2 100644 (file)
 
 from __future__ import print_function
 
+import collections
+import os
 import subprocess
 
+_colors = {
+    "empty": "\033[0m",
+    "red": "\033[1;31m",
+    "green": "\033[1;32m",
+    "yellow": "\033[1;33m",
+    "blue": "\033[1;34m"
+}
+
+if "TERM" not in os.environ:
+    # if there is no "TERM" environment variable
+    # assume that we can't output colors.
+    # So reset the ANSI color escapes.
+    _colors = _colors.fromkeys(_colors, "")
+
+_TerminalType = collections.namedtuple('Terminal', _colors.keys())
+class _Terminal(_TerminalType):
+
+    def pprint(self, text, color=_colors["empty"]):
+        print("%s%s%s" % (color, text, self.empty))
+
+Terminal = _Terminal(**_colors)
+
 
 class Executor(object):
-    _TERM_RED = "\033[1;31m"
-    _TERM_YELLOW = "\033[1;33m"
-    _TERM_GREEN = "\033[1;32m"
-    _TERM_BLUE = "\033[1;34m"
-    _TERM_EMPTY = "\033[0m"
 
     @staticmethod
     def cmd_line(cmd, args=[]):
@@ -30,14 +49,13 @@ class Executor(object):
 
     @staticmethod
     def print_cmd_line(cmd, args=[]):
-        print("%s%s%s" % (Executor._TERM_BLUE, Executor.cmd_line(cmd, args),
-                          Executor._TERM_EMPTY))
+        Terminal.pprint(Executor.cmd_line(cmd, args), Terminal.blue)
         print()
 
     @staticmethod
     def fail(msg):
         print()
-        print("%s%s%s" % (Executor._TERM_RED, msg, Executor._TERM_EMPTY))
+        Terminal.pprint(msg, Terminal.red)
         print()
         exit(1)
 
index 5f7c7f3d0eabcabfb66485b53278278bf251a7dc..480b50195c0485494d326c38c17ccc7a2fe2f4e8 100644 (file)
 # limitations under the License.
 
 import os
-
+import sys
 
 class Platform(object):
     def __init__(self):
-        _os, _, _, _, _arch = os.uname()
+        if sys.platform == "win32":
+            _os = "windows"
+            _arch = "i686" # TODO: allow x86_64 also
+        else:
+            _os, _, _, _, _arch = os.uname()
         self._os = _os
         self._arch = _arch
 
diff --git a/tools/iotjs_build_info.js b/tools/iotjs_build_info.js
deleted file mode 100644 (file)
index fa48918..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors
- *
- * 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.
- */
-
-/* Just for the testrunner to get runtime information about the build. */
-var builtins = process.builtin_modules;
-
-if (process.env.IOTJS_ENV.indexOf("experimental") > -1)
-    stability = "experimental"
-else
-    stability = "stable"
-
-result = {
-    'builtins': builtins,
-    'stability': stability
-}
-
-console.log(JSON.stringify(result))
index 3a8c48878058d7146c66e7d872f8b4d5d9a78d8f..2bf9c84da5c4454c2d4ab5aac8b540e5c843782a 100755 (executable)
@@ -26,6 +26,14 @@ import struct
 from common_py.system.filesystem import FileSystem as fs
 from common_py import path
 
+
+def normalize_str(text):
+    if not isinstance(text, str):
+        return text.decode('utf-8')
+
+    return text
+
+
 def regroup(l, n):
     return [l[i:i+n] for i in range(0, len(l), n)]
 
@@ -47,48 +55,6 @@ def remove_whitespaces(code):
     return re.sub('\n+', '\n', re.sub('\n +', '\n', code))
 
 
-def force_str(string):
-    if not isinstance(string, str):
-        return string.decode('utf-8')
-    else:
-        return string
-
-
-def parse_literals(code):
-    JERRY_SNAPSHOT_VERSION = 12
-    JERRY_SNAPSHOT_MAGIC = 0x5952524A
-
-    literals = set()
-    # header format:
-    # uint32_t magic
-    # uint32_t version
-    # uint32_t global opts
-    # uint32_t literal table offset
-    header = struct.unpack('I' * 4, code[0:4 * 4])
-    if header[0] != JERRY_SNAPSHOT_MAGIC:
-        print('Incorrect snapshot format! Magic number is incorrect')
-        exit(1)
-    if header[1] != JERRY_SNAPSHOT_VERSION:
-        print ('Please check jerry snapshot version (Last confirmed: %d)'
-               % JERRY_SNAPSHOT_VERSION)
-        exit(1)
-
-    code_ptr = header[3] + 4
-
-    while code_ptr < len(code):
-        length = struct.unpack('H', code[code_ptr : code_ptr + 2])[0]
-        code_ptr = code_ptr + 2
-        if length == 0:
-            continue
-        if length < 32:
-            item = struct.unpack('%ds' % length,
-                                 code[code_ptr : code_ptr + length])
-            literals.add(force_str(item[0]))
-        code_ptr = code_ptr + length + (length % 2)
-
-    return literals
-
-
 LICENSE = '''
 /* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors
  *
@@ -218,7 +184,7 @@ def merge_snapshots(snapshot_infos, snapshot_tool):
     return code
 
 
-def get_snapshot_contents(js_path, snapshot_tool):
+def get_snapshot_contents(js_path, snapshot_tool, literals=None):
     """ Convert the given module with the snapshot generator
         and return the resulting bytes.
     """
@@ -234,18 +200,20 @@ def get_snapshot_contents(js_path, snapshot_tool):
 
         if module_name != "iotjs":
             fwrapped.write("});\n")
-
-    ret = subprocess.call([snapshot_tool,
-                           "generate",
-                           "-o", snapshot_path,
-                           wrapped_path])
+    cmd = [snapshot_tool, "generate", "-o", snapshot_path]
+    if literals:
+        cmd.extend(["--static", "--load-literals-list-format", literals])
+    ret = subprocess.call(cmd + [wrapped_path])
 
     fs.remove(wrapped_path)
     if ret != 0:
-        msg = "Failed to dump %s: - %d" % (js_path, ret)
-        print("%s%s%s" % ("\033[1;31m", msg, "\033[0m"))
-        fs.remove(snapshot_path)
-        exit(1)
+        if literals == None:
+            msg = "Failed to dump %s: - %d" % (js_path, ret)
+            print("%s%s%s" % ("\033[1;31m", msg, "\033[0m"))
+            exit(1)
+        else:
+            print("Unable to create static snapshot from '%s'. Falling back "
+                  "to normal snapshot." % js_path)
 
     return snapshot_path
 
@@ -262,9 +230,52 @@ def get_js_contents(js_path, is_debug_mode=False):
     return code
 
 
-def js2c(buildtype, js_modules, snapshot_tool=None, verbose=False):
-    is_debug_mode = (buildtype == "debug")
+def get_literals_from_snapshots(snapshot_tool, snapshot_list):
+    literals_path = fs.join(path.SRC_ROOT, 'js', 'literals.list')
+    cmd = [snapshot_tool, "litdump", "-o", literals_path]
+    cmd.extend(snapshot_list)
+
+    ret = subprocess.call(cmd)
+
+    if ret != 0:
+        msg = "Failed to dump the literals: - %d" % ret
+        print("%s%s%s" % ("\033[1;31m", msg, "\033[0m"))
+        exit(1)
+
+    return literals_path
+
+
+def read_literals(literals_path):
+    literals_set = set()
+    with open(literals_path, 'rb') as fin:
+        num = ''
+        while True:
+            c = normalize_str(fin.read(1))
+            if not c:
+                break
+            elif c == ' ':
+                text = normalize_str(fin.read(int(num)))
+                literals_set.add(text)
+                num = ''
+            else:
+                num += c
+
+    return literals_set
+
+
+def write_literals_to_file(literals_set, literals_path):
+    sorted_lit = sorted(literals_set, key=lambda x: (len(x), x))
+    with open(literals_path, 'wb') as flit:
+        for lit in sorted_lit:
+            entry = "%d %s\n" % (len(lit), lit)
+            flit.write(entry.encode('utf-8'))
+
+
+def js2c(options, js_modules):
+    is_debug_mode = (options.buildtype == "debug")
+    snapshot_tool = options.snapshot_tool
     no_snapshot = (snapshot_tool == None)
+    verbose = options.verbose
     magic_string_set = set()
 
     str_const_regex = re.compile('^#define IOTJS_MAGIC_STRING_\w+\s+"(\w+)"$')
@@ -285,13 +296,13 @@ def js2c(buildtype, js_modules, snapshot_tool=None, verbose=False):
 
         snapshot_infos = []
         js_module_names = []
-        for idx, module in enumerate(sorted(js_modules)):
-            [name, js_path] = module.split('=', 1)
-            js_module_names.append(name)
-            if verbose:
-                print('Processing module: %s' % name)
+        if no_snapshot:
+            for idx, module in enumerate(sorted(js_modules)):
+                [name, js_path] = module.split('=', 1)
+                js_module_names.append(name)
+                if verbose:
+                    print('Processing module: %s' % name)
 
-            if no_snapshot:
                 code = get_js_contents(js_path, is_debug_mode)
                 code_string = format_code(code, 1)
 
@@ -300,25 +311,49 @@ def js2c(buildtype, js_modules, snapshot_tool=None, verbose=False):
                                                        NAME_UPPER=name.upper(),
                                                        SIZE=len(code),
                                                        CODE=code_string))
-            else:
+            modules_struct = [
+               '  {{ {0}_n, {0}_s, SIZE_{1} }},'.format(name, name.upper())
+               for name in sorted(js_module_names)
+            ]
+            modules_struct.append('  { NULL, NULL, 0 }')
+            native_struct_h = NATIVE_STRUCT_H
+        else:
+            # Generate snapshot files from JS files
+            for idx, module in enumerate(sorted(js_modules)):
+                [name, js_path] = module.split('=', 1)
+                js_module_names.append(name)
+                if verbose:
+                    print('Processing (1st phase) module: %s' % name)
                 code_path = get_snapshot_contents(js_path, snapshot_tool)
                 info = {'name': name, 'path': code_path, 'idx': idx}
                 snapshot_infos.append(info)
 
+            # Get the literal list from the snapshots
+            if verbose:
+                print('Creating literal list file for static snapshot '
+                      'creation')
+            literals_path = get_literals_from_snapshots(snapshot_tool,
+                [info['path'] for info in snapshot_infos])
+            magic_string_set |= read_literals(literals_path)
+            # Update the literals list file
+            write_literals_to_file(magic_string_set, literals_path)
+
+            # Generate static-snapshots if possible
+            for idx, module in enumerate(sorted(js_modules)):
+                [name, js_path] = module.split('=', 1)
+                if verbose:
+                    print('Processing (2nd phase) module: %s' % name)
+
+                get_snapshot_contents(js_path, snapshot_tool, literals_path)
+
                 fout_h.write(MODULE_SNAPSHOT_VARIABLES_H.format(NAME=name))
                 fout_c.write(MODULE_SNAPSHOT_VARIABLES_C.format(NAME=name,
                                                                 IDX=idx))
+            fs.remove(literals_path)
 
-        if no_snapshot:
-            modules_struct = [
-               '  {{ {0}_n, {0}_s, SIZE_{1} }},'.format(name, name.upper())
-               for name in sorted(js_module_names)
-            ]
-            modules_struct.append('  { NULL, NULL, 0 }')
-        else:
+            # Merge the snapshot files
             code = merge_snapshots(snapshot_infos, snapshot_tool)
             code_string = format_code(code, 1)
-            magic_string_set |= parse_literals(code)
 
             name = 'iotjs_js_modules'
             fout_h.write(MODULE_VARIABLES_H.format(NAME=name))
@@ -331,10 +366,6 @@ def js2c(buildtype, js_modules, snapshot_tool=None, verbose=False):
                 for info in snapshot_infos
             ]
             modules_struct.append('  { NULL, 0 }')
-
-        if no_snapshot:
-            native_struct_h = NATIVE_STRUCT_H
-        else:
             native_struct_h = NATIVE_SNAPSHOT_STRUCT_H
 
         fout_h.write(native_struct_h)
@@ -352,7 +383,7 @@ def js2c(buildtype, js_modules, snapshot_tool=None, verbose=False):
         sorted_strings = sorted(magic_string_set, key=lambda x: (len(x), x))
         for idx, magic_string in enumerate(sorted_strings):
             magic_text = repr(magic_string)[1:-1]
-            magic_text = magic_text.replace('"', '\"')
+            magic_text = magic_text.replace('"', '\\"')
 
             fout_magic_str.write('  MAGICSTR_EX_DEF(MAGIC_STR_%d, "%s") \\\n'
                                  % (idx, magic_text))
@@ -384,5 +415,5 @@ if __name__ == "__main__":
     else:
         print('Using "%s" as snapshot tool' % options.snapshot_tool)
 
-    modules = options.modules.replace(',', ' ').split()
-    js2c(options.buildtype, modules, options.snapshot_tool, options.verbose)
+    modules = options.modules.split(',')
+    js2c(options, modules)
index 02957a87a7fc7806893cb19904423050751b5770..a44f506e7be176389ee0c51a0f497ba8b6884758 100755 (executable)
@@ -18,19 +18,25 @@ from __future__ import print_function
 
 import argparse
 import json
+import multiprocessing
 import os
-import signal
 import subprocess
 import sys
 import time
 
+try:
+    import queue
+except ImportError:
+    # Backwards compatibility
+    import Queue as queue
+
+
 from collections import OrderedDict
 from common_py import path
 from common_py.system.filesystem import FileSystem as fs
-from common_py.system.executor import Executor as ex
+from common_py.system.executor import Executor
+from common_py.system.executor import Terminal
 from common_py.system.platform import Platform
-from jsonmerge import Merger
-
 
 # Defines the folder that will contain the coverage info.
 # The path must be consistent with the measure_coverage.sh script.
@@ -55,15 +61,6 @@ process.on('exit', function() {{
 """
 )
 
-JSON_SCHEMA = {
-                "properties": {
-                    "run_pass": {
-                        "mergeStrategy": "arrayMergeById",
-                        "mergeOptions": { "idRef": "name"}
-                    }
-                }
-}
-
 # Append coverage source to the appropriate test.
 def append_coverage_code(testfile, coverage):
     if not coverage:
@@ -93,25 +90,25 @@ def remove_coverage_code(testfile, coverage):
 
 class Reporter(object):
     @staticmethod
-    def message(msg="", color=ex._TERM_EMPTY):
-        print("%s%s%s" % (color, msg, ex._TERM_EMPTY))
+    def message(msg="", color=Terminal.empty):
+        print("%s%s%s" % (color, msg, Terminal.empty))
 
     @staticmethod
     def report_testset(testset):
         Reporter.message()
-        Reporter.message("Testset: %s" % testset, ex._TERM_BLUE)
+        Reporter.message("Testset: %s" % testset, Terminal.blue)
 
     @staticmethod
     def report_pass(test, time):
-        Reporter.message("  PASS: %s (%ss)" % (test, time), ex._TERM_GREEN)
+        Reporter.message("  PASS: %s (%ss)" % (test, time), Terminal.green)
 
     @staticmethod
     def report_fail(test, time):
-        Reporter.message("  FAIL: %s (%ss)" % (test, time), ex._TERM_RED)
+        Reporter.message("  FAIL: %s (%ss)" % (test, time), Terminal.red)
 
     @staticmethod
     def report_timeout(test):
-        Reporter.message("  TIMEOUT: %s" % test, ex._TERM_RED)
+        Reporter.message("  TIMEOUT: %s" % test, Terminal.red)
 
     @staticmethod
     def report_skip(test, reason):
@@ -120,7 +117,7 @@ class Reporter(object):
         if reason:
             skip_message += "   (Reason: %s)" % reason
 
-        Reporter.message(skip_message, ex._TERM_YELLOW)
+        Reporter.message(skip_message, Terminal.yellow)
 
     @staticmethod
     def report_configuration(testrunner):
@@ -135,47 +132,38 @@ class Reporter(object):
     @staticmethod
     def report_final(results):
         Reporter.message()
-        Reporter.message("Finished with all tests:", ex._TERM_BLUE)
-        Reporter.message("  PASS:    %d" % results["pass"], ex._TERM_GREEN)
-        Reporter.message("  FAIL:    %d" % results["fail"], ex._TERM_RED)
-        Reporter.message("  TIMEOUT: %d" % results["timeout"], ex._TERM_RED)
-        Reporter.message("  SKIP:    %d" % results["skip"], ex._TERM_YELLOW)
-
-
-class TimeoutException(Exception):
-    pass
-
-
-def alarm_handler(signum, frame):
-    raise TimeoutException
+        Reporter.message("Finished with all tests:", Terminal.blue)
+        Reporter.message("  PASS:    %d" % results["pass"], Terminal.green)
+        Reporter.message("  FAIL:    %d" % results["fail"], Terminal.red)
+        Reporter.message("  TIMEOUT: %d" % results["timeout"], Terminal.red)
+        Reporter.message("  SKIP:    %d" % results["skip"], Terminal.yellow)
 
 
 class TestRunner(object):
     def __init__(self, options):
+        self._process_pool = multiprocessing.Pool(processes=1)
         self.iotjs = fs.abspath(options.iotjs)
         self.quiet = options.quiet
-        self.testsets = options.testsets
+        self.platform = options.platform
         self.timeout = options.timeout
         self.valgrind = options.valgrind
         self.coverage = options.coverage
         self.skip_modules = []
         self.results = {}
-        self._environment = os.environ.copy()
-        self._environment["IOTJS_PATH"] = fs.dirname(self.iotjs)
+        self._msg_queue = multiprocessing.Queue(1)
 
         if options.skip_modules:
             self.skip_modules = options.skip_modules.split(",")
 
         # Process the iotjs build information.
-        iotjs_output = ex.check_run_cmd_output(self.iotjs,
-                                    [path.BUILD_INFO_PATH])
+        iotjs_output = Executor.check_run_cmd_output(self.iotjs,
+                                                     [path.BUILD_INFO_PATH])
         build_info = json.loads(iotjs_output)
 
-        self.builtins = build_info["builtins"]
+        self.builtins = set(build_info["builtins"])
+        self.features = set(build_info["features"])
         self.stability = build_info["stability"]
 
-        # Define own alarm handler to handle timeout.
-        signal.signal(signal.SIGALRM, alarm_handler)
 
     def run(self):
         Reporter.report_configuration(self)
@@ -190,13 +178,6 @@ class TestRunner(object):
         with open(fs.join(path.TEST_ROOT, "testsets.json")) as testsets_file:
             testsets = json.load(testsets_file, object_pairs_hook=OrderedDict)
 
-        if self.testsets:
-            with open(fs.join(path.TEST_ROOT, self.testsets)) as testsets_file:
-                ext_testsets = json.load(testsets_file,
-                                         object_pairs_hook=OrderedDict)
-                merger = Merger(JSON_SCHEMA)
-                testsets = merger.merge(testsets, ext_testsets)
-
         for testset, tests in testsets.items():
             self.run_testset(testset, tests)
 
@@ -228,11 +209,11 @@ class TestRunner(object):
                 continue
 
             # Show the output.
-            if not self.quiet:
-                print(output, end="")
+            if not self.quiet and output:
+                print(output.decode("utf8"), end="")
 
             is_normal_run = (not expected_failure and exitcode == 0)
-            is_expected_fail = (expected_failure and exitcode <= 2)
+            is_expected_fail = (expected_failure and exitcode in [1, 2])
             if is_normal_run or is_expected_fail:
                 Reporter.report_pass(test["name"], runtime)
                 self.results["pass"] += 1
@@ -240,6 +221,17 @@ class TestRunner(object):
                 Reporter.report_fail(test["name"], runtime)
                 self.results["fail"] += 1
 
+    @staticmethod
+    def run_subprocess(parent_queue, command):
+        process = subprocess.Popen(args=command,
+                                   cwd=path.TEST_ROOT,
+                                   stdout=subprocess.PIPE,
+                                   stderr=subprocess.STDOUT)
+
+        stdout = process.communicate()[0]
+        exitcode = process.returncode
+
+        parent_queue.put_nowait([exitcode, stdout])
 
     def run_test(self, testfile, timeout):
         command = [self.iotjs, testfile]
@@ -253,55 +245,61 @@ class TestRunner(object):
 
             command = ["valgrind"] + valgrind_options + command
 
-        signal.alarm(timeout)
-
         try:
+            process = multiprocessing.Process(target=TestRunner.run_subprocess,
+                                              args=(self._msg_queue, command,))
             start = time.time()
-            process = subprocess.Popen(args=command,
-                                       cwd=path.TEST_ROOT,
-                                       stdout=subprocess.PIPE,
-                                       stderr=subprocess.STDOUT,
-                                       env=self._environment)
-
-            stdout = process.communicate()[0]
-            exitcode = process.returncode
+            process.start()
+            process.join(timeout)
             runtime = round((time.time() - start), 2)
 
-            signal.alarm(0)
+            if process.is_alive():
+                raise multiprocessing.TimeoutError("Test still running")
+
+            # At this point the queue must have data!
+            # If not then it is also a timeout event
+            exitcode, stdout = self._msg_queue.get_nowait()
 
-        except TimeoutException:
-            process.kill()
+        except (multiprocessing.TimeoutError, queue.Full):
+            process.terminate()
             return -1, None, None
 
         return exitcode, stdout, runtime
 
     def skip_test(self, test):
-        skip_list = test.get("skip", [])
+        skip_list = set(test.get("skip", []))
 
         # Skip by the `skip` attribute in testsets.json file.
-        for i in ["all", Platform().os(), self.stability]:
+        for i in ["all", self.platform, self.stability]:
             if i in skip_list:
                 return True
 
-        name_parts = test["name"][0:-3].split('_')
+        required_modules = set(test.get("required-modules", []))
+        required_features = set(test.get("required-features", []))
 
-        # Test filename does not start with 'test_' so we'll just
-        # assume we support it.
-        if name_parts[0] != 'test':
-            return False
+        unsupported_modules = required_modules - self.builtins
+        unsupported_features = required_features - self.features
+        skipped_modules = required_modules.intersection(skip_list)
 
-        tested_module = name_parts[1]
+        # Skip the test if the tested module requires a module
+        # which is not compiled into the binary
+        if unsupported_modules:
+            test["reason"] = "Required module(s) unsupported by iotjs build: "
+            test["reason"] += ', '.join(sorted(unsupported_modules))
+            return True
 
-        # Skip the test if it requires a module that is defined by
-        # the `--skip-modules` flag.
-        if tested_module in self.skip_modules:
-            test["reason"] = "the required module is skipped by testrunner"
+        # Skip the test if it requires a module that is skipped by the
+        # testrunner
+        if skipped_modules:
+            test["reason"] = "Required module(s) skipped by testrunner: "
+            test["reason"] += ', '.join(sorted(skipped_modules))
             return True
 
-        # Skip the test if it requires a module that is not
-        # compiled into the binary.
-        if tested_module not in self.builtins:
-            test["reason"] = "unsupported module by iotjs build"
+        # Skip the test if it uses features which are
+        # unavailable in the current iotjs build
+        if unsupported_features:
+            test["reason"] = "Required feature(s) unsupported by iotjs build: "
+            test["reason"] += ', '.join(sorted(unsupported_features))
             return True
 
         return False
@@ -312,13 +310,12 @@ def get_args():
 
     parser.add_argument("iotjs", action="store",
                         help="path to the iotjs binary file")
+    parser.add_argument('--platform', default=Platform().os(),
+                        help='Specify the platform (default: %(default)s)')
     parser.add_argument("--quiet", action="store_true", default=False,
                         help="show or hide the output of the tests")
     parser.add_argument("--skip-modules", action="store", metavar='list',
                         help="module list to skip test of specific modules")
-    parser.add_argument("--testsets", action="store",
-                        help="JSON file to extend or override the default "
-                             "testsets")
     parser.add_argument("--timeout", action="store", default=300, type=int,
                         help="default timeout for the tests in seconds")
     parser.add_argument("--valgrind", action="store_true", default=False,
index c85fb70f0e3e5b86d42907e734e2283377446613..49423edb27cc9fa4e52b418c81fd8533a8a92f73 100755 (executable)
@@ -31,15 +31,20 @@ TRAVIS_BUILD_PATH = fs.join(os.environ['TRAVIS_BUILD_DIR'])
 # IoT.js path in docker
 DOCKER_IOTJS_PATH = fs.join(DOCKER_ROOT_PATH, 'work_space/iotjs')
 
+# Node server path in docker
+DOCKER_NODE_SERVER_PATH = fs.join(DOCKER_ROOT_PATH, 'work_space/node_server')
+
 DOCKER_TIZENRT_PATH = fs.join(DOCKER_ROOT_PATH, 'TizenRT')
 DOCKER_TIZENRT_OS_PATH = fs.join(DOCKER_TIZENRT_PATH, 'os')
 DOCKER_TIZENRT_OS_TOOLS_PATH = fs.join(DOCKER_TIZENRT_OS_PATH, 'tools')
 
-DOCKER_NUTTX_PATH =fs.join(DOCKER_ROOT_PATH, 'nuttx')
+DOCKER_NUTTX_PATH = fs.join(DOCKER_ROOT_PATH, 'nuttx')
+DOCKER_NUTTX_TOOLS_PATH = fs.join(DOCKER_NUTTX_PATH, 'tools')
+DOCKER_NUTTX_APPS_PATH = fs.join(DOCKER_ROOT_PATH, 'apps')
 
 DOCKER_NAME = 'iotjs_docker'
 BUILDTYPES = ['debug', 'release']
-TIZENRT_TAG = '1.1_Public_Release'
+TIZENRT_TAG = '2.0_Public_M2'
 
 # Common buildoptions for sanitizer jobs.
 BUILDOPTIONS_SANITIZER = [
@@ -52,7 +57,6 @@ BUILDOPTIONS_SANITIZER = [
     '--no-check-valgrind',
     '--no-snapshot',
     '--profile=test/profiles/host-linux.profile',
-    '--testsets=testsets-host-linux.json',
     '--run-test=full',
     '--target-arch=i686'
 ]
@@ -61,27 +65,50 @@ def run_docker():
     ex.check_run_cmd('docker', ['run', '-dit', '--privileged',
                      '--name', DOCKER_NAME, '-v',
                      '%s:%s' % (TRAVIS_BUILD_PATH, DOCKER_IOTJS_PATH),
-                     'iotjs/ubuntu:0.6'])
+                     '--add-host', 'test.mosquitto.org:127.0.0.1',
+                     '--add-host', 'echo.websocket.org:127.0.0.1',
+                     '--add-host', 'httpbin.org:127.0.0.1',
+                     'iotjs/ubuntu:0.9'])
 
-def exec_docker(cwd, cmd):
+def exec_docker(cwd, cmd, env=[], is_background=False):
     exec_cmd = 'cd %s && ' % cwd + ' '.join(cmd)
-    ex.check_run_cmd('docker', [
-                     'exec', '-it', DOCKER_NAME, 'bash', '-c', exec_cmd])
+    if is_background:
+        docker_args = ['exec', '-dit']
+    else:
+        docker_args = ['exec', '-it']
+
+    for e in env:
+        docker_args.append('-e')
+        docker_args.append(e)
+
+    docker_args += [DOCKER_NAME, 'bash', '-c', exec_cmd]
+    ex.check_run_cmd('docker', docker_args)
 
-def set_release_config_tizenrt():
+def start_mosquitto_server():
+    exec_docker(DOCKER_ROOT_PATH, ['mosquitto', '-d'])
+
+def start_node_server():
+    exec_docker(DOCKER_NODE_SERVER_PATH, ['node', 'server.js'], [], True)
+
+def set_config_tizenrt(buildtype):
     exec_docker(DOCKER_ROOT_PATH, [
-                'cp', 'tizenrt_release_config',
+                'cp',
+                fs.join(DOCKER_IOTJS_PATH,
+                        'config/tizenrt/artik05x/configs/',
+                        buildtype, 'defconfig'),
                 fs.join(DOCKER_TIZENRT_OS_PATH, '.config')])
 
-def build_iotjs(buildtype, args=[]):
+def build_iotjs(buildtype, args=[], env=[]):
     exec_docker(DOCKER_IOTJS_PATH, [
                 './tools/build.py',
                 '--clean',
-                '--buildtype=' + buildtype] + args)
+                '--buildtype=' + buildtype] + args, env)
 
 if __name__ == '__main__':
     if os.getenv('RUN_DOCKER') == 'yes':
         run_docker()
+        start_mosquitto_server()
+        start_node_server()
 
     test = os.getenv('OPTS')
     if test == 'host-linux':
@@ -89,14 +116,19 @@ if __name__ == '__main__':
             build_iotjs(buildtype, [
                         '--cmake-param=-DENABLE_MODULE_ASSERT=ON',
                         '--run-test=full',
-                        '--profile=profiles/minimal.profile',
-                        '--testsets=testsets-minimal.json'])
+                        '--profile=profiles/minimal.profile'])
 
         for buildtype in BUILDTYPES:
             build_iotjs(buildtype, [
                         '--run-test=full',
-                        '--profile=test/profiles/host-linux.profile',
-                        '--testsets=testsets-host-linux.json'])
+                        '--profile=test/profiles/host-linux.profile'])
+
+    elif test == 'mock-linux':
+        for buildtype in BUILDTYPES:
+            build_iotjs(buildtype, [
+                        '--run-test=full',
+                        '--target-os=mock',
+                        '--profile=test/profiles/mock-linux.profile'])
 
     elif test == 'rpi2':
         for buildtype in BUILDTYPES:
@@ -106,6 +138,7 @@ if __name__ == '__main__':
                         '--profile=test/profiles/rpi2-linux.profile'])
 
     elif test == 'artik053':
+        exec_docker(DOCKER_TIZENRT_PATH, ['git', 'fetch', '--tags'])
         # Checkout specified tag
         exec_docker(DOCKER_TIZENRT_PATH, ['git', 'checkout', TIZENRT_TAG])
         # Set configure
@@ -113,15 +146,31 @@ if __name__ == '__main__':
                     './configure.sh', 'artik053/iotjs'])
 
         for buildtype in BUILDTYPES:
-            if buildtype == 'release':
-                set_release_config_tizenrt()
+            set_config_tizenrt(buildtype)
             exec_docker(DOCKER_TIZENRT_OS_PATH, [
-                        'make', 'IOTJS_ROOT_DIR=' + DOCKER_IOTJS_PATH,
-                        'IOTJS_BUILD_OPTION='
-                        '--profile=test/profiles/tizenrt.profile'])
+                        'make', 'IOTJS_ROOT_DIR=%s' % DOCKER_IOTJS_PATH,
+                        'IOTJS_BUILD_OPTION="--buildtype=%s '
+                        '--profile=test/profiles/tizenrt.profile"' % buildtype
+                        ])
 
     elif test == 'stm32f4dis':
+        # Copy the application files to apps/system/iotjs.
+        exec_docker(DOCKER_ROOT_PATH, [
+                    'cp', '-r',
+                    fs.join(DOCKER_IOTJS_PATH,'config/nuttx/stm32f4dis/app/'),
+                    fs.join(DOCKER_NUTTX_APPS_PATH, 'system/iotjs/')])
+
+        exec_docker(DOCKER_ROOT_PATH, [
+                    'cp', '-r',
+                    fs.join(DOCKER_IOTJS_PATH,
+                            'config/nuttx/stm32f4dis/config.travis'),
+                    fs.join(DOCKER_NUTTX_PATH,
+                            'configs/stm32f4discovery/usbnsh/defconfig')])
+
         for buildtype in BUILDTYPES:
+            exec_docker(DOCKER_NUTTX_PATH, ['make', 'distclean'])
+            exec_docker(DOCKER_NUTTX_TOOLS_PATH,
+                        ['./configure.sh', 'stm32f4discovery/usbnsh'])
             exec_docker(DOCKER_NUTTX_PATH, ['make', 'clean'])
             exec_docker(DOCKER_NUTTX_PATH, ['make', 'context'])
             # Build IoT.js
@@ -153,14 +202,12 @@ if __name__ == '__main__':
 
     elif test == "misc":
         ex.check_run_cmd('tools/check_signed_off.sh', ['--travis'])
-
-        exec_docker(DOCKER_IOTJS_PATH, ['tools/check_tidy.py'])
+        ex.check_run_cmd('tools/check_tidy.py')
 
     elif test == "external-modules":
         for buildtype in BUILDTYPES:
             build_iotjs(buildtype, [
                         '--run-test=full',
-                        '--testsets=testsets-external-modules.json',
                         '--profile=test/profiles/host-linux.profile',
                         '--external-modules=test/external_modules/'
                         'mymodule1,test/external_modules/mymodule2',
@@ -171,8 +218,7 @@ if __name__ == '__main__':
         for buildtype in BUILDTYPES:
             build_iotjs(buildtype, [
                         '--run-test=full',
-                        '--jerry-profile=es2015-subset',
-                        '--testsets=testsets-es2015.json'])
+                        '--jerry-profile=es2015-subset'])
 
     elif test == "no-snapshot":
         for buildtype in BUILDTYPES:
@@ -185,19 +231,22 @@ if __name__ == '__main__':
                              '--run-test=full',
                              '--buildtype=' + buildtype,
                              '--clean',
-                             '--profile=test/profiles/host-darwin.profile',
-                             '--testsets=testsets-host-linux.json'])
+                             '--profile=test/profiles/host-darwin.profile'])
 
     elif test == "asan":
-        ex.check_run_cmd('./tools/build.py', [
-                         '--compile-flag=-fsanitize=address',
-                         '--compile-flag=-O2'
-                         ] + BUILDOPTIONS_SANITIZER)
+        build_iotjs('debug', [
+                    '--compile-flag=-fsanitize=address',
+                    '--compile-flag=-O2'
+                    ] + BUILDOPTIONS_SANITIZER,
+                    ['ASAN_OPTIONS=detect_stack_use_after_return=1:'
+                    'check_initialization_order=true:strict_init_order=true',
+                    'TIMEOUT=600'])
 
     elif test == "ubsan":
-        ex.check_run_cmd('./tools/build.py', [
-                         '--compile-flag=-fsanitize=undefined'
-                         ] + BUILDOPTIONS_SANITIZER)
+        build_iotjs('debug', [
+                    '--compile-flag=-fsanitize=undefined'
+                    ] + BUILDOPTIONS_SANITIZER,
+                    ['UBSAN_OPTIONS=print_stacktrace=1', 'TIMEOUT=600'])
 
     elif test == "coverity":
         ex.check_run_cmd('./tools/build.py', ['--clean'])