diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index e60dcfee..1e15d24c 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -12,38 +12,29 @@ permissions: contents: read jobs: - build: + self-built-v8-cache-warmup: strategy: # set in accordance with number of v8-versions, so caching can kick in properly max-parallel: 2 matrix: - operating-system: + operating-system: # &self-built-v8-operating-systems - ubuntu-latest # - windows-latest -# - macos-latest - php-versions: -# - '8.1' -# - '8.2' - - '8.3' - - '8.4' - v8-versions: + - macos-latest + v8-versions: # &self-built-v8-v8-versions - 10.9.194 # - 11.9.172 - 12.9.203 -# - 13.1.104 + - 13.5.212 runs-on: ${{ matrix.operating-system }} steps: - - name: Checkout code - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-versions }} - coverage: none + - name: Prepare cache folder v8 ${{ matrix.v8-versions }} + run: | + sudo mkdir -p /opt/v8/self-built/{lib,include} + sudo chown -R $(id -u):$(id -g) /opt/v8/self-built - name: Restore cache v8 ${{ matrix.v8-versions }} build id: v8-build-cache @@ -57,29 +48,79 @@ jobs: if: steps.v8-build-cache.outputs.cache-hit != 'true' uses: newkdev/setup-depot-tools@v1.0.1 + - name: Set up Clang + if: ${{ matrix.operating-system == 'ubuntu-latest' }} + run: | + sudo apt update + sudo apt install -y clang-19 lld-19 + sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-19 100 + sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-19 100 + - name: Build v8 ${{ matrix.v8-versions }} if: steps.v8-build-cache.outputs.cache-hit != 'true' run: | # Store extra tools somewhere undisturbing + set -x cd "$(mktemp -d)" - fetch v8 + ARCH=$(uname -m) + if [[ "$ARCH" == "x86_64" ]]; then + V8CONFIG="x64.release" + ARCH_SHORT="x64" + elif [[ "$ARCH" == "arm64" ]]; then + V8CONFIG="arm64.release" + ARCH_SHORT="arm64" + else + echo "Unknown architecture: $ARCH" >&2 + exit 1 + fi + fetch --nohooks --no-history v8 cd v8 - - git checkout ${{ matrix.v8-versions }} - gclient sync -D + git fetch --tag origin refs/tags/${{ matrix.v8-versions }} 1>&2 > /dev/null + git checkout ${{ matrix.v8-versions }} 1>&2 > /dev/null + gclient sync -D 1>&2 > /dev/null # Setup GN # Warnings are no errors - @see https://issues.chromium.org/issues/42203398#comment9 - tools/dev/v8gen.py -vv x64.release -- is_component_build=true use_custom_libcxx=false treat_warnings_as_errors=false + if [[ "${{ runner.os }}" == "macOS" ]]; then + # Run gn gen with args as v8gen does not override target_cpu properly + gn gen out.gn/$V8CONFIG --args='target_cpu="'$ARCH_SHORT'" v8_target_cpu="'$ARCH_SHORT'" is_component_build=true use_custom_libcxx=true treat_warnings_as_errors=false' + else + tools/dev/v8gen.py -vv $V8CONFIG -- is_component_build=true use_custom_libcxx=true treat_warnings_as_errors=false + fi # Build - ninja -C out.gn/x64.release/ + ninja -C out.gn/$V8CONFIG/ - # Install to /opt/v8/self-built - sudo mkdir -p /opt/v8/self-built/{lib,include} - sudo cp out.gn/x64.release/lib*.so out.gn/x64.release/*_blob.bin out.gn/x64.release/icudtl.dat /opt/v8/self-built/lib/ - sudo cp -R include/* /opt/v8/self-built/include/ + if [[ "${{ runner.os }}" == "macOS" ]]; then + LIB_EXT=dylib + else + LIB_EXT=so + fi + # Copy all V8 libraries and support files + cp -v out.gn/$V8CONFIG/lib*.${LIB_EXT}* out.gn/$V8CONFIG/*_blob.bin out.gn/$V8CONFIG/icudtl.dat /opt/v8/self-built/lib/ + # Copy all V8 static libraries as well + cp -v out.gn/$V8CONFIG/obj/libv8_*.a /opt/v8/self-built/lib/ 2>/dev/null || true + # Copy headers + cp -R include/* /opt/v8/self-built/include/ + # Create symlinks for libraries without version numbers + cd /opt/v8/self-built/lib/ + for lib in lib*.${LIB_EXT}.*; do + if [[ $lib == *\.${LIB_EXT}.* ]]; then + ln -sf $lib ${lib%%.*} 2>/dev/null || true + fi + done + # Set library search path + if [[ "${{ runner.os }}" == "Linux" ]]; then + echo "/opt/v8/self-built/lib" | sudo tee /etc/ld.so.conf.d/v8.conf + sudo ldconfig + elif [[ "${{ runner.os }}" == "macOS" ]]; then + # On macOS, update DYLD_LIBRARY_PATH for the current session + echo "DYLD_LIBRARY_PATH=/opt/v8/self-built/lib" >> $GITHUB_ENV + # Also create symlinks in /usr/local/lib for system-wide access + sudo mkdir -p /usr/local/lib/v8 + sudo ln -sf /opt/v8/self-built/lib/*.dylib* /usr/local/lib/v8/ + fi # Go back to origin cd "${GITHUB_WORKSPACE}" @@ -91,23 +132,106 @@ jobs: path: /opt/v8/self-built key: ${{ steps.v8-build-cache.outputs.cache-primary-key }} + self-built-v8: + needs: self-built-v8-cache-warmup + + strategy: + matrix: + operating-system: # *self-built-v8-operating-systems + - ubuntu-latest +# - windows-latest + - macos-latest + v8-versions: # *self-built-v8-v8-versions + - 10.9.194 +# - 11.9.172 + - 12.9.203 + - 13.5.212 + php-versions: +# - '8.1' + - '8.2' + - '8.3' + - '8.4' + + runs-on: ${{ matrix.operating-system }} + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + coverage: none + + - name: Set up Clang + if: ${{ matrix.operating-system == 'ubuntu-latest' }} + run: | + sudo apt update + sudo apt install -y clang-19 lld-19 + sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-19 100 + sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-19 100 + + - name: Download cache v8 ${{ matrix.v8-versions }} build + uses: actions/cache/restore@v4 + with: + path: /opt/v8/self-built + key: ${{ runner.os }}-${{ matrix.v8-versions }}-v8-build + - name: Build extension run: | + # Set library paths based on OS + if [[ "${{ runner.os }}" == "Linux" ]]; then + export LD_LIBRARY_PATH="/opt/v8/self-built/lib:${LD_LIBRARY_PATH:-}" + # Ensure linker can find the libraries + echo "/opt/v8/self-built/lib" | sudo tee /etc/ld.so.conf.d/v8js.conf + sudo ldconfig + echo "=== Library search paths ===" + ldconfig -p | grep v8 || true + elif [[ "${{ runner.os }}" == "macOS" ]]; then + export DYLD_LIBRARY_PATH="/opt/v8/self-built/lib:${DYLD_LIBRARY_PATH:-}" + fi + + # List V8 libraries for debugging + echo "=== Available V8 libraries ===" + ls -la /opt/v8/self-built/lib/ + + # Build the extension phpize - ./configure --with-v8js=/opt/v8/self-built LDFLAGS="-lstdc++" CPPFLAGS="-DV8_COMPRESS_POINTERS -DV8_ENABLE_SANDBOX" - make + + # Configure with explicit library paths + echo "=== Running configure ===" + ./configure \ + --with-v8js=/opt/v8/self-built \ + LDFLAGS="-L/opt/v8/self-built/lib -Wl,-rpath=/opt/v8/self-built/lib" \ + CPPFLAGS="-I/opt/v8/self-built/include -DV8_COMPRESS_POINTERS -DV8_ENABLE_SANDBOX" \ + LIBS="-lstdc++" \ + V8_LIBS="-L/opt/v8/self-built/lib -lv8 -lv8_libplatform -lv8_libbase -lstdc++ -lpthread -ldl" + + # Build with verbose output + echo "=== Building extension ===" + make -j$(nproc) V=1 + + # Verify the linked libraries + if [[ "${{ runner.os }}" == "Linux" ]]; then + echo "=== Checking linked libraries ===" + ldd modules/v8js.so | grep -i v8 || true + fi + + # Run tests + echo "=== Running tests ===" make test - name: Archive test results if: failure() uses: actions/upload-artifact@v4 with: - name: phpt-test-results + name: phpt-test-results-on-${{ runner.os }}-${{ matrix.v8-versions }}-${{ matrix.php-versions }} path: | php_test_results*.txt tests/*.out - alpine: + alpine-package-manager-apk: runs-on: ubuntu-latest steps: @@ -135,7 +259,52 @@ jobs: if: failure() uses: actions/upload-artifact@v4 with: - name: phpt-test-results + name: phpt-test-results-on-alpine + path: | + php_test_results*.txt + tests/*.out + + macos-package-manager-brew: + strategy: + matrix: + php-versions: + - '8.2' + - '8.3' + - '8.4' + + runs-on: macos-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + coverage: none + + - name: Set up Homebrew + uses: Homebrew/actions/setup-homebrew@master + + - name: Install dependencies + run: | + brew install v8 + # Symlink icudtl.dat to the default location + ln -sf /opt/homebrew/Cellar/v8/$(brew list --versions v8 | awk '{print $2}')/libexec/icudtl.dat /opt/homebrew/lib/icudtl.dat + + - name: Build extension + run: | + phpize + ./configure --with-v8js=/opt/homebrew CPPFLAGS="-DV8_COMPRESS_POINTERS -DV8_ENABLE_SANDBOX" + make + make test + + - name: Archive test results + if: failure() + uses: actions/upload-artifact@v4 + with: + name: phpt-test-results-on-macos-brew-${{ matrix.php-versions }} path: | php_test_results*.txt tests/*.out diff --git a/README.Linux.md b/README.Linux.md index 6bc69625..37f6c2f1 100644 --- a/README.Linux.md +++ b/README.Linux.md @@ -89,23 +89,27 @@ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git export PATH=`pwd`/depot_tools:"$PATH" # Download v8 -fetch v8 +fetch --nohooks --no-history v8 +gclient sync -D --no-history cd v8 # (optional) If you'd like to build a certain version: +git fetch --tag origin refs/tags/12.0.267.36 git checkout 12.0.267.36 gclient sync -D +ARCH=$(uname -m) + # Setup GN -tools/dev/v8gen.py -vv x64.release -- is_component_build=true use_custom_libcxx=false +tools/dev/v8gen.py -vv ${ARCH}.release -- is_component_build=true use_custom_libcxx=false # Build -ninja -C out.gn/x64.release/ +ninja -C out.gn/${ARCH}.release/ # Install to /opt/v8/ sudo mkdir -p /opt/v8/{lib,include} -sudo cp out.gn/x64.release/lib*.so out.gn/x64.release/*_blob.bin \ - out.gn/x64.release/icudtl.dat /opt/v8/lib/ +sudo cp out.gn/${ARCH}.release/lib*.so out.gn/${ARCH}.release/*_blob.bin \ + out.gn/${ARCH}.release/icudtl.dat /opt/v8/lib/ sudo cp -R include/* /opt/v8/include/ ``` diff --git a/README.MacOS.md b/README.MacOS.md index 9a11c82a..098ff2fd 100644 --- a/README.MacOS.md +++ b/README.MacOS.md @@ -16,8 +16,24 @@ cd /tmp git clone https://github.com/phpv8/v8js.git cd v8js phpize -./configure --with-v8js=/opt/homebrew CPPFLAGS="-DV8_COMPRESS_POINTERS" +./configure --with-v8js=/opt/homebrew CPPFLAGS="-DV8_COMPRESS_POINTERS -DV8_ENABLE_SANDBOX" make -j4 make test make install ``` + +V8Js' build system assumes that the `icudtl.dat` file is located next to the `libv8.so` +library file and compiles the path into the library itself. If for whatever reason the +`icudtl.dat` file is stored at a different place during runtime, you need to set the +php.ini variable `v8js.icudtl_dat_path` to point to the file. Otherwise locale-aware +features of V8 will not work as expected. + +To avoid having to configure `v8js.icudtl_dat_path` manually, you can symlink or copy the ICU data file into the default library location. For Homebrew users, run: + +In case of a brew installed v8, run: + +``` +ln -sf /opt/homebrew/Cellar/v8/$(brew list --versions v8 | awk '{print $2}')/libexec/icudtl.dat /opt/homebrew/lib/icudtl.dat +``` + +This ensures V8Js will find `icudtl.dat` automatically and timezone/i18n support will work out of the box. diff --git a/config.m4 b/config.m4 index 835eedf9..0490bc71 100644 --- a/config.m4 +++ b/config.m4 @@ -24,31 +24,78 @@ if test "$PHP_V8JS" != "no"; then AC_MSG_CHECKING([for V8 files in default path]) ARCH=$(uname -m) - + + AC_MSG_NOTICE([Searching for V8 in: $SEARCH_PATH]) + AC_MSG_NOTICE([Looking for library: $SEARCH_FOR]) + AC_MSG_NOTICE([System architecture: $ARCH]) + AC_MSG_NOTICE([PHP library directory: $PHP_LIBDIR]) + + found_v8=no + for i in $SEARCH_PATH ; do - if test -r "$i/$PHP_LIBDIR/$SEARCH_FOR" -a -r "$i/include/$libname/v8.h"; then - V8_INCLUDE_DIR="$i/include/$libname" - V8_LIBRARY_DIR="$i/$PHP_LIBDIR" - AC_MSG_RESULT(found in $i) - break 2 + AC_MSG_NOTICE([Checking path: $i]) + + # Check for standard installation + if test -r "$i/$PHP_LIBDIR/$SEARCH_FOR"; then + AC_MSG_NOTICE([ Found library: $i/$PHP_LIBDIR/$SEARCH_FOR]) + + if test -r "$i/include/$libname/v8.h"; then + AC_MSG_NOTICE([ Found include file: $i/include/$libname/v8.h]) + V8_INCLUDE_DIR="$i/include/$libname" + V8_LIBRARY_DIR="$i/$PHP_LIBDIR" + AC_MSG_RESULT([found standard installation in $i]) + found_v8=yes + break 2 + else + AC_MSG_NOTICE([ Missing include file: $i/include/$libname/v8.h]) + fi + else + AC_MSG_NOTICE([ Missing library: $i/$PHP_LIBDIR/$SEARCH_FOR]) fi - # Debian installations - if test -r "$i/$PHP_LIBDIR/$ARCH-linux-gnu/$SEARCH_FOR"; then - V8_INCLUDE_DIR="$i/include/$libname" - V8_LIBRARY_DIR="$i/$PHP_LIBDIR/$ARCH-linux-gnu" - AC_MSG_RESULT(found in $i) - break 2 + # Check for Debian installations + DEBIAN_PATH="$i/$PHP_LIBDIR/$ARCH-linux-gnu" + if test -r "$DEBIAN_PATH/$SEARCH_FOR"; then + AC_MSG_NOTICE([ Found Debian library: $DEBIAN_PATH/$SEARCH_FOR]) + + if test -r "$i/include/$libname/v8.h"; then + AC_MSG_NOTICE([ Found include file: $i/include/$libname/v8.h]) + V8_INCLUDE_DIR="$i/include/$libname" + V8_LIBRARY_DIR="$DEBIAN_PATH" + AC_MSG_RESULT([found Debian installation in $i]) + found_v8=yes + break 2 + else + AC_MSG_NOTICE([ Missing Debian include file: $i/include/$libname/v8.h]) + fi + else + AC_MSG_NOTICE([ Missing Debian library: $DEBIAN_PATH/$SEARCH_FOR]) fi - # Manual installations - if test -r "$i/$PHP_LIBDIR/$SEARCH_FOR" -a -r "$i/include/libplatform/libplatform.h"; then - V8_INCLUDE_DIR="$i/include" - V8_LIBRARY_DIR="$i/$PHP_LIBDIR" - AC_MSG_RESULT(found in $i) - break 2 + # Check for manual installations + if test -r "$i/$PHP_LIBDIR/$SEARCH_FOR"; then + AC_MSG_NOTICE([ Found manual library: $i/$PHP_LIBDIR/$SEARCH_FOR]) + + if test -r "$i/include/libplatform/libplatform.h"; then + AC_MSG_NOTICE([ Found manual include file: $i/include/libplatform/libplatform.h]) + V8_INCLUDE_DIR="$i/include" + V8_LIBRARY_DIR="$i/$PHP_LIBDIR" + AC_MSG_RESULT([found manual installation in $i]) + found_v8=yes + break 2 + else + AC_MSG_NOTICE([ Missing manual include file: $i/include/libplatform/libplatform.h]) + fi fi + + AC_MSG_NOTICE([No V8 found in $i]) done + + if test "$found_v8" = "no"; then + AC_MSG_NOTICE([V8 not found in any search path]) + AC_MSG_NOTICE([Searched for library: $SEARCH_FOR]) + AC_MSG_NOTICE([Searched paths: $SEARCH_PATH]) + fi done AC_DEFINE_UNQUOTED([PHP_V8_EXEC_PATH], "$V8_LIBRARY_DIR/$SEARCH_FOR", [Full path to libv8 library file]) @@ -117,7 +164,13 @@ if test "$PHP_V8JS" != "no"; then AC_LANG_PUSH([C++]) CPPFLAGS="$CPPFLAGS -I$V8_INCLUDE_DIR -std=$ac_cv_v8_cstd" - LDFLAGS="$LDFLAGS -L$V8_LIBRARY_DIR" + LDFLAGS="-L$V8_LIBRARY_DIR -Wl,-rpath,$V8_LIBRARY_DIR $LDFLAGS" + # Try both libc++ and libstdc++ + LIBS="-L$V8_LIBRARY_DIR -lv8_libbase -lc++ -lstdc++ -lpthread -ldl $LIBS" + + AC_MSG_NOTICE([LIBS for v8_libplatform check: $LIBS]) + AC_MSG_NOTICE([LDFLAGS for v8_libplatform check: $LDFLAGS]) + AC_MSG_NOTICE([CPPFLAGS for v8_libplatform check: $CPPFLAGS]) if test "$libname" = "v8"; then AC_MSG_CHECKING([for libv8_libplatform]) @@ -136,7 +189,7 @@ if test "$PHP_V8JS" != "no"; then ]) V8_CHECK_LINK([], [], [], [ - V8_CHECK_LINK([-lv8_libbase], [], [], [ + V8_CHECK_LINK([-lv8_libbase -lc++ -lstdc++ -lpthread -ldl], [], [], [ AC_MSG_ERROR([could not find libv8_libplatform library]) ]) ]) diff --git a/tests/set_memory_limit_001.phpt b/tests/set_memory_limit_001.phpt index b20b753e..d35a2cdc 100644 --- a/tests/set_memory_limit_001.phpt +++ b/tests/set_memory_limit_001.phpt @@ -13,20 +13,23 @@ if (getenv("SKIP_SLOW_TESTS")) { $JS = <<< EOT var jsfunc = function() { - var text = "abcdefghijklmnopqrstuvwyxz0123456789"; + var text = "abcdefghijklmnopqrstuvwyxz0123456789"; // 36 bytes var memory = ""; - for (var i = 0; i < 100; ++i) { - for (var j = 0; j < 10000; ++j) { + // should generate 360 MB + for (var i = 0; i < 10_000; ++i) { + for (var j = 0; j < 1000; ++j) { memory += text; - } - sleep(0); + } + sleep(0); } + + return memory; }; jsfunc; EOT; $v8 = new V8Js(); -$v8->setMemoryLimit(10000000); +$v8->setMemoryLimit(10_000_000); $func = $v8->executeString($JS); var_dump($func); diff --git a/tests/set_memory_limit_002.phpt b/tests/set_memory_limit_002.phpt new file mode 100644 index 00000000..78bbd9db --- /dev/null +++ b/tests/set_memory_limit_002.phpt @@ -0,0 +1,48 @@ +--TEST-- +Test V8::setMemoryLimit() : Memory limit can be set but does not trigger when not exceeded +--SKIPIF-- + +--FILE-- +setMemoryLimit(10_000_000); + +$func = $v8->executeString($JS); +var_dump($func); + +try { + $func(); +} catch (V8JsMemoryLimitException $e) { + print get_class($e); print PHP_EOL; + print $e->getMessage(); print PHP_EOL; +} +?> +===EOF=== +--EXPECTF-- +object(V8Function)#%d (0) { +} +===EOF=== diff --git a/tests/set_memory_limit_003.phpt b/tests/set_memory_limit_003.phpt index 179dfe2e..e10669fb 100644 --- a/tests/set_memory_limit_003.phpt +++ b/tests/set_memory_limit_003.phpt @@ -14,14 +14,17 @@ if (getenv("SKIP_SLOW_TESTS")) { $JS = <<< EOT var jsfunc = function() { PHP.imposeMemoryLimit(); - var text = "abcdefghijklmnopqrstuvwyxz0123456789"; + var text = "abcdefghijklmnopqrstuvwyxz0123456789"; // 36 bytes var memory = ""; - for (var i = 0; i < 100; ++i) { - for (var j = 0; j < 10000; ++j) { + // should generate 360 MB + for (var i = 0; i < 10_000; ++i) { + for (var j = 0; j < 1000; ++j) { memory += text; - } - sleep(0); + } + sleep(0); } + + return memory; }; jsfunc; EOT; @@ -29,7 +32,7 @@ EOT; $v8 = new V8Js(); $v8->imposeMemoryLimit = function() use ($v8) { - $v8->setMemoryLimit(10000000); + $v8->setMemoryLimit(10_000_000); }; $func = $v8->executeString($JS); diff --git a/tests/time_limit.phpt b/tests/time_limit.phpt index 7d5dc994..60e9b73a 100644 --- a/tests/time_limit.phpt +++ b/tests/time_limit.phpt @@ -12,8 +12,12 @@ if (getenv("SKIP_SLOW_TESTS")) { 2000) { // 2 seconds safety valve + break; + } var encoded = encodeURI(text); } EOT; diff --git a/v8js_array_access.cc b/v8js_array_access.cc index 36752136..e6c0e0d2 100644 --- a/v8js_array_access.cc +++ b/v8js_array_access.cc @@ -59,7 +59,12 @@ static zval v8js_array_access_dispatch(zend_object *object, const char *method_n V8JS_INTERCEPTED v8js_array_access_getter(uint32_t index, const v8::PropertyCallbackInfo& info) /* {{{ */ { v8::Isolate *isolate = info.GetIsolate(); - v8::Local self = info.Holder(); + v8::Local self; + #if PHP_V8_API_VERSION >= 13000000 + self = info.This(); + #else + self = info.Holder(); + #endif zend_object *object = reinterpret_cast(self->GetAlignedPointerFromInternalField(1)); @@ -83,7 +88,12 @@ V8JS_INTERCEPTED v8js_array_access_setter(uint32_t index, v8::Local v const V8JS_SETTER_PROPERTY_CALLBACK_INFO &info) /* {{{ */ { v8::Isolate *isolate = info.GetIsolate(); - v8::Local self = info.Holder(); + v8::Local self; + #if PHP_V8_API_VERSION >= 13000000 + self = info.This(); + #else + self = info.Holder(); + #endif zend_object *object = reinterpret_cast(self->GetAlignedPointerFromInternalField(1)); @@ -157,7 +167,12 @@ static bool v8js_array_access_isset_p(zend_object *object, int index) /* {{{ */ static void v8js_array_access_length(v8::Local property, const v8::PropertyCallbackInfo& info) /* {{{ */ { v8::Isolate *isolate = info.GetIsolate(); - v8::Local self = info.Holder(); + v8::Local self; + #if PHP_V8_API_VERSION >= 13000000 + self = info.This(); + #else + self = info.Holder(); + #endif zend_object *object = reinterpret_cast(self->GetAlignedPointerFromInternalField(1)); @@ -169,7 +184,12 @@ static void v8js_array_access_length(v8::Local property, const v8::P V8JS_INTERCEPTED v8js_array_access_deleter(uint32_t index, const v8::PropertyCallbackInfo& info) /* {{{ */ { v8::Isolate *isolate = info.GetIsolate(); - v8::Local self = info.Holder(); + v8::Local self; + #if PHP_V8_API_VERSION >= 13000000 + self = info.This(); + #else + self = info.Holder(); + #endif zend_object *object = reinterpret_cast(self->GetAlignedPointerFromInternalField(1)); @@ -187,7 +207,12 @@ V8JS_INTERCEPTED v8js_array_access_deleter(uint32_t index, const v8::PropertyCal V8JS_INTERCEPTED v8js_array_access_query(uint32_t index, const v8::PropertyCallbackInfo& info) /* {{{ */ { v8::Isolate *isolate = info.GetIsolate(); - v8::Local self = info.Holder(); + v8::Local self; + #if PHP_V8_API_VERSION >= 13000000 + self = info.This(); + #else + self = info.Holder(); + #endif zend_object *object = reinterpret_cast(self->GetAlignedPointerFromInternalField(1)); @@ -206,7 +231,13 @@ V8JS_INTERCEPTED v8js_array_access_query(uint32_t index, const v8::PropertyCallb void v8js_array_access_enumerator(const v8::PropertyCallbackInfo& info) /* {{{ */ { v8::Isolate *isolate = info.GetIsolate(); - v8::Local self = info.Holder(); + v8::Local self; + + #if PHP_V8_API_VERSION >= 13000000 + self = info.This(); + #else + self = info.Holder(); + #endif zend_object *object = reinterpret_cast(self->GetAlignedPointerFromInternalField(1)); @@ -240,7 +271,14 @@ V8JS_INTERCEPTED v8js_array_access_named_getter(v8::Local property_nam return V8JS_INTERCEPTED_YES; } - v8::Local ret_value = v8js_named_property_callback(info.GetIsolate(), info.Holder(), property, V8JS_PROP_GETTER); + v8::Local holder; + #if PHP_V8_API_VERSION >= 13000000 + holder = info.This(); + #else + holder = info.Holder(); + #endif + + v8::Local ret_value = v8js_named_property_callback(info.GetIsolate(), holder, property, V8JS_PROP_GETTER); if(ret_value.IsEmpty()) { v8::Local arr = v8::Array::New(isolate); diff --git a/v8js_object_export.cc b/v8js_object_export.cc index 8027d380..46163b90 100644 --- a/v8js_object_export.cc +++ b/v8js_object_export.cc @@ -212,7 +212,11 @@ static void v8js_call_php_func(zend_object *object, zend_function *method_ptr, c return_value = v8js_propagate_exception(ctx); } else if (Z_TYPE(retval) == IS_OBJECT && Z_OBJ(retval) == object) { // special case: "return $this" + #if PHP_V8_API_VERSION >= 13000000 + return_value = info.This(); + #else return_value = info.Holder(); + #endif } else { return_value = zval_to_v8js(&retval, isolate); } @@ -227,7 +231,12 @@ static void v8js_call_php_func(zend_object *object, zend_function *method_ptr, c /* Callback for PHP methods and functions */ void v8js_php_callback(const v8::FunctionCallbackInfo& info) /* {{{ */ { - v8::Local self = info.Holder(); + v8::Local self; + #if PHP_V8_API_VERSION >= 13000000 + self = info.This(); + #else + self = info.Holder(); + #endif zend_object *object = reinterpret_cast(self->GetAlignedPointerFromInternalField(1)); zend_function *method_ptr; @@ -364,7 +373,12 @@ static void v8js_named_property_enumerator(const v8::PropertyCallbackInfo v8_context = isolate->GetEnteredOrMicrotaskContext(); - v8::Local self = info.Holder(); + v8::Local self; + #if PHP_V8_API_VERSION >= 13000000 + self = info.This(); + #else + self = info.Holder(); + #endif v8::Local result = v8::Array::New(isolate, 0); uint32_t result_len = 0; @@ -466,7 +480,12 @@ static void v8js_invoke_callback(const v8::FunctionCallbackInfo& info v8::Isolate *isolate = info.GetIsolate(); v8::Local v8_context = isolate->GetEnteredOrMicrotaskContext(); - v8::Local self = info.Holder(); + v8::Local self; + #if PHP_V8_API_VERSION >= 13000000 + self = info.This(); + #else + self = info.Holder(); + #endif v8::Local cb = v8::Local::Cast(info.Data()); int argc = info.Length(), i; v8::Local *argv = static_cast *>(alloca(sizeof(v8::Local) * argc)); @@ -511,7 +530,12 @@ static void v8js_fake_call_impl(const v8::FunctionCallbackInfo& info) v8::Isolate *isolate = info.GetIsolate(); v8::Local v8_context = isolate->GetEnteredOrMicrotaskContext(); - v8::Local self = info.Holder(); + v8::Local self; + #if PHP_V8_API_VERSION >= 13000000 + self = info.This(); + #else + self = info.Holder(); + #endif v8::Local return_value = V8JS_NULL; char *error; @@ -859,7 +883,13 @@ v8::Local v8js_named_property_callback(v8::Isolate *isolate, v8::Loca static V8JS_INTERCEPTED v8js_named_property_getter(v8::Local property, const v8::PropertyCallbackInfo &info) /* {{{ */ { - v8::Local r = v8js_named_property_callback(info.GetIsolate(), info.Holder(), property, V8JS_PROP_GETTER); + v8::Local self; + #if PHP_V8_API_VERSION >= 13000000 + self = info.This(); + #else + self = info.Holder(); + #endif + v8::Local r = v8js_named_property_callback(info.GetIsolate(), self, property, V8JS_PROP_GETTER); if (r.IsEmpty()) { return V8JS_INTERCEPTED_NO; @@ -872,7 +902,13 @@ static V8JS_INTERCEPTED v8js_named_property_getter(v8::Local property, static V8JS_INTERCEPTED v8js_named_property_setter(v8::Local property, v8::Local value, const V8JS_SETTER_PROPERTY_CALLBACK_INFO &info) /* {{{ */ { - v8::Local r = v8js_named_property_callback(info.GetIsolate(), info.Holder(), property, V8JS_PROP_SETTER, value); + v8::Local self; + #if PHP_V8_API_VERSION >= 13000000 + self = info.This(); + #else + self = info.Holder(); + #endif + v8::Local r = v8js_named_property_callback(info.GetIsolate(), self, property, V8JS_PROP_SETTER, value); #if PHP_V8_HAS_INTERCEPTED return r.IsEmpty() ? v8::Intercepted::kNo : v8::Intercepted::kYes; #else @@ -883,7 +919,13 @@ static V8JS_INTERCEPTED v8js_named_property_setter(v8::Local property, static V8JS_INTERCEPTED v8js_named_property_query(v8::Local property, const v8::PropertyCallbackInfo &info) /* {{{ */ { - v8::Local r = v8js_named_property_callback(info.GetIsolate(), info.Holder(), property, V8JS_PROP_QUERY); + v8::Local self; + #if PHP_V8_API_VERSION >= 13000000 + self = info.This(); + #else + self = info.Holder(); + #endif + v8::Local r = v8js_named_property_callback(info.GetIsolate(), self, property, V8JS_PROP_QUERY); if (r.IsEmpty()) { return V8JS_INTERCEPTED_NO; } @@ -901,7 +943,13 @@ static V8JS_INTERCEPTED v8js_named_property_query(v8::Local property, static V8JS_INTERCEPTED v8js_named_property_deleter(v8::Local property, const v8::PropertyCallbackInfo &info) /* {{{ */ { - v8::Local r = v8js_named_property_callback(info.GetIsolate(), info.Holder(), property, V8JS_PROP_DELETER); + v8::Local self; + #if PHP_V8_API_VERSION >= 13000000 + self = info.This(); + #else + self = info.Holder(); + #endif + v8::Local r = v8js_named_property_callback(info.GetIsolate(), self, property, V8JS_PROP_DELETER); if (r.IsEmpty()) { return V8JS_INTERCEPTED_NO; }