mirror of
https://github.com/phpv8/v8js.git
synced 2024-12-22 12:51:52 +00:00
Merge remote-tracking branch 'origin/master' into php7
Conflicts: README.md v8js.cc v8js_class.cc v8js_exceptions.cc v8js_object_export.cc v8js_v8.cc v8js_v8object_class.cc
This commit is contained in:
commit
5cba44ccd0
@ -3,6 +3,11 @@ ifneq (,$(realpath $(EXTENSION_DIR)/json.so))
|
|||||||
PHP_TEST_SHARED_EXTENSIONS+=-d extension=$(EXTENSION_DIR)/json.so
|
PHP_TEST_SHARED_EXTENSIONS+=-d extension=$(EXTENSION_DIR)/json.so
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# add pthreads extension, if available
|
||||||
|
ifneq (,$(realpath $(EXTENSION_DIR)/pthreads.so))
|
||||||
|
PHP_TEST_SHARED_EXTENSIONS+=-d extension=$(EXTENSION_DIR)/pthreads.so
|
||||||
|
endif
|
||||||
|
|
||||||
testv8: all
|
testv8: all
|
||||||
$(PHP_EXECUTABLE) -n -d extension_dir=./modules -d extension=v8js.so test.php
|
$(PHP_EXECUTABLE) -n -d extension_dir=./modules -d extension=v8js.so test.php
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ svn co http://src.chromium.org/svn/trunk/deps/third_party/cygwin@66844 third_par
|
|||||||
svn co http://googletest.googlecode.com/svn/trunk testing/gtest --revision 643
|
svn co http://googletest.googlecode.com/svn/trunk testing/gtest --revision 643
|
||||||
svn co http://googlemock.googlecode.com/svn/trunk testing/gmock --revision 410
|
svn co http://googlemock.googlecode.com/svn/trunk testing/gmock --revision 410
|
||||||
|
|
||||||
python build\gyp_v8 -Dcomponent=shared_library
|
python build\gyp_v8 -Dcomponent=shared_library -Dv8_use_snapshot=0
|
||||||
"\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.com" /build Release build/All.sln
|
"\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.com" /build Release build/All.sln
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -97,9 +97,9 @@ mkdir vc12\x86\deps\lib
|
|||||||
and unpack to below `\php-sdk\phpdev\vc12\x86`
|
and unpack to below `\php-sdk\phpdev\vc12\x86`
|
||||||
* from `\v8\build\Release\lib` copy `icui18n.lib`, `icuuc.lib` and `v8.lib`
|
* from `\v8\build\Release\lib` copy `icui18n.lib`, `icuuc.lib` and `v8.lib`
|
||||||
to deps\lib folder
|
to deps\lib folder
|
||||||
* from `\v8\include copy` all v8*.h files to deps\include folder
|
* from `\v8\include` copy all v8*.h files to deps\include folder
|
||||||
* within the PHP source code folder create a sub-directory named `pecl`
|
* download V8Js and unpack it into a separate directory below `ext` folder
|
||||||
* download V8Js and unpack it into a seperate directory below the `pecl` folder
|
* make sure `config.w32` file inside that folder defines version of the compiled v8
|
||||||
|
|
||||||
(still in "VS2013 x86 Native Tools Command Prompt")
|
(still in "VS2013 x86 Native Tools Command Prompt")
|
||||||
|
|
||||||
|
30
README.md
30
README.md
@ -17,7 +17,7 @@ of this repository.
|
|||||||
Minimum requirements
|
Minimum requirements
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
- V8 Javascript Engine library (libv8) master <https://github.com/v8/v8/> (trunk)
|
- V8 Javascript Engine library (libv8) master <https://github.com/v8/v8-git-mirror> (trunk)
|
||||||
|
|
||||||
V8 is Google's open source Javascript engine.
|
V8 is Google's open source Javascript engine.
|
||||||
V8 is written in C++ and is used in Google Chrome, the open source browser from Google.
|
V8 is written in C++ and is used in Google Chrome, the open source browser from Google.
|
||||||
@ -26,7 +26,7 @@ Minimum requirements
|
|||||||
|
|
||||||
- PHP 7.0.0+
|
- PHP 7.0.0+
|
||||||
|
|
||||||
This embedded implementation of the V8 engine uses thread locking so it should work with ZTS enabled.
|
This embedded implementation of the V8 engine uses thread locking so it works with ZTS enabled.
|
||||||
|
|
||||||
|
|
||||||
Compiling latest version
|
Compiling latest version
|
||||||
@ -55,6 +55,7 @@ class V8Js
|
|||||||
|
|
||||||
const FLAG_NONE = 1;
|
const FLAG_NONE = 1;
|
||||||
const FLAG_FORCE_ARRAY = 2;
|
const FLAG_FORCE_ARRAY = 2;
|
||||||
|
const FLAG_PROPAGATE_PHP_EXCEPTIONS = 4;
|
||||||
|
|
||||||
const DEBUG_AUTO_BREAK_NEVER = 1;
|
const DEBUG_AUTO_BREAK_NEVER = 1;
|
||||||
const DEBUG_AUTO_BREAK_ONCE = 2;
|
const DEBUG_AUTO_BREAK_ONCE = 2;
|
||||||
@ -304,3 +305,28 @@ PHP Objects implementing ArrayAccess, Countable
|
|||||||
The above rule that PHP objects are generally converted to JavaScript objects also applies to PHP objects of `ArrayObject` type or other classes, that implement both the `ArrayAccess` and the `Countable` interface -- even so they behave like PHP arrays.
|
The above rule that PHP objects are generally converted to JavaScript objects also applies to PHP objects of `ArrayObject` type or other classes, that implement both the `ArrayAccess` and the `Countable` interface -- even so they behave like PHP arrays.
|
||||||
|
|
||||||
This behaviour can be changed by enabling the php.ini flag `v8js.use_array_access`. If set, objects of PHP classes that implement the aforementioned interfaces are converted to JavaScript Array-like objects. This is by-index access of this object results in immediate calls to the `offsetGet` or `offsetSet` PHP methods (effectively this is live-binding of JavaScript against the PHP object). Such an Array-esque object also supports calling every attached public method of the PHP object + methods of JavaScript's native Array.prototype methods (as long as they are not overloaded by PHP methods).
|
This behaviour can be changed by enabling the php.ini flag `v8js.use_array_access`. If set, objects of PHP classes that implement the aforementioned interfaces are converted to JavaScript Array-like objects. This is by-index access of this object results in immediate calls to the `offsetGet` or `offsetSet` PHP methods (effectively this is live-binding of JavaScript against the PHP object). Such an Array-esque object also supports calling every attached public method of the PHP object + methods of JavaScript's native Array.prototype methods (as long as they are not overloaded by PHP methods).
|
||||||
|
|
||||||
|
Exceptions
|
||||||
|
==========
|
||||||
|
|
||||||
|
If the JavaScript code throws (without catching), causes errors or doesn't
|
||||||
|
compile, `V8JsScriptException` exceptions are thrown unless the `V8Js` object
|
||||||
|
is constructed with `report_uncaught_exceptions` set `FALSE`.
|
||||||
|
|
||||||
|
PHP exceptions that occur due to calls from JavaScript code by default are
|
||||||
|
*not* re-thrown into JavaScript context but cause the JavaScript execution to
|
||||||
|
be stopped immediately and then are reported at the location calling the JS code.
|
||||||
|
|
||||||
|
This behaviour can be changed by setting the `FLAG_PROPAGATE_PHP_EXCEPTIONS`
|
||||||
|
flag. If it is set, PHP exception (objects) are converted to JavaScript
|
||||||
|
objects obeying the above rules and re-thrown in JavaScript context. If they
|
||||||
|
are not caught by JavaScript code the execution stops and a
|
||||||
|
`V8JsScriptException` is thrown, which has the original PHP exception accessible
|
||||||
|
via `getPrevious` method.
|
||||||
|
|
||||||
|
V8Js versions 0.2.4 and before did not stop JS code execution on PHP exceptions,
|
||||||
|
but silently ignored them (even so succeeding PHP calls from within the same piece
|
||||||
|
of JS code were not executed by the PHP engine). This behaviour is considered as
|
||||||
|
a bug and hence was fixed with 0.2.5 release. Nevertheless there is a
|
||||||
|
compatibility php.ini switch (`v8js.compat_php_exceptions`) which turns previous
|
||||||
|
behaviour back on.
|
||||||
|
152
package.xml
152
package.xml
@ -16,11 +16,11 @@
|
|||||||
<email>stesie@php.net</email>
|
<email>stesie@php.net</email>
|
||||||
<active>yes</active>
|
<active>yes</active>
|
||||||
</lead>
|
</lead>
|
||||||
<date>2015-07-26</date>
|
<date>2015-09-26</date>
|
||||||
<time>00:04:15</time>
|
<time>12:31:47</time>
|
||||||
<version>
|
<version>
|
||||||
<release>0.2.1</release>
|
<release>0.2.6</release>
|
||||||
<api>0.2.1</api>
|
<api>0.2.6</api>
|
||||||
</version>
|
</version>
|
||||||
<stability>
|
<stability>
|
||||||
<release>beta</release>
|
<release>beta</release>
|
||||||
@ -28,10 +28,7 @@
|
|||||||
</stability>
|
</stability>
|
||||||
<license uri="http://www.php.net/license">The MIT License (MIT)</license>
|
<license uri="http://www.php.net/license">The MIT License (MIT)</license>
|
||||||
<notes>
|
<notes>
|
||||||
- adapt to latest v8 API (v8 versions from 3.24.6 up to latest 4.6 branch supported now)
|
- Fix reference counting issue on PHP->JS->PHP exception propagation
|
||||||
- fixed FLAG_FORCE_ARRAY behaviour regarding property assignments
|
|
||||||
- properly stop (and restart) timer thread (for memory & cpu limits)
|
|
||||||
- fixed crash on failed module bootstrapping
|
|
||||||
</notes>
|
</notes>
|
||||||
<contents>
|
<contents>
|
||||||
<dir baseinstalldir="/" name="/">
|
<dir baseinstalldir="/" name="/">
|
||||||
@ -69,8 +66,15 @@
|
|||||||
<file baseinstalldir="/" md5sum="72f2ffb206047d5918d4eb5f32284e3c" name="tests/checkstring_compile.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="72f2ffb206047d5918d4eb5f32284e3c" name="tests/checkstring_compile.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="0e6c4098d0f370b2fa8f433ab6026c6a" name="tests/closures_basic.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="0e6c4098d0f370b2fa8f433ab6026c6a" name="tests/closures_basic.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="1f5c7e8895220923d0203653fbebfc6f" name="tests/closures_dynamic.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="1f5c7e8895220923d0203653fbebfc6f" name="tests/closures_dynamic.phpt" role="test" />
|
||||||
|
<file baseinstalldir="/" md5sum="50f7ba3626131cf015e26b7dc296d20d" name="tests/commonjs_caching_001.phpt" role="test" />
|
||||||
|
<file baseinstalldir="/" md5sum="9bcac28a73d4d274c0e62802fd7af96b" name="tests/commonjs_caching_002.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="90c628544fa6f401221237511a9a4fb7" name="tests/commonjs_modules.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="90c628544fa6f401221237511a9a4fb7" name="tests/commonjs_modules.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="24e2a74c0d15b94cbcdc926d1e19af0c" name="tests/commonjs_multiassign.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="24e2a74c0d15b94cbcdc926d1e19af0c" name="tests/commonjs_multiassign.phpt" role="test" />
|
||||||
|
<file baseinstalldir="/" md5sum="1d7a8f251186c47ce92fe7b1fbb0abc0" name="tests/commonjs_normalise_001.phpt" role="test" />
|
||||||
|
<file baseinstalldir="/" md5sum="3d705ba0a7c22a73be170c9bae2303ba" name="tests/commonjs_normalise_002.phpt" role="test" />
|
||||||
|
<file baseinstalldir="/" md5sum="8e0e5d784e6f7f896dcc94acbf909bbc" name="tests/commonjs_normalise_003.phpt" role="test" />
|
||||||
|
<file baseinstalldir="/" md5sum="b573c7fa2e53c8d20eb88dfb747811fc" name="tests/commonjs_normalise_004.phpt" role="test" />
|
||||||
|
<file baseinstalldir="/" md5sum="e9eb81a3065e2858d79fb772e837982c" name="tests/commonjs_normalise_005.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="6980e6a4c02cf3de87c0eab762fe2a69" name="tests/compile_string.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="6980e6a4c02cf3de87c0eab762fe2a69" name="tests/compile_string.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="177659c1f2be8fb1b018341f896b7cd6" name="tests/compile_string_isolate.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="177659c1f2be8fb1b018341f896b7cd6" name="tests/compile_string_isolate.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="bf4fed6b841034477cb61e3303fb1362" name="tests/construct.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="bf4fed6b841034477cb61e3303fb1362" name="tests/construct.phpt" role="test" />
|
||||||
@ -88,7 +92,7 @@
|
|||||||
<file baseinstalldir="/" md5sum="7da1f96584a7ed1edd19c73dd80f01d6" name="tests/exception.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="7da1f96584a7ed1edd19c73dd80f01d6" name="tests/exception.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="1942e8949e4b323d6ef92aef92334103" name="tests/exception_clearing.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="1942e8949e4b323d6ef92aef92334103" name="tests/exception_clearing.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="446308298f2562a0dd7779486fa561aa" name="tests/exception_propagation_1.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="446308298f2562a0dd7779486fa561aa" name="tests/exception_propagation_1.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="74026d3872c248782bf98dcc8e05ef41" name="tests/exception_propagation_2.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="fafb380c87c0241f18fc4b5d318b282f" name="tests/exception_propagation_2.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="f90813f9ac47107b4630461816ad6221" name="tests/exception_propagation_3.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="f90813f9ac47107b4630461816ad6221" name="tests/exception_propagation_3.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="cf4ef4abb30a47214e7f368b378f54a8" name="tests/exception_start_column.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="cf4ef4abb30a47214e7f368b378f54a8" name="tests/exception_start_column.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="8ed403ca3798d987b0f29e0132c7686f" name="tests/execute_flags.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="8ed403ca3798d987b0f29e0132c7686f" name="tests/execute_flags.phpt" role="test" />
|
||||||
@ -111,7 +115,9 @@
|
|||||||
<file baseinstalldir="/" md5sum="7d240e23d061f59599109cc679084da4" name="tests/has_property_after_dispose.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="7d240e23d061f59599109cc679084da4" name="tests/has_property_after_dispose.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="1443aef2fda8793abd79c06a29639797" name="tests/inheritance_basic.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="1443aef2fda8793abd79c06a29639797" name="tests/inheritance_basic.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="afdb74aca312497cce114a8d9dba6ee9" name="tests/issue_116-v8function-injection.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="afdb74aca312497cce114a8d9dba6ee9" name="tests/issue_116-v8function-injection.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="422d9e9af28d9c7e8042bbf9496fc04c" name="tests/issue_127_001.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="6d4e573daaf2ca5c177230541c31fc96" name="tests/issue_127_001.phpt" role="test" />
|
||||||
|
<file baseinstalldir="/" md5sum="3ff639cdb2f80e8b0a256aa12fce9c5d" name="tests/issue_156_001.phpt" role="test" />
|
||||||
|
<file baseinstalldir="/" md5sum="858c759b267b903dcdd65b5f208dc07f" name="tests/issue_160_basic.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="9f1e697d63231a03da06de97c14a5076" name="tests/js-construct-basic.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="9f1e697d63231a03da06de97c14a5076" name="tests/js-construct-basic.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="0e951523a9abae08b531ecd3193a2581" name="tests/js-construct-direct-call.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="0e951523a9abae08b531ecd3193a2581" name="tests/js-construct-direct-call.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="7733d7eb9693e1c799a3d071a7804b13" name="tests/js-construct-protected-ctor.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="7733d7eb9693e1c799a3d071a7804b13" name="tests/js-construct-protected-ctor.phpt" role="test" />
|
||||||
@ -129,6 +135,13 @@
|
|||||||
<file baseinstalldir="/" md5sum="ed1d6d0aafe39f41545c375507507564" name="tests/object_passback.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="ed1d6d0aafe39f41545c375507507564" name="tests/object_passback.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="95e8658755180e9dc7533c0ed4d61bb2" name="tests/object_prototype.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="95e8658755180e9dc7533c0ed4d61bb2" name="tests/object_prototype.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="732770da7b148dcb702894dcb9462674" name="tests/object_reuse.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="732770da7b148dcb702894dcb9462674" name="tests/object_reuse.phpt" role="test" />
|
||||||
|
<file baseinstalldir="/" md5sum="e49bb15778697eea7d717de4cfc0c385" name="tests/php_exceptions_001.phpt" role="test" />
|
||||||
|
<file baseinstalldir="/" md5sum="bc07bbc424d078d3d0590540a67648ba" name="tests/php_exceptions_002.phpt" role="test" />
|
||||||
|
<file baseinstalldir="/" md5sum="3913092b6336924271fd9315a87d0973" name="tests/php_exceptions_003.phpt" role="test" />
|
||||||
|
<file baseinstalldir="/" md5sum="66c0769781344af35f63d5d1b7a50852" name="tests/php_exceptions_004.phpt" role="test" />
|
||||||
|
<file baseinstalldir="/" md5sum="610889e09e1579075ef973ef41883e8f" name="tests/php_exceptions_005.phpt" role="test" />
|
||||||
|
<file baseinstalldir="/" md5sum="59e80f305f84f2effbac279261f8c5a6" name="tests/php_exceptions_006.phpt" role="test" />
|
||||||
|
<file baseinstalldir="/" md5sum="c513770deccefc87636a30aa4329f779" name="tests/php_exceptions_basic.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="3cc6c105f2413e4270eba038e6a2dffd" name="tests/property_exists.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="3cc6c105f2413e4270eba038e6a2dffd" name="tests/property_exists.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="065d238a0c45902ce226622847e5e341" name="tests/property_visibility-delete.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="065d238a0c45902ce226622847e5e341" name="tests/property_visibility-delete.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="4aa538bcaa3ab56b2fad8b6105ec1717" name="tests/property_visibility-enumerate.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="4aa538bcaa3ab56b2fad8b6105ec1717" name="tests/property_visibility-enumerate.phpt" role="test" />
|
||||||
@ -158,39 +171,40 @@
|
|||||||
<file baseinstalldir="/" md5sum="35ce3816ae00e697fca26142c46e0c79" name="tests/v8_write_property.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="35ce3816ae00e697fca26142c46e0c79" name="tests/v8_write_property.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="ae504a63e5ff800e3aa7d529835d0e8e" name="tests/variable_passing.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="ae504a63e5ff800e3aa7d529835d0e8e" name="tests/variable_passing.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="1bd7738aeeb5cf80d80561554f59f2ed" name="tests/var_dump.phpt" role="test" />
|
<file baseinstalldir="/" md5sum="1bd7738aeeb5cf80d80561554f59f2ed" name="tests/var_dump.phpt" role="test" />
|
||||||
<file baseinstalldir="/" md5sum="19150f213fb00790c51f22989b39ff55" name="config.m4" role="src" />
|
<file baseinstalldir="/" md5sum="63c4b2873ccc935571ae7fbb1baeab7b" name="config.m4" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="987d834d2edc84ead98dc1fddba2ad73" name="config.w32" role="src" />
|
<file baseinstalldir="/" md5sum="987d834d2edc84ead98dc1fddba2ad73" name="config.w32" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="cea72666538d5b0b80a64ccdbda24919" name="CREDITS" role="doc" />
|
<file baseinstalldir="/" md5sum="cea72666538d5b0b80a64ccdbda24919" name="CREDITS" role="doc" />
|
||||||
<file baseinstalldir="/" md5sum="9f5b5f41204bcde55d9df87d5a970b30" name="LICENSE" role="doc" />
|
<file baseinstalldir="/" md5sum="9f5b5f41204bcde55d9df87d5a970b30" name="LICENSE" role="doc" />
|
||||||
<file baseinstalldir="/" md5sum="25260e0bc3111b01f700fad13544d6a9" name="Makefile.frag" role="src" />
|
<file baseinstalldir="/" md5sum="25260e0bc3111b01f700fad13544d6a9" name="Makefile.frag" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="31e331386def7ce98943694151c0d5cb" name="Makefile.travis" role="src" />
|
<file baseinstalldir="/" md5sum="31e331386def7ce98943694151c0d5cb" name="Makefile.travis" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="0e23fa6446e52a3b1cff8b18a6e0bd79" name="php_v8js.h" role="src" />
|
<file baseinstalldir="/" md5sum="0e23fa6446e52a3b1cff8b18a6e0bd79" name="php_v8js.h" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="b81ab8ff4f87d883363b02fe358da87c" name="php_v8js_macros.h" role="src" />
|
<file baseinstalldir="/" md5sum="0d986531818b0e31633f2db3a242afb7" name="php_v8js_macros.h" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="8d36541e788d9f2de7d19d4e167a1b3b" name="README.Linux.md" role="doc" />
|
<file baseinstalldir="/" md5sum="ec19e63ca9310bfc4dc4dbd357c779ae" name="README.Linux.md" role="doc" />
|
||||||
<file baseinstalldir="/" md5sum="4a65a3f9995d325a2c2ccb23224ea503" name="README.MacOS.md" role="doc" />
|
<file baseinstalldir="/" md5sum="4a65a3f9995d325a2c2ccb23224ea503" name="README.MacOS.md" role="doc" />
|
||||||
<file baseinstalldir="/" md5sum="00cc5dd1c69120c7156abd08efafacba" name="README.md" role="doc" />
|
<file baseinstalldir="/" md5sum="177459a9628e3c8c31b305f20c970f8d" name="README.md" role="doc" />
|
||||||
<file baseinstalldir="/" md5sum="f7baf040ec2145f7eeccd5540ebb085f" name="README.Win32.md" role="doc" />
|
<file baseinstalldir="/" md5sum="9839870e001306943797003e8828d855" name="README.Win32.md" role="doc" />
|
||||||
<file baseinstalldir="/" md5sum="542f52c54898f33ac53b173970cba305" name="test.php" role="php" />
|
<file baseinstalldir="/" md5sum="542f52c54898f33ac53b173970cba305" name="test.php" role="php" />
|
||||||
<file baseinstalldir="/" md5sum="65294fadb5ed766094b1f587fc20ad37" name="TODO" role="doc" />
|
<file baseinstalldir="/" md5sum="65294fadb5ed766094b1f587fc20ad37" name="TODO" role="doc" />
|
||||||
<file baseinstalldir="/" md5sum="d1e8223596fac67062055261b6cf1180" name="v8js.cc" role="src" />
|
<file baseinstalldir="/" md5sum="cc54d77b4d0044d7b143989f2dc12b94" name="v8js.cc" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="358c628b2627319e40fd7e5092f19872" name="v8js_array_access.cc" role="src" />
|
<file baseinstalldir="/" md5sum="358c628b2627319e40fd7e5092f19872" name="v8js_array_access.cc" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="7baf3fe5b77d1374b39a1d8332e05df4" name="v8js_array_access.h" role="src" />
|
<file baseinstalldir="/" md5sum="7baf3fe5b77d1374b39a1d8332e05df4" name="v8js_array_access.h" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="5504a5f186152a48ef3b3819bd53a676" name="v8js_class.cc" role="src" />
|
<file baseinstalldir="/" md5sum="6c213918edf4f46ac630498e92bb99f6" name="v8js_class.cc" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="afd1c86428a25cc71c35a6f9e3ea04bb" name="v8js_class.h" role="src" />
|
<file baseinstalldir="/" md5sum="444a6fda6259076cd2a419cf59ab2c42" name="v8js_class.h" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="795e65a077e963de413eb6947edd1f94" name="v8js_commonjs.cc" role="src" />
|
<file baseinstalldir="/" md5sum="88b49988a5ef55edbd7ba085e7857f64" name="v8js_commonjs.cc" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="6b3d174805b6c97bdec88b9479e8ce6c" name="v8js_convert.cc" role="src" />
|
<file baseinstalldir="/" md5sum="32a5d1a65f64ec37ec294f496fc11ff1" name="v8js_commonjs.h" role="src" />
|
||||||
|
<file baseinstalldir="/" md5sum="c061344705c42fb705bffb2959fc1001" name="v8js_convert.cc" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="ede2cf80141b1831c7e7ab50dc57236f" name="v8js_debug.cc" role="src" />
|
<file baseinstalldir="/" md5sum="ede2cf80141b1831c7e7ab50dc57236f" name="v8js_debug.cc" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="cbdb6ed29c9ece278aa2aeab75dbe61f" name="v8js_debug.h" role="src" />
|
<file baseinstalldir="/" md5sum="cbdb6ed29c9ece278aa2aeab75dbe61f" name="v8js_debug.h" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="1867ebcefbc577aed051f40d9ccc58ad" name="v8js_exceptions.cc" role="src" />
|
<file baseinstalldir="/" md5sum="40b66c44650a8127618c7fc48bf4b0b2" name="v8js_exceptions.cc" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="587370513a019c34f2ddaac3b1f4cbf8" name="v8js_exceptions.h" role="src" />
|
<file baseinstalldir="/" md5sum="9d13bf5f413c2d76664670e847e1a801" name="v8js_exceptions.h" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="3b5845c5f4109366257a9e35975703ac" name="v8js_methods.cc" role="src" />
|
<file baseinstalldir="/" md5sum="9f3ad8c136cdc3ebc2bdf993491f9ad8" name="v8js_methods.cc" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="55bfab106f9a92e8909aa6fba344037c" name="v8js_object_export.cc" role="src" />
|
<file baseinstalldir="/" md5sum="d688b8eb822736d49f7282d22546d6bc" name="v8js_object_export.cc" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="281fb591fbebc3d23e04196cdb3ec64a" name="v8js_object_export.h" role="src" />
|
<file baseinstalldir="/" md5sum="281fb591fbebc3d23e04196cdb3ec64a" name="v8js_object_export.h" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="767d38eec0b407fba5e30398444e180e" name="v8js_timer.cc" role="src" />
|
<file baseinstalldir="/" md5sum="d96c0e1eeaf1693813236f7e5da61e09" name="v8js_timer.cc" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="49f609c8cea6033f2ad1e6c9c829a571" name="v8js_timer.h" role="src" />
|
<file baseinstalldir="/" md5sum="49f609c8cea6033f2ad1e6c9c829a571" name="v8js_timer.h" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="41b036ea855a1c8682a93d50dd834a67" name="v8js_v8.cc" role="src" />
|
<file baseinstalldir="/" md5sum="b3ba6b76f92683c55b45bce351af887e" name="v8js_v8.cc" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="72cc4af7af63c62138d4156faf784ec9" name="v8js_v8.h" role="src" />
|
<file baseinstalldir="/" md5sum="0c4829d52ff46116c381b1b66ec27541" name="v8js_v8.h" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="842fb2dea63c473cdfaf501321a6a530" name="v8js_v8object_class.cc" role="src" />
|
<file baseinstalldir="/" md5sum="82908f4e741755efa2aedfb486945a40" name="v8js_v8object_class.cc" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="8a80d71ff40dfa833d3b58ac94475a9f" name="v8js_v8object_class.h" role="src" />
|
<file baseinstalldir="/" md5sum="8a80d71ff40dfa833d3b58ac94475a9f" name="v8js_v8object_class.h" role="src" />
|
||||||
<file baseinstalldir="/" md5sum="29be67d9bf8bfb1642d1219356109063" name="v8js_variables.cc" role="src" />
|
<file baseinstalldir="/" md5sum="29be67d9bf8bfb1642d1219356109063" name="v8js_variables.cc" role="src" />
|
||||||
</dir>
|
</dir>
|
||||||
@ -331,5 +345,87 @@
|
|||||||
- fixed crash on failed module bootstrapping
|
- fixed crash on failed module bootstrapping
|
||||||
</notes>
|
</notes>
|
||||||
</release>
|
</release>
|
||||||
|
<release>
|
||||||
|
<version>
|
||||||
|
<release>0.2.2</release>
|
||||||
|
<api>0.2.2</api>
|
||||||
|
</version>
|
||||||
|
<stability>
|
||||||
|
<release>beta</release>
|
||||||
|
<api>beta</api>
|
||||||
|
</stability>
|
||||||
|
<date>2015-08-26</date>
|
||||||
|
<license uri="http://www.php.net/license">The MIT License (MIT)</license>
|
||||||
|
<notes>
|
||||||
|
- Fix CommonJS module caching
|
||||||
|
- Fix use-after-free issue on CommonJS module reuse
|
||||||
|
- Fix memory leaks in CommonJS module loader
|
||||||
|
- Fix memory leak regarding lost script resources (compileScript call et al)
|
||||||
|
- Improve V8Function call performance
|
||||||
|
</notes>
|
||||||
|
</release>
|
||||||
|
<release>
|
||||||
|
<version>
|
||||||
|
<release>0.2.3</release>
|
||||||
|
<api>0.2.3</api>
|
||||||
|
</version>
|
||||||
|
<stability>
|
||||||
|
<release>beta</release>
|
||||||
|
<api>beta</api>
|
||||||
|
</stability>
|
||||||
|
<date>2015-08-27</date>
|
||||||
|
<license uri="http://www.php.net/license">The MIT License (MIT)</license>
|
||||||
|
<notes>
|
||||||
|
- Fix FLAG_FORCE_ARRAY affecting V8Function objects
|
||||||
|
- Fix memory leak with repeated calls of methods on exported PHP objects
|
||||||
|
</notes>
|
||||||
|
</release>
|
||||||
|
<release>
|
||||||
|
<version>
|
||||||
|
<release>0.2.4</release>
|
||||||
|
<api>0.2.4</api>
|
||||||
|
</version>
|
||||||
|
<stability>
|
||||||
|
<release>beta</release>
|
||||||
|
<api>beta</api>
|
||||||
|
</stability>
|
||||||
|
<date>2015-09-01</date>
|
||||||
|
<license uri="http://www.php.net/license">The MIT License (MIT)</license>
|
||||||
|
<notes>
|
||||||
|
- Fix memory leak with repeated Array exports from PHP to JS
|
||||||
|
</notes>
|
||||||
|
</release>
|
||||||
|
<release>
|
||||||
|
<version>
|
||||||
|
<release>0.2.5</release>
|
||||||
|
<api>0.2.5</api>
|
||||||
|
</version>
|
||||||
|
<stability>
|
||||||
|
<release>beta</release>
|
||||||
|
<api>beta</api>
|
||||||
|
</stability>
|
||||||
|
<date>2015-09-23</date>
|
||||||
|
<license uri="http://www.php.net/license">The MIT License (MIT)</license>
|
||||||
|
<notes>
|
||||||
|
- Stop JS execution on PHP exceptions (instead of continuing silently)
|
||||||
|
- Allow propagation of PHP exceptions to JS context (disabled by default)
|
||||||
|
- Add v8js.compat_php_exceptions php.ini switch to switch previous behaviour back on
|
||||||
|
</notes>
|
||||||
|
</release>
|
||||||
|
<release>
|
||||||
|
<version>
|
||||||
|
<release>0.2.6</release>
|
||||||
|
<api>0.2.6</api>
|
||||||
|
</version>
|
||||||
|
<stability>
|
||||||
|
<release>beta</release>
|
||||||
|
<api>beta</api>
|
||||||
|
</stability>
|
||||||
|
<date>2015-09-26</date>
|
||||||
|
<license uri="http://www.php.net/license">The MIT License (MIT)</license>
|
||||||
|
<notes>
|
||||||
|
- Fix reference counting issue on PHP->JS->PHP exception propagation
|
||||||
|
</notes>
|
||||||
|
</release>
|
||||||
</changelog>
|
</changelog>
|
||||||
</package>
|
</package>
|
||||||
|
@ -52,7 +52,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* V8Js Version */
|
/* V8Js Version */
|
||||||
#define PHP_V8JS_VERSION "0.2.1"
|
#define PHP_V8JS_VERSION "0.2.6"
|
||||||
|
|
||||||
/* Hidden field name used to link JS wrappers with underlying PHP object */
|
/* Hidden field name used to link JS wrappers with underlying PHP object */
|
||||||
#define PHPJS_OBJECT_KEY "phpjs::object"
|
#define PHPJS_OBJECT_KEY "phpjs::object"
|
||||||
@ -69,13 +69,10 @@ extern "C" {
|
|||||||
# define V8JS_CONST (char *)
|
# define V8JS_CONST (char *)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Global flags */
|
|
||||||
#define V8JS_GLOBAL_SET_FLAGS(isolate,flags) V8JS_GLOBAL(isolate)->SetHiddenValue(V8JS_SYM("__php_flags__"), V8JS_INT(flags))
|
|
||||||
#define V8JS_GLOBAL_GET_FLAGS(isolate) V8JS_GLOBAL(isolate)->GetHiddenValue(V8JS_SYM("__php_flags__"))->IntegerValue();
|
|
||||||
|
|
||||||
/* Options */
|
/* Options */
|
||||||
#define V8JS_FLAG_NONE (1<<0)
|
#define V8JS_FLAG_NONE (1<<0)
|
||||||
#define V8JS_FLAG_FORCE_ARRAY (1<<1)
|
#define V8JS_FLAG_FORCE_ARRAY (1<<1)
|
||||||
|
#define V8JS_FLAG_PROPAGATE_PHP_EXCEPTIONS (1<<2)
|
||||||
|
|
||||||
#define V8JS_DEBUG_AUTO_BREAK_NEVER 0
|
#define V8JS_DEBUG_AUTO_BREAK_NEVER 0
|
||||||
#define V8JS_DEBUG_AUTO_BREAK_ONCE 1
|
#define V8JS_DEBUG_AUTO_BREAK_ONCE 1
|
||||||
@ -104,16 +101,13 @@ struct v8js_timer_ctx;
|
|||||||
|
|
||||||
/* Module globals */
|
/* Module globals */
|
||||||
ZEND_BEGIN_MODULE_GLOBALS(v8js)
|
ZEND_BEGIN_MODULE_GLOBALS(v8js)
|
||||||
|
// Thread-local cache whether V8 has been initialized so far
|
||||||
int v8_initialized;
|
int v8_initialized;
|
||||||
#if !defined(_WIN32) && PHP_V8_API_VERSION >= 3029036
|
|
||||||
v8::Platform *v8_platform;
|
|
||||||
#endif
|
|
||||||
HashTable *extensions;
|
|
||||||
|
|
||||||
/* Ini globals */
|
/* Ini globals */
|
||||||
char *v8_flags; /* V8 command line flags */
|
|
||||||
bool use_date; /* Generate JS Date objects instead of PHP DateTime */
|
bool use_date; /* Generate JS Date objects instead of PHP DateTime */
|
||||||
bool use_array_access; /* Convert ArrayAccess, Countable objects to array-like objects */
|
bool use_array_access; /* Convert ArrayAccess, Countable objects to array-like objects */
|
||||||
|
bool compat_php_exceptions; /* Don't stop JS execution on PHP exception */
|
||||||
|
|
||||||
// Timer thread globals
|
// Timer thread globals
|
||||||
std::deque<v8js_timer_ctx *> timer_stack;
|
std::deque<v8js_timer_ctx *> timer_stack;
|
||||||
@ -130,6 +124,39 @@ ZEND_EXTERN_MODULE_GLOBALS(v8js)
|
|||||||
|
|
||||||
#define V8JSG(v) ZEND_MODULE_GLOBALS_ACCESSOR(v8js, v)
|
#define V8JSG(v) ZEND_MODULE_GLOBALS_ACCESSOR(v8js, v)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process-wide globals
|
||||||
|
*
|
||||||
|
* The zend_v8js_globals structure declared above is created once per thread
|
||||||
|
* (in a ZTS environment). If a multi-threaded PHP process uses V8 there is
|
||||||
|
* some stuff shared among all of these threads
|
||||||
|
*
|
||||||
|
* - whether V8 has been initialized at all
|
||||||
|
* - the V8 backend platform
|
||||||
|
* - loaded extensions
|
||||||
|
* - V8 "command line" flags
|
||||||
|
*
|
||||||
|
* In a ZTS-enabled environment access to all of these variables must happen
|
||||||
|
* while holding a mutex lock.
|
||||||
|
*/
|
||||||
|
struct _v8js_process_globals {
|
||||||
|
#ifdef ZTS
|
||||||
|
int v8_initialized;
|
||||||
|
std::mutex lock;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HashTable *extensions;
|
||||||
|
|
||||||
|
/* V8 command line flags */
|
||||||
|
char *v8_flags;
|
||||||
|
|
||||||
|
#if !defined(_WIN32) && PHP_V8_API_VERSION >= 3029036
|
||||||
|
v8::Platform *v8_platform;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct _v8js_process_globals v8js_process_globals;
|
||||||
|
|
||||||
/* Register builtin methods into passed object */
|
/* Register builtin methods into passed object */
|
||||||
void v8js_register_methods(v8::Handle<v8::ObjectTemplate>, v8js_ctx *c);
|
void v8js_register_methods(v8::Handle<v8::ObjectTemplate>, v8js_ctx *c);
|
||||||
|
|
||||||
|
@ -14,6 +14,9 @@ class Foo {
|
|||||||
$this->v8->foo = $this;
|
$this->v8->foo = $this;
|
||||||
$this->v8->executeString('fooobar', 'throw_0');
|
$this->v8->executeString('fooobar', 'throw_0');
|
||||||
var_dump($this->v8->getPendingException());
|
var_dump($this->v8->getPendingException());
|
||||||
|
// the exception is not cleared before the next executeString call,
|
||||||
|
// hence the next *exiting* executeString will throw.
|
||||||
|
// In this case this is the executeString call in bar() function.
|
||||||
$this->v8->executeString('try { PHP.foo.bar(); } catch (e) { print(e + " caught!\n"); }', 'trycatch1');
|
$this->v8->executeString('try { PHP.foo.bar(); } catch (e) { print(e + " caught!\n"); }', 'trycatch1');
|
||||||
$this->v8->executeString('try { PHP.foo.bar(); } catch (e) { print(e + " caught!\n"); }', 'trycatch2');
|
$this->v8->executeString('try { PHP.foo.bar(); } catch (e) { print(e + " caught!\n"); }', 'trycatch2');
|
||||||
}
|
}
|
||||||
@ -21,6 +24,8 @@ class Foo {
|
|||||||
public function bar()
|
public function bar()
|
||||||
{
|
{
|
||||||
echo "To Bar!\n";
|
echo "To Bar!\n";
|
||||||
|
// This executeString call throws a PHP exception, not propagated
|
||||||
|
// to JS, hence immediately triggering the top-level catch handler.
|
||||||
$this->v8->executeString('throw new Error();', 'throw_1');
|
$this->v8->executeString('throw new Error();', 'throw_1');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,7 +76,7 @@ object(V8JsScriptException)#%d (13) {
|
|||||||
["file"]=>
|
["file"]=>
|
||||||
string(%d) "%s"
|
string(%d) "%s"
|
||||||
["line"]=>
|
["line"]=>
|
||||||
int(24)
|
int(29)
|
||||||
["function"]=>
|
["function"]=>
|
||||||
string(11) "__construct"
|
string(11) "__construct"
|
||||||
["class"]=>
|
["class"]=>
|
||||||
@ -100,6 +105,5 @@ object(V8JsScriptException)#%d (13) {
|
|||||||
at throw_0:1:1"
|
at throw_0:1:1"
|
||||||
}
|
}
|
||||||
To Bar!
|
To Bar!
|
||||||
Error caught!
|
|
||||||
PHP Exception: throw_0:1: ReferenceError: fooobar is not defined
|
PHP Exception: throw_0:1: ReferenceError: fooobar is not defined
|
||||||
===EOF===
|
===EOF===
|
||||||
|
33
tests/issue_156_001.phpt
Normal file
33
tests/issue_156_001.phpt
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : Backwards compatibility for issue #156
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||||
|
--INI--
|
||||||
|
v8js.compat_php_exceptions = 1
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$v8 = new V8Js();
|
||||||
|
|
||||||
|
$v8->throwPHPException = function () {
|
||||||
|
echo "throwing PHP exception now ...\n";
|
||||||
|
throw new \Exception('foo');
|
||||||
|
};
|
||||||
|
|
||||||
|
$JS = <<< EOT
|
||||||
|
PHP.throwPHPException();
|
||||||
|
print("... old behaviour was to not stop JS execution on PHP exceptions\\n");
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$v8->executeString($JS, 'issue_156_001.js');
|
||||||
|
} catch(Exception $e) {
|
||||||
|
var_dump($e->getMessage());
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECT--
|
||||||
|
throwing PHP exception now ...
|
||||||
|
... old behaviour was to not stop JS execution on PHP exceptions
|
||||||
|
string(3) "foo"
|
||||||
|
===EOF===
|
23
tests/issue_160_basic.phpt
Normal file
23
tests/issue_160_basic.phpt
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : Issue #160 V8Function affected by V8Js::FLAG_FORCE_ARRAY
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$v8 = new V8Js();
|
||||||
|
|
||||||
|
$JS = <<<EOT
|
||||||
|
(function(foo) { print(foo); });
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
$func = $v8->executeString($JS, 'test', V8Js::FLAG_FORCE_ARRAY);
|
||||||
|
|
||||||
|
var_dump($func);
|
||||||
|
$func("Test-Foo Func Call\n");
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECTF--
|
||||||
|
object(V8Function)#%d (0) {
|
||||||
|
}
|
||||||
|
Test-Foo Func Call
|
||||||
|
===EOF===
|
50
tests/php_exceptions_001.phpt
Normal file
50
tests/php_exceptions_001.phpt
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : PHP Exception handling (repeated)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
function throwException() {
|
||||||
|
throw new \Exception("Test-Exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$v8 = new V8Js();
|
||||||
|
$v8->foo = new \Foo();
|
||||||
|
|
||||||
|
$JS = <<< EOT
|
||||||
|
try {
|
||||||
|
PHP.foo.throwException();
|
||||||
|
// the exception should abort further execution,
|
||||||
|
// hence the print must not pop up
|
||||||
|
print("after throwException\\n");
|
||||||
|
} catch(e) {
|
||||||
|
// JS should not catch in default mode
|
||||||
|
print("JS caught exception");
|
||||||
|
}
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
for($i = 0; $i < 5; $i ++) {
|
||||||
|
var_dump($i);
|
||||||
|
try {
|
||||||
|
$v8->executeString($JS);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
var_dump($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECTF--
|
||||||
|
int(0)
|
||||||
|
string(14) "Test-Exception"
|
||||||
|
int(1)
|
||||||
|
string(14) "Test-Exception"
|
||||||
|
int(2)
|
||||||
|
string(14) "Test-Exception"
|
||||||
|
int(3)
|
||||||
|
string(14) "Test-Exception"
|
||||||
|
int(4)
|
||||||
|
string(14) "Test-Exception"
|
||||||
|
===EOF===
|
67
tests/php_exceptions_002.phpt
Normal file
67
tests/php_exceptions_002.phpt
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : PHP Exception handling (multi-level)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
function throwException() {
|
||||||
|
throw new \Exception("Test-Exception");
|
||||||
|
}
|
||||||
|
|
||||||
|
function recurse($i) {
|
||||||
|
echo "recurse[$i] ...\n";
|
||||||
|
global $work;
|
||||||
|
$work($i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$v8 = new V8Js();
|
||||||
|
$v8->foo = new \Foo();
|
||||||
|
|
||||||
|
$work = $v8->executeString(<<<EOT
|
||||||
|
var work = function(level) {
|
||||||
|
if(level--) {
|
||||||
|
PHP.foo.recurse(level);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PHP.foo.throwException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
work;
|
||||||
|
EOT
|
||||||
|
);
|
||||||
|
|
||||||
|
for($i = 0; $i < 5; $i ++) {
|
||||||
|
var_dump($i);
|
||||||
|
try {
|
||||||
|
$work($i);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
var_dump($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECT--
|
||||||
|
int(0)
|
||||||
|
string(14) "Test-Exception"
|
||||||
|
int(1)
|
||||||
|
recurse[0] ...
|
||||||
|
string(14) "Test-Exception"
|
||||||
|
int(2)
|
||||||
|
recurse[1] ...
|
||||||
|
recurse[0] ...
|
||||||
|
string(14) "Test-Exception"
|
||||||
|
int(3)
|
||||||
|
recurse[2] ...
|
||||||
|
recurse[1] ...
|
||||||
|
recurse[0] ...
|
||||||
|
string(14) "Test-Exception"
|
||||||
|
int(4)
|
||||||
|
recurse[3] ...
|
||||||
|
recurse[2] ...
|
||||||
|
recurse[1] ...
|
||||||
|
recurse[0] ...
|
||||||
|
string(14) "Test-Exception"
|
||||||
|
===EOF===
|
36
tests/php_exceptions_003.phpt
Normal file
36
tests/php_exceptions_003.phpt
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : PHP Exception handling (basic JS propagation)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
function throwException() {
|
||||||
|
throw new \Exception("Test-Exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$v8 = new V8Js();
|
||||||
|
$v8->foo = new \Foo();
|
||||||
|
|
||||||
|
$JS = <<< EOT
|
||||||
|
try {
|
||||||
|
PHP.foo.throwException();
|
||||||
|
// the exception should abort further execution,
|
||||||
|
// hence the print must not pop up
|
||||||
|
print("after throwException\\n");
|
||||||
|
} catch(e) {
|
||||||
|
print("JS caught exception!\\n");
|
||||||
|
var_dump(e.getMessage());
|
||||||
|
}
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
$v8->executeString($JS, 'php_exceptions_003', V8Js::FLAG_PROPAGATE_PHP_EXCEPTIONS);
|
||||||
|
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECTF--
|
||||||
|
JS caught exception!
|
||||||
|
string(14) "Test-Exception"
|
||||||
|
===EOF===
|
36
tests/php_exceptions_004.phpt
Normal file
36
tests/php_exceptions_004.phpt
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : PHP Exception handling (PHP->JS->PHP back propagation)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
function throwException() {
|
||||||
|
throw new \Exception("Test-Exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$v8 = new V8Js();
|
||||||
|
$v8->foo = new \Foo();
|
||||||
|
|
||||||
|
$JS = <<< EOT
|
||||||
|
PHP.foo.throwException();
|
||||||
|
// the exception should abort further execution,
|
||||||
|
// hence the print must not pop up
|
||||||
|
print("after throwException\\n");
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$v8->executeString($JS, 'php_exceptions_004', V8Js::FLAG_PROPAGATE_PHP_EXCEPTIONS);
|
||||||
|
}
|
||||||
|
catch(V8JsScriptException $e) {
|
||||||
|
echo "Got V8JsScriptException\n";
|
||||||
|
var_dump($e->getPrevious()->getMessage());
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECTF--
|
||||||
|
Got V8JsScriptException
|
||||||
|
string(14) "Test-Exception"
|
||||||
|
===EOF===
|
43
tests/php_exceptions_005.phpt
Normal file
43
tests/php_exceptions_005.phpt
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : PHP Exception handling (JS throw PHP-exception)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
function getException() {
|
||||||
|
return new \Exception("Test-Exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$v8 = new V8Js();
|
||||||
|
$v8->foo = new \Foo();
|
||||||
|
|
||||||
|
$JS = <<< EOT
|
||||||
|
var ex = PHP.foo.getException();
|
||||||
|
print("after getException\\n");
|
||||||
|
throw ex;
|
||||||
|
print("after throw\\n");
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$v8->executeString($JS, 'php_exceptions_005');
|
||||||
|
}
|
||||||
|
catch(V8JsScriptException $e) {
|
||||||
|
echo "Got V8JsScriptException\n";
|
||||||
|
var_dump($e->getMessage());
|
||||||
|
var_dump($e->getPrevious()->getMessage());
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECTF--
|
||||||
|
after getException
|
||||||
|
Got V8JsScriptException
|
||||||
|
string(%d) "php_exceptions_005:3: exception 'Exception' with message 'Test-Exception' in %s
|
||||||
|
Stack trace:
|
||||||
|
#0 [internal function]: Foo->getException()
|
||||||
|
#1 %s: V8Js->executeString('var ex = PHP.fo...', 'php_exceptions_...')
|
||||||
|
#2 {main}"
|
||||||
|
string(14) "Test-Exception"
|
||||||
|
===EOF===
|
40
tests/php_exceptions_006.phpt
Normal file
40
tests/php_exceptions_006.phpt
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : PHP Exception handling (JS throws normal PHP-object)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
function getNonExceptionObject() {
|
||||||
|
return new \Foo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$v8 = new V8Js();
|
||||||
|
$v8->foo = new \Foo();
|
||||||
|
|
||||||
|
$JS = <<< EOT
|
||||||
|
var ex = PHP.foo.getNonExceptionObject();
|
||||||
|
print("after getNonExceptionObject\\n");
|
||||||
|
throw ex;
|
||||||
|
print("after throw\\n");
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$v8->executeString($JS, 'php_exceptions_006');
|
||||||
|
}
|
||||||
|
catch(V8JsScriptException $e) {
|
||||||
|
echo "Got V8JsScriptException\n";
|
||||||
|
var_dump($e->getMessage());
|
||||||
|
// previous exception should be NULL, as it is *not* a php exception
|
||||||
|
var_dump($e->getPrevious());
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECTF--
|
||||||
|
after getNonExceptionObject
|
||||||
|
Got V8JsScriptException
|
||||||
|
string(34) "php_exceptions_006:3: [object Foo]"
|
||||||
|
NULL
|
||||||
|
===EOF===
|
42
tests/php_exceptions_basic.phpt
Normal file
42
tests/php_exceptions_basic.phpt
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : PHP Exception handling (basic)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
function throwException() {
|
||||||
|
throw new \Exception("Test-Exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$v8 = new V8Js();
|
||||||
|
$v8->foo = new \Foo();
|
||||||
|
|
||||||
|
$JS = <<< EOT
|
||||||
|
try {
|
||||||
|
PHP.foo.throwException();
|
||||||
|
// the exception should abort further execution,
|
||||||
|
// hence the print must not pop up
|
||||||
|
print("after throwException\\n");
|
||||||
|
} catch(e) {
|
||||||
|
// JS should not catch in default mode
|
||||||
|
print("JS caught exception");
|
||||||
|
}
|
||||||
|
EOT;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$v8->executeString($JS);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
var_dump($e->getMessage());
|
||||||
|
var_dump($e->getFile());
|
||||||
|
var_dump($e->getLine());
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECTF--
|
||||||
|
string(14) "Test-Exception"
|
||||||
|
string(%d) "%sphp_exceptions_basic.php"
|
||||||
|
int(5)
|
||||||
|
===EOF===
|
65
tests/pthreads_001.phpt
Normal file
65
tests/pthreads_001.phpt
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : Pthreads test #1
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
require_once(dirname(__FILE__) . '/skipif.inc');
|
||||||
|
if(!class_exists('Thread')) {
|
||||||
|
die('skip pthreads extension required');
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class Workhorse extends Thread
|
||||||
|
{
|
||||||
|
protected $val;
|
||||||
|
|
||||||
|
public function __construct($val)
|
||||||
|
{
|
||||||
|
$this->val = $val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function run()
|
||||||
|
{
|
||||||
|
$v8 = new V8Js();
|
||||||
|
$v8->val = $this->val;
|
||||||
|
$v8->sync_var_dump = function($value) {
|
||||||
|
$this->synchronized(function($thread) use ($value) {
|
||||||
|
while(!$thread->readyToPrint) {
|
||||||
|
$thread->wait();
|
||||||
|
}
|
||||||
|
var_dump($value);
|
||||||
|
$thread->notify();
|
||||||
|
}, $this);
|
||||||
|
};
|
||||||
|
|
||||||
|
$v8->executeString('PHP.sync_var_dump(PHP.val);');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$foo = new Workhorse('foo');
|
||||||
|
$bar = new Workhorse('bar');
|
||||||
|
|
||||||
|
$foo->start();
|
||||||
|
$bar->start();
|
||||||
|
|
||||||
|
$bar->synchronized(function($thread) {
|
||||||
|
$thread->readyToPrint = true;
|
||||||
|
$thread->notify();
|
||||||
|
$thread->wait();
|
||||||
|
}, $bar);
|
||||||
|
|
||||||
|
$foo->synchronized(function($thread) {
|
||||||
|
$thread->readyToPrint = true;
|
||||||
|
$thread->notify();
|
||||||
|
$thread->wait();
|
||||||
|
}, $foo);
|
||||||
|
|
||||||
|
$foo->join();
|
||||||
|
$bar->join();
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECT--
|
||||||
|
string(3) "bar"
|
||||||
|
string(3) "foo"
|
||||||
|
===EOF===
|
125
v8js.cc
125
v8js.cc
@ -28,55 +28,77 @@ extern "C" {
|
|||||||
#include "v8js_v8object_class.h"
|
#include "v8js_v8object_class.h"
|
||||||
|
|
||||||
ZEND_DECLARE_MODULE_GLOBALS(v8js)
|
ZEND_DECLARE_MODULE_GLOBALS(v8js)
|
||||||
|
struct _v8js_process_globals v8js_process_globals;
|
||||||
|
|
||||||
/* {{{ INI Settings */
|
/* {{{ INI Settings */
|
||||||
|
|
||||||
static ZEND_INI_MH(v8js_OnUpdateV8Flags) /* {{{ */
|
static ZEND_INI_MH(v8js_OnUpdateV8Flags) /* {{{ */
|
||||||
{
|
{
|
||||||
|
bool immutable = false;
|
||||||
|
|
||||||
|
#ifdef ZTS
|
||||||
|
v8js_process_globals.lock.lock();
|
||||||
|
|
||||||
|
if(v8js_process_globals.v8_initialized) {
|
||||||
|
v8js_process_globals.lock.unlock();
|
||||||
|
immutable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
v8js_process_globals.lock.unlock();
|
||||||
|
#else
|
||||||
|
immutable = V8JSG(v8_initialized);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(immutable) {
|
||||||
|
/* V8 already has been initialized -> cannot be changed anymore */
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
if (new_value) {
|
if (new_value) {
|
||||||
if (V8JSG(v8_flags)) {
|
if (v8js_process_globals.v8_flags) {
|
||||||
free(V8JSG(v8_flags));
|
free(v8js_process_globals.v8_flags);
|
||||||
V8JSG(v8_flags) = NULL;
|
v8js_process_globals.v8_flags = NULL;
|
||||||
}
|
}
|
||||||
if (!new_value->val[0]) {
|
if (!new_value->val[0]) {
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
V8JSG(v8_flags) = zend_strndup(new_value->val, new_value->len);
|
v8js_process_globals.v8_flags = zend_strndup(new_value->val, new_value->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool v8js_ini_to_bool(const zend_string *new_value) /* {{{ */
|
||||||
|
{
|
||||||
|
if (new_value->len == 2 && strcasecmp("on", new_value->val) == 0) {
|
||||||
|
return true;
|
||||||
|
} else if (new_value->len == 3 && strcasecmp("yes", new_value->val) == 0) {
|
||||||
|
return true;
|
||||||
|
} else if (new_value->len == 4 && strcasecmp("true", new_value->val) == 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return (bool) atoi(new_value->val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
static ZEND_INI_MH(v8js_OnUpdateUseDate) /* {{{ */
|
static ZEND_INI_MH(v8js_OnUpdateUseDate) /* {{{ */
|
||||||
{
|
{
|
||||||
bool value;
|
V8JSG(use_date) = v8js_ini_to_bool(new_value);
|
||||||
if (new_value->len == 2 && strcasecmp("on", new_value->val) == 0) {
|
|
||||||
value = (bool) 1;
|
|
||||||
} else if (new_value->len == 3 && strcasecmp("yes", new_value->val) == 0) {
|
|
||||||
value = (bool) 1;
|
|
||||||
} else if (new_value->len == 4 && strcasecmp("true", new_value->val) == 0) {
|
|
||||||
value = (bool) 1;
|
|
||||||
} else {
|
|
||||||
value = (bool) atoi(new_value->val);
|
|
||||||
}
|
|
||||||
V8JSG(use_date) = value;
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static ZEND_INI_MH(v8js_OnUpdateUseArrayAccess) /* {{{ */
|
static ZEND_INI_MH(v8js_OnUpdateUseArrayAccess) /* {{{ */
|
||||||
{
|
{
|
||||||
bool value;
|
V8JSG(use_array_access) = v8js_ini_to_bool(new_value);
|
||||||
if (new_value->len == 2 && strcasecmp("on", new_value->val) == 0) {
|
return SUCCESS;
|
||||||
value = (bool) 1;
|
}
|
||||||
} else if (new_value->len == 3 && strcasecmp("yes", new_value->val) == 0) {
|
/* }}} */
|
||||||
value = (bool) 1;
|
|
||||||
} else if (new_value->len == 4 && strcasecmp("true", new_value->val) == 0) {
|
static ZEND_INI_MH(v8js_OnUpdateCompatExceptions) /* {{{ */
|
||||||
value = (bool) 1;
|
{
|
||||||
} else {
|
V8JSG(compat_php_exceptions) = v8js_ini_to_bool(new_value);
|
||||||
value = (bool) atoi(new_value->val);
|
|
||||||
}
|
|
||||||
V8JSG(use_array_access) = value;
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@ -85,6 +107,7 @@ ZEND_INI_BEGIN() /* {{{ */
|
|||||||
ZEND_INI_ENTRY("v8js.flags", NULL, ZEND_INI_ALL, v8js_OnUpdateV8Flags)
|
ZEND_INI_ENTRY("v8js.flags", NULL, ZEND_INI_ALL, v8js_OnUpdateV8Flags)
|
||||||
ZEND_INI_ENTRY("v8js.use_date", "0", ZEND_INI_ALL, v8js_OnUpdateUseDate)
|
ZEND_INI_ENTRY("v8js.use_date", "0", ZEND_INI_ALL, v8js_OnUpdateUseDate)
|
||||||
ZEND_INI_ENTRY("v8js.use_array_access", "0", ZEND_INI_ALL, v8js_OnUpdateUseArrayAccess)
|
ZEND_INI_ENTRY("v8js.use_array_access", "0", ZEND_INI_ALL, v8js_OnUpdateUseArrayAccess)
|
||||||
|
ZEND_INI_ENTRY("v8js.compat_php_exceptions", "0", ZEND_INI_ALL, v8js_OnUpdateCompatExceptions)
|
||||||
ZEND_INI_END()
|
ZEND_INI_END()
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
@ -119,6 +142,35 @@ PHP_MINIT_FUNCTION(v8js)
|
|||||||
static PHP_MSHUTDOWN_FUNCTION(v8js)
|
static PHP_MSHUTDOWN_FUNCTION(v8js)
|
||||||
{
|
{
|
||||||
UNREGISTER_INI_ENTRIES();
|
UNREGISTER_INI_ENTRIES();
|
||||||
|
|
||||||
|
bool v8_initialized;
|
||||||
|
|
||||||
|
#ifdef ZTS
|
||||||
|
v8_initialized = v8js_process_globals.v8_initialized;
|
||||||
|
#else
|
||||||
|
v8_initialized = V8JSG(v8_initialized);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(v8_initialized) {
|
||||||
|
v8::V8::Dispose();
|
||||||
|
#if !defined(_WIN32) && PHP_V8_API_VERSION >= 3029036
|
||||||
|
v8::V8::ShutdownPlatform();
|
||||||
|
// @fixme call virtual destructor somehow
|
||||||
|
//delete v8js_process_globals.v8_platform;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v8js_process_globals.v8_flags) {
|
||||||
|
free(v8js_process_globals.v8_flags);
|
||||||
|
v8js_process_globals.v8_flags = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v8js_process_globals.extensions) {
|
||||||
|
zend_hash_destroy(v8js_process_globals.extensions);
|
||||||
|
free(v8js_process_globals.extensions);
|
||||||
|
v8js_process_globals.extensions = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
@ -174,9 +226,7 @@ static PHP_GINIT_FUNCTION(v8js)
|
|||||||
run the destructors manually.
|
run the destructors manually.
|
||||||
*/
|
*/
|
||||||
#ifdef ZTS
|
#ifdef ZTS
|
||||||
v8js_globals->extensions = NULL;
|
|
||||||
v8js_globals->v8_initialized = 0;
|
v8js_globals->v8_initialized = 0;
|
||||||
v8js_globals->v8_flags = NULL;
|
|
||||||
|
|
||||||
v8js_globals->timer_thread = NULL;
|
v8js_globals->timer_thread = NULL;
|
||||||
v8js_globals->timer_stop = false;
|
v8js_globals->timer_stop = false;
|
||||||
@ -192,29 +242,10 @@ static PHP_GINIT_FUNCTION(v8js)
|
|||||||
*/
|
*/
|
||||||
static PHP_GSHUTDOWN_FUNCTION(v8js)
|
static PHP_GSHUTDOWN_FUNCTION(v8js)
|
||||||
{
|
{
|
||||||
if (v8js_globals->extensions) {
|
|
||||||
zend_hash_destroy(v8js_globals->extensions);
|
|
||||||
free(v8js_globals->extensions);
|
|
||||||
v8js_globals->extensions = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (v8js_globals->v8_flags) {
|
|
||||||
free(v8js_globals->v8_flags);
|
|
||||||
v8js_globals->v8_flags = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ZTS
|
#ifdef ZTS
|
||||||
v8js_globals->timer_stack.~deque();
|
v8js_globals->timer_stack.~deque();
|
||||||
v8js_globals->timer_mutex.~mutex();
|
v8js_globals->timer_mutex.~mutex();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (v8js_globals->v8_initialized) {
|
|
||||||
v8::V8::Dispose();
|
|
||||||
#if !defined(_WIN32) && PHP_V8_API_VERSION >= 3029036
|
|
||||||
v8::V8::ShutdownPlatform();
|
|
||||||
delete v8js_globals->v8_platform;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -2,12 +2,13 @@
|
|||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| PHP Version 5 |
|
| PHP Version 5 |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| Copyright (c) 1997-2013 The PHP Group |
|
| Copyright (c) 1997-2015 The PHP Group |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| http://www.opensource.org/licenses/mit-license.php MIT License |
|
| http://www.opensource.org/licenses/mit-license.php MIT License |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| Author: Jani Taskinen <jani.taskinen@iki.fi> |
|
| Author: Jani Taskinen <jani.taskinen@iki.fi> |
|
||||||
| Author: Patrick Reilly <preilly@php.net> |
|
| Author: Patrick Reilly <preilly@php.net> |
|
||||||
|
| Author: Stefan Siegl <stesie@php.net> |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -103,6 +104,22 @@ static void v8js_free_storage(zend_object *object TSRMLS_DC) /* {{{ */
|
|||||||
c->object_name.~Persistent();
|
c->object_name.~Persistent();
|
||||||
c->global_template.Reset();
|
c->global_template.Reset();
|
||||||
c->global_template.~Persistent();
|
c->global_template.~Persistent();
|
||||||
|
c->array_tmpl.Reset();
|
||||||
|
c->array_tmpl.~Persistent();
|
||||||
|
|
||||||
|
/* Clear persistent call_impl & method_tmpls templates */
|
||||||
|
for (std::map<v8js_tmpl_t *, v8js_tmpl_t>::iterator it = c->call_impls.begin();
|
||||||
|
it != c->call_impls.end(); ++it) {
|
||||||
|
// No need to free it->first, as it is stored in c->template_cache and freed below
|
||||||
|
it->second.Reset();
|
||||||
|
}
|
||||||
|
c->call_impls.~map();
|
||||||
|
|
||||||
|
for (std::map<zend_function *, v8js_tmpl_t>::iterator it = c->method_tmpls.begin();
|
||||||
|
it != c->method_tmpls.end(); ++it) {
|
||||||
|
it->second.Reset();
|
||||||
|
}
|
||||||
|
c->method_tmpls.~map();
|
||||||
|
|
||||||
/* Clear persistent handles in template cache */
|
/* Clear persistent handles in template cache */
|
||||||
for (std::map<const zend_string *,v8js_tmpl_t>::iterator it = c->template_cache.begin();
|
for (std::map<const zend_string *,v8js_tmpl_t>::iterator it = c->template_cache.begin();
|
||||||
@ -196,6 +213,7 @@ static zend_object* v8js_new(zend_class_entry *ce TSRMLS_DC) /* {{{ */
|
|||||||
new(&c->object_name) v8::Persistent<v8::String>();
|
new(&c->object_name) v8::Persistent<v8::String>();
|
||||||
new(&c->context) v8::Persistent<v8::Context>();
|
new(&c->context) v8::Persistent<v8::Context>();
|
||||||
new(&c->global_template) v8::Persistent<v8::FunctionTemplate>();
|
new(&c->global_template) v8::Persistent<v8::FunctionTemplate>();
|
||||||
|
new(&c->array_tmpl) v8::Persistent<v8::FunctionTemplate>();
|
||||||
|
|
||||||
new(&c->modules_stack) std::vector<char*>();
|
new(&c->modules_stack) std::vector<char*>();
|
||||||
new(&c->modules_base) std::vector<char*>();
|
new(&c->modules_base) std::vector<char*>();
|
||||||
@ -206,6 +224,8 @@ static zend_object* v8js_new(zend_class_entry *ce TSRMLS_DC) /* {{{ */
|
|||||||
|
|
||||||
new(&c->weak_closures) std::map<v8js_tmpl_t *, v8js_persistent_obj_t>();
|
new(&c->weak_closures) std::map<v8js_tmpl_t *, v8js_persistent_obj_t>();
|
||||||
new(&c->weak_objects) std::map<zend_object *, v8js_persistent_obj_t>();
|
new(&c->weak_objects) std::map<zend_object *, v8js_persistent_obj_t>();
|
||||||
|
new(&c->call_impls) std::map<v8js_tmpl_t *, v8js_tmpl_t>();
|
||||||
|
new(&c->method_tmpls) std::map<zend_function *, v8js_tmpl_t>();
|
||||||
|
|
||||||
new(&c->v8js_v8objects) std::list<v8js_v8object *>();
|
new(&c->v8js_v8objects) std::list<v8js_v8object *>();
|
||||||
new(&c->script_objects) std::vector<v8js_script *>();
|
new(&c->script_objects) std::vector<v8js_script *>();
|
||||||
@ -480,7 +500,7 @@ static void v8js_compile_script(zval *this_ptr, zend_string *str, zend_string *i
|
|||||||
|
|
||||||
/* Compile errors? */
|
/* Compile errors? */
|
||||||
if (script.IsEmpty()) {
|
if (script.IsEmpty()) {
|
||||||
v8js_throw_script_exception(&try_catch TSRMLS_CC);
|
v8js_throw_script_exception(c->isolate, &try_catch TSRMLS_CC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
res = (v8js_script *)emalloc(sizeof(v8js_script));
|
res = (v8js_script *)emalloc(sizeof(v8js_script));
|
||||||
@ -774,10 +794,17 @@ static int v8js_register_extension(zend_string *name, zend_string *source, zval
|
|||||||
{
|
{
|
||||||
v8js_jsext *jsext = NULL;
|
v8js_jsext *jsext = NULL;
|
||||||
|
|
||||||
if (!V8JSG(extensions)) {
|
#ifdef ZTS
|
||||||
V8JSG(extensions) = (HashTable *) malloc(sizeof(HashTable));
|
v8js_process_globals.lock.lock();
|
||||||
zend_hash_init(V8JSG(extensions), 1, NULL, v8js_jsext_dtor, 1);
|
#endif
|
||||||
} else if (zend_hash_exists(V8JSG(extensions), name)) {
|
|
||||||
|
if (!v8js_process_globals.extensions) {
|
||||||
|
v8js_process_globals.extensions = (HashTable *) malloc(sizeof(HashTable));
|
||||||
|
zend_hash_init(v8js_process_globals.extensions, 1, NULL, v8js_jsext_dtor, 1);
|
||||||
|
} else if (zend_hash_exists(v8js_process_globals.extensions, name)) {
|
||||||
|
#ifdef ZTS
|
||||||
|
v8js_process_globals.lock.unlock();
|
||||||
|
#endif
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -789,6 +816,9 @@ static int v8js_register_extension(zend_string *name, zend_string *source, zval
|
|||||||
if (v8js_create_ext_strarr(&jsext->deps, jsext->deps_count, Z_ARRVAL_P(deps_arr)) == FAILURE) {
|
if (v8js_create_ext_strarr(&jsext->deps, jsext->deps_count, Z_ARRVAL_P(deps_arr)) == FAILURE) {
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid dependency array passed");
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid dependency array passed");
|
||||||
v8js_jsext_free_storage(jsext);
|
v8js_jsext_free_storage(jsext);
|
||||||
|
#ifdef ZTS
|
||||||
|
v8js_process_globals.lock.unlock();
|
||||||
|
#endif
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -805,11 +835,18 @@ static int v8js_register_extension(zend_string *name, zend_string *source, zval
|
|||||||
|
|
||||||
jsext->extension = new v8::Extension(ZSTR_VAL(jsext->name), ZSTR_VAL(jsext->source), jsext->deps_count, jsext->deps);
|
jsext->extension = new v8::Extension(ZSTR_VAL(jsext->name), ZSTR_VAL(jsext->source), jsext->deps_count, jsext->deps);
|
||||||
|
|
||||||
if (!zend_hash_add_ptr(V8JSG(extensions), jsext->name, jsext)) {
|
if (!zend_hash_add_ptr(v8js_process_globals.extensions, jsext->name, jsext)) {
|
||||||
v8js_jsext_free_storage(jsext);
|
v8js_jsext_free_storage(jsext);
|
||||||
|
#ifdef ZTS
|
||||||
|
v8js_process_globals.lock.unlock();
|
||||||
|
#endif
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ZTS
|
||||||
|
v8js_process_globals.lock.unlock();
|
||||||
|
#endif
|
||||||
|
|
||||||
jsext->extension->set_auto_enable(auto_enable ? true : false);
|
jsext->extension->set_auto_enable(auto_enable ? true : false);
|
||||||
v8::RegisterExtension(jsext->extension);
|
v8::RegisterExtension(jsext->extension);
|
||||||
|
|
||||||
@ -857,8 +894,12 @@ static PHP_METHOD(V8Js, getExtensions)
|
|||||||
|
|
||||||
array_init(return_value);
|
array_init(return_value);
|
||||||
|
|
||||||
if (V8JSG(extensions)) {
|
#ifdef ZTS
|
||||||
ZEND_HASH_FOREACH_KEY_VAL(V8JSG(extensions), index, key, val) {
|
v8js_process_globals.lock.lock();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (v8js_process_globals.extensions) {
|
||||||
|
ZEND_HASH_FOREACH_KEY_VAL(v8js_process_globals.extensions, index, key, val) {
|
||||||
if (key) {
|
if (key) {
|
||||||
jsext = (v8js_jsext *) Z_PTR_P(val);
|
jsext = (v8js_jsext *) Z_PTR_P(val);
|
||||||
array_init(&ext);
|
array_init(&ext);
|
||||||
@ -873,6 +914,10 @@ static PHP_METHOD(V8Js, getExtensions)
|
|||||||
}
|
}
|
||||||
} ZEND_HASH_FOREACH_END();
|
} ZEND_HASH_FOREACH_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ZTS
|
||||||
|
v8js_process_globals.lock.unlock();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
@ -1039,6 +1084,7 @@ PHP_MINIT_FUNCTION(v8js_class) /* {{{ */
|
|||||||
|
|
||||||
zend_declare_class_constant_long(php_ce_v8js, ZEND_STRL("FLAG_NONE"), V8JS_FLAG_NONE TSRMLS_CC);
|
zend_declare_class_constant_long(php_ce_v8js, ZEND_STRL("FLAG_NONE"), V8JS_FLAG_NONE TSRMLS_CC);
|
||||||
zend_declare_class_constant_long(php_ce_v8js, ZEND_STRL("FLAG_FORCE_ARRAY"), V8JS_FLAG_FORCE_ARRAY TSRMLS_CC);
|
zend_declare_class_constant_long(php_ce_v8js, ZEND_STRL("FLAG_FORCE_ARRAY"), V8JS_FLAG_FORCE_ARRAY TSRMLS_CC);
|
||||||
|
zend_declare_class_constant_long(php_ce_v8js, ZEND_STRL("FLAG_PROPAGATE_PHP_EXCEPTIONS"), V8JS_FLAG_PROPAGATE_PHP_EXCEPTIONS TSRMLS_CC);
|
||||||
|
|
||||||
#ifdef ENABLE_DEBUGGER_SUPPORT
|
#ifdef ENABLE_DEBUGGER_SUPPORT
|
||||||
zend_declare_class_constant_long(php_ce_v8js, ZEND_STRL("DEBUG_AUTO_BREAK_NEVER"), V8JS_DEBUG_AUTO_BREAK_NEVER TSRMLS_CC);
|
zend_declare_class_constant_long(php_ce_v8js, ZEND_STRL("DEBUG_AUTO_BREAK_NEVER"), V8JS_DEBUG_AUTO_BREAK_NEVER TSRMLS_CC);
|
||||||
|
@ -39,12 +39,15 @@ struct v8js_ctx {
|
|||||||
int in_execution;
|
int in_execution;
|
||||||
v8::Isolate *isolate;
|
v8::Isolate *isolate;
|
||||||
|
|
||||||
|
long flags;
|
||||||
|
|
||||||
long time_limit;
|
long time_limit;
|
||||||
bool time_limit_hit;
|
bool time_limit_hit;
|
||||||
long memory_limit;
|
long memory_limit;
|
||||||
bool memory_limit_hit;
|
bool memory_limit_hit;
|
||||||
|
|
||||||
v8::Persistent<v8::FunctionTemplate> global_template;
|
v8js_tmpl_t global_template;
|
||||||
|
v8js_tmpl_t array_tmpl;
|
||||||
|
|
||||||
zval module_loader;
|
zval module_loader;
|
||||||
std::vector<char *> modules_stack;
|
std::vector<char *> modules_stack;
|
||||||
@ -54,6 +57,8 @@ struct v8js_ctx {
|
|||||||
|
|
||||||
std::map<zend_object *, v8js_persistent_obj_t> weak_objects;
|
std::map<zend_object *, v8js_persistent_obj_t> weak_objects;
|
||||||
std::map<v8js_tmpl_t *, v8js_persistent_obj_t> weak_closures;
|
std::map<v8js_tmpl_t *, v8js_persistent_obj_t> weak_closures;
|
||||||
|
std::map<v8js_tmpl_t *, v8js_tmpl_t> call_impls;
|
||||||
|
std::map<zend_function *, v8js_tmpl_t> method_tmpls;
|
||||||
|
|
||||||
std::list<v8js_v8object *> v8js_v8objects;
|
std::list<v8js_v8object *> v8js_v8objects;
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ int v8js_to_zval(v8::Handle<v8::Value> jsValue, zval *return_value, int flags, v
|
|||||||
RETVAL_ZVAL(&zval_object, 1, 0);
|
RETVAL_ZVAL(&zval_object, 1, 0);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
if ((flags & V8JS_FLAG_FORCE_ARRAY) || jsValue->IsArray()) {
|
if ((flags & V8JS_FLAG_FORCE_ARRAY && !jsValue->IsFunction()) || jsValue->IsArray()) {
|
||||||
array_init(return_value);
|
array_init(return_value);
|
||||||
return v8js_get_properties_hash(jsValue, Z_ARRVAL_P(return_value), flags, isolate TSRMLS_CC);
|
return v8js_get_properties_hash(jsValue, Z_ARRVAL_P(return_value), flags, isolate TSRMLS_CC);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,12 +2,13 @@
|
|||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| PHP Version 5 |
|
| PHP Version 5 |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| Copyright (c) 1997-2013 The PHP Group |
|
| Copyright (c) 1997-2015 The PHP Group |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| http://www.opensource.org/licenses/mit-license.php MIT License |
|
| http://www.opensource.org/licenses/mit-license.php MIT License |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| Author: Jani Taskinen <jani.taskinen@iki.fi> |
|
| Author: Jani Taskinen <jani.taskinen@iki.fi> |
|
||||||
| Author: Patrick Reilly <preilly@php.net> |
|
| Author: Patrick Reilly <preilly@php.net> |
|
||||||
|
| Author: Stefan Siegl <stesie@php.net> |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ zend_class_entry *php_ce_v8js_memory_limit_exception;
|
|||||||
|
|
||||||
/* {{{ Class: V8JsScriptException */
|
/* {{{ Class: V8JsScriptException */
|
||||||
|
|
||||||
void v8js_create_script_exception(zval *return_value, v8::TryCatch *try_catch TSRMLS_DC) /* {{{ */
|
void v8js_create_script_exception(zval *return_value, v8::Isolate *isolate, v8::TryCatch *try_catch TSRMLS_DC) /* {{{ */
|
||||||
{
|
{
|
||||||
v8::String::Utf8Value exception(try_catch->Exception());
|
v8::String::Utf8Value exception(try_catch->Exception());
|
||||||
const char *exception_string = ToCString(exception);
|
const char *exception_string = ToCString(exception);
|
||||||
@ -81,6 +82,22 @@ void v8js_create_script_exception(zval *return_value, v8::TryCatch *try_catch TS
|
|||||||
const char* stacktrace_string = ToCString(stacktrace);
|
const char* stacktrace_string = ToCString(stacktrace);
|
||||||
PHPV8_EXPROP(_string, JsTrace, stacktrace_string);
|
PHPV8_EXPROP(_string, JsTrace, stacktrace_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(try_catch->Exception()->IsObject()) {
|
||||||
|
v8::Local<v8::Value> php_ref = try_catch->Exception()->ToObject()->GetHiddenValue(V8JS_SYM(PHPJS_OBJECT_KEY));
|
||||||
|
|
||||||
|
if(!php_ref.IsEmpty()) {
|
||||||
|
assert(php_ref->IsExternal());
|
||||||
|
zval *php_exception = reinterpret_cast<zval *>(v8::External::Cast(*php_ref)->Value());
|
||||||
|
|
||||||
|
zend_class_entry *exception_ce = zend_exception_get_default(TSRMLS_C);
|
||||||
|
if (Z_TYPE_P(php_exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(php_exception), exception_ce TSRMLS_CC)) {
|
||||||
|
Z_ADDREF_P(php_exception);
|
||||||
|
zend_exception_set_previous(Z_OBJ_P(return_value), Z_OBJ_P(php_exception));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PHPV8_EXPROP(_string, message, message_string);
|
PHPV8_EXPROP(_string, message, message_string);
|
||||||
@ -89,7 +106,7 @@ void v8js_create_script_exception(zval *return_value, v8::TryCatch *try_catch TS
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
void v8js_throw_script_exception(v8::TryCatch *try_catch TSRMLS_DC) /* {{{ */
|
void v8js_throw_script_exception(v8::Isolate *isolate, v8::TryCatch *try_catch TSRMLS_DC) /* {{{ */
|
||||||
{
|
{
|
||||||
v8::String::Utf8Value exception(try_catch->Exception());
|
v8::String::Utf8Value exception(try_catch->Exception());
|
||||||
const char *exception_string = ToCString(exception);
|
const char *exception_string = ToCString(exception);
|
||||||
@ -98,7 +115,7 @@ void v8js_throw_script_exception(v8::TryCatch *try_catch TSRMLS_DC) /* {{{ */
|
|||||||
if (try_catch->Message().IsEmpty()) {
|
if (try_catch->Message().IsEmpty()) {
|
||||||
zend_throw_exception(php_ce_v8js_script_exception, (char *) exception_string, 0 TSRMLS_CC);
|
zend_throw_exception(php_ce_v8js_script_exception, (char *) exception_string, 0 TSRMLS_CC);
|
||||||
} else {
|
} else {
|
||||||
v8js_create_script_exception(&zexception, try_catch TSRMLS_CC);
|
v8js_create_script_exception(&zexception, isolate, try_catch TSRMLS_CC);
|
||||||
zend_throw_exception_object(&zexception TSRMLS_CC);
|
zend_throw_exception_object(&zexception TSRMLS_CC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,13 @@
|
|||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| PHP Version 5 |
|
| PHP Version 5 |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| Copyright (c) 1997-2013 The PHP Group |
|
| Copyright (c) 1997-2015 The PHP Group |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| http://www.opensource.org/licenses/mit-license.php MIT License |
|
| http://www.opensource.org/licenses/mit-license.php MIT License |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| Author: Jani Taskinen <jani.taskinen@iki.fi> |
|
| Author: Jani Taskinen <jani.taskinen@iki.fi> |
|
||||||
| Author: Patrick Reilly <preilly@php.net> |
|
| Author: Patrick Reilly <preilly@php.net> |
|
||||||
|
| Author: Stefan Siegl <stesie@php.net> |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -19,8 +20,8 @@ extern zend_class_entry *php_ce_v8js_script_exception;
|
|||||||
extern zend_class_entry *php_ce_v8js_time_limit_exception;
|
extern zend_class_entry *php_ce_v8js_time_limit_exception;
|
||||||
extern zend_class_entry *php_ce_v8js_memory_limit_exception;
|
extern zend_class_entry *php_ce_v8js_memory_limit_exception;
|
||||||
|
|
||||||
void v8js_create_script_exception(zval *return_value, v8::TryCatch *try_catch TSRMLS_DC);
|
void v8js_create_script_exception(zval *return_value, v8::Isolate *isolate, v8::TryCatch *try_catch TSRMLS_DC);
|
||||||
void v8js_throw_script_exception(v8::TryCatch *try_catch TSRMLS_DC);
|
void v8js_throw_script_exception(v8::Isolate *isolate, v8::TryCatch *try_catch TSRMLS_DC);
|
||||||
|
|
||||||
PHP_MINIT_FUNCTION(v8js_exceptions);
|
PHP_MINIT_FUNCTION(v8js_exceptions);
|
||||||
|
|
||||||
|
@ -26,20 +26,7 @@ extern "C" {
|
|||||||
V8JS_METHOD(exit) /* {{{ */
|
V8JS_METHOD(exit) /* {{{ */
|
||||||
{
|
{
|
||||||
v8::Isolate *isolate = info.GetIsolate();
|
v8::Isolate *isolate = info.GetIsolate();
|
||||||
|
v8js_terminate_execution(isolate);
|
||||||
/* Unfortunately just calling TerminateExecution on the isolate is not
|
|
||||||
* enough, since v8 just marks the thread as "to be aborted" and doesn't
|
|
||||||
* immediately do so. Hence we enter an endless loop after signalling
|
|
||||||
* termination, so we definitely don't execute JS code after the exit()
|
|
||||||
* statement. */
|
|
||||||
v8::Locker locker(isolate);
|
|
||||||
v8::Isolate::Scope isolate_scope(isolate);
|
|
||||||
v8::HandleScope handle_scope(isolate);
|
|
||||||
|
|
||||||
v8::Local<v8::String> source = V8JS_STR("for(;;);");
|
|
||||||
v8::Local<v8::Script> script = v8::Script::Compile(source);
|
|
||||||
v8::V8::TerminateExecution(isolate);
|
|
||||||
script->Run();
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ extern "C" {
|
|||||||
#include "ext/standard/php_string.h"
|
#include "ext/standard/php_string.h"
|
||||||
#include "zend_interfaces.h"
|
#include "zend_interfaces.h"
|
||||||
#include "zend_closures.h"
|
#include "zend_closures.h"
|
||||||
|
#include "zend_exceptions.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "php_v8js_macros.h"
|
#include "php_v8js_macros.h"
|
||||||
@ -33,13 +34,13 @@ static void v8js_weak_object_callback(const v8::WeakCallbackData<v8::Object, zen
|
|||||||
/* Callback for PHP methods and functions */
|
/* Callback for PHP methods and functions */
|
||||||
static void v8js_call_php_func(zend_object *object, zend_function *method_ptr, v8::Isolate *isolate, const v8::FunctionCallbackInfo<v8::Value>& info TSRMLS_DC) /* {{{ */
|
static void v8js_call_php_func(zend_object *object, zend_function *method_ptr, v8::Isolate *isolate, const v8::FunctionCallbackInfo<v8::Value>& info TSRMLS_DC) /* {{{ */
|
||||||
{
|
{
|
||||||
v8::Handle<v8::Value> return_value;
|
v8::Handle<v8::Value> return_value = V8JS_NULL;
|
||||||
zend_fcall_info fci;
|
zend_fcall_info fci;
|
||||||
zend_fcall_info_cache fcc;
|
zend_fcall_info_cache fcc;
|
||||||
zval fname, retval, **argv = NULL;
|
zval fname, retval, **argv = NULL;
|
||||||
unsigned int argc = info.Length(), min_num_args = 0, max_num_args = 0;
|
unsigned int argc = info.Length(), min_num_args = 0, max_num_args = 0;
|
||||||
char *error;
|
char *error;
|
||||||
int error_len, i, flags = V8JS_FLAG_NONE;
|
int error_len, i;
|
||||||
|
|
||||||
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
||||||
|
|
||||||
@ -84,7 +85,6 @@ static void v8js_call_php_func(zend_object *object, zend_function *method_ptr, v
|
|||||||
|
|
||||||
/* Convert parameters passed from V8 */
|
/* Convert parameters passed from V8 */
|
||||||
if (argc) {
|
if (argc) {
|
||||||
flags = V8JS_GLOBAL_GET_FLAGS(isolate);
|
|
||||||
fci.params = (zval *) safe_emalloc(argc, sizeof(zval), 0);
|
fci.params = (zval *) safe_emalloc(argc, sizeof(zval), 0);
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
v8::Local<v8::Value> php_object;
|
v8::Local<v8::Value> php_object;
|
||||||
@ -97,7 +97,7 @@ static void v8js_call_php_func(zend_object *object, zend_function *method_ptr, v
|
|||||||
ZVAL_OBJ(&fci.params[i], object);
|
ZVAL_OBJ(&fci.params[i], object);
|
||||||
Z_ADDREF_P(&fci.params[i]);
|
Z_ADDREF_P(&fci.params[i]);
|
||||||
} else {
|
} else {
|
||||||
if (v8js_to_zval(info[i], &fci.params[i], flags, isolate TSRMLS_CC) == FAILURE) {
|
if (v8js_to_zval(info[i], &fci.params[i], ctx->flags, isolate TSRMLS_CC) == FAILURE) {
|
||||||
error_len = spprintf(&error, 0, "converting parameter #%d passed to %s() failed", i + 1, method_ptr->common.function_name);
|
error_len = spprintf(&error, 0, "converting parameter #%d passed to %s() failed", i + 1, method_ptr->common.function_name);
|
||||||
return_value = V8JS_THROW(isolate, Error, error, error_len);
|
return_value = V8JS_THROW(isolate, Error, error, error_len);
|
||||||
efree(error);
|
efree(error);
|
||||||
@ -132,7 +132,7 @@ static void v8js_call_php_func(zend_object *object, zend_function *method_ptr, v
|
|||||||
isolate->Enter();
|
isolate->Enter();
|
||||||
}
|
}
|
||||||
zend_catch {
|
zend_catch {
|
||||||
v8::V8::TerminateExecution(isolate);
|
v8js_terminate_execution(isolate);
|
||||||
V8JSG(fatal_error_abort) = 1;
|
V8JSG(fatal_error_abort) = 1;
|
||||||
}
|
}
|
||||||
zend_end_try();
|
zend_end_try();
|
||||||
@ -146,7 +146,19 @@ failure:
|
|||||||
efree(fci.params);
|
efree(fci.params);
|
||||||
}
|
}
|
||||||
|
|
||||||
return_value = zval_to_v8js(&retval, isolate TSRMLS_CC);
|
if(EG(exception) && !V8JSG(compat_php_exceptions)) {
|
||||||
|
if(ctx->flags & V8JS_FLAG_PROPAGATE_PHP_EXCEPTIONS) {
|
||||||
|
zval tmp_zv;
|
||||||
|
ZVAL_OBJ(&tmp_zv, EG(exception));
|
||||||
|
return_value = isolate->ThrowException(zval_to_v8js(&tmp_zv, isolate TSRMLS_CC));
|
||||||
|
zend_clear_exception(TSRMLS_C);
|
||||||
|
} else {
|
||||||
|
v8js_terminate_execution(isolate);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return_value = zval_to_v8js(&retval, isolate TSRMLS_CC);
|
||||||
|
}
|
||||||
|
|
||||||
zval_dtor(&retval);
|
zval_dtor(&retval);
|
||||||
zval_dtor(&fname);
|
zval_dtor(&fname);
|
||||||
|
|
||||||
@ -505,6 +517,7 @@ template<typename T>
|
|||||||
v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<T> &info, property_op_t callback_type, v8::Local<v8::Value> set_value) /* {{{ */
|
v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<T> &info, property_op_t callback_type, v8::Local<v8::Value> set_value) /* {{{ */
|
||||||
{
|
{
|
||||||
v8::Isolate *isolate = info.GetIsolate();
|
v8::Isolate *isolate = info.GetIsolate();
|
||||||
|
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
||||||
v8::String::Utf8Value cstr(property);
|
v8::String::Utf8Value cstr(property);
|
||||||
const char *name = ToCString(cstr);
|
const char *name = ToCString(cstr);
|
||||||
uint name_len = property->Utf8Length();
|
uint name_len = property->Utf8Length();
|
||||||
@ -524,9 +537,8 @@ v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::String> property
|
|||||||
zval zobject;
|
zval zobject;
|
||||||
ZVAL_OBJ(&zobject, object);
|
ZVAL_OBJ(&zobject, object);
|
||||||
|
|
||||||
v8::Local<v8::FunctionTemplate> tmpl =
|
v8js_tmpl_t *tmpl_ptr = reinterpret_cast<v8js_tmpl_t *>(self->GetAlignedPointerFromInternalField(0));
|
||||||
v8::Local<v8::FunctionTemplate>::New
|
v8::Local<v8::FunctionTemplate> tmpl = v8::Local<v8::FunctionTemplate>::New(isolate, *tmpl_ptr);
|
||||||
(isolate, *reinterpret_cast<v8js_tmpl_t *>(self->GetAlignedPointerFromInternalField(0)));
|
|
||||||
ce = scope = object->ce;
|
ce = scope = object->ce;
|
||||||
|
|
||||||
/* First, check the (case-insensitive) method table */
|
/* First, check the (case-insensitive) method table */
|
||||||
@ -560,14 +572,35 @@ v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::String> property
|
|||||||
// Fake __call implementation
|
// Fake __call implementation
|
||||||
// (only use this if method_ptr==NULL, which means
|
// (only use this if method_ptr==NULL, which means
|
||||||
// there is no actual PHP __call() implementation)
|
// there is no actual PHP __call() implementation)
|
||||||
v8::Local<v8::Function> cb =
|
v8::Local<v8::FunctionTemplate> ft;
|
||||||
v8::FunctionTemplate::New(isolate,
|
try {
|
||||||
v8js_fake_call_impl, V8JS_NULL,
|
ft = v8::Local<v8::FunctionTemplate>::New
|
||||||
v8::Signature::New(isolate, tmpl))->GetFunction();
|
(isolate, ctx->call_impls.at(tmpl_ptr));
|
||||||
|
}
|
||||||
|
catch (const std::out_of_range &) {
|
||||||
|
ft = v8::FunctionTemplate::New(isolate,
|
||||||
|
v8js_fake_call_impl, V8JS_NULL,
|
||||||
|
v8::Signature::New(isolate, tmpl));
|
||||||
|
v8js_tmpl_t *persistent_ft = &ctx->call_impls[tmpl_ptr];
|
||||||
|
persistent_ft->Reset(isolate, ft);
|
||||||
|
}
|
||||||
|
v8::Local<v8::Function> cb = ft->GetFunction();
|
||||||
cb->SetName(property);
|
cb->SetName(property);
|
||||||
ret_value = cb;
|
ret_value = cb;
|
||||||
} else {
|
} else {
|
||||||
ret_value = PHP_V8JS_CALLBACK(isolate, method_ptr, tmpl);
|
v8::Local<v8::FunctionTemplate> ft;
|
||||||
|
try {
|
||||||
|
ft = v8::Local<v8::FunctionTemplate>::New
|
||||||
|
(isolate, ctx->method_tmpls.at(method_ptr));
|
||||||
|
}
|
||||||
|
catch (const std::out_of_range &) {
|
||||||
|
ft = v8::FunctionTemplate::New(isolate, v8js_php_callback,
|
||||||
|
v8::External::New((isolate), method_ptr),
|
||||||
|
v8::Signature::New((isolate), tmpl));
|
||||||
|
v8js_tmpl_t *persistent_ft = &ctx->method_tmpls[method_ptr];
|
||||||
|
persistent_ft->Reset(isolate, ft);
|
||||||
|
}
|
||||||
|
ret_value = ft->GetFunction();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (callback_type == V8JS_PROP_QUERY) {
|
} else if (callback_type == V8JS_PROP_QUERY) {
|
||||||
@ -623,9 +656,7 @@ v8::Local<v8::Value> v8js_named_property_callback(v8::Local<v8::String> property
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if (callback_type == V8JS_PROP_SETTER) {
|
} else if (callback_type == V8JS_PROP_SETTER) {
|
||||||
int flags = V8JS_GLOBAL_GET_FLAGS(isolate);
|
if (v8js_to_zval(set_value, &php_value, ctx->flags, isolate TSRMLS_CC) != SUCCESS) {
|
||||||
|
|
||||||
if (v8js_to_zval(set_value, &php_value, flags, isolate TSRMLS_CC) != SUCCESS) {
|
|
||||||
ret_value = v8::Handle<v8::Value>();
|
ret_value = v8::Handle<v8::Value>();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -833,12 +864,22 @@ static v8::Handle<v8::Object> v8js_wrap_array_to_object(v8::Isolate *isolate, zv
|
|||||||
zend_string *key;
|
zend_string *key;
|
||||||
ulong index;
|
ulong index;
|
||||||
|
|
||||||
// @todo re-use template likewise
|
v8js_ctx *ctx = (v8js_ctx *) isolate->GetData(0);
|
||||||
v8::Local<v8::FunctionTemplate> new_tpl = v8::FunctionTemplate::New(isolate, 0);
|
v8::Local<v8::FunctionTemplate> new_tpl;
|
||||||
|
|
||||||
/* Call it Array, but it is not a native array, especially it doesn't have
|
if(ctx->array_tmpl.IsEmpty()) {
|
||||||
* have the typical Array.prototype functions. */
|
new_tpl = v8::FunctionTemplate::New(isolate, 0);
|
||||||
new_tpl->SetClassName(V8JS_SYM("Array"));
|
|
||||||
|
/* Call it Array, but it is not a native array, especially it doesn't have
|
||||||
|
* have the typical Array.prototype functions. */
|
||||||
|
new_tpl->SetClassName(V8JS_SYM("Array"));
|
||||||
|
|
||||||
|
/* Store for later re-use */
|
||||||
|
ctx->array_tmpl.Reset(isolate, new_tpl);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
new_tpl = v8::Local<v8::FunctionTemplate>::New(isolate, ctx->array_tmpl);
|
||||||
|
}
|
||||||
|
|
||||||
v8::Handle<v8::Object> newobj = new_tpl->InstanceTemplate()->NewInstance();
|
v8::Handle<v8::Object> newobj = new_tpl->InstanceTemplate()->NewInstance();
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ static void v8js_timer_interrupt_handler(v8::Isolate *isolate, void *data) { /*
|
|||||||
|
|
||||||
if (timer_ctx->memory_limit > 0 && hs.used_heap_size() > timer_ctx->memory_limit) {
|
if (timer_ctx->memory_limit > 0 && hs.used_heap_size() > timer_ctx->memory_limit) {
|
||||||
timer_ctx->killed = true;
|
timer_ctx->killed = true;
|
||||||
v8js_terminate_execution(c TSRMLS_CC);
|
v8::V8::TerminateExecution(c->isolate);
|
||||||
c->memory_limit_hit = true;
|
c->memory_limit_hit = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,7 +79,7 @@ void v8js_timer_thread(zend_v8js_globals *globals) /* {{{ */
|
|||||||
}
|
}
|
||||||
else if(timer_ctx->time_limit > 0 && now > timer_ctx->time_point) {
|
else if(timer_ctx->time_limit > 0 && now > timer_ctx->time_point) {
|
||||||
timer_ctx->killed = true;
|
timer_ctx->killed = true;
|
||||||
v8js_terminate_execution(c TSRMLS_CC);
|
v8::V8::TerminateExecution(c->isolate);
|
||||||
c->time_limit_hit = true;
|
c->time_limit_hit = true;
|
||||||
}
|
}
|
||||||
else if (timer_ctx->memory_limit > 0) {
|
else if (timer_ctx->memory_limit > 0) {
|
||||||
|
63
v8js_v8.cc
63
v8js_v8.cc
@ -2,12 +2,13 @@
|
|||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| PHP Version 5 |
|
| PHP Version 5 |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| Copyright (c) 1997-2013 The PHP Group |
|
| Copyright (c) 1997-2015 The PHP Group |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| http://www.opensource.org/licenses/mit-license.php MIT License |
|
| http://www.opensource.org/licenses/mit-license.php MIT License |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
| Author: Jani Taskinen <jani.taskinen@iki.fi> |
|
| Author: Jani Taskinen <jani.taskinen@iki.fi> |
|
||||||
| Author: Patrick Reilly <preilly@php.net> |
|
| Author: Patrick Reilly <preilly@php.net> |
|
||||||
|
| Author: Stefan Siegl <stesie@php.net> |
|
||||||
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -36,26 +37,42 @@ extern "C" {
|
|||||||
|
|
||||||
void v8js_v8_init(TSRMLS_D) /* {{{ */
|
void v8js_v8_init(TSRMLS_D) /* {{{ */
|
||||||
{
|
{
|
||||||
/* Run only once */
|
/* Run only once; thread-local test first */
|
||||||
if (V8JSG(v8_initialized)) {
|
if (V8JSG(v8_initialized)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set thread-local flag, that V8 was initialized. */
|
||||||
|
V8JSG(v8_initialized) = 1;
|
||||||
|
|
||||||
|
#ifdef ZTS
|
||||||
|
v8js_process_globals.lock.lock();
|
||||||
|
|
||||||
|
if(v8js_process_globals.v8_initialized) {
|
||||||
|
/* V8 already has been initialized by another thread */
|
||||||
|
v8js_process_globals.lock.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(_WIN32) && PHP_V8_API_VERSION >= 3029036
|
#if !defined(_WIN32) && PHP_V8_API_VERSION >= 3029036
|
||||||
V8JSG(v8_platform) = v8::platform::CreateDefaultPlatform();
|
v8js_process_globals.v8_platform = v8::platform::CreateDefaultPlatform();
|
||||||
v8::V8::InitializePlatform(V8JSG(v8_platform));
|
v8::V8::InitializePlatform(v8js_process_globals.v8_platform);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set V8 command line flags (must be done before V8::Initialize()!) */
|
/* Set V8 command line flags (must be done before V8::Initialize()!) */
|
||||||
if (V8JSG(v8_flags)) {
|
if (v8js_process_globals.v8_flags) {
|
||||||
v8::V8::SetFlagsFromString(V8JSG(v8_flags), strlen(V8JSG(v8_flags)));
|
v8::V8::SetFlagsFromString(v8js_process_globals.v8_flags,
|
||||||
|
strlen(v8js_process_globals.v8_flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize V8 */
|
/* Initialize V8 */
|
||||||
v8::V8::Initialize();
|
v8::V8::Initialize();
|
||||||
|
|
||||||
/* Run only once */
|
#ifdef ZTS
|
||||||
V8JSG(v8_initialized) = 1;
|
v8js_process_globals.v8_initialized = 1;
|
||||||
|
v8js_process_globals.lock.unlock();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
@ -77,7 +94,7 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value,
|
|||||||
v8::TryCatch try_catch;
|
v8::TryCatch try_catch;
|
||||||
|
|
||||||
/* Set flags for runtime use */
|
/* Set flags for runtime use */
|
||||||
V8JS_GLOBAL_SET_FLAGS(isolate, flags);
|
c->flags = flags;
|
||||||
|
|
||||||
/* Check if timezone has been changed and notify V8 */
|
/* Check if timezone has been changed and notify V8 */
|
||||||
tz = getenv("TZ");
|
tz = getenv("TZ");
|
||||||
@ -176,13 +193,13 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value,
|
|||||||
|
|
||||||
/* Report immediately if report_uncaught is true */
|
/* Report immediately if report_uncaught is true */
|
||||||
if (c->report_uncaught) {
|
if (c->report_uncaught) {
|
||||||
v8js_throw_script_exception(&try_catch TSRMLS_CC);
|
v8js_throw_script_exception(c->isolate, &try_catch TSRMLS_CC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exception thrown from JS, preserve it for future execution */
|
/* Exception thrown from JS, preserve it for future execution */
|
||||||
if (result.IsEmpty()) {
|
if (result.IsEmpty()) {
|
||||||
v8js_create_script_exception(&c->pending_exception, &try_catch TSRMLS_CC);
|
v8js_create_script_exception(&c->pending_exception, c->isolate, &try_catch TSRMLS_CC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,10 +216,28 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value,
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
void v8js_terminate_execution(v8js_ctx *c TSRMLS_DC) /* {{{ */
|
void v8js_terminate_execution(v8::Isolate *isolate) /* {{{ */
|
||||||
{
|
{
|
||||||
// Forcefully terminate the current thread of V8 execution in the isolate
|
if(v8::V8::IsExecutionTerminating(isolate)) {
|
||||||
v8::V8::TerminateExecution(c->isolate);
|
/* Execution already terminating, needn't trigger it again and
|
||||||
|
* especially must not execute the spinning loop (which would cause
|
||||||
|
* crashes in V8 itself, at least with 4.2 and 4.3 version lines). */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unfortunately just calling TerminateExecution on the isolate is not
|
||||||
|
* enough, since v8 just marks the thread as "to be aborted" and doesn't
|
||||||
|
* immediately do so. Hence we enter an endless loop after signalling
|
||||||
|
* termination, so we definitely don't execute JS code after the exit()
|
||||||
|
* statement. */
|
||||||
|
v8::Locker locker(isolate);
|
||||||
|
v8::Isolate::Scope isolate_scope(isolate);
|
||||||
|
v8::HandleScope handle_scope(isolate);
|
||||||
|
|
||||||
|
v8::Local<v8::String> source = V8JS_STR("for(;;);");
|
||||||
|
v8::Local<v8::Script> script = v8::Script::Compile(source);
|
||||||
|
v8::V8::TerminateExecution(isolate);
|
||||||
|
script->Run();
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -49,15 +49,15 @@ void v8js_v8_init(TSRMLS_D);
|
|||||||
void v8js_v8_call(v8js_ctx *c, zval **return_value,
|
void v8js_v8_call(v8js_ctx *c, zval **return_value,
|
||||||
long flags, long time_limit, long memory_limit,
|
long flags, long time_limit, long memory_limit,
|
||||||
std::function< v8::Local<v8::Value>(v8::Isolate *) >& v8_call TSRMLS_DC);
|
std::function< v8::Local<v8::Value>(v8::Isolate *) >& v8_call TSRMLS_DC);
|
||||||
void v8js_terminate_execution(v8js_ctx *c TSRMLS_DC);
|
void v8js_terminate_execution(v8::Isolate *isolate);
|
||||||
|
|
||||||
/* Fetch V8 object properties */
|
/* Fetch V8 object properties */
|
||||||
int v8js_get_properties_hash(v8::Handle<v8::Value> jsValue, HashTable *retval, int flags, v8::Isolate *isolate TSRMLS_DC);
|
int v8js_get_properties_hash(v8::Handle<v8::Value> jsValue, HashTable *retval, int flags, v8::Isolate *isolate TSRMLS_DC);
|
||||||
|
|
||||||
#define V8JS_CTX_PROLOGUE(ctx) \
|
#define V8JS_CTX_PROLOGUE_EX(ctx, ret) \
|
||||||
if (!V8JSG(v8_initialized)) { \
|
if (!V8JSG(v8_initialized)) { \
|
||||||
zend_error(E_ERROR, "V8 not initialized"); \
|
zend_error(E_ERROR, "V8 not initialized"); \
|
||||||
return; \
|
return ret; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
v8::Isolate *isolate = (ctx)->isolate; \
|
v8::Isolate *isolate = (ctx)->isolate; \
|
||||||
@ -67,6 +67,9 @@ int v8js_get_properties_hash(v8::Handle<v8::Value> jsValue, HashTable *retval, i
|
|||||||
v8::Local<v8::Context> v8_context = v8::Local<v8::Context>::New(isolate, (ctx)->context); \
|
v8::Local<v8::Context> v8_context = v8::Local<v8::Context>::New(isolate, (ctx)->context); \
|
||||||
v8::Context::Scope context_scope(v8_context);
|
v8::Context::Scope context_scope(v8_context);
|
||||||
|
|
||||||
|
#define V8JS_CTX_PROLOGUE(ctx) \
|
||||||
|
V8JS_CTX_PROLOGUE_EX(ctx,)
|
||||||
|
|
||||||
#define V8JS_BEGIN_CTX(ctx, object) \
|
#define V8JS_BEGIN_CTX(ctx, object) \
|
||||||
v8js_ctx *(ctx); \
|
v8js_ctx *(ctx); \
|
||||||
(ctx) = Z_V8JS_CTX_OBJ_P(object); \
|
(ctx) = Z_V8JS_CTX_OBJ_P(object); \
|
||||||
|
@ -60,13 +60,7 @@ static int v8js_v8object_has_property(zval *object, zval *member, int has_set_ex
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Isolate *isolate = obj->ctx->isolate;
|
V8JS_CTX_PROLOGUE_EX(obj->ctx, retval);
|
||||||
v8::Locker locker(isolate);
|
|
||||||
v8::Isolate::Scope isolate_scope(isolate);
|
|
||||||
v8::HandleScope local_scope(isolate);
|
|
||||||
v8::Local<v8::Context> temp_context = v8::Context::New(isolate);
|
|
||||||
v8::Context::Scope temp_scope(temp_context);
|
|
||||||
|
|
||||||
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
||||||
|
|
||||||
if (Z_TYPE_P(member) == IS_STRING && v8obj->IsObject() && !v8obj->IsFunction())
|
if (Z_TYPE_P(member) == IS_STRING && v8obj->IsObject() && !v8obj->IsFunction())
|
||||||
@ -125,13 +119,7 @@ static zval *v8js_v8object_read_property(zval *object, zval *member, int type, v
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Isolate *isolate = obj->ctx->isolate;
|
V8JS_CTX_PROLOGUE_EX(obj->ctx, retval);
|
||||||
v8::Locker locker(isolate);
|
|
||||||
v8::Isolate::Scope isolate_scope(isolate);
|
|
||||||
v8::HandleScope local_scope(isolate);
|
|
||||||
v8::Local<v8::Context> temp_context = v8::Context::New(isolate);
|
|
||||||
v8::Context::Scope temp_scope(temp_context);
|
|
||||||
|
|
||||||
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
||||||
|
|
||||||
if (Z_TYPE_P(member) == IS_STRING && v8obj->IsObject() && !v8obj->IsFunction())
|
if (Z_TYPE_P(member) == IS_STRING && v8obj->IsObject() && !v8obj->IsFunction())
|
||||||
@ -165,13 +153,7 @@ static void v8js_v8object_write_property(zval *object, zval *member, zval *value
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Isolate *isolate = obj->ctx->isolate;
|
V8JS_CTX_PROLOGUE(obj->ctx);
|
||||||
v8::Locker locker(isolate);
|
|
||||||
v8::Isolate::Scope isolate_scope(isolate);
|
|
||||||
v8::HandleScope local_scope(isolate);
|
|
||||||
v8::Local<v8::Context> temp_context = v8::Context::New(isolate);
|
|
||||||
v8::Context::Scope temp_scope(temp_context);
|
|
||||||
|
|
||||||
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
||||||
|
|
||||||
if (v8obj->IsObject() && !v8obj->IsFunction()) {
|
if (v8obj->IsObject() && !v8obj->IsFunction()) {
|
||||||
@ -190,13 +172,7 @@ static void v8js_v8object_unset_property(zval *object, zval *member, void **cach
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Isolate *isolate = obj->ctx->isolate;
|
V8JS_CTX_PROLOGUE(obj->ctx);
|
||||||
v8::Locker locker(isolate);
|
|
||||||
v8::Isolate::Scope isolate_scope(isolate);
|
|
||||||
v8::HandleScope local_scope(isolate);
|
|
||||||
v8::Local<v8::Context> temp_context = v8::Context::New(isolate);
|
|
||||||
v8::Context::Scope temp_scope(temp_context);
|
|
||||||
|
|
||||||
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
||||||
|
|
||||||
if (v8obj->IsObject() && !v8obj->IsFunction()) {
|
if (v8obj->IsObject() && !v8obj->IsFunction()) {
|
||||||
@ -235,12 +211,7 @@ static HashTable *v8js_v8object_get_properties(zval *object TSRMLS_DC) /* {{{ */
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Isolate *isolate = obj->ctx->isolate;
|
V8JS_CTX_PROLOGUE_EX(obj->ctx, NULL);
|
||||||
v8::Locker locker(isolate);
|
|
||||||
v8::Isolate::Scope isolate_scope(isolate);
|
|
||||||
v8::HandleScope local_scope(isolate);
|
|
||||||
v8::Local<v8::Context> temp_context = v8::Context::New(isolate);
|
|
||||||
v8::Context::Scope temp_scope(temp_context);
|
|
||||||
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
||||||
|
|
||||||
if (v8js_get_properties_hash(v8obj, obj->properties, obj->flags, isolate TSRMLS_CC) == SUCCESS) {
|
if (v8js_get_properties_hash(v8obj, obj->properties, obj->flags, isolate TSRMLS_CC) == SUCCESS) {
|
||||||
@ -269,12 +240,7 @@ static zend_function *v8js_v8object_get_method(zend_object **object_ptr, zend_st
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Isolate *isolate = obj->ctx->isolate;
|
V8JS_CTX_PROLOGUE_EX(obj->ctx, NULL);
|
||||||
v8::Locker locker(isolate);
|
|
||||||
v8::Isolate::Scope isolate_scope(isolate);
|
|
||||||
v8::HandleScope local_scope(isolate);
|
|
||||||
v8::Local<v8::Context> temp_context = v8::Context::New(isolate);
|
|
||||||
v8::Context::Scope temp_scope(temp_context);
|
|
||||||
v8::Local<v8::String> jsKey = V8JS_ZSTR(method);
|
v8::Local<v8::String> jsKey = V8JS_ZSTR(method);
|
||||||
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
||||||
|
|
||||||
@ -360,12 +326,7 @@ static int v8js_v8object_get_closure(zval *object, zend_class_entry **ce_ptr, ze
|
|||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::Isolate *isolate = obj->ctx->isolate;
|
V8JS_CTX_PROLOGUE_EX(obj->ctx, FAILURE);
|
||||||
v8::Locker locker(isolate);
|
|
||||||
v8::Isolate::Scope isolate_scope(isolate);
|
|
||||||
v8::HandleScope local_scope(isolate);
|
|
||||||
v8::Local<v8::Context> temp_context = v8::Context::New(isolate);
|
|
||||||
v8::Context::Scope temp_scope(temp_context);
|
|
||||||
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
v8::Local<v8::Value> v8obj = v8::Local<v8::Value>::New(isolate, obj->v8obj);
|
||||||
|
|
||||||
if (!v8obj->IsFunction()) {
|
if (!v8obj->IsFunction()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user