diff --git a/.gitignore b/.gitignore index 625612e..4886176 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ tests/* !tests/.testsuite.php !tests/.v8-helpers.php !tests/.tracking_dtors.php +!tests/stubs .deps *.lo @@ -13,6 +14,7 @@ acinclude.m4 aclocal.m4 autom4te.cache build +confdefs.h config.guess config.h config.h.in @@ -27,7 +29,7 @@ configure.ac install-sh libtool ltmain.sh -Makefile +/Makefile Makefile.fragments Makefile.global Makefile.objects @@ -40,3 +42,5 @@ tmp-php.ini /conftest* /*.tgz +.virtualenv + diff --git a/.travis.yml b/.travis.yml index ac02d35..3a78b48 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,41 +1,24 @@ -sudo: required dist: trusty +sudo: required -language: php - -php: - - 7.0 - - 7.1 - - nightly - -matrix: - allow_failures: - - php: nightly +services: + - docker env: global: - - NO_INTERACTION=1 - - TEST_TIMEOUT=120 + - V8=6.6.313 matrix: - - V8=6.2 - - V8=6.2 TEST_PHP_ARGS=-m + - PHP=7.2 + - PHP=7.2 TEST_PHP_ARGS=-m before_install: - - sudo add-apt-repository ppa:pinepain/libv8-${V8} -y - - sudo apt-get update -q - - sudo apt-get install -y libv8-${V8}-dev - - php -i - - php-config || true - -before_script: - - echo 'variables_order = "EGPCS"' >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini - - phpize && ./configure && make + # docker on travis doesn't allow anything before FROM, let's fix that + - sed -i -e "s/:latest/:${V8}/g" Dockerfile + - docker build -t ${TRAVIS_REPO_SLUG} --build-arg PHP=${PHP} . script: - - sh -c "make test | tee result.txt" - - sh test-report.sh - -addons: - apt: - packages: - - valgrind + - docker run + -e TEST_PHP_ARGS + -v `pwd`:/root/php-v8 + ${TRAVIS_REPO_SLUG} + bash -c "phpize && ./configure && make test | tee result.txt; ./test-report.sh" diff --git a/CMakeLists.txt b/CMakeLists.txt index a1ff7df..ac962e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,8 +3,8 @@ project(php-v8) # NOTE: This CMake file is just for syntax highlighting in CLion -include_directories(/usr/local/opt/v8@6.2/include) -include_directories(/usr/local/opt/v8@6.2/include/libplatform) +include_directories(/usr/local/opt/v8@6.6/include) +include_directories(/usr/local/opt/v8@6.6/include/libplatform) include_directories(/usr/local/include/php) include_directories(/usr/local/include/php/TSRM) diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..993e418 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,26 @@ +FROM phpv8/libv8:latest + +ARG PHP=7.2 + +ENV DEBIAN_FRONTEND noninteractive +ENV TERM=xterm-256color +ENV LC_ALL=C.UTF-8 +ENV NO_INTERACTION=1 +ENV REPORT_EXIT_STATUS=1 + +RUN echo "deb http://ppa.launchpad.net/ondrej/php/ubuntu xenial main" > /etc/apt/sources.list.d/ondrej-php-xenial.list && \ + apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4F4EA0AAE5267A6C && \ + apt-get update && \ + apt-get install -y valgrind && \ + apt-get install -y php${PHP} php${PHP}-cli php${PHP}-dev php${PHP}-fpm && \ + rm -rf /var/lib/apt/lists/* && \ + echo 'variables_order = "EGPCS"' >> `php --ini | grep "Loaded Configuration File" | awk '{print $4}'` && \ + php -i && \ + php-config || true && \ + mkdir /root/php-v8 + +WORKDIR /root/php-v8 + +#COPY . /root/php-v8 +#RUN phpize && ./configure && make + diff --git a/LICENSE b/LICENSE index e1d5450..31e9a34 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License -Copyright (c) 2015-2017 Bogdan Padalko +Copyright (c) 2015-2018 Bogdan Padalko 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 diff --git a/README.md b/README.md index 41f6893..15c2d96 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,40 @@ # php-v8 PHP extension for V8 JavaScript engine -[![Build Status](https://travis-ci.org/pinepain/php-v8.svg)](https://travis-ci.org/pinepain/php-v8) -[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/pinepain/php-v8/master/LICENSE) +[![Build Status](https://api.travis-ci.org/phpv8/php-v8.svg?branch=master)](https://travis-ci.org/phpv8/php-v8) +[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/phpv8/php-v8/master/LICENSE) +[![Docs](https://readthedocs.org/projects/php-v8/badge/)](https://php-v8.readthedocs.io) -This extension is for PHP 7 only. + +**This extension requires PHP >= 7.2**. Last version that supports PHP 7.1 is v0.2.2 and for PHP 7.0 is v0.1.9. **This extension is still under heavy development and its public API may change without any warning. Use at your own risk.** +Work in progress documentation could be found at https://php-v8.readthedocs.io. You can also use tests and +stubs as reference. + +## Why (aka Rationale) + +This tool solves following domain problems: + + - execute arbitrary untrusted code from user; + - provide restricted/experimental api to end-user; + - allow to use that with scripting/DSL language; + - limit execution time and used memory; + - use common language that is familiar to large audience; + - be well-maintainable and mature. + +By accident (not by design) this tool could also be used to: + + - render React/Vue/Angular components in PHP; + - implement node.js in PHP; + - increase the number of "why", "why not just <...>" questions. + +If you have any other use, feels free to share + ## About -[php-v8](https://github.com/pinepain/php-v8) is a PHP 7.x extension +[php-v8](https://github.com/phpv8/php-v8) is a PHP 7.x extension that brings [V8](https://developers.google.com/v8/intro) JavaScript engine API to PHP with some abstraction in mind and provides an accurate native V8 C++ API implementation available from PHP. @@ -24,7 +48,7 @@ provides an accurate native V8 C++ API implementation available from PHP. - provides a both-way interaction with PHP and V8 objects, arrays and functions; - execution time and memory limits; - multiple isolates and contexts at the same time; - - it works; + - it works. With this extension almost everything that the native V8 C++ API provides can be used. It provides a way to pass PHP scalars, objects and functions to the V8 runtime and specify interactions with passed values (objects and functions only, as scalars @@ -48,12 +72,15 @@ $source = new \V8\StringValue($isolate, "'Hello' + ', World!'"); $script = new \V8\Script($context, $source); $result = $script->run($context); -echo $result->toString($context)->value(), PHP_EOL; +echo $result->value(), PHP_EOL; ``` which will output `Hello, World!`. See how it's shorter and more readable than [that C++ version][v8-hello-world]? And it also doesn't limit you from V8 API utilizing to implement more amazing stuff. +## Quick start + +You can try php-v8 in `phpv8/php-v8`: `docker run -it phpv8/php-v8 bash -c "php test.php"` ## Stub files @@ -61,18 +88,22 @@ If you are also using Composer, it is recommended to add the [php-v8-stub][php-v package as a dev-mode requirement. It provides skeleton definitions and annotations to enable support for auto-completion in your IDE and other code-analysis tools. - composer require --dev pinepain/php-v8-stubs + composer require --dev phpv8/php-v8-stubs + +## High-level wrapper library +There is [phpv8/js-sandbox](https://github.com/phpv8/js-sandbox) library that provides high-level abstraction +on top of php-v8 extension and makes embedding JavaScript in PHP easier. ## Installation ### Requirements #### V8 -You will need a recent v8 Google JavaScript engine version installed. At this time the extension is tested on 6.2.2. +You will need a recent v8 Google JavaScript engine version installed. At this time v8 >= 6.6.313 required. #### PHP -This extension is PHP7-only. It works and tested with both PHP 7.0 and PHP 7.1. +**This extension requires PHP >= 7.2**. Last version that supports PHP 7.1 is v0.2.2 and for PHP 7.0 is v0.1.9. #### OS This extension works and tested on x64 Linux and macOS. As of written it is Ubuntu 16.04 LTS Xenial Xerus, amd64 @@ -86,15 +117,14 @@ and macOS 10.12.5. Windows is not supported at this time. $ sudo add-apt-repository -y ppa:ondrej/php $ sudo add-apt-repository -y ppa:pinepain/php $ sudo apt-get update -y -$ sudo apt-get install -y php7.1 php-v8 +$ sudo apt-get install -y php7.2 php-v8 $ php --ri v8 ``` While [pinepain/php](https://launchpad.net/~pinepain/+archive/ubuntu/php) PPA targets to contain all necessary extensions with dependencies, you may find -[pinepain/libv8-6.2](https://launchpad.net/~pinepain/+archive/ubuntu/libv8-6.2), -[pinepain/libv8-experimental](https://launchpad.net/~pinepain/+archive/ubuntu/libv8-experimental) and -[pinepain/php-v8](https://launchpad.net/~pinepain/+archive/ubuntu/php-v8) standalone PPAs useful. +[pinepain/libv8](https://launchpad.net/~pinepain/+archive/ubuntu/libv8) and +[pinepain/php](https://launchpad.net/~pinepain/+archive/ubuntu/php-v8) standalone PPAs useful. #### OS X (homebrew) @@ -102,17 +132,17 @@ extensions with dependencies, you may find ``` $ brew tap homebrew/dupes $ brew tap homebrew/php -$ brew tap pinepain/devtools -$ brew install php71 php71-v8 +$ brew tap phpv8/tap +$ brew install php72 php72-v8 $ php --ri v8 ``` -For macOS php-v8 formulae and dependencies provided by [pinepain/devtools](https://github.com/pinepain/homebrew-devtools) tap. +For macOS php-v8 formulae and dependencies provided by [phpv8/tap](https://github.com/phpv8/homebrew-tap) tap. ### Building php-v8 from sources ``` -git clone https://github.com/pinepain/php-v8.git +git clone https://github.com/phpv8/php-v8.git cd php-v8 phpize && ./configure && make make test @@ -125,6 +155,7 @@ $ sudo make install ``` ## Developers note + - to be able to customize some tests make sure you have `variables_order = "EGPCS"` in your php.ini - `export DEV_TESTS=1` allows to run tests that are made for development reasons (e.g. test some weird behavior or for debugging) - To prevent the test suite from asking you to send results to the PHP QA team do `export NO_INTERACTION=1` @@ -132,8 +163,30 @@ $ sudo make install - To track memory usage you may want to use `smem`, `pmem` or even `lsof` to see what shared object are loaded and `free` to display free and used memory in the system. - - [pinepain/libv8-experimental](https://launchpad.net/~pinepain/+archive/ubuntu/libv8-experimental) normally contains - `libv8` version that used in current `master` branch. + - [pinepain/experimental](https://launchpad.net/~pinepain/+archive/ubuntu/experimental) may contain `libv8` + version that used in current `master` branch. + +### Docker + +First, let's build docker image `docker build -t phpv8/php-v8 .` that we'll use later for development. By default, +it contains PHP 7.2, though you can change that by passing `--build-arg PHP=MAJOR.MINOR` where MAJOR.MINOR version +present in [ondrej/php](https://launchpad.net/~ondrej/+archive/ubuntu/php) PPA. + +To start playing with php-v8 in docker, run ```docker run -e TEST_PHP_ARGS -v `pwd`:/root/php-v8 -it phpv8/php-v8 bash``. +Now you can build php-v8 as usual with `phpize && ./configure && make`. Don't forget to run `make test`! + +### Docs + +We use [Sphinx](http://www.sphinx-doc.org/en/master/) to buld docs and [Read The Docs](https://readthedocs.org/) to host +it. + +To rebuild docs locally run in a project root: + + virtualenv -p `which python` .virtualenv + source .virtualenv/bin/activate + cd docs + make html + ## Credits @@ -151,11 +204,11 @@ My thanks to the following people and projects, without whom this extension woul ## License -Copyright (c) 2015-2017 Bogdan Padalko <pinepain@gmail.com> +Copyright (c) 2015-2018 Bogdan Padalko <thepinepain@gmail.com> -[php-v8](https://github.com/pinepain/php-v8) PHP extension is licensed under the [MIT license](http://opensource.org/licenses/MIT). +[php-v8](https://github.com/phpv8/php-v8) PHP extension is licensed under the [MIT license](http://opensource.org/licenses/MIT). [v8-hello-world]: https://chromium.googlesource.com/v8/v8/+/master/samples/hello-world.cc [v8-intro]: https://developers.google.com/v8/intro -[php-v8-stubs]: https://github.com/pinepain/php-v8-stubs +[php-v8-stubs]: https://github.com/phpv8/php-v8-stubs diff --git a/Vagrantfile b/Vagrantfile deleted file mode 100644 index 0233d3e..0000000 --- a/Vagrantfile +++ /dev/null @@ -1,26 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -VAGRANTFILE_API_VERSION = "2" - -Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| - config.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'" # Prevent TTY Errors - - config.vm.box = "bento/ubuntu-16.04" - # config.vm.box_check_update = false - - config.vm.network "private_network", ip: "192.168.33.44" - - config.vm.synced_folder ".", "/home/vagrant/php-v8" - - config.vm.provider "virtualbox" do |vb| - # Don't boot with headless mode - # vb.gui = true - - # Use VBoxManage to customize the VM. For example to change memory: - vb.customize ["modifyvm", :id, "--memory", 2048] - vb.customize ["modifyvm", :id, "--cpus", 2] - end - - config.vm.provision "shell", path: './scripts/provision/provision.sh', privileged: false -end diff --git a/book.json b/book.json new file mode 100644 index 0000000..95e6692 --- /dev/null +++ b/book.json @@ -0,0 +1,3 @@ +{ + "root": "./docs" +} diff --git a/config.m4 b/config.m4 index e0fc77c..fff8923 100644 --- a/config.m4 +++ b/config.m4 @@ -2,20 +2,31 @@ PHP_ARG_WITH(v8, for V8 Javascript Engine, [ --with-v8 Include V8 JavaScript Engine]) if test "$PHP_V8" != "no"; then + + AC_MSG_CHECKING([Check for supported PHP versions]) + PHP_REF_FOUND_VERSION=`${PHP_CONFIG} --version` + PHP_REF_FOUND_VERNUM=`${PHP_CONFIG} --vernum` + + if test "$PHP_REF_FOUND_VERNUM" -lt "70200"; then + AC_MSG_ERROR([not supported. PHP version >= 7.2 required (found $PHP_REF_FOUND_VERSION)]) + else + AC_MSG_RESULT([supported ($PHP_REF_FOUND_VERSION)]) + fi + V8_LIB_DIR="" V8_INCLUDE_DIR="" SEARCH_PATH="/usr/local /usr" SEARCH_FOR="include/v8.h" - V8_MIN_API_VERSION_STR=6.2.2 + V8_MIN_API_VERSION_STR=6.6.313 DESIRED_V8_VERSION=`echo "${V8_MIN_API_VERSION_STR}" | $AWK 'BEGIN { FS = "."; } { printf "%s.%s", [$]1, [$]2;}'` # Path where v8 from packages we recommend are installed, it's /opt/libv8-MAJOR.MINOR on Ubuntu - # and /usr/local/opt/v8@MAJOR.MINOR on macOS - PRIORITY_SEARCH_PATH="/opt/libv8-${DESIRED_V8_VERSION} /usr/local/opt/v8@${DESIRED_V8_VERSION}" - SEARCH_PATH="${PRIORITY_SEARCH_PATH} /usr/local /usr" + # and /usr/local/opt/v8@MAJOR.MINOR on macOS. For Docker image it's just /opt/libv8 + PRIORITY_SEARCH_PATH="/opt/libv8-${DESIRED_V8_VERSION} /usr/local/opt/v8@${DESIRED_V8_VERSION} /opt/libv8" + SEARCH_PATH="${PRIORITY_SEARCH_PATH} ${SEARCH_PATH}" if test -r $PHP_V8/$SEARCH_FOR; then V8_ROOT_DIR=$PHP_V8 @@ -106,7 +117,7 @@ if test "$PHP_V8" != "no"; then PHP_SUBST(V8_SHARED_LIBADD) PHP_REQUIRE_CXX() - CPPFLAGS="$CPPFLAGS -std=c++11" + CPPFLAGS="$CPPFLAGS -std=c++14" # On OS X clang reports warnings in zeng_strings.h, like # php/Zend/zend_string.h:326:2: warning: 'register' storage class specifier is deprecated [-Wdeprecated-register] @@ -150,7 +161,7 @@ if test "$PHP_V8" != "no"; then v8.cc \ src/php_v8_a.cc \ src/php_v8_enums.cc \ - src/php_v8_exception.cc \ + src/php_v8_exception_manager.cc \ src/php_v8_ext_mem_interface.cc \ src/php_v8_try_catch.cc \ src/php_v8_message.cc \ @@ -192,17 +203,21 @@ if test "$PHP_V8" != "no"; then src/php_v8_set.cc \ src/php_v8_date.cc \ src/php_v8_regexp.cc \ + src/php_v8_promise.cc \ + src/php_v8_promise_resolver.cc \ + src/php_v8_proxy.cc \ src/php_v8_number_object.cc \ src/php_v8_boolean_object.cc \ src/php_v8_string_object.cc \ src/php_v8_symbol_object.cc \ src/php_v8_template.cc \ src/php_v8_return_value.cc \ - src/php_v8_callback_info.cc \ + src/php_v8_callback_info_interface.cc \ src/php_v8_function_callback_info.cc \ src/php_v8_property_callback_info.cc \ src/php_v8_named_property_handler_configuration.cc \ src/php_v8_indexed_property_handler_configuration.cc \ + src/php_v8_json.cc \ ], $ext_shared, , -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) PHP_ADD_BUILD_DIR($ext_builddir/src) diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..e35d885 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +_build diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..f9f2aa6 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = php-v8 +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..65dfb42 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/stable/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + +# import sys, os +# from sphinx.highlighting import lexers +# from pygments.lexers.web import PhpLexer +# +# +# lexers['php'] = PhpLexer(startinline=True, linenos=1) +# lexers['php-annotations'] = PhpLexer(startinline=True, linenos=1) +# primary_domain = 'php' + + +import sys +import os +import shlex +from sphinx.highlighting import lexers +from pygments.lexers.web import PhpLexer + +lexers['php'] = PhpLexer(startinline=True, linenos=1) + +primary_domain = 'php' +highlight_language = 'php' + +# -- Project information ----------------------------------------------------- + +project = u'php-v8' +copyright = u'2018, Bogdan Padalko' +author = u'Bogdan Padalko' + +# The short X.Y version +version = u'' +# The full version, including alpha/beta/rc tags +release = u'' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.doctest', + 'sphinx.ext.todo', + 'sphinx.ext.coverage', + 'sphinxcontrib.phpdomain' + #'sphinxcontrib.spelling' +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path . +exclude_patterns = [u'_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'php-v8doc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'php-v8.tex', u'php-v8 Documentation', + u'Bogdan Padalko', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'php-v8', u'php-v8 Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'php-v8', u'php-v8 Documentation', + author, 'php-v8', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Extension configuration ------------------------------------------------- + +spelling_word_list_filename='spelling_wordlist.txt' + +# -- Options for todo extension ---------------------------------------------- + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True diff --git a/docs/development/index.rst b/docs/development/index.rst new file mode 100644 index 0000000..48cbf7f --- /dev/null +++ b/docs/development/index.rst @@ -0,0 +1,12 @@ +=============== +Release process +=============== + +Here you can find basics to the release process + + +.. toctree:: + :maxdepth: 3 + + release-php-v8 + release-libv8 diff --git a/docs/development/release-libv8.rst b/docs/development/release-libv8.rst new file mode 100644 index 0000000..7dd34b1 --- /dev/null +++ b/docs/development/release-libv8.rst @@ -0,0 +1,48 @@ +************* +Release libv8 +************* + +Currently Docker is the recommended way to distribute and use both php-v8 and libv8 itself. We also support building +``libv8`` in macOS with Homebrew via `phpv8/tap`_ tap. + +To track v8 changes you can use these links: + +* https://github.com/v8/v8/commits/master/include/v8.h - to keep track on v8 upstream changes +* https://omahaproxy.appspot.com/ - to keep track v8 channel(version) heads and what version is used in chrome + +Building docker image +===================== + +#. Build `phpv8/libv8`_ docker image, tag it with the relevant v8 full version and push to Docker Hub. + Hint: use ``Makefile``. +#. You may want to set proper ``V8`` version in ``php-v8`` by updating it in ``.travis.yml``. + +After docker images rebuilt/published +===================================== + +#. Update min required ``libv8`` version in `php-v8`_ ``config.m4``, ``V8_MIN_API_VERSION_STR=X.Y.Z``. +#. If there was new docker images published, update reference to them in `php-v8`_ ``.travis.yml`` + and in `php-v8`_ ``Dockerfile``, and set proper ``V8`` and ``TAG`` value there. +#. Update reference to ``v8@X.Y`` in `php-v8`_ `CMakeLists.txt` on minor version bump. +#. Also, update references to v8 version in `php-v8`_/scripts/provision/provision.sh, + it's normally could be done by replacing old version with new, e.g. ``6.3`` => ``6.4``. +#. On every version bump update `php-v8`_ ``README.md`` file with proper min v8 version required/tested. +#. **Make sure** you tested `php-v8`_ locally first before pushing to remote, + upgrading v8 could be tricky as it may break BC even in patch releases. +#. Note, that doing all this in a separate branch and merging that later into master is a nice and safe idea + (note, you may skip PR overhead and do fast-forward merge locally to master). +#. Commit message should state that it is v8 version bump, e.g. ``Require libv8 >= X.Y.Z`` +#. Push changes and make sure build is green. If not, fix code/update tests and repeat. + + +Building packages for macOS Homebrew +==================================== + +#. **Skip this step if you are updating v8 patch release version.** If it is a minor version bump, create new ``v8@X.Y`` formula. +#. **Skip this step if you are updating v8 patch release version.** Create new ``v8:X.Y`` Package on bintray for it. +#. Remove/reset formula ``revision`` if it is version bump and not rebuild. +#. Build ``v8@X.Y`` (locally or with TravisCI if it provides relevant macOS version) and publish. + +.. _php-v8: https://github.com/phpv8/php-v8 +.. _phpv8/libv8: https://github.com/phpv8/dockerfiles/tree/master/libv8 +.. _phpv8/tap: https://github.com/phpv8/homebrew-tap diff --git a/docs/development/release-php-v8.rst b/docs/development/release-php-v8.rst new file mode 100644 index 0000000..4f03ba3 --- /dev/null +++ b/docs/development/release-php-v8.rst @@ -0,0 +1,51 @@ +************** +Release php-v8 +************** + +GitHub release +============== + +#. Make sure current state is ready for release: + + - All relevant PR merged and issues closed. + - Build passed. + +#. Prepare release notes by creating release draft on github. +#. Update ``PHP_V8_VERSION`` to have desired version and set ``PHP_V8_REVISION`` to ``release`` in ``php_v8.h``. +#. Run ``./scripts/refresh-package-xml.php -f`` to update ``package.xml`` with proper ``php-v8`` version and update directories + and files tree. +#. Update ``package.xml`` ```` with release notes. Keep eye on special characters to properly escape them, + e.g. ``>`` should be written as ``>`` instead. +#. Commit all changes with ``Prepare X.Y.Z release`` commit message. +#. Push this commit and make sure it will pass the build. +#. Tag it with ``vX.Y.Z`` tag and push. Create github release from a draft prepared in step above. +#. Close relevant milestone, if any. +#. Run ``./scripts/subsplit.sh`` to update ``php-v8-stubs`` which are available in a separate read-only repository to match + packagist and composer expectations. + +PECL release +============ + +#. Run ``pecl package`` in your build machine (it's normally vagrant box used for ``php-v8`` development). It should create + ``v8-X.Y.Z.tgz`` file. +#. Log in to PECL and upload file from previous step at https://pecl.php.net/release-upload.php. Verify that release info + is accurate and confirm release. + +Docker image release +==================== + +#. Go into `pinepain/dockerfiles `_ ``php-v8`` folder. +#. Make sure you have valid stable and latest versions in ``Makefile``. +#. To avoid caching, run ``make clean-stable`` to remove any image for the current stable version + and ``make clean-latest`` to do the same for the current latest version. +#. Run ``make stable`` to build and upload current stable version + and ``make latest`` to build and upload the latest version. + +After all +========= + +#. Update `js-sandbox`_ dependencies, if required, to use latest ``php-v8`` and other dependencies, if any. +#. Update ``PHP_V8_VERSION`` to the next version and set ``PHP_V8_REVISION`` to ``dev`` in ``php_v8.h``. +#. Commit changes with ``Back to dev [skip ci]`` message and push them to master. + +.. _js-sandbox: https://github.com/pinepain/js-sandbox diff --git a/docs/getting-started/index.rst b/docs/getting-started/index.rst new file mode 100644 index 0000000..fc10ce0 --- /dev/null +++ b/docs/getting-started/index.rst @@ -0,0 +1,152 @@ +*************** +Getting started +*************** + +About +===== + +`php-v8`_ is a PHP 7.x extension that brings `V8`_ JavaScript engine API to PHP with some abstraction in mind and +provides an accurate native V8 C++ API implementation available from PHP. + +Key features: +------------- + + - provides up-to-date JavaScript engine with recent `ECMA`_ features supported; + - accurate native V8 C++ API implementation available from PHP; + - solid experience between native V8 C++ API and V8 API in PHP; + - no magic; no assumptions; + - does what it is asked to do; + - hides complexity with isolates and contexts scope management under the hood; + - provides a both-way interaction with PHP and V8 objects, arrays and functions; + - execution time and memory limits; + - multiple isolates and contexts at the same time; + - it works. + +With this extension almost everything that the native V8 C++ API provides can be used. It provides a way to pass PHP scalars, +objects and functions to the V8 runtime and specify interactions with passed values (objects and functions only, as scalars +become js scalars too). While specific functionality will be done in PHP user space rather than in this C/C++ extension, +it lets you get into V8 hacking faster, reduces time costs and gives you a more maintainable solution. And it doesn't +make any assumptions for you, so you stay in control, it does exactly what you ask it to do. + +With php-v8 you can even implement NodeJs in PHP. Not sure whether anyone should/will do this anyway, but it's doable. + +Demo +==== + +Here is a `Hello World`_ from V8 `Getting Started` developers guide page implemented in raw php-v8: + +.. code:: php + + run($context); + + echo $result->value(), PHP_EOL; + +Installation +============ + + +Requirements +------------ + +V8 +"" + +You will need a recent v8 Google JavaScript engine version installed. At this time v8 >= 6.6.313 required. + +PHP +""" + +**This extension requires PHP >= 7.2**. Last version that supports PHP 7.1 is v0.2.2 and for PHP 7.0 is v0.1.9. + + +OS +""" + +This extension works and tested on x64 Linux and macOS. As of written it is Ubuntu 16.04 LTS Xenial Xerus, amd64 +and macOS 10.12.5. Windows is not supported at this time. + +Quick guide +----------- + +Docker +"""""" + +There is default ``phpv8/php-v8`` docker image with basic dependencies to evaluate and play with php-v8: + +.. code-block:: bash + + docker run -it phpv8/php-v8 bash -c "php test.php" + + +Ubuntu +"""""" + +There is + +.. code-block:: bash + + $ sudo add-apt-repository -y ppa:ondrej/php + $ sudo add-apt-repository -y ppa:pinepain/php + $ sudo apt-get update -y + $ sudo apt-get install -y php7.2 php-v8 + $ php --ri v8 + + +While `pinepain/php `_ PPA targets to contain all necessary +extensions with dependencies, you may find following standalone PPAs useful: + +- `pinepain/libv8-6.6 `_ +- `pinepain/experimental `_ +- `phpv8/php-v8 `_ + + + +OS X (homebrew) +""""""""""""""" + +.. code-block:: bash + + $ brew tap homebrew/dupes + $ brew tap homebrew/php + $ brew tap phpv8/tap + $ brew install php71 php71-v8 + $ php --ri v8 + +For macOS php-v8 formulae and dependencies provided by `phpv8/tap `_ tap. + +Building php-v8 from sources +---------------------------- + +.. code-block:: bash + + git clone https://github.com/phpv8/php-v8.git + cd php-v8 + phpize && ./configure && make + make test + +To install extension globally run + +.. code-block:: bash + + $ sudo make install + +.. _V8: https://developers.google.com/v8/intro +.. _php-v8: https://github.com/phpv8/php-v8 +.. _Hello World: https://chromium.googlesource.com/v8/v8/+/master/samples/hello-world.cc +.. _Getting Started: https://developers.google.com/v8/intro +.. _php-v8-stubs: https://github.com/phpv8/php-v8-stubs +.. _ECMA: http://kangax.github.io/compat-table diff --git a/docs/getting-started/performance-tricks.rst b/docs/getting-started/performance-tricks.rst new file mode 100644 index 0000000..c8c2076 --- /dev/null +++ b/docs/getting-started/performance-tricks.rst @@ -0,0 +1,266 @@ +****************** +Performance tricks +****************** + +If you: + + * use ``php-v8`` extension for short-lived tasks or + * you have your :class:`Context` short-lived + +it is likely that you won't be able benefit from ``V8`` runtime optimizations. +However, you can still improve your performance. + +*Important note*: all caching techniques are V8 version-specific and platform specific, some caches won't even work on +different CPU with different instructions set, you have to test following techniques for your environment and +infrastructure and be ready to fallback to raw, cache-less flow. + + +Let's say you have an typical Hello, world! script: + +.. code:: php + + run($context); + + echo $result->value(), PHP_EOL; + +Let's reshape it a bit to make it more suitable for further tweaks by introducing :class:`ScriptCompiler`: + +.. code:: php + + run($context); + + echo $result->value(), PHP_EOL; + +Script code cache +================= + +Using script code cache could boost your performance from 5% to 25% or even more, itlargely depends on your script and +host. On slower machines it may give you better result in terms of performance gain %%, while on faster it may be not so +large, according to performance benchmark. + +.. code:: php + + isRejected()) { + throw new RuntimeException('Script code cache rejected!'); + } + + $result = $script->run($context); + + echo $result->value(), PHP_EOL; + + +Isolate startup data +==================== + +Startup data can speedup your context creation by populating them with script run result. It can save from 1% to 3%, so +it's not so effective as script code cache, however, the benchmark was done on using quite simple example, +so if you have a lot of entities that you need to bootstrap your context with, your saving may be more. + +.. code:: php + + run($context); + + echo $result->value(), PHP_EOL; + + +Combining both approaches +========================= + +Combining both techniques is you friend in boosting performance: + +.. code:: php + + isRejected()) { + throw new RuntimeException('Script code cache rejected!'); + } + + $script = ScriptCompiler::compile($context, $source); + + $result = $script->run($context); + + echo $result->value(), PHP_EOL; + +Benchmarks +========== + + +Note, that your mileage may varies so you are highly encouraged to run benchmarks located under project's root ``/pref`` +folder by yourself on your hardware, in your infra and even with your js script. + +From Ubuntu in Docker on macOS +------------------------------ +4 cores, 16Gb memory + +.. code:: bash + + # php -v + PHP 7.2.2-3+ubuntu16.04.1+deb.sury.org+1 (cli) (built: Feb 6 2018 16:11:23) ( NTS ) + Copyright (c) 1997-2018 The PHP Group + Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies + with Zend OPcache v7.2.2-3+ubuntu16.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies + + # php --ri v8 + V8 support => enabled + Version => v0.2.1-master-dev + Revision => 5d7c3e4 + Compiled => Feb 25 2018 @ 11:29:00 + + V8 Engine Compiled Version => 6.6.313 + V8 Engine Linked Version => 6.6.313 + + +*Less is better* + ++---------------------------------+-------------+----------+--------+---------------------------+ +| subject | mode | stdev | rstdev | diff (*less is better*) | ++=================================+=============+==========+========+===========================+ +| Cold Isolate, no code cache | 3,602.599us | 49.778us | 1.38% | +26.98% | ++---------------------------------+-------------+----------+--------+---------------------------+ +| Cold Isolate, with code cache | 2,885.638us | 39.775us | 1.36% | +2.86% | ++---------------------------------+-------------+----------+--------+---------------------------+ +| Warm Isolate, no code cache | 3,489.959us | 44.036us | 1.27% | +22.46% | ++---------------------------------+-------------+----------+--------+---------------------------+ +| Warm Isolate, with code cache | 2,813.156us | 43.351us | 1.53% | 0.00% | ++---------------------------------+-------------+----------+--------+---------------------------+ + +From macOS host +--------------- +4 cores, 16Gb memory + +.. code:: bash + + $ php -v + PHP 7.2.2 (cli) (built: Feb 1 2018 11:50:40) ( NTS ) + Copyright (c) 1997-2018 The PHP Group + Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies + with Zend OPcache v7.2.2, Copyright (c) 1999-2018, by Zend Technologies + + $ php --ri v8 + V8 support => enabled + Version => v0.2.1-master-dev + Revision => 5d7c3e4 + Compiled => Feb 25 2018 @ 11:42:00 + + V8 Engine Compiled Version => 6.6.313 + V8 Engine Linked Version => 6.6.313 + + + + ++---------------------------------+-------------+-----------+--------+---------------------------+ +| subject | mode | stdev | rstdev | diff (*less is better*) | ++=================================+=============+===========+========+===========================+ +| Cold Isolate, no code cache | 8,732.585us | 97.889us | 1.11% | +6.90% | ++---------------------------------+-------------+-----------+--------+---------------------------+ +| Cold Isolate, with code cache | 8,290.880us | 141.583us | 1.69% | +1.78% | ++---------------------------------+-------------+-----------+--------+---------------------------+ +| Warm Isolate, no code cache | 8,722.684us | 104.547us | 1.19% | +6.68% | ++---------------------------------+-------------+-----------+--------+---------------------------+ +| Warm Isolate, with code cache | 8,194.924us | 70.345us | 0.85% | 0.00% | ++---------------------------------+-------------+-----------+--------+---------------------------+ diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..c8b8cc5 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,39 @@ +Welcome to php-v8's documentation! +================================== + +About +===== + +`php-v8`_ is a PHP 7.x extension that brings `V8`_ JavaScript engine API to PHP with some abstraction in mind and +provides an accurate native V8 C++ API implementation available from PHP. + +Hello, world! +============= + +.. code:: php + + run($context) + ->value(), PHP_EOL; + +Content +======= + +.. toctree:: + :maxdepth: 2 + + getting-started/index + getting-started/performance-tricks + development/index + +.. _V8: https://developers.google.com/v8/intro +.. _php-v8: https://github.com/phpv8/php-v8 diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..65d9e97 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,5 @@ +sphinx~=1.7.1 +sphinx-rtd-theme~=0.1.6 +sphinxcontrib-phpdomain~=0.4.1 + +#sphinxcontrib-spelling~=4.1.0 diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt new file mode 100644 index 0000000..e69de29 diff --git a/package.xml b/package.xml index 1675db4..d5522fa 100644 --- a/package.xml +++ b/package.xml @@ -1,8 +1,8 @@ diff --git a/tests/V8Script_run_uncaught_exception.phpt b/tests/Script_run_uncaught_exception.phpt similarity index 100% rename from tests/V8Script_run_uncaught_exception.phpt rename to tests/Script_run_uncaught_exception.phpt diff --git a/tests/V8Script_terminate_script_execution.phpt b/tests/Script_terminate_script_execution.phpt similarity index 97% rename from tests/V8Script_terminate_script_execution.phpt rename to tests/Script_terminate_script_execution.phpt index 3245d36..69249f5 100644 --- a/tests/V8Script_terminate_script_execution.phpt +++ b/tests/Script_terminate_script_execution.phpt @@ -38,7 +38,7 @@ $terminate = new V8\FunctionTemplate($isolate, function (\V8\FunctionCallbackInf $e = null; }); -$global_template->set(new \V8\StringValue($isolate, 'terminate'), $terminate, \V8\PropertyAttribute::DontDelete); +$global_template->set(new \V8\StringValue($isolate, 'terminate'), $terminate, \V8\PropertyAttribute::DONT_DELETE); $context = new V8\Context($isolate, $global_template); $v8_helper->injectConsoleLog($context); diff --git a/tests/V8SetObject.phpt b/tests/SetObject.phpt similarity index 96% rename from tests/V8SetObject.phpt rename to tests/SetObject.phpt index e41ea05..d6aa4d9 100644 --- a/tests/V8SetObject.phpt +++ b/tests/SetObject.phpt @@ -187,6 +187,8 @@ V8\SetObject(V8\Value)->isUint32Array(): bool(false) V8\SetObject(V8\Value)->isInt32Array(): bool(false) V8\SetObject(V8\Value)->isFloat32Array(): bool(false) V8\SetObject(V8\Value)->isFloat64Array(): bool(false) +V8\SetObject(V8\Value)->isBigInt64Array(): bool(false) +V8\SetObject(V8\Value)->isBigUint64Array(): bool(false) V8\SetObject(V8\Value)->isDataView(): bool(false) V8\SetObject(V8\Value)->isSharedArrayBuffer(): bool(false) V8\SetObject(V8\Value)->isProxy(): bool(false) @@ -195,25 +197,25 @@ V8\SetObject(V8\Value)->isProxy(): bool(false) Converters: ----------- V8\SetObject(V8\Value)->toBoolean(): - object(V8\BooleanValue)#121 (1) { + object(V8\BooleanValue)#124 (1) { ["isolate":"V8\Value":private]=> object(V8\Isolate)#3 (0) { } } V8\SetObject(V8\Value)->toNumber(): - object(V8\NumberValue)#121 (1) { + object(V8\NumberValue)#124 (1) { ["isolate":"V8\Value":private]=> object(V8\Isolate)#3 (0) { } } V8\SetObject(V8\Value)->toString(): - object(V8\StringValue)#121 (1) { + object(V8\StringValue)#124 (1) { ["isolate":"V8\Value":private]=> object(V8\Isolate)#3 (0) { } } V8\SetObject(V8\Value)->toDetailString(): - object(V8\StringValue)#121 (1) { + object(V8\StringValue)#124 (1) { ["isolate":"V8\Value":private]=> object(V8\Isolate)#3 (0) { } @@ -231,19 +233,19 @@ V8\SetObject(V8\Value)->toObject(): } } V8\SetObject(V8\Value)->toInteger(): - object(V8\Int32Value)#121 (1) { + object(V8\Int32Value)#124 (1) { ["isolate":"V8\Value":private]=> object(V8\Isolate)#3 (0) { } } V8\SetObject(V8\Value)->toUint32(): - object(V8\Int32Value)#121 (1) { + object(V8\Int32Value)#124 (1) { ["isolate":"V8\Value":private]=> object(V8\Isolate)#3 (0) { } } V8\SetObject(V8\Value)->toInt32(): - object(V8\Int32Value)#121 (1) { + object(V8\Int32Value)#124 (1) { ["isolate":"V8\Value":private]=> object(V8\Isolate)#3 (0) { } diff --git a/tests/V8Source.phpt b/tests/Source.phpt similarity index 87% rename from tests/V8Source.phpt rename to tests/Source.phpt index c48538b..24da056 100644 --- a/tests/V8Source.phpt +++ b/tests/Source.phpt @@ -109,24 +109,18 @@ object(V8\ScriptCompiler\Source)#9 (3) { ["resource_name":"V8\ScriptOrigin":private]=> string(7) "test.js" ["resource_line_offset":"V8\ScriptOrigin":private]=> - int(0) + NULL ["resource_column_offset":"V8\ScriptOrigin":private]=> - int(0) - ["options":"V8\ScriptOrigin":private]=> - object(V8\ScriptOriginOptions)#6 (4) { - ["is_shared_cross_origin":"V8\ScriptOriginOptions":private]=> - bool(false) - ["is_opaque":"V8\ScriptOriginOptions":private]=> - bool(false) - ["is_wasm":"V8\ScriptOriginOptions":private]=> - bool(false) - ["is_module":"V8\ScriptOriginOptions":private]=> - bool(false) - } + NULL ["script_id":"V8\ScriptOrigin":private]=> - int(0) + NULL ["source_map_url":"V8\ScriptOrigin":private]=> string(0) "" + ["options":"V8\ScriptOrigin":private]=> + object(V8\ScriptOriginOptions)#6 (1) { + ["flags":"V8\ScriptOriginOptions":private]=> + int(0) + } } ["cached_data":"V8\ScriptCompiler\Source":private]=> NULL @@ -178,24 +172,18 @@ object(V8\ScriptCompiler\Source)#9 (3) { ["resource_name":"V8\ScriptOrigin":private]=> string(7) "test.js" ["resource_line_offset":"V8\ScriptOrigin":private]=> - int(0) + NULL ["resource_column_offset":"V8\ScriptOrigin":private]=> - int(0) - ["options":"V8\ScriptOrigin":private]=> - object(V8\ScriptOriginOptions)#6 (4) { - ["is_shared_cross_origin":"V8\ScriptOriginOptions":private]=> - bool(false) - ["is_opaque":"V8\ScriptOriginOptions":private]=> - bool(false) - ["is_wasm":"V8\ScriptOriginOptions":private]=> - bool(false) - ["is_module":"V8\ScriptOriginOptions":private]=> - bool(false) - } + NULL ["script_id":"V8\ScriptOrigin":private]=> - int(0) + NULL ["source_map_url":"V8\ScriptOrigin":private]=> string(0) "" + ["options":"V8\ScriptOrigin":private]=> + object(V8\ScriptOriginOptions)#6 (1) { + ["flags":"V8\ScriptOriginOptions":private]=> + int(0) + } } ["cached_data":"V8\ScriptCompiler\Source":private]=> object(V8\ScriptCompiler\CachedData)#7 (0) { diff --git a/tests/V8StackFrame.phpt b/tests/StackFrame.phpt similarity index 80% rename from tests/V8StackFrame.phpt rename to tests/StackFrame.phpt index 217ea96..b6b1382 100644 --- a/tests/V8StackFrame.phpt +++ b/tests/StackFrame.phpt @@ -15,18 +15,19 @@ $helper->dump($obj); $helper->space(); $helper->header('Test getters (default)'); -$helper->method_matches_with_output($obj, 'getLineNumber', V8\Message::kNoLineNumberInfo); -$helper->method_matches_with_output($obj, 'getColumn', V8\Message::kNoColumnInfo); -$helper->method_matches_with_output($obj, 'getScriptId', V8\Message::kNoScriptIdInfo); +$helper->method_matches_with_output($obj, 'getLineNumber', null); +$helper->method_matches_with_output($obj, 'getColumn', null); +$helper->method_matches_with_output($obj, 'getScriptId', null); $helper->method_matches_with_output($obj, 'getScriptName', ''); $helper->method_matches_with_output($obj, 'getScriptNameOrSourceURL', ''); $helper->method_matches_with_output($obj, 'getFunctionName', ''); $helper->method_matches_with_output($obj, 'isEval', false); $helper->method_matches_with_output($obj, 'isConstructor', false); +$helper->method_matches_with_output($obj, 'isWasm', false); $helper->space(); -$obj = new V8\StackFrame(1, 2, 3, 'script_name', 'script_name_or_source_url', 'function_name', true, true); +$obj = new V8\StackFrame(1, 2, 3, 'script_name', 'script_name_or_source_url', 'function_name', true, true, true); $helper->header('Object representation'); @@ -42,19 +43,20 @@ $helper->method_matches_with_output($obj, 'getScriptNameOrSourceURL', 'script_na $helper->method_matches_with_output($obj, 'getFunctionName', 'function_name'); $helper->method_matches_with_output($obj, 'isEval', true); $helper->method_matches_with_output($obj, 'isConstructor', true); +$helper->method_matches_with_output($obj, 'isWasm', true); $helper->space(); ?> --EXPECT-- Object representation (default): -------------------------------- -object(V8\StackFrame)#2 (8) { +object(V8\StackFrame)#2 (9) { ["line_number":"V8\StackFrame":private]=> - int(0) + NULL ["column":"V8\StackFrame":private]=> - int(0) + NULL ["script_id":"V8\StackFrame":private]=> - int(0) + NULL ["script_name":"V8\StackFrame":private]=> string(0) "" ["script_name_or_source_url":"V8\StackFrame":private]=> @@ -65,24 +67,27 @@ object(V8\StackFrame)#2 (8) { bool(false) ["is_constructor":"V8\StackFrame":private]=> bool(false) + ["is_wasm":"V8\StackFrame":private]=> + bool(false) } Test getters (default): ----------------------- -V8\StackFrame::getLineNumber() matches expected 0 -V8\StackFrame::getColumn() matches expected 0 -V8\StackFrame::getScriptId() matches expected 0 +V8\StackFrame::getLineNumber() matches expected NULL +V8\StackFrame::getColumn() matches expected NULL +V8\StackFrame::getScriptId() matches expected NULL V8\StackFrame::getScriptName() matches expected '' V8\StackFrame::getScriptNameOrSourceURL() matches expected '' V8\StackFrame::getFunctionName() matches expected '' V8\StackFrame::isEval() matches expected false V8\StackFrame::isConstructor() matches expected false +V8\StackFrame::isWasm() matches expected false Object representation: ---------------------- -object(V8\StackFrame)#3 (8) { +object(V8\StackFrame)#3 (9) { ["line_number":"V8\StackFrame":private]=> int(1) ["column":"V8\StackFrame":private]=> @@ -99,6 +104,8 @@ object(V8\StackFrame)#3 (8) { bool(true) ["is_constructor":"V8\StackFrame":private]=> bool(true) + ["is_wasm":"V8\StackFrame":private]=> + bool(true) } @@ -112,3 +119,4 @@ V8\StackFrame::getScriptNameOrSourceURL() matches expected 'script_name_or_sourc V8\StackFrame::getFunctionName() matches expected 'function_name' V8\StackFrame::isEval() matches expected true V8\StackFrame::isConstructor() matches expected true +V8\StackFrame::isWasm() matches expected true diff --git a/tests/V8StackTrace.phpt b/tests/StackTrace.phpt similarity index 91% rename from tests/V8StackTrace.phpt rename to tests/StackTrace.phpt index 347bd06..1f19b54 100644 --- a/tests/V8StackTrace.phpt +++ b/tests/StackTrace.phpt @@ -52,13 +52,13 @@ object(V8\StackTrace)#7 (1) { ["frames":"V8\StackTrace":private]=> array(2) { [0]=> - object(V8\StackFrame)#5 (8) { + object(V8\StackFrame)#5 (9) { ["line_number":"V8\StackFrame":private]=> int(1) ["column":"V8\StackFrame":private]=> - int(0) + NULL ["script_id":"V8\StackFrame":private]=> - int(0) + NULL ["script_name":"V8\StackFrame":private]=> string(0) "" ["script_name_or_source_url":"V8\StackFrame":private]=> @@ -69,15 +69,17 @@ object(V8\StackTrace)#7 (1) { bool(false) ["is_constructor":"V8\StackFrame":private]=> bool(false) + ["is_wasm":"V8\StackFrame":private]=> + bool(false) } [1]=> - object(V8\StackFrame)#6 (8) { + object(V8\StackFrame)#6 (9) { ["line_number":"V8\StackFrame":private]=> int(2) ["column":"V8\StackFrame":private]=> - int(0) + NULL ["script_id":"V8\StackFrame":private]=> - int(0) + NULL ["script_name":"V8\StackFrame":private]=> string(0) "" ["script_name_or_source_url":"V8\StackFrame":private]=> @@ -88,6 +90,8 @@ object(V8\StackTrace)#7 (1) { bool(false) ["is_constructor":"V8\StackFrame":private]=> bool(false) + ["is_wasm":"V8\StackFrame":private]=> + bool(false) } } } diff --git a/tests/V8StackTrace_currentStackTrace.phpt b/tests/StackTrace_currentStackTrace.phpt similarity index 100% rename from tests/V8StackTrace_currentStackTrace.phpt rename to tests/StackTrace_currentStackTrace.phpt diff --git a/tests/V8StartupData_createFromSource.phpt b/tests/StartupData_createFromSource.phpt similarity index 77% rename from tests/V8StartupData_createFromSource.phpt rename to tests/StartupData_createFromSource.phpt index 2552446..411f35f 100644 --- a/tests/V8StartupData_createFromSource.phpt +++ b/tests/StartupData_createFromSource.phpt @@ -17,15 +17,14 @@ $helper->space(); $helper->assert('Snapshot blob is large binary string', is_string($data->getData()) && strlen($data->getData()) > 400000); -$helper->assert('Snapshot raw_size is the same as binary_string length', $data->getRawSize(), strlen($data->getData())); -$helper->assert('Snapshot raw_size is the same as binary_string length', $data->getRawSize(), strlen($data->getData())); - +$helper->assert('Snapshot blob is not rejected', $data->isRejected(), false); $isolate = new \V8\Isolate($data); -$data = null; - $context = new \V8\Context($isolate); +$helper->assert('Snapshot blob is not rejected', $data->isRejected(), false); +$data = null; + $helper->assert('Context global is affected by snapshot blob', $context->globalObject()->get($context, new \V8\StringValue($isolate, 'test_snapshot'))->isFunction()); @@ -46,8 +45,8 @@ object(V8\StartupData)#2 (0) { Snapshot blob is large binary string: ok -Snapshot raw_size is the same as binary_string length: ok -Snapshot raw_size is the same as binary_string length: ok +Snapshot blob is not rejected: ok +Snapshot blob is not rejected: ok Context global is affected by snapshot blob: ok diff --git a/tests/StartupData_warmUpSnapshotDataBlob.phpt b/tests/StartupData_warmUpSnapshotDataBlob.phpt new file mode 100644 index 0000000..8d70f1a --- /dev/null +++ b/tests/StartupData_warmUpSnapshotDataBlob.phpt @@ -0,0 +1,40 @@ +--TEST-- +V8\StartupData::warmUpSnapshotDataBlob +--SKIPIF-- + +--FILE-- +assert('Context should have test function', $v8_helper->CompileTryRun($context, 'test_snapshot()')->value(), 'hello, world'); + +$wam_source = 'test_snapshot = function () { return "hello, warm world";}'; + +$warm_data = V8\StartupData::warmUpSnapshotDataBlob($data, $wam_source); + + +$isolate = new V8\Isolate($warm_data); +$context = new \V8\Context($isolate); + + +$helper->assert('Warm data has no side effects', $res = $v8_helper->CompileTryRun($context, 'test_snapshot()')->value(), 'hello, world'); + + +?> +--EXPECT-- +Context should have test function: ok +Warm data has no side effects: ok diff --git a/tests/V8StringObject.phpt b/tests/StringObject.phpt similarity index 96% rename from tests/V8StringObject.phpt rename to tests/StringObject.phpt index 3eef85e..4956377 100644 --- a/tests/V8StringObject.phpt +++ b/tests/StringObject.phpt @@ -1,7 +1,7 @@ --TEST-- V8\StringObject --SKIPIF-- - + --FILE-- valueOf(): - object(V8\StringValue)#119 (1) { + object(V8\StringValue)#122 (1) { ["isolate":"V8\Value":private]=> object(V8\Isolate)#3 (0) { } @@ -137,6 +137,8 @@ V8\StringObject(V8\Value)->isUint32Array(): bool(false) V8\StringObject(V8\Value)->isInt32Array(): bool(false) V8\StringObject(V8\Value)->isFloat32Array(): bool(false) V8\StringObject(V8\Value)->isFloat64Array(): bool(false) +V8\StringObject(V8\Value)->isBigInt64Array(): bool(false) +V8\StringObject(V8\Value)->isBigUint64Array(): bool(false) V8\StringObject(V8\Value)->isDataView(): bool(false) V8\StringObject(V8\Value)->isSharedArrayBuffer(): bool(false) V8\StringObject(V8\Value)->isProxy(): bool(false) @@ -202,6 +204,8 @@ V8\StringObject(V8\Value)->isUint32Array(): bool(false) V8\StringObject(V8\Value)->isInt32Array(): bool(false) V8\StringObject(V8\Value)->isFloat32Array(): bool(false) V8\StringObject(V8\Value)->isFloat64Array(): bool(false) +V8\StringObject(V8\Value)->isBigInt64Array(): bool(false) +V8\StringObject(V8\Value)->isBigUint64Array(): bool(false) V8\StringObject(V8\Value)->isDataView(): bool(false) V8\StringObject(V8\Value)->isSharedArrayBuffer(): bool(false) V8\StringObject(V8\Value)->isProxy(): bool(false) diff --git a/tests/V8StringValue.phpt b/tests/StringValue.phpt similarity index 96% rename from tests/V8StringValue.phpt rename to tests/StringValue.phpt index 37b3f54..c441b66 100644 --- a/tests/V8StringValue.phpt +++ b/tests/StringValue.phpt @@ -32,6 +32,10 @@ $helper->assert('StringValue extends NameValue', $value instanceof \V8\NameValue $helper->assert('StringValue extends Value', $value instanceof \V8\Value); $helper->line(); +$helper->header('Class constants'); +$helper->dump_object_constants($value); +$helper->space(); + $helper->header('Accessors'); $helper->method_matches($value, 'getIsolate', $isolate); $helper->method_export($value, 'value'); @@ -114,6 +118,11 @@ object(V8\StringValue)#5 (1) { StringValue extends NameValue: ok StringValue extends Value: ok +Class constants: +---------------- +V8\StringValue::MAX_LENGTH = 1073741799 + + Accessors: ---------- V8\StringValue::getIsolate() matches expected value @@ -170,6 +179,8 @@ V8\StringValue(V8\Value)->isUint32Array(): bool(false) V8\StringValue(V8\Value)->isInt32Array(): bool(false) V8\StringValue(V8\Value)->isFloat32Array(): bool(false) V8\StringValue(V8\Value)->isFloat64Array(): bool(false) +V8\StringValue(V8\Value)->isBigInt64Array(): bool(false) +V8\StringValue(V8\Value)->isBigUint64Array(): bool(false) V8\StringValue(V8\Value)->isDataView(): bool(false) V8\StringValue(V8\Value)->isSharedArrayBuffer(): bool(false) V8\StringValue(V8\Value)->isProxy(): bool(false) diff --git a/tests/V8String_range_error_length.phpt b/tests/String_range_error_length.phpt similarity index 100% rename from tests/V8String_range_error_length.phpt rename to tests/String_range_error_length.phpt diff --git a/tests/V8SymbolObject.phpt b/tests/SymbolObject.phpt similarity index 96% rename from tests/V8SymbolObject.phpt rename to tests/SymbolObject.phpt index 30e568a..02be4c1 100644 --- a/tests/V8SymbolObject.phpt +++ b/tests/SymbolObject.phpt @@ -1,9 +1,7 @@ --TEST-- V8\SymbolObject --SKIPIF-- - + --FILE-- valueOf(): - object(V8\SymbolValue)#119 (1) { + object(V8\SymbolValue)#122 (1) { ["isolate":"V8\Value":private]=> object(V8\Isolate)#3 (0) { } @@ -144,6 +142,8 @@ V8\SymbolObject(V8\Value)->isUint32Array(): bool(false) V8\SymbolObject(V8\Value)->isInt32Array(): bool(false) V8\SymbolObject(V8\Value)->isFloat32Array(): bool(false) V8\SymbolObject(V8\Value)->isFloat64Array(): bool(false) +V8\SymbolObject(V8\Value)->isBigInt64Array(): bool(false) +V8\SymbolObject(V8\Value)->isBigUint64Array(): bool(false) V8\SymbolObject(V8\Value)->isDataView(): bool(false) V8\SymbolObject(V8\Value)->isSharedArrayBuffer(): bool(false) V8\SymbolObject(V8\Value)->isProxy(): bool(false) diff --git a/tests/V8SymbolValue.phpt b/tests/SymbolValue.phpt similarity index 91% rename from tests/V8SymbolValue.phpt rename to tests/SymbolValue.phpt index b0b287b..7592efe 100644 --- a/tests/V8SymbolValue.phpt +++ b/tests/SymbolValue.phpt @@ -1,7 +1,7 @@ --TEST-- V8\SymbolValue --SKIPIF-- - + --FILE-- run_checks($res, 'Checkers on Symbol value from script'); function test_For(\V8\Context $context, PhpV8Testsuite $helper) { - $value = V8\SymbolValue::for($context, new \V8\StringValue($context->getIsolate(), 'test')); + $value = V8\SymbolValue::createFor($context, new \V8\StringValue($context->getIsolate(), 'test')); $helper->assert('Symbol For(string) returned', $value instanceof \V8\SymbolValue); $helper->pretty_dump('Symbol For(string) name', $value->name()->value()); $helper->line(); @@ -144,22 +144,22 @@ $v8_helper->CompileRun($context, 'test_For()'); $helper->assert('Isolate not in context', !$isolate->inContext()); -$value = V8\SymbolValue::forApi($context, new \V8\StringValue($isolate, 'test')); +$value = V8\SymbolValue::createForApi($context, new \V8\StringValue($isolate, 'test')); $helper->assert('Symbol ForApi(string) returned', $value instanceof \V8\SymbolValue); $helper->pretty_dump('Symbol ForApi(string) name', $value->name()->value()); $helper->line(); $static_getters = [ - 'GetHasInstance', - 'GetIsConcatSpreadable', - 'GetIterator', - 'GetMatch', - 'GetReplace', - 'GetSearch', - 'GetSplit', - 'GetToPrimitive', - 'GetToStringTag', - 'GetUnscopables', + 'getHasInstanceSymbol', + 'getIsConcatSpreadableSymbol', + 'getIteratorSymbol', + 'getMatchSymbol', + 'getReplaceSymbol', + 'getSearchSymbol', + 'getSplitSymbol', + 'getToPrimitiveSymbol', + 'getToStringTagSymbol', + 'getUnscopablesSymbol', ]; foreach ($static_getters as $static_getter) { @@ -244,6 +244,8 @@ V8\SymbolValue(V8\Value)->isUint32Array(): bool(false) V8\SymbolValue(V8\Value)->isInt32Array(): bool(false) V8\SymbolValue(V8\Value)->isFloat32Array(): bool(false) V8\SymbolValue(V8\Value)->isFloat64Array(): bool(false) +V8\SymbolValue(V8\Value)->isBigInt64Array(): bool(false) +V8\SymbolValue(V8\Value)->isBigUint64Array(): bool(false) V8\SymbolValue(V8\Value)->isDataView(): bool(false) V8\SymbolValue(V8\Value)->isSharedArrayBuffer(): bool(false) V8\SymbolValue(V8\Value)->isProxy(): bool(false) @@ -254,7 +256,7 @@ Null constructor: Object representation: ---------------------- -object(V8\SymbolValue)#92 (1) { +object(V8\SymbolValue)#94 (1) { ["isolate":"V8\Value":private]=> object(V8\Isolate)#3 (0) { } @@ -320,6 +322,8 @@ V8\SymbolValue(V8\Value)->isUint32Array(): bool(false) V8\SymbolValue(V8\Value)->isInt32Array(): bool(false) V8\SymbolValue(V8\Value)->isFloat32Array(): bool(false) V8\SymbolValue(V8\Value)->isFloat64Array(): bool(false) +V8\SymbolValue(V8\Value)->isBigInt64Array(): bool(false) +V8\SymbolValue(V8\Value)->isBigUint64Array(): bool(false) V8\SymbolValue(V8\Value)->isDataView(): bool(false) V8\SymbolValue(V8\Value)->isSharedArrayBuffer(): bool(false) V8\SymbolValue(V8\Value)->isProxy(): bool(false) @@ -396,6 +400,8 @@ V8\SymbolValue(V8\Value)->isUint32Array(): bool(false) V8\SymbolValue(V8\Value)->isInt32Array(): bool(false) V8\SymbolValue(V8\Value)->isFloat32Array(): bool(false) V8\SymbolValue(V8\Value)->isFloat64Array(): bool(false) +V8\SymbolValue(V8\Value)->isBigInt64Array(): bool(false) +V8\SymbolValue(V8\Value)->isBigUint64Array(): bool(false) V8\SymbolValue(V8\Value)->isDataView(): bool(false) V8\SymbolValue(V8\Value)->isSharedArrayBuffer(): bool(false) V8\SymbolValue(V8\Value)->isProxy(): bool(false) @@ -476,6 +482,8 @@ V8\SymbolValue(V8\Value)->isUint32Array(): bool(false) V8\SymbolValue(V8\Value)->isInt32Array(): bool(false) V8\SymbolValue(V8\Value)->isFloat32Array(): bool(false) V8\SymbolValue(V8\Value)->isFloat64Array(): bool(false) +V8\SymbolValue(V8\Value)->isBigInt64Array(): bool(false) +V8\SymbolValue(V8\Value)->isBigUint64Array(): bool(false) V8\SymbolValue(V8\Value)->isDataView(): bool(false) V8\SymbolValue(V8\Value)->isSharedArrayBuffer(): bool(false) V8\SymbolValue(V8\Value)->isProxy(): bool(false) @@ -535,6 +543,8 @@ V8\StringValue(V8\Value)->isUint32Array(): bool(false) V8\StringValue(V8\Value)->isInt32Array(): bool(false) V8\StringValue(V8\Value)->isFloat32Array(): bool(false) V8\StringValue(V8\Value)->isFloat64Array(): bool(false) +V8\StringValue(V8\Value)->isBigInt64Array(): bool(false) +V8\StringValue(V8\Value)->isBigUint64Array(): bool(false) V8\StringValue(V8\Value)->isDataView(): bool(false) V8\StringValue(V8\Value)->isSharedArrayBuffer(): bool(false) V8\StringValue(V8\Value)->isProxy(): bool(false) @@ -589,6 +599,8 @@ V8\SymbolValue(V8\Value)->isUint32Array(): bool(false) V8\SymbolValue(V8\Value)->isInt32Array(): bool(false) V8\SymbolValue(V8\Value)->isFloat32Array(): bool(false) V8\SymbolValue(V8\Value)->isFloat64Array(): bool(false) +V8\SymbolValue(V8\Value)->isBigInt64Array(): bool(false) +V8\SymbolValue(V8\Value)->isBigUint64Array(): bool(false) V8\SymbolValue(V8\Value)->isDataView(): bool(false) V8\SymbolValue(V8\Value)->isSharedArrayBuffer(): bool(false) V8\SymbolValue(V8\Value)->isProxy(): bool(false) @@ -605,41 +617,41 @@ Symbol ForApi(string) returned: ok Symbol ForApi(string) name: string(4) "test" Isolate not in context: ok -Symbol GetHasInstance() returned: ok -Symbol GetHasInstance() name: string(18) "Symbol.hasInstance" +Symbol getHasInstanceSymbol() returned: ok +Symbol getHasInstanceSymbol() name: string(18) "Symbol.hasInstance" Isolate not in context: ok -Symbol GetIsConcatSpreadable() returned: ok -Symbol GetIsConcatSpreadable() name: string(25) "Symbol.isConcatSpreadable" +Symbol getIsConcatSpreadableSymbol() returned: ok +Symbol getIsConcatSpreadableSymbol() name: string(25) "Symbol.isConcatSpreadable" Isolate not in context: ok -Symbol GetIterator() returned: ok -Symbol GetIterator() name: string(15) "Symbol.iterator" +Symbol getIteratorSymbol() returned: ok +Symbol getIteratorSymbol() name: string(15) "Symbol.iterator" Isolate not in context: ok -Symbol GetMatch() returned: ok -Symbol GetMatch() name: string(12) "Symbol.match" +Symbol getMatchSymbol() returned: ok +Symbol getMatchSymbol() name: string(12) "Symbol.match" Isolate not in context: ok -Symbol GetReplace() returned: ok -Symbol GetReplace() name: string(14) "Symbol.replace" +Symbol getReplaceSymbol() returned: ok +Symbol getReplaceSymbol() name: string(14) "Symbol.replace" Isolate not in context: ok -Symbol GetSearch() returned: ok -Symbol GetSearch() name: string(13) "Symbol.search" +Symbol getSearchSymbol() returned: ok +Symbol getSearchSymbol() name: string(13) "Symbol.search" Isolate not in context: ok -Symbol GetSplit() returned: ok -Symbol GetSplit() name: string(12) "Symbol.split" +Symbol getSplitSymbol() returned: ok +Symbol getSplitSymbol() name: string(12) "Symbol.split" Isolate not in context: ok -Symbol GetToPrimitive() returned: ok -Symbol GetToPrimitive() name: string(18) "Symbol.toPrimitive" +Symbol getToPrimitiveSymbol() returned: ok +Symbol getToPrimitiveSymbol() name: string(18) "Symbol.toPrimitive" Isolate not in context: ok -Symbol GetToStringTag() returned: ok -Symbol GetToStringTag() name: string(18) "Symbol.toStringTag" +Symbol getToStringTagSymbol() returned: ok +Symbol getToStringTagSymbol() name: string(18) "Symbol.toStringTag" Isolate not in context: ok -Symbol GetUnscopables() returned: ok -Symbol GetUnscopables() name: string(18) "Symbol.unscopables" +Symbol getUnscopablesSymbol() returned: ok +Symbol getUnscopablesSymbol() name: string(18) "Symbol.unscopables" diff --git a/tests/V8TryCatch.phpt b/tests/TryCatch.phpt similarity index 81% rename from tests/V8TryCatch.phpt rename to tests/TryCatch.phpt index a65ba21..b8a42b5 100644 --- a/tests/V8TryCatch.phpt +++ b/tests/TryCatch.phpt @@ -24,9 +24,9 @@ $helper->space(); $helper->header('Test getters (default)'); $helper->method_matches($obj, 'getIsolate', $isolate); $helper->method_matches($obj, 'getContext', $context); -$helper->method_matches($obj, 'exception', null); -$helper->method_matches($obj, 'message', null); -$helper->method_matches($obj, 'stackTrace', null); +$helper->method_matches($obj, 'getException', null); +$helper->method_matches($obj, 'getMessage', null); +$helper->method_matches($obj, 'getStackTrace', null); $helper->method_matches($obj, 'canContinue', false); $helper->method_matches($obj, 'hasTerminated', false); @@ -47,9 +47,9 @@ $helper->space(); $helper->header('Test getters'); $helper->method_matches($obj, 'getIsolate', $isolate); $helper->method_matches($obj, 'getContext', $context); -$helper->method_matches($obj, 'exception', $exception); -$helper->method_matches($obj, 'message', $message); -$helper->method_matches($obj, 'stackTrace', $trace); +$helper->method_matches($obj, 'getException', $exception); +$helper->method_matches($obj, 'getMessage', $message); +$helper->method_matches($obj, 'getStackTrace', $trace); $helper->method_matches($obj, 'canContinue', true); $helper->method_matches($obj, 'hasTerminated', true); @@ -67,6 +67,8 @@ $isolate = null; $context = null; echo 'END', PHP_EOL; +// EXPECTF: ---/string\(\d+\) ".+\/tests\/TryCatch.php"/ +// EXPECTF: +++string(%d) "%s/tests/TryCatch.php" ?> --EXPECTF-- Object representation (default): @@ -100,9 +102,9 @@ Test getters (default): ----------------------- V8\TryCatch::getIsolate() matches expected value V8\TryCatch::getContext() matches expected value -V8\TryCatch::exception() matches expected value -V8\TryCatch::message() matches expected value -V8\TryCatch::stackTrace() matches expected value +V8\TryCatch::getException() matches expected value +V8\TryCatch::getMessage() matches expected value +V8\TryCatch::getStackTrace() matches expected value V8\TryCatch::canContinue() matches expected value V8\TryCatch::hasTerminated() matches expected value @@ -138,7 +140,7 @@ object(V8\TryCatch)#11 (8) { } } ["message":"V8\TryCatch":private]=> - object(V8\Message)#6 (12) { + object(V8\Message)#6 (11) { ["message":"V8\Message":private]=> string(7) "message" ["script_origin":"V8\Message":private]=> @@ -146,24 +148,18 @@ object(V8\TryCatch)#11 (8) { ["resource_name":"V8\ScriptOrigin":private]=> string(13) "resource_name" ["resource_line_offset":"V8\ScriptOrigin":private]=> - int(0) + NULL ["resource_column_offset":"V8\ScriptOrigin":private]=> - int(0) - ["options":"V8\ScriptOrigin":private]=> - object(V8\ScriptOriginOptions)#8 (4) { - ["is_shared_cross_origin":"V8\ScriptOriginOptions":private]=> - bool(false) - ["is_opaque":"V8\ScriptOriginOptions":private]=> - bool(false) - ["is_wasm":"V8\ScriptOriginOptions":private]=> - bool(false) - ["is_module":"V8\ScriptOriginOptions":private]=> - bool(false) - } + NULL ["script_id":"V8\ScriptOrigin":private]=> - int(0) + NULL ["source_map_url":"V8\ScriptOrigin":private]=> string(0) "" + ["options":"V8\ScriptOrigin":private]=> + object(V8\ScriptOriginOptions)#8 (1) { + ["flags":"V8\ScriptOriginOptions":private]=> + int(0) + } } ["source_line":"V8\Message":private]=> string(4) "line" @@ -176,19 +172,17 @@ object(V8\TryCatch)#11 (8) { } } ["line_number":"V8\Message":private]=> - int(0) + NULL ["start_position":"V8\Message":private]=> - int(-1) + NULL ["end_position":"V8\Message":private]=> - int(-1) + NULL ["start_column":"V8\Message":private]=> - int(0) + NULL ["end_column":"V8\Message":private]=> - int(0) - ["is_shared_cross_origin":"V8\Message":private]=> - bool(false) - ["is_opaque":"V8\Message":private]=> - bool(false) + NULL + ["error_level":"V8\Message":private]=> + NULL } ["can_continue":"V8\TryCatch":private]=> bool(true) @@ -203,9 +197,9 @@ object(V8\TryCatch)#11 (8) { ["code":protected]=> int(0) ["file":protected]=> - string(%d) "%s/V8TryCatch.php" + string(%d) "%s/tests/TryCatch.php" ["line":protected]=> - int(%d) + int(36) ["trace":"Exception":private]=> array(0) { } @@ -219,9 +213,9 @@ Test getters: ------------- V8\TryCatch::getIsolate() matches expected value V8\TryCatch::getContext() matches expected value -V8\TryCatch::exception() matches expected value -V8\TryCatch::message() matches expected value -V8\TryCatch::stackTrace() matches expected value +V8\TryCatch::getException() matches expected value +V8\TryCatch::getMessage() matches expected value +V8\TryCatch::getStackTrace() matches expected value V8\TryCatch::canContinue() matches expected value V8\TryCatch::hasTerminated() matches expected value V8\TryCatch::getExternalException() matches expected value diff --git a/tests/V8TryCatch_from_script.phpt b/tests/TryCatch_from_script.phpt similarity index 94% rename from tests/V8TryCatch_from_script.phpt rename to tests/TryCatch_from_script.phpt index ee55512..4f5c7ee 100644 --- a/tests/V8TryCatch_from_script.phpt +++ b/tests/TryCatch_from_script.phpt @@ -42,7 +42,7 @@ $nested_try_catch_func_tpl = new \v8Tests\TrackingDtors\FunctionTemplate($isolat $helper->assert('TryCatch holds the same isolate it was thrown', $try_catch->getIsolate(), $isolate); $helper->assert('TryCatch holds the same context it was thrown', $try_catch->getContext(), $nested_context); - $helper->dump($e->getTryCatch()->message()->get()); + $helper->dump($e->getTryCatch()->getMessage()->get()); $helper->line(); } }); @@ -70,10 +70,10 @@ try { $helper->assert('TryCatch holds the same isolate it was thrown', $try_catch->getIsolate(), $script->getIsolate()); $helper->assert('TryCatch holds the same context it was thrown', $try_catch->getContext(), $script->getContext()); - $helper->dump($e->getTryCatch()->message()->get()); + $helper->dump($e->getTryCatch()->getMessage()->get()); $helper->line(); - $helper->assert('TryCatchException message has not stack trace', $e->getTryCatch()->message()->getStackTrace() === null); + $helper->assert('TryCatchException message has not stack trace', $e->getTryCatch()->getMessage()->getStackTrace() === null); $helper->line(); } @@ -85,7 +85,7 @@ try { $helper->exception_export($e); $helper->line(); - $helper->assert('TryCatchException message has stack trace', $e->getTryCatch()->message()->getStackTrace() instanceof \V8\StackTrace); + $helper->assert('TryCatchException message has stack trace', $e->getTryCatch()->getMessage()->getStackTrace() instanceof \V8\StackTrace); $helper->line(); } @@ -113,7 +113,7 @@ try { $helper->assert('TryCatch holds the same isolate it was thrown', $try_catch->getIsolate(), $script->getIsolate()); $helper->assert('TryCatch holds the same context it was thrown', $try_catch->getContext(), $script->getContext()); - $helper->dump($e->getTryCatch()->message()->get()); + $helper->dump($e->getTryCatch()->getMessage()->get()); $helper->line(); } @@ -127,7 +127,7 @@ try { $helper->assert('TryCatchException holds the same context it was thrown', $e->getContext(), $context); $helper->assert('TryCatchException holds the same isolate it was thrown', $e->getIsolate(), $isolate); - $helper->dump($e->getTryCatch()->message()->get()); + $helper->dump($e->getTryCatch()->getMessage()->get()); $helper->line(); } diff --git a/tests/V8Uint32Value.phpt b/tests/Uint32Value.phpt similarity index 97% rename from tests/V8Uint32Value.phpt rename to tests/Uint32Value.phpt index de2482b..c467f5d 100644 --- a/tests/V8Uint32Value.phpt +++ b/tests/Uint32Value.phpt @@ -134,6 +134,8 @@ V8\Uint32Value(V8\Value)->isUint32Array(): bool(false) V8\Uint32Value(V8\Value)->isInt32Array(): bool(false) V8\Uint32Value(V8\Value)->isFloat32Array(): bool(false) V8\Uint32Value(V8\Value)->isFloat64Array(): bool(false) +V8\Uint32Value(V8\Value)->isBigInt64Array(): bool(false) +V8\Uint32Value(V8\Value)->isBigUint64Array(): bool(false) V8\Uint32Value(V8\Value)->isDataView(): bool(false) V8\Uint32Value(V8\Value)->isSharedArrayBuffer(): bool(false) V8\Uint32Value(V8\Value)->isProxy(): bool(false) @@ -141,7 +143,7 @@ V8\Uint32Value(V8\Value)->isProxy(): bool(false) V8\Uint32Value::toString() converting: -------------------------------------- -object(V8\StringValue)#79 (1) { +object(V8\StringValue)#81 (1) { ["isolate":"V8\Value":private]=> object(V8\Isolate)#3 (0) { } diff --git a/tests/V8UnboundScript.phpt b/tests/UnboundScript.phpt similarity index 94% rename from tests/V8UnboundScript.phpt rename to tests/UnboundScript.phpt index 0ec3818..09cc87f 100644 --- a/tests/V8UnboundScript.phpt +++ b/tests/UnboundScript.phpt @@ -30,10 +30,6 @@ $helper->header('UnboundScript representation'); $helper->dump($unbound); $helper->space(); -$helper->header('Class constants'); -$helper->dump_object_constants($unbound); -$helper->space(); - $helper->header('Accessors'); $helper->method_matches($unbound, 'getIsolate', $isolate); $helper->method_matches_instanceof($unbound, 'bindToContext', V8\Script::class, [$context]); @@ -75,11 +71,6 @@ object(V8\UnboundScript)#6 (1) { } -Class constants: ----------------- -V8\UnboundScript::kNoScriptId = 0 - - Accessors: ---------- V8\UnboundScript::getIsolate() matches expected value diff --git a/tests/V8Undefined.phpt b/tests/Undefined.phpt similarity index 96% rename from tests/V8Undefined.phpt rename to tests/Undefined.phpt index 38959e5..9d09057 100644 --- a/tests/V8Undefined.phpt +++ b/tests/Undefined.phpt @@ -147,6 +147,8 @@ V8\UndefinedValue(V8\Value)->isUint32Array(): bool(false) V8\UndefinedValue(V8\Value)->isInt32Array(): bool(false) V8\UndefinedValue(V8\Value)->isFloat32Array(): bool(false) V8\UndefinedValue(V8\Value)->isFloat64Array(): bool(false) +V8\UndefinedValue(V8\Value)->isBigInt64Array(): bool(false) +V8\UndefinedValue(V8\Value)->isBigUint64Array(): bool(false) V8\UndefinedValue(V8\Value)->isDataView(): bool(false) V8\UndefinedValue(V8\Value)->isSharedArrayBuffer(): bool(false) V8\UndefinedValue(V8\Value)->isProxy(): bool(false) @@ -160,7 +162,7 @@ V8\UndefinedValue(V8\Value)->numberValue(): float(NAN) V8\UndefinedValue::toString() converting: ----------------------------------------- -object(V8\StringValue)#89 (1) { +object(V8\StringValue)#91 (1) { ["isolate":"V8\Value":private]=> object(V8\Isolate)#3 (0) { } @@ -217,6 +219,8 @@ V8\UndefinedValue(V8\Value)->isUint32Array(): bool(false) V8\UndefinedValue(V8\Value)->isInt32Array(): bool(false) V8\UndefinedValue(V8\Value)->isFloat32Array(): bool(false) V8\UndefinedValue(V8\Value)->isFloat64Array(): bool(false) +V8\UndefinedValue(V8\Value)->isBigInt64Array(): bool(false) +V8\UndefinedValue(V8\Value)->isBigUint64Array(): bool(false) V8\UndefinedValue(V8\Value)->isDataView(): bool(false) V8\UndefinedValue(V8\Value)->isSharedArrayBuffer(): bool(false) V8\UndefinedValue(V8\Value)->isProxy(): bool(false) diff --git a/tests/V8UndefinedValue_destruct.phpt b/tests/UndefinedValue_destruct.phpt similarity index 100% rename from tests/V8UndefinedValue_destruct.phpt rename to tests/UndefinedValue_destruct.phpt diff --git a/tests/V8UndefinedValue_invalid_ctor_arg_type.phpt b/tests/UndefinedValue_invalid_ctor_arg_type.phpt similarity index 86% rename from tests/V8UndefinedValue_invalid_ctor_arg_type.phpt rename to tests/UndefinedValue_invalid_ctor_arg_type.phpt index 2c42579..fb8281f 100644 --- a/tests/V8UndefinedValue_invalid_ctor_arg_type.phpt +++ b/tests/UndefinedValue_invalid_ctor_arg_type.phpt @@ -1,9 +1,7 @@ --TEST-- V8\UndefinedValue::__construct() - with invalid arg type --SKIPIF-- - + --FILE-- ---FILE-- -header('Object representation'); -$helper->dump($isolate); -$helper->line(); - -$helper->method_export($isolate, 'getHeapStatistics'); - -$isolate = null; - -// EXPECTF: ---/float\(.+\)/ -// EXPECTF: +++float(%f) -?> ---EXPECTF-- -Object representation: ----------------------- -object(V8\Isolate)#2 (0) { -} - -V8\Isolate->getHeapStatistics(): - object(V8\HeapStatistics)#26 (9) { - ["total_heap_size":"V8\HeapStatistics":private]=> - float(%f) - ["total_heap_size_executable":"V8\HeapStatistics":private]=> - float(%f) - ["total_physical_size":"V8\HeapStatistics":private]=> - float(%f) - ["total_available_size":"V8\HeapStatistics":private]=> - float(%f) - ["used_heap_size":"V8\HeapStatistics":private]=> - float(%f) - ["heap_size_limit":"V8\HeapStatistics":private]=> - float(%f) - ["malloced_memory":"V8\HeapStatistics":private]=> - float(%f) - ["peak_malloced_memory":"V8\HeapStatistics":private]=> - float(%f) - ["does_zap_garbage":"V8\HeapStatistics":private]=> - bool(false) - } diff --git a/tests/V8ScriptCompiler_compile.phpt b/tests/V8ScriptCompiler_compile.phpt deleted file mode 100644 index 562a5d9..0000000 --- a/tests/V8ScriptCompiler_compile.phpt +++ /dev/null @@ -1,356 +0,0 @@ ---TEST-- -V8\ScriptCompiler::compile() ---SKIPIF-- - ---FILE-- -header('Compiling'); - - $source_string = new V8\StringValue($isolate, '"test"'); - $source = new \V8\ScriptCompiler\Source($source_string); - $script = V8\ScriptCompiler::compile($context, $source); - $helper->assert('Compile script', $script instanceof \V8\Script); - - $source_string = new V8\StringValue($isolate, 'var i = 0; while (true) {i++;}'); - $source = new \V8\ScriptCompiler\Source($source_string); - $script = V8\ScriptCompiler::compile($context, $source); - $helper->assert('Compile script', $script instanceof \V8\Script); - - try { - $source_string = new V8\StringValue($isolate, 'garbage garbage garbage'); - $source = new \V8\ScriptCompiler\Source($source_string); - $script = V8\ScriptCompiler::compile($context, $source); - } catch (\V8\Exceptions\TryCatchException $e) { - $helper->exception_export($e); - //$helper->dump($e->getTryCatch()); - } - - try { - $origin = new \V8\ScriptOrigin('test-module.js', 0, 0, false, 0, "", false, false, true); - - $source_string = new V8\StringValue($isolate, '"test"'); - $source = new \V8\ScriptCompiler\Source($source_string, $origin); - $script = V8\ScriptCompiler::compile($context, $source); - } catch (\V8\Exceptions\Exception $e) { - $helper->exception_export($e); - } - - $helper->space(); -} - -{ - $helper->header('Testing'); - - $source_string = new V8\StringValue($isolate, '"test " + status'); - $source = new \V8\ScriptCompiler\Source($source_string); - $script = V8\ScriptCompiler::compile($context, $source); - - $context->globalObject()->set($context, new \V8\StringValue($isolate, 'status'), new \V8\StringValue($isolate, 'passed')); - $helper->dump($script->run($context)->value()); - - $helper->space(); -} - -{ - $helper->header('Test cache when no cache set'); - - $source_string = new V8\StringValue($isolate, '"test " + status'); - $source = new \V8\ScriptCompiler\Source($source_string); - $helper->assert('Source cache data is not set', $source->getCachedData() === null); - try { - $script = V8\ScriptCompiler::compile($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeParserCache); - } catch (\V8\Exceptions\Exception $e) { - $helper->exception_export($e); - } -} - -{ - $helper->header('Test generating code cache'); - $source_string = new V8\StringValue($isolate, '"test " + status'); - $source = new \V8\ScriptCompiler\Source($source_string); - $helper->assert('Source cache data is NULL', $source->getCachedData() === null); - $script = V8\ScriptCompiler::compile($context, $source, V8\ScriptCompiler\CompileOptions::kProduceCodeCache); - $helper->assert('Source cache data is update', $source->getCachedData() != null); - $helper->assert('Source cache data is not rejected', $source->getCachedData()->isRejected() === false); - - $cache_data = $source->getCachedData(); - $helper->line(); -} - -{ - $helper->header('Test consuming code cache'); - - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - $script = V8\ScriptCompiler::compile($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeCodeCache); - $helper->assert('Source cache data is still set', $source->getCachedData() != null); - $helper->assert('Source cache data is not rejected', $source->getCachedData()->isRejected() === false); - - $helper->line(); -} - -{ - $helper->header('Test consuming code cache for wrong source'); - $source_string = new V8\StringValue($isolate, '"other " + status'); - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - $script = V8\ScriptCompiler::compile($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeCodeCache); - $helper->assert('Source cache data is still set', $source->getCachedData() != null); - $helper->assert('Source cache data is rejected', $source->getCachedData()->isRejected() === true); - - $helper->line(); -} - -{ - $helper->header('Test consuming code cache for source with different formatting'); - $source_string = new V8\StringValue($isolate, ' "test " + status'); - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - $script = V8\ScriptCompiler::compile($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeCodeCache); - $helper->assert('Source cache data is still set', $source->getCachedData() != null); - $helper->assert('Source cache data is not rejected', $source->getCachedData()->isRejected() !== false); - - $helper->line(); -} - -{ - $helper->header('Test generating code cache when it already set'); - $source_string = new V8\StringValue($isolate, '"test " + status'); - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - $script = V8\ScriptCompiler::compile($context, $source, V8\ScriptCompiler\CompileOptions::kProduceCodeCache); - $helper->assert('Source cache data is still set', $source->getCachedData() != null); - $helper->assert('Source cache data is rejected', $source->getCachedData()->isRejected() === true); - - $helper->line(); -} - -{ - $helper->header('Test consuming code cache when requesting parser cache'); - - $source_string = new V8\StringValue($isolate, '"test " + status'); - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - $script = V8\ScriptCompiler::compile($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeParserCache); - $helper->assert('Source cache data is still set', $source->getCachedData() != null); - $helper->assert('Source cache data is not rejected', $source->getCachedData()->isRejected() !== true); - - $helper->line(); -} - -{ - $helper->header('Test parser cache generated not for for all code'); - - $source_string = new V8\StringValue($isolate, '"test " + status'); - $source = new \V8\ScriptCompiler\Source($source_string); - $helper->assert('Source cache data is NULL', $source->getCachedData() === null); - $script = V8\ScriptCompiler::compile($context, $source, V8\ScriptCompiler\CompileOptions::kProduceParserCache); - $helper->assert('Source cache data is NOT updated', $source->getCachedData() === null); - - $helper->line(); -} - -$parser_cache_src= 'function test(arg1, args) { - if (arg1 > arg2) { - return 1+1; - } else { - return arg1 + arg2; - } -}'; - -{ - $helper->header('Test generating parser cache'); - - $source_string = new V8\StringValue($isolate, $parser_cache_src); - $source = new \V8\ScriptCompiler\Source($source_string); - $helper->assert('Source cache data is NULL', $source->getCachedData() === null); - $script = V8\ScriptCompiler::compile($context, $source, V8\ScriptCompiler\CompileOptions::kProduceParserCache); - $helper->assert('Source cache data is update', $source->getCachedData() != null); - $helper->assert('Source cache data is not rejected', $source->getCachedData()->isRejected() === false); - - $cache_data = $source->getCachedData(); - - //$helper->dump($cache_data->getData()); - $helper->line(); -} - -{ - $helper->header('Test consuming parser cache'); - - $source_string = new V8\StringValue($isolate, $parser_cache_src); - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - $script = V8\ScriptCompiler::compile($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeParserCache); - $helper->assert('Source cache data is still set', $source->getCachedData() != null); - $helper->assert('Source cache data is not rejected', $source->getCachedData()->isRejected() === false); - - $helper->line(); -} - -{ - $helper->header('Test consuming parser cache on different source (function with the same name)'); - - $bin = $cache_data->getData(); - $source_string = new V8\StringValue($isolate, 'function test() { return 1+1;}'); - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - try { - $script = V8\ScriptCompiler::compile($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeParserCache); - } catch (\V8\Exceptions\TryCatchException $e) { - $helper->exception_export($e); - } - - $helper->line(); -} - -{ - $helper->header('Test consuming parser cache on different source'); - - $bin = $cache_data->getData(); - $source_string = new V8\StringValue($isolate, 'function test2() { return 1+1;}'); - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - $script = V8\ScriptCompiler::compile($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeParserCache); - $helper->assert('Source cache data is still set', $source->getCachedData() != null); - $helper->assert('Source cache data is rejected', $source->getCachedData()->isRejected() === true); - $helper->assert('Source cache data is not changed', $source->getCachedData()->getData() === $bin); - - $helper->line(); -} - -{ - $helper->header('Test consuming parser cache on the same source with different formatting'); - - $source_string = new V8\StringValue($isolate, ' ' . $parser_cache_src); - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - $script = V8\ScriptCompiler::compile($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeParserCache); - $helper->assert('Source cache data is still set', $source->getCachedData() != null); - $helper->assert('Source cache data is rejected', $source->getCachedData()->isRejected() === true); - - $helper->line(); -} - -{ - $helper->header('Test consuming code cache when parser cache given'); - - $source_string = new V8\StringValue($isolate, $parser_cache_src); - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - $script = V8\ScriptCompiler::compile($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeCodeCache); - $helper->assert('Source cache data is still set', $source->getCachedData() != null); - $helper->assert('Source cache data is not rejected', $source->getCachedData()->isRejected() === false); - - $helper->line(); -} - - - -?> ---EXPECT-- -Compiling: ----------- -Compile script: ok -Compile script: ok -V8\Exceptions\TryCatchException: SyntaxError: Unexpected identifier -V8\Exceptions\Exception: Unable to compile module as script - - -Testing: --------- -string(11) "test passed" - - -Test cache when no cache set: ------------------------------ -Source cache data is not set: ok -V8\Exceptions\Exception: Unable to consume cache when it's not set -Test generating code cache: ---------------------------- -Source cache data is NULL: ok -Source cache data is update: ok -Source cache data is not rejected: ok - -Test consuming code cache: --------------------------- -Source cache data is set: ok -Source cache data is still set: ok -Source cache data is not rejected: ok - -Test consuming code cache for wrong source: -------------------------------------------- -Source cache data is set: ok -Source cache data is still set: ok -Source cache data is rejected: ok - -Test consuming code cache for source with different formatting: ---------------------------------------------------------------- -Source cache data is set: ok -Source cache data is still set: ok -Source cache data is not rejected: ok - -Test generating code cache when it already set: ------------------------------------------------ -Source cache data is set: ok -Source cache data is still set: ok -Source cache data is rejected: ok - -Test consuming code cache when requesting parser cache: -------------------------------------------------------- -Source cache data is set: ok -Source cache data is still set: ok -Source cache data is not rejected: ok - -Test parser cache generated not for for all code: -------------------------------------------------- -Source cache data is NULL: ok -Source cache data is NOT updated: ok - -Test generating parser cache: ------------------------------ -Source cache data is NULL: ok -Source cache data is update: ok -Source cache data is not rejected: ok - -Test consuming parser cache: ----------------------------- -Source cache data is set: ok -Source cache data is still set: ok -Source cache data is not rejected: ok - -Test consuming parser cache on different source (function with the same name): ------------------------------------------------------------------------------- -Source cache data is set: ok -V8\Exceptions\TryCatchException: SyntaxError: Unexpected end of input - -Test consuming parser cache on different source: ------------------------------------------------- -Source cache data is set: ok -Source cache data is still set: ok -Source cache data is rejected: ok -Source cache data is not changed: ok - -Test consuming parser cache on the same source with different formatting: -------------------------------------------------------------------------- -Source cache data is set: ok -Source cache data is still set: ok -Source cache data is rejected: ok - -Test consuming code cache when parser cache given: --------------------------------------------------- -Source cache data is set: ok -Source cache data is still set: ok -Source cache data is not rejected: ok diff --git a/tests/V8ScriptCompiler_compileUnbound.phpt b/tests/V8ScriptCompiler_compileUnbound.phpt deleted file mode 100644 index f0ea485..0000000 --- a/tests/V8ScriptCompiler_compileUnbound.phpt +++ /dev/null @@ -1,296 +0,0 @@ ---TEST-- -V8\ScriptCompiler::compileUnboundScript() ---SKIPIF-- - ---FILE-- -header('Compiling'); - - $source_string = new V8\StringValue($isolate, '"test"'); - $source = new \V8\ScriptCompiler\Source($source_string); - $unbound = V8\ScriptCompiler::compileUnboundScript($context, $source); - $helper->assert('Compile script', $unbound instanceof \V8\UnboundScript); - - $source_string = new V8\StringValue($isolate, 'var i = 0; while (true) {i++;}'); - $source = new \V8\ScriptCompiler\Source($source_string); - $unbound = V8\ScriptCompiler::compileUnboundScript($context, $source); - $helper->assert('Compile script', $unbound instanceof \V8\UnboundScript); - - try { - $source_string = new V8\StringValue($isolate, 'garbage garbage garbage'); - $source = new \V8\ScriptCompiler\Source($source_string); - $unbound = V8\ScriptCompiler::compileUnboundScript($context, $source); - } catch (\V8\Exceptions\TryCatchException $e) { - $helper->exception_export($e); - //$helper->dump($e->getTryCatch()); - } - - try { - $origin = new \V8\ScriptOrigin('test-module.js', 0, 0, false, 0, "", false, false, true); - - $source_string = new V8\StringValue($isolate, '"test"'); - $source = new \V8\ScriptCompiler\Source($source_string, $origin); - $unbound = V8\ScriptCompiler::compileUnboundScript($context, $source); - } catch (\V8\Exceptions\Exception $e) { - $helper->exception_export($e); - } - - $helper->space(); -} - -{ - $helper->header('Testing'); - - $source_string = new V8\StringValue($isolate, '"test " + status'); - $source = new \V8\ScriptCompiler\Source($source_string); - $unbound = V8\ScriptCompiler::compileUnboundScript($context, $source); - - $context->globalObject()->set($context, new \V8\StringValue($isolate, 'status'), new \V8\StringValue($isolate, 'passed')); - - $context2 = new \V8\Context($isolate); - $context2->globalObject()->set($context2, new \V8\StringValue($isolate, 'status'), new \V8\StringValue($isolate, 'passed for second context')); - - - $helper->dump($unbound->bindToContext($context)->run($context)->value()); - $helper->dump($unbound->bindToContext($context2)->run($context)->value()); - $helper->dump($unbound->bindToContext($context2)->run($context2)->value()); - $helper->dump($unbound->bindToContext($context)->run($context2)->value()); - - $helper->space(); -} - -{ - $helper->header('Test cache when no cache set'); - - $source_string = new V8\StringValue($isolate, '"test " + status');; - $source = new \V8\ScriptCompiler\Source($source_string); - $helper->assert('Source cache data is not set', $source->getCachedData() === null); - try { - $unbound = V8\ScriptCompiler::compileUnboundScript($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeParserCache); - } catch (\V8\Exceptions\Exception $e) { - $helper->exception_export($e); - } -} - -{ - $helper->header('Test generating code cache'); - $source_string = new V8\StringValue($isolate, '"test " + status');; - $source = new \V8\ScriptCompiler\Source($source_string); - $helper->assert('Source cache data is NULL', $source->getCachedData() === null); - $unbound = V8\ScriptCompiler::compileUnboundScript($context, $source, V8\ScriptCompiler\CompileOptions::kProduceCodeCache); - $helper->assert('Source cache data is update', $source->getCachedData() != null); - $helper->assert('Source cache data is not rejected', $source->getCachedData()->isRejected() === false); - - $cache_data = $source->getCachedData(); - $helper->line(); -} - -{ - $helper->header('Test consuming code cache'); - - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - $unbound = V8\ScriptCompiler::compileUnboundScript($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeCodeCache); - $helper->assert('Source cache data is still set', $source->getCachedData() != null); - $helper->assert('Source cache data is not rejected', $source->getCachedData()->isRejected() === false); - - $helper->line(); -} - -{ - $helper->header('Test consuming code cache for wrong source'); - $source_string = new V8\StringValue($isolate, '"other " + status');; - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - $unbound = V8\ScriptCompiler::compileUnboundScript($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeCodeCache); - $helper->assert('Source cache data is still set', $source->getCachedData() != null); - $helper->assert('Source cache data is rejected', $source->getCachedData()->isRejected() === true); - - $helper->line(); -} - -{ - $helper->header('Test consuming code cache for source with different formatting'); - $source_string = new V8\StringValue($isolate, ' "test " + status');; - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - $unbound = V8\ScriptCompiler::compileUnboundScript($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeCodeCache); - $helper->assert('Source cache data is still set', $source->getCachedData() != null); - $helper->assert('Source cache data is not rejected', $source->getCachedData()->isRejected() !== false); - - $helper->line(); -} - -{ - $helper->header('Test generating code cache when it already set'); - $source_string = new V8\StringValue($isolate, '"test " + status');; - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - $unbound = V8\ScriptCompiler::compileUnboundScript($context, $source, V8\ScriptCompiler\CompileOptions::kProduceCodeCache); - $helper->assert('Source cache data is still set', $source->getCachedData() != null); - $helper->assert('Source cache data is rejected', $source->getCachedData()->isRejected() === true); - - $helper->line(); -} - -{ - $helper->header('Test consuming code cache when requesting parser cache'); - - $source_string = new V8\StringValue($isolate, '"test " + status');; - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - $unbound = V8\ScriptCompiler::compileUnboundScript($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeParserCache); - $helper->assert('Source cache data is still set', $source->getCachedData() != null); - $helper->assert('Source cache data is not rejected', $source->getCachedData()->isRejected() !== true); - - $helper->line(); -} - -{ - $helper->header('Test parser cache genereted not for for all code'); - - $source_string = new V8\StringValue($isolate, '"test " + status');; - $source = new \V8\ScriptCompiler\Source($source_string); - $helper->assert('Source cache data is NULL', $source->getCachedData() === null); - $unbound = V8\ScriptCompiler::compileUnboundScript($context, $source, V8\ScriptCompiler\CompileOptions::kProduceParserCache); - $helper->assert('Source cache data is NOT updated', $source->getCachedData() === null); - - $helper->line(); -} - -{ - $helper->header('Test generating parser cache'); - - $source_string = new V8\StringValue($isolate, 'function test() { return 1+1;}');; - $source = new \V8\ScriptCompiler\Source($source_string); - $helper->assert('Source cache data is NULL', $source->getCachedData() === null); - $unbound = V8\ScriptCompiler::compileUnboundScript($context, $source, V8\ScriptCompiler\CompileOptions::kProduceParserCache); - $helper->assert('Source cache data is update', $source->getCachedData() != null); - $helper->assert('Source cache data is not rejected', $source->getCachedData()->isRejected() === false); - - $cache_data = $source->getCachedData(); - $helper->line(); -} - - -{ - $helper->header('Test consuming parser cache'); - - $source_string = new V8\StringValue($isolate, 'function test() { return 1+1;}');; - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - $unbound = V8\ScriptCompiler::compileUnboundScript($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeParserCache); - $helper->assert('Source cache data is still set', $source->getCachedData() != null); - $helper->assert('Source cache data is not rejected', $source->getCachedData()->isRejected() === false); - - $helper->line(); -} - -{ - $helper->header('Test consuming code cache when parser cache given'); - - $source_string = new V8\StringValue($isolate, 'function test() { return 1+1;}');; - $source = new \V8\ScriptCompiler\Source($source_string, null, $cache_data); - $helper->assert('Source cache data is set', $source->getCachedData() != null); - $unbound = V8\ScriptCompiler::compileUnboundScript($context, $source, V8\ScriptCompiler\CompileOptions::kConsumeCodeCache); - $helper->assert('Source cache data is still set', $source->getCachedData() != null); - $helper->assert('Source cache data is not rejected', $source->getCachedData()->isRejected() === false); - - $helper->line(); -} - - - -?> ---EXPECT-- -Compiling: ----------- -Compile script: ok -Compile script: ok -V8\Exceptions\TryCatchException: SyntaxError: Unexpected identifier -V8\Exceptions\Exception: Unable to compile module as unbound script - - -Testing: --------- -string(11) "test passed" -string(30) "test passed for second context" -string(30) "test passed for second context" -string(11) "test passed" - - -Test cache when no cache set: ------------------------------ -Source cache data is not set: ok -V8\Exceptions\Exception: Unable to consume cache when it's not set -Test generating code cache: ---------------------------- -Source cache data is NULL: ok -Source cache data is update: ok -Source cache data is not rejected: ok - -Test consuming code cache: --------------------------- -Source cache data is set: ok -Source cache data is still set: ok -Source cache data is not rejected: ok - -Test consuming code cache for wrong source: -------------------------------------------- -Source cache data is set: ok -Source cache data is still set: ok -Source cache data is rejected: ok - -Test consuming code cache for source with different formatting: ---------------------------------------------------------------- -Source cache data is set: ok -Source cache data is still set: ok -Source cache data is not rejected: ok - -Test generating code cache when it already set: ------------------------------------------------ -Source cache data is set: ok -Source cache data is still set: ok -Source cache data is rejected: ok - -Test consuming code cache when requesting parser cache: -------------------------------------------------------- -Source cache data is set: ok -Source cache data is still set: ok -Source cache data is not rejected: ok - -Test parser cache genereted not for for all code: -------------------------------------------------- -Source cache data is NULL: ok -Source cache data is NOT updated: ok - -Test generating parser cache: ------------------------------ -Source cache data is NULL: ok -Source cache data is update: ok -Source cache data is not rejected: ok - -Test consuming parser cache: ----------------------------- -Source cache data is set: ok -Source cache data is still set: ok -Source cache data is not rejected: ok - -Test consuming code cache when parser cache given: --------------------------------------------------- -Source cache data is set: ok -Source cache data is still set: ok -Source cache data is not rejected: ok diff --git a/tests/V8Value_empty.phpt b/tests/Value_empty.phpt similarity index 100% rename from tests/V8Value_empty.phpt rename to tests/Value_empty.phpt diff --git a/tests/stubs/isolate-snapshot-6.3.180-mac.bin b/tests/stubs/isolate-snapshot-6.3.180-mac.bin new file mode 100644 index 0000000..775628e Binary files /dev/null and b/tests/stubs/isolate-snapshot-6.3.180-mac.bin differ diff --git a/tests/stubs/isolate-snapshot-6.3.248-mac.bin b/tests/stubs/isolate-snapshot-6.3.248-mac.bin new file mode 100644 index 0000000..66a6881 Binary files /dev/null and b/tests/stubs/isolate-snapshot-6.3.248-mac.bin differ diff --git a/tests/stubs/isolate-snapshot-test.bin b/tests/stubs/isolate-snapshot-test.bin new file mode 100644 index 0000000..775628e Binary files /dev/null and b/tests/stubs/isolate-snapshot-test.bin differ diff --git a/v8.cc b/v8.cc index da47596..692c9cd 100644 --- a/v8.cc +++ b/v8.cc @@ -1,7 +1,7 @@ /* - * This file is part of the pinepain/php-v8 PHP extension. + * This file is part of the phpv8/php-v8 PHP extension. * - * Copyright (c) 2015-2017 Bogdan Padalko + * Copyright (c) 2015-2018 Bogdan Padalko * * Licensed under the MIT license: http://opensource.org/licenses/MIT * @@ -21,7 +21,7 @@ #include "php_v8_startup_data.h" #include "php_v8_heap_statistics.h" #include "php_v8_exceptions.h" -#include "php_v8_exception.h" +#include "php_v8_exception_manager.h" #include "php_v8_try_catch.h" #include "php_v8_message.h" #include "php_v8_stack_frame.h" @@ -53,6 +53,9 @@ #include "php_v8_set.h" #include "php_v8_date.h" #include "php_v8_regexp.h" +#include "php_v8_proxy.h" +#include "php_v8_promise_resolver.h" +#include "php_v8_promise.h" #include "php_v8_number_object.h" #include "php_v8_boolean_object.h" #include "php_v8_string_object.h" @@ -60,11 +63,12 @@ #include "php_v8_object.h" #include "php_v8_template.h" #include "php_v8_return_value.h" -#include "php_v8_callback_info.h" #include "php_v8_property_callback_info.h" #include "php_v8_function_callback_info.h" +#include "php_v8_callback_info_interface.h" #include "php_v8_named_property_handler_configuration.h" #include "php_v8_indexed_property_handler_configuration.h" +#include "php_v8_json.h" #include "php_v8_value.h" #include "php_v8_data.h" @@ -116,7 +120,7 @@ PHP_MINIT_FUNCTION(v8) PHP_MINIT(php_v8_source)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(php_v8_script_compiler)(INIT_FUNC_ARGS_PASSTHRU); - PHP_MINIT(php_v8_exception)(INIT_FUNC_ARGS_PASSTHRU); + PHP_MINIT(php_v8_exception_manger)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(php_v8_try_catch)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(php_v8_message)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(php_v8_stack_frame)(INIT_FUNC_ARGS_PASSTHRU); @@ -145,6 +149,9 @@ PHP_MINIT_FUNCTION(v8) PHP_MINIT(php_v8_set)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(php_v8_date)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(php_v8_regexp)(INIT_FUNC_ARGS_PASSTHRU); + PHP_MINIT(php_v8_promise)(INIT_FUNC_ARGS_PASSTHRU); + PHP_MINIT(php_v8_promise_resolver)(INIT_FUNC_ARGS_PASSTHRU); + PHP_MINIT(php_v8_proxy)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(php_v8_number_object)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(php_v8_boolean_object)(INIT_FUNC_ARGS_PASSTHRU); @@ -158,13 +165,15 @@ PHP_MINIT_FUNCTION(v8) PHP_MINIT(php_v8_return_value)(INIT_FUNC_ARGS_PASSTHRU); - PHP_MINIT(php_v8_callback_info)(INIT_FUNC_ARGS_PASSTHRU); + PHP_MINIT(php_v8_callback_info_interface)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(php_v8_property_callback_info)(INIT_FUNC_ARGS_PASSTHRU); /* PropertyCallbackInfo inherits CallbackInfo */ PHP_MINIT(php_v8_function_callback_info)(INIT_FUNC_ARGS_PASSTHRU); /* FunctionCallbackInfo inherits CallbackInfo */ PHP_MINIT(php_v8_named_property_handler_configuration)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(php_v8_indexed_property_handler_configuration)(INIT_FUNC_ARGS_PASSTHRU); + PHP_MINIT(php_v8_json)(INIT_FUNC_ARGS_PASSTHRU); + /* If you have INI entries, uncomment these lines REGISTER_INI_ENTRIES(); */