mirror of
https://github.com/phpv8/v8js.git
synced 2024-12-22 14:01:53 +00:00
Merge pull request #484 from stesie/remove-deprecated-stuff
Remove supprt for V8 extensions, uncaught exceptions & V8Js::checkString method
This commit is contained in:
commit
461230be27
38
README.md
38
README.md
@ -78,11 +78,9 @@ class V8Js
|
|||||||
* Initializes and starts V8 engine and returns new V8Js object with it's own V8 context.
|
* Initializes and starts V8 engine and returns new V8Js object with it's own V8 context.
|
||||||
* @param string $object_name
|
* @param string $object_name
|
||||||
* @param array $variables
|
* @param array $variables
|
||||||
* @param array $extensions
|
|
||||||
* @param bool $report_uncaught_exceptions
|
|
||||||
* @param string $snapshot_blob
|
* @param string $snapshot_blob
|
||||||
*/
|
*/
|
||||||
public function __construct($object_name = "PHP", array $variables = [], array $extensions = [], $report_uncaught_exceptions = TRUE, $snapshot_blob = NULL)
|
public function __construct($object_name = "PHP", array $variables = [], $snapshot_blob = NULL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -177,30 +175,8 @@ class V8Js
|
|||||||
|
|
||||||
/** Static methods **/
|
/** Static methods **/
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers persistent context independent global Javascript extension.
|
|
||||||
* NOTE! These extensions exist until PHP is shutdown and they need to be registered before V8 is initialized.
|
|
||||||
* For best performance V8 is initialized only once per process thus this call has to be done before any V8Js objects are created!
|
|
||||||
* @param string $extension_name
|
|
||||||
* @param string $code
|
|
||||||
* @param array $dependencies
|
|
||||||
* @param bool $auto_enable
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function registerExtension($extension_name, $code, array $dependencies, $auto_enable = FALSE)
|
|
||||||
{}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns extensions successfully registered with V8Js::registerExtension().
|
|
||||||
* @return array|string[]
|
|
||||||
*/
|
|
||||||
public static function getExtensions()
|
|
||||||
{}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a custom V8 heap snapshot with the provided JavaScript source embedded.
|
* Creates a custom V8 heap snapshot with the provided JavaScript source embedded.
|
||||||
* Snapshots are supported by V8 4.3.7 and higher. For older versions of V8 this
|
|
||||||
* extension doesn't provide this method.
|
|
||||||
* @param string $embed_source
|
* @param string $embed_source
|
||||||
* @return string|false
|
* @return string|false
|
||||||
*/
|
*/
|
||||||
@ -353,15 +329,6 @@ This behaviour can be changed by enabling the php.ini flag `v8js.use_array_acces
|
|||||||
Snapshots
|
Snapshots
|
||||||
=========
|
=========
|
||||||
|
|
||||||
First of all snapshots are incompatible with extensions. So when you see
|
|
||||||
|
|
||||||
#
|
|
||||||
# Fatal error in ../src/snapshot/startup-serializer.cc, line 122
|
|
||||||
# Check failed: !isolate->has_installed_extensions().
|
|
||||||
#
|
|
||||||
|
|
||||||
you need to remove all extension registrations.
|
|
||||||
|
|
||||||
First of all [custom startup snapshots](https://v8project.blogspot.de/2015/09/custom-startup-snapshots.html)
|
First of all [custom startup snapshots](https://v8project.blogspot.de/2015/09/custom-startup-snapshots.html)
|
||||||
is a feature provided by V8 itself, built on top of it's general heap snapshots feature. The idea is that, since
|
is a feature provided by V8 itself, built on top of it's general heap snapshots feature. The idea is that, since
|
||||||
it is quite common to load some JavaScript library prior to any actual work to be done, that this library code
|
it is quite common to load some JavaScript library prior to any actual work to be done, that this library code
|
||||||
@ -390,8 +357,7 @@ Exceptions
|
|||||||
==========
|
==========
|
||||||
|
|
||||||
If the JavaScript code throws (without catching), causes errors or doesn't
|
If the JavaScript code throws (without catching), causes errors or doesn't
|
||||||
compile, `V8JsScriptException` exceptions are thrown unless the `V8Js` object
|
compile, `V8JsScriptException` exceptions are thrown.
|
||||||
is constructed with `report_uncaught_exceptions` set `FALSE`.
|
|
||||||
|
|
||||||
PHP exceptions that occur due to calls from JavaScript code by default are
|
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
|
*not* re-thrown into JavaScript context but cause the JavaScript execution to
|
||||||
|
@ -138,7 +138,6 @@ ZEND_EXTERN_MODULE_GLOBALS(v8js)
|
|||||||
*
|
*
|
||||||
* - whether V8 has been initialized at all
|
* - whether V8 has been initialized at all
|
||||||
* - the V8 backend platform
|
* - the V8 backend platform
|
||||||
* - loaded extensions
|
|
||||||
* - V8 "command line" flags
|
* - V8 "command line" flags
|
||||||
*
|
*
|
||||||
* In a ZTS-enabled environment access to all of these variables must happen
|
* In a ZTS-enabled environment access to all of these variables must happen
|
||||||
@ -150,8 +149,6 @@ struct _v8js_process_globals {
|
|||||||
std::mutex lock;
|
std::mutex lock;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HashTable *extensions;
|
|
||||||
|
|
||||||
/* V8 command line flags */
|
/* V8 command line flags */
|
||||||
char *v8_flags;
|
char *v8_flags;
|
||||||
|
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
--TEST--
|
|
||||||
Test V8::executeString() : Script validator test
|
|
||||||
--SKIPIF--
|
|
||||||
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
|
||||||
--FILE--
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$v8 = new V8Js();
|
|
||||||
var_dump($v8->checkString('print("Hello World!");'));
|
|
||||||
|
|
||||||
try {
|
|
||||||
var_dump($v8->checkString('print("Hello World!);'));
|
|
||||||
} catch (V8JsScriptException $e) {
|
|
||||||
var_dump($e->getMessage());
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
===EOF===
|
|
||||||
--EXPECTF--
|
|
||||||
Deprecated: %s V8Js::checkString() is deprecated in %s on line %d
|
|
||||||
bool(true)
|
|
||||||
|
|
||||||
Deprecated: %s V8Js::checkString() is deprecated in %s on line %d
|
|
||||||
string(%d) "V8Js::checkString():1: SyntaxError: %s"
|
|
||||||
===EOF===
|
|
@ -22,7 +22,7 @@ if (strlen($snap) > 0) {
|
|||||||
var_dump("snapshot successfully created");
|
var_dump("snapshot successfully created");
|
||||||
}
|
}
|
||||||
|
|
||||||
$v8 = new V8Js('PHP', array(), array(), true, $snap);
|
$v8 = new V8Js('PHP', array(), $snap);
|
||||||
$v8->executeString('var_dump(doublify(23));');
|
$v8->executeString('var_dump(doublify(23));');
|
||||||
?>
|
?>
|
||||||
===EOF===
|
===EOF===
|
||||||
|
@ -1,90 +0,0 @@
|
|||||||
--TEST--
|
|
||||||
Test V8::executeString() : Exception clearing test
|
|
||||||
--SKIPIF--
|
|
||||||
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
|
||||||
--FILE--
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$v8 = new V8Js(null, array(), array(), false);
|
|
||||||
|
|
||||||
var_dump($v8->getPendingException());
|
|
||||||
|
|
||||||
$v8->clearPendingException();
|
|
||||||
var_dump($v8->getPendingException());
|
|
||||||
|
|
||||||
$v8->executeString('fooobar', 'throw_0');
|
|
||||||
var_dump($v8->getPendingException());
|
|
||||||
|
|
||||||
$v8->clearPendingException();
|
|
||||||
var_dump($v8->getPendingException());
|
|
||||||
|
|
||||||
?>
|
|
||||||
===EOF===
|
|
||||||
--EXPECTF--
|
|
||||||
Deprecated: V8Js::__construct(): Disabling exception reporting is deprecated, $report_uncaught_exceptions != true in %s%eexception_clearing.php on line 3
|
|
||||||
|
|
||||||
Deprecated: %s V8Js::getPendingException() is deprecated in %s%eexception_clearing.php on line 5
|
|
||||||
NULL
|
|
||||||
|
|
||||||
Deprecated: %s V8Js::clearPendingException() is deprecated in %s%eexception_clearing.php on line 7
|
|
||||||
|
|
||||||
Deprecated: %s V8Js::getPendingException() is deprecated in %s%eexception_clearing.php on line 8
|
|
||||||
NULL
|
|
||||||
|
|
||||||
Deprecated: %s V8Js::getPendingException() is deprecated in %s%eexception_clearing.php on line 11
|
|
||||||
object(V8JsScriptException)#%d (13) {
|
|
||||||
["message":protected]=>
|
|
||||||
string(49) "throw_0:1: ReferenceError: fooobar is not defined"
|
|
||||||
["string":"Exception":private]=>
|
|
||||||
string(0) ""
|
|
||||||
["code":protected]=>
|
|
||||||
int(0)
|
|
||||||
["file":protected]=>
|
|
||||||
string(%d) "%s"
|
|
||||||
["line":protected]=>
|
|
||||||
int(10)
|
|
||||||
["trace":"Exception":private]=>
|
|
||||||
array(1) {
|
|
||||||
[0]=>
|
|
||||||
array(6) {
|
|
||||||
["file"]=>
|
|
||||||
string(%d) "%s"
|
|
||||||
["line"]=>
|
|
||||||
int(10)
|
|
||||||
["function"]=>
|
|
||||||
string(13) "executeString"
|
|
||||||
["class"]=>
|
|
||||||
string(4) "V8Js"
|
|
||||||
["type"]=>
|
|
||||||
string(2) "->"
|
|
||||||
["args"]=>
|
|
||||||
array(2) {
|
|
||||||
[0]=>
|
|
||||||
string(7) "fooobar"
|
|
||||||
[1]=>
|
|
||||||
string(7) "throw_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
["previous":"Exception":private]=>
|
|
||||||
NULL
|
|
||||||
["JsFileName":protected]=>
|
|
||||||
string(7) "throw_0"
|
|
||||||
["JsLineNumber":protected]=>
|
|
||||||
int(1)
|
|
||||||
["JsStartColumn":protected]=>
|
|
||||||
int(0)
|
|
||||||
["JsEndColumn":protected]=>
|
|
||||||
int(1)
|
|
||||||
["JsSourceLine":protected]=>
|
|
||||||
string(7) "fooobar"
|
|
||||||
["JsTrace":protected]=>
|
|
||||||
string(57) "ReferenceError: fooobar is not defined
|
|
||||||
at throw_0:1:1"
|
|
||||||
}
|
|
||||||
|
|
||||||
Deprecated: %s V8Js::clearPendingException() is deprecated in %s%eexception_clearing.php on line 13
|
|
||||||
|
|
||||||
Deprecated: %s V8Js::getPendingException() is deprecated in %s%eexception_clearing.php on line 14
|
|
||||||
NULL
|
|
||||||
===EOF===
|
|
@ -1,37 +0,0 @@
|
|||||||
--TEST--
|
|
||||||
Test V8::executeString() : Exception propagation test 1
|
|
||||||
--SKIPIF--
|
|
||||||
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
|
||||||
--FILE--
|
|
||||||
<?php
|
|
||||||
|
|
||||||
class Foo {
|
|
||||||
private $v8 = NULL;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->v8 = new V8Js();
|
|
||||||
$this->v8->foo = $this;
|
|
||||||
$this->v8->executeString('fooobar', 'throw_0');
|
|
||||||
var_dump($this->v8->getPendingException());
|
|
||||||
$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');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function bar()
|
|
||||||
{
|
|
||||||
echo "To Bar!\n";
|
|
||||||
$this->v8->executeString('throw new Error();', 'throw_1');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$foo = new Foo();
|
|
||||||
} catch (V8JsScriptException $e) {
|
|
||||||
echo "PHP Exception: ", $e->getMessage(), "\n"; //var_dump($e);
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
===EOF===
|
|
||||||
--EXPECTF--
|
|
||||||
PHP Exception: throw_0:1: ReferenceError: fooobar is not defined
|
|
||||||
===EOF===
|
|
@ -1,112 +0,0 @@
|
|||||||
--TEST--
|
|
||||||
Test V8::executeString() : Exception propagation test 2
|
|
||||||
--SKIPIF--
|
|
||||||
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
|
||||||
--FILE--
|
|
||||||
<?php
|
|
||||||
|
|
||||||
class Foo {
|
|
||||||
private $v8 = NULL;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->v8 = new V8Js(null, array(), array(), false);
|
|
||||||
$this->v8->foo = $this;
|
|
||||||
$this->v8->executeString('fooobar', 'throw_0');
|
|
||||||
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"); }', 'trycatch2');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function bar()
|
|
||||||
{
|
|
||||||
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');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$foo = new Foo();
|
|
||||||
} catch (V8JsScriptException $e) {
|
|
||||||
echo "PHP Exception: ", $e->getMessage(), "\n"; //var_dump($e);
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
===EOF===
|
|
||||||
--EXPECTF--
|
|
||||||
Deprecated: V8Js::__construct(): Disabling exception reporting is deprecated, $report_uncaught_exceptions != true in %s%eexception_propagation_2.php on line 8
|
|
||||||
|
|
||||||
Deprecated: %s V8Js::getPendingException() is deprecated in %s%eexception_propagation_2.php on line 11
|
|
||||||
object(V8JsScriptException)#%d (13) {
|
|
||||||
["message":protected]=>
|
|
||||||
string(49) "throw_0:1: ReferenceError: fooobar is not defined"
|
|
||||||
["string":"Exception":private]=>
|
|
||||||
string(0) ""
|
|
||||||
["code":protected]=>
|
|
||||||
int(0)
|
|
||||||
["file":protected]=>
|
|
||||||
string(%d) "%s"
|
|
||||||
["line":protected]=>
|
|
||||||
int(10)
|
|
||||||
["trace":"Exception":private]=>
|
|
||||||
array(2) {
|
|
||||||
[0]=>
|
|
||||||
array(6) {
|
|
||||||
["file"]=>
|
|
||||||
string(%d) "%s"
|
|
||||||
["line"]=>
|
|
||||||
int(10)
|
|
||||||
["function"]=>
|
|
||||||
string(13) "executeString"
|
|
||||||
["class"]=>
|
|
||||||
string(4) "V8Js"
|
|
||||||
["type"]=>
|
|
||||||
string(2) "->"
|
|
||||||
["args"]=>
|
|
||||||
array(2) {
|
|
||||||
[0]=>
|
|
||||||
string(7) "fooobar"
|
|
||||||
[1]=>
|
|
||||||
string(7) "throw_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[1]=>
|
|
||||||
array(6) {
|
|
||||||
["file"]=>
|
|
||||||
string(%d) "%s"
|
|
||||||
["line"]=>
|
|
||||||
int(29)
|
|
||||||
["function"]=>
|
|
||||||
string(11) "__construct"
|
|
||||||
["class"]=>
|
|
||||||
string(3) "Foo"
|
|
||||||
["type"]=>
|
|
||||||
string(2) "->"
|
|
||||||
["args"]=>
|
|
||||||
array(0) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
["previous":"Exception":private]=>
|
|
||||||
NULL
|
|
||||||
["JsFileName":protected]=>
|
|
||||||
string(7) "throw_0"
|
|
||||||
["JsLineNumber":protected]=>
|
|
||||||
int(1)
|
|
||||||
["JsStartColumn":protected]=>
|
|
||||||
int(0)
|
|
||||||
["JsEndColumn":protected]=>
|
|
||||||
int(1)
|
|
||||||
["JsSourceLine":protected]=>
|
|
||||||
string(7) "fooobar"
|
|
||||||
["JsTrace":protected]=>
|
|
||||||
string(57) "ReferenceError: fooobar is not defined
|
|
||||||
at throw_0:1:1"
|
|
||||||
}
|
|
||||||
To Bar!
|
|
||||||
PHP Exception: throw_0:1: ReferenceError: fooobar is not defined
|
|
||||||
===EOF===
|
|
@ -1,39 +0,0 @@
|
|||||||
--TEST--
|
|
||||||
Test V8::executeString() : Exception propagation test 3
|
|
||||||
--SKIPIF--
|
|
||||||
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
|
||||||
--FILE--
|
|
||||||
<?php
|
|
||||||
|
|
||||||
class Foo {
|
|
||||||
private $v8 = NULL;
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->v8 = new V8Js(null, array(), array(), false);
|
|
||||||
$this->v8->foo = $this;
|
|
||||||
$this->v8->executeString('function foobar() { throw new SyntaxError(); }', 'throw_1');
|
|
||||||
$this->v8->executeString('try { foobar(); } catch (e) { print(e + " caught in JS!\n"); }', 'trycatch1');
|
|
||||||
$this->v8->executeString('try { PHP.foo.bar(); } catch (e) { print(e + " caught via PHP callback!\n"); }', 'trycatch2');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function bar()
|
|
||||||
{
|
|
||||||
echo "To Bar!\n";
|
|
||||||
$this->v8->executeString('throw new Error();', 'throw_2');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$foo = new Foo();
|
|
||||||
} catch (V8JsScriptException $e) {
|
|
||||||
echo "PHP Exception: ", $e->getMessage(), "\n";
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
===EOF===
|
|
||||||
--EXPECTF--
|
|
||||||
Deprecated: V8Js::__construct(): Disabling exception reporting is deprecated, $report_uncaught_exceptions != true in %s%eexception_propagation_3.php on line 8
|
|
||||||
SyntaxError caught in JS!
|
|
||||||
To Bar!
|
|
||||||
Error caught via PHP callback!
|
|
||||||
===EOF===
|
|
@ -1,42 +0,0 @@
|
|||||||
--TEST--
|
|
||||||
Test V8::registerExtension() : Basic extension registering
|
|
||||||
--SKIPIF--
|
|
||||||
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
|
||||||
--FILE--
|
|
||||||
<?php
|
|
||||||
|
|
||||||
V8Js::registerExtension('a', 'print("world!\n");', array('b'));
|
|
||||||
V8Js::registerExtension('b', 'print("Hello ");');
|
|
||||||
|
|
||||||
var_dump(V8JS::getExtensions());
|
|
||||||
|
|
||||||
$a = new V8Js('myobj', array(), array('a'));
|
|
||||||
?>
|
|
||||||
===EOF===
|
|
||||||
--EXPECTF--
|
|
||||||
Deprecated: %s V8Js::registerExtension() is deprecated in %s%eextensions_basic.php on line 3
|
|
||||||
|
|
||||||
Deprecated: %s V8Js::registerExtension() is deprecated in %s%eextensions_basic.php on line 4
|
|
||||||
|
|
||||||
Deprecated: %s V8Js::getExtensions() is deprecated in %s%eextensions_basic.php on line 6
|
|
||||||
array(2) {
|
|
||||||
["a"]=>
|
|
||||||
array(2) {
|
|
||||||
["auto_enable"]=>
|
|
||||||
bool(false)
|
|
||||||
["deps"]=>
|
|
||||||
array(1) {
|
|
||||||
[0]=>
|
|
||||||
string(1) "b"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
["b"]=>
|
|
||||||
array(1) {
|
|
||||||
["auto_enable"]=>
|
|
||||||
bool(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Deprecated: V8Js::__construct(): Use of extensions is deprecated, $extensions array passed in %s%eextensions_basic.php on line 8
|
|
||||||
Hello world!
|
|
||||||
===EOF===
|
|
@ -1,52 +0,0 @@
|
|||||||
--TEST--
|
|
||||||
Test V8::registerExtension() : Circular dependencies
|
|
||||||
--SKIPIF--
|
|
||||||
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
|
||||||
--FILE--
|
|
||||||
<?php
|
|
||||||
|
|
||||||
V8Js::registerExtension('a', 'print("A");', array('b'));
|
|
||||||
V8Js::registerExtension('b', 'print("B");', array('a'));
|
|
||||||
|
|
||||||
var_dump(V8JS::getExtensions());
|
|
||||||
|
|
||||||
$a = new V8Js('myobj', array(), array('a'));
|
|
||||||
?>
|
|
||||||
--EXPECTF--
|
|
||||||
Deprecated: %s V8Js::registerExtension() is deprecated in %s%eextensions_circular_dependency.php on line 3
|
|
||||||
|
|
||||||
Deprecated: %s V8Js::registerExtension() is deprecated in %s%eextensions_circular_dependency.php on line 4
|
|
||||||
|
|
||||||
Deprecated: %s V8Js::getExtensions() is deprecated in %s%eextensions_circular_dependency.php on line 6
|
|
||||||
array(2) {
|
|
||||||
["a"]=>
|
|
||||||
array(2) {
|
|
||||||
["auto_enable"]=>
|
|
||||||
bool(false)
|
|
||||||
["deps"]=>
|
|
||||||
array(1) {
|
|
||||||
[0]=>
|
|
||||||
string(1) "b"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
["b"]=>
|
|
||||||
array(2) {
|
|
||||||
["auto_enable"]=>
|
|
||||||
bool(false)
|
|
||||||
["deps"]=>
|
|
||||||
array(1) {
|
|
||||||
[0]=>
|
|
||||||
string(1) "a"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Deprecated: V8Js::__construct(): Use of extensions is deprecated, $extensions array passed in %s%eextensions_circular_dependency.php on line 8
|
|
||||||
|
|
||||||
Warning: Fatal V8 error in v8::Context::New(): Circular extension dependency in %s on line 8
|
|
||||||
|
|
||||||
Fatal error: Uncaught V8JsException: Failed to create V8 context. Check that registered extensions do not have errors. in %s:8
|
|
||||||
Stack trace:
|
|
||||||
#0 %s(8): V8Js->__construct('myobj', Array, Array)
|
|
||||||
#1 {main}
|
|
||||||
thrown in %s on line 8
|
|
@ -1,44 +0,0 @@
|
|||||||
--TEST--
|
|
||||||
Test V8::registerExtension() : Register extension with errors
|
|
||||||
--SKIPIF--
|
|
||||||
<?php
|
|
||||||
require_once(dirname(__FILE__) . '/skipif.inc');
|
|
||||||
|
|
||||||
ob_start(NULL, 0, PHP_OUTPUT_HANDLER_CLEANABLE | PHP_OUTPUT_HANDLER_REMOVABLE);
|
|
||||||
phpinfo(INFO_MODULES);
|
|
||||||
$minfo = ob_get_contents();
|
|
||||||
ob_end_clean();
|
|
||||||
|
|
||||||
if(preg_match("/V8 Engine Linked Version => (.*)/", $minfo, $matches)) {
|
|
||||||
$version = explode('.', $matches[1]);
|
|
||||||
if($version[0] < 5 || ($version[0] == 5 && $version[1] < 7)) {
|
|
||||||
// old v8 version, has shorter error message and hence doesn't
|
|
||||||
// fit our EXCEPTF below
|
|
||||||
echo "SKIP too old V8 version";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
|
||||||
--FILE--
|
|
||||||
<?php
|
|
||||||
|
|
||||||
$handlebarsJs = "var root = typeof global !== 'undefined' ? global : window, \$Handlebars = 'test';";
|
|
||||||
echo "-- registerExtension --\n";
|
|
||||||
V8Js::registerExtension('handlebars', $handlebarsJs, [], true);
|
|
||||||
echo "-- creating V8Js object --\n";
|
|
||||||
$v8 = new V8Js();
|
|
||||||
var_dump($v8);
|
|
||||||
?>
|
|
||||||
===EOF===
|
|
||||||
--EXPECTF--
|
|
||||||
-- registerExtension --
|
|
||||||
|
|
||||||
Deprecated: %s V8Js::registerExtension() is deprecated in %s%eextensions_error.php on line 5
|
|
||||||
-- creating V8Js object --
|
|
||||||
Error installing extension 'handlebars'.
|
|
||||||
|
|
||||||
Fatal error: Uncaught V8JsException: Failed to create V8 context. Check that registered extensions do not have errors. in %s%eextensions_error.php:7
|
|
||||||
Stack trace:
|
|
||||||
#0 %s%eextensions_error.php(7): V8Js->__construct()
|
|
||||||
#1 {main}
|
|
||||||
thrown in %s%eextensions_error.php on line 7
|
|
@ -19,7 +19,6 @@ var_dump(typeof PHP.executeString);
|
|||||||
var_dump(typeof PHP.compileString);
|
var_dump(typeof PHP.compileString);
|
||||||
var_dump(typeof PHP.executeScript);
|
var_dump(typeof PHP.executeScript);
|
||||||
var_dump(typeof PHP.checkString);
|
var_dump(typeof PHP.checkString);
|
||||||
var_dump(typeof PHP.getPendingException);
|
|
||||||
var_dump(typeof PHP.setModuleNormaliser);
|
var_dump(typeof PHP.setModuleNormaliser);
|
||||||
var_dump(typeof PHP.setModuleLoader);
|
var_dump(typeof PHP.setModuleLoader);
|
||||||
var_dump(typeof PHP.registerExtension);
|
var_dump(typeof PHP.registerExtension);
|
||||||
@ -52,6 +51,5 @@ string(9) "undefined"
|
|||||||
string(9) "undefined"
|
string(9) "undefined"
|
||||||
string(9) "undefined"
|
string(9) "undefined"
|
||||||
string(9) "undefined"
|
string(9) "undefined"
|
||||||
string(9) "undefined"
|
|
||||||
string(6) "caught"
|
string(6) "caught"
|
||||||
===EOF===
|
===EOF===
|
||||||
|
@ -12,7 +12,7 @@ $unicode = 'äöüßÜÄÖÜ߀áàâÁÀµ²³▁▂▃▄▅▆▇█
|
|||||||
$snapshot = V8Js::createSnapshot("var snapshot = {unicode: '" . $unicode . "'}");
|
$snapshot = V8Js::createSnapshot("var snapshot = {unicode: '" . $unicode . "'}");
|
||||||
|
|
||||||
# start V8Js
|
# start V8Js
|
||||||
$jscript = new V8Js('php', array(), array(), true, $snapshot);
|
$jscript = new V8Js('php', array(), $snapshot);
|
||||||
|
|
||||||
# insert unicode via php var
|
# insert unicode via php var
|
||||||
$jscript->unicode = $unicode;
|
$jscript->unicode = $unicode;
|
||||||
|
341
v8js_class.cc
341
v8js_class.cc
@ -59,17 +59,6 @@ static void v8js_script_free(v8js_script *res);
|
|||||||
|
|
||||||
int le_v8js_script;
|
int le_v8js_script;
|
||||||
|
|
||||||
/* {{{ Extension container */
|
|
||||||
struct v8js_jsext {
|
|
||||||
zend_bool auto_enable;
|
|
||||||
HashTable *deps_ht;
|
|
||||||
const char **deps;
|
|
||||||
int deps_count;
|
|
||||||
zend_string *name;
|
|
||||||
zend_string *source;
|
|
||||||
};
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
#ifdef USE_INTERNAL_ALLOCATOR
|
#ifdef USE_INTERNAL_ALLOCATOR
|
||||||
class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
|
class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
|
||||||
public:
|
public:
|
||||||
@ -89,7 +78,6 @@ static void v8js_free_storage(zend_object *object) /* {{{ */
|
|||||||
|
|
||||||
zend_object_std_dtor(&c->std);
|
zend_object_std_dtor(&c->std);
|
||||||
|
|
||||||
zval_ptr_dtor(&c->pending_exception);
|
|
||||||
zval_ptr_dtor(&c->module_normaliser);
|
zval_ptr_dtor(&c->module_normaliser);
|
||||||
zval_ptr_dtor(&c->module_loader);
|
zval_ptr_dtor(&c->module_loader);
|
||||||
|
|
||||||
@ -247,73 +235,6 @@ static zend_object* v8js_new(zend_class_entry *ce) /* {{{ */
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static void v8js_free_ext_strarr(const char **arr, int count) /* {{{ */
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (arr) {
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
if (arr[i]) {
|
|
||||||
free((void *) arr[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(arr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
static void v8js_jsext_free_storage(v8js_jsext *jsext) /* {{{ */
|
|
||||||
{
|
|
||||||
if (jsext->deps_ht) {
|
|
||||||
zend_hash_destroy(jsext->deps_ht);
|
|
||||||
free(jsext->deps_ht);
|
|
||||||
}
|
|
||||||
if (jsext->deps) {
|
|
||||||
v8js_free_ext_strarr(jsext->deps, jsext->deps_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free the persisted non-interned strings we allocated.
|
|
||||||
if (jsext->name) {
|
|
||||||
zend_string_release(jsext->name);
|
|
||||||
}
|
|
||||||
if (jsext->source) {
|
|
||||||
zend_string_release(jsext->source);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(jsext);
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
static void v8js_jsext_dtor(zval *zv) /* {{{ */
|
|
||||||
{
|
|
||||||
v8js_jsext_free_storage(reinterpret_cast<v8js_jsext *>(Z_PTR_P(zv)));
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
static int v8js_create_ext_strarr(const char ***retval, int count, HashTable *ht) /* {{{ */
|
|
||||||
{
|
|
||||||
const char **exts = NULL;
|
|
||||||
HashPosition pos;
|
|
||||||
zval *tmp;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
exts = (const char **) calloc(1, count * sizeof(char *));
|
|
||||||
zend_hash_internal_pointer_reset_ex(ht, &pos);
|
|
||||||
while ((tmp = zend_hash_get_current_data_ex(ht, &pos))) {
|
|
||||||
if (Z_TYPE_P(tmp) == IS_STRING) {
|
|
||||||
exts[i++] = zend_strndup(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
|
|
||||||
} else {
|
|
||||||
v8js_free_ext_strarr(exts, i);
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
zend_hash_move_forward_ex(ht, &pos);
|
|
||||||
}
|
|
||||||
*retval = exts;
|
|
||||||
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
static void v8js_fatal_error_handler(const char *location, const char *message) /* {{{ */
|
static void v8js_fatal_error_handler(const char *location, const char *message) /* {{{ */
|
||||||
{
|
{
|
||||||
if (location) {
|
if (location) {
|
||||||
@ -328,15 +249,12 @@ static void v8js_fatal_error_handler(const char *location, const char *message)
|
|||||||
((ZSTR_LEN(key) == sizeof(mname) - 1) && \
|
((ZSTR_LEN(key) == sizeof(mname) - 1) && \
|
||||||
!strncasecmp(ZSTR_VAL(key), mname, ZSTR_LEN(key)))
|
!strncasecmp(ZSTR_VAL(key), mname, ZSTR_LEN(key)))
|
||||||
|
|
||||||
/* {{{ proto void V8Js::__construct([string object_name [, array variables [, array extensions [, bool report_uncaught_exceptions [, string snapshot_blob]]]]])
|
/* {{{ proto void V8Js::__construct([string object_name [, array variables [, string snapshot_blob]]])
|
||||||
__construct for V8Js */
|
__construct for V8Js */
|
||||||
static PHP_METHOD(V8Js, __construct)
|
static PHP_METHOD(V8Js, __construct)
|
||||||
{
|
{
|
||||||
zend_string *object_name = NULL;
|
zend_string *object_name = NULL;
|
||||||
zend_bool report_uncaught = 1;
|
zval *vars_arr = NULL;
|
||||||
zval *vars_arr = NULL, *exts_arr = NULL;
|
|
||||||
const char **exts = NULL;
|
|
||||||
int exts_count = 0;
|
|
||||||
zval *snapshot_blob = NULL;
|
zval *snapshot_blob = NULL;
|
||||||
|
|
||||||
v8js_ctx *c = Z_V8JS_CTX_OBJ_P(getThis())
|
v8js_ctx *c = Z_V8JS_CTX_OBJ_P(getThis())
|
||||||
@ -346,7 +264,7 @@ static PHP_METHOD(V8Js, __construct)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!aabz", &object_name, &vars_arr, &exts_arr, &report_uncaught, &snapshot_blob) == FAILURE) {
|
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!az", &object_name, &vars_arr, &snapshot_blob) == FAILURE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,14 +272,8 @@ static PHP_METHOD(V8Js, __construct)
|
|||||||
v8js_v8_init();
|
v8js_v8_init();
|
||||||
|
|
||||||
/* Throw PHP exception if uncaught exceptions exist */
|
/* Throw PHP exception if uncaught exceptions exist */
|
||||||
c->report_uncaught = report_uncaught;
|
|
||||||
ZVAL_NULL(&c->pending_exception);
|
|
||||||
c->in_execution = 0;
|
c->in_execution = 0;
|
||||||
|
|
||||||
if (report_uncaught != 1) {
|
|
||||||
php_error_docref(NULL, E_DEPRECATED, "Disabling exception reporting is deprecated, $report_uncaught_exceptions != true");
|
|
||||||
}
|
|
||||||
|
|
||||||
new (&c->create_params) v8::Isolate::CreateParams();
|
new (&c->create_params) v8::Isolate::CreateParams();
|
||||||
|
|
||||||
#ifdef USE_INTERNAL_ALLOCATOR
|
#ifdef USE_INTERNAL_ALLOCATOR
|
||||||
@ -401,26 +313,6 @@ static PHP_METHOD(V8Js, __construct)
|
|||||||
ZVAL_NULL(&c->module_normaliser);
|
ZVAL_NULL(&c->module_normaliser);
|
||||||
ZVAL_NULL(&c->module_loader);
|
ZVAL_NULL(&c->module_loader);
|
||||||
|
|
||||||
/* Include extensions used by this context */
|
|
||||||
/* Note: Extensions registered with auto_enable do not need to be added separately like this. */
|
|
||||||
if (exts_arr)
|
|
||||||
{
|
|
||||||
exts_count = zend_hash_num_elements(Z_ARRVAL_P(exts_arr));
|
|
||||||
|
|
||||||
if (exts_count != 0) {
|
|
||||||
php_error_docref(NULL, E_DEPRECATED, "Use of extensions is deprecated, $extensions array passed");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (v8js_create_ext_strarr(&exts, exts_count, Z_ARRVAL_P(exts_arr)) == FAILURE) {
|
|
||||||
zend_throw_exception(php_ce_v8js_exception,
|
|
||||||
"Invalid extensions array passed", 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Declare configuration for extensions */
|
|
||||||
v8::ExtensionConfiguration extension_conf(exts_count, exts);
|
|
||||||
|
|
||||||
// Isolate execution
|
// Isolate execution
|
||||||
v8::Isolate *isolate = c->isolate;
|
v8::Isolate *isolate = c->isolate;
|
||||||
v8::Locker locker(isolate);
|
v8::Locker locker(isolate);
|
||||||
@ -442,17 +334,10 @@ static PHP_METHOD(V8Js, __construct)
|
|||||||
v8js_register_methods(global_template, c);
|
v8js_register_methods(global_template, c);
|
||||||
|
|
||||||
/* Create context */
|
/* Create context */
|
||||||
v8::Local<v8::Context> context = v8::Context::New(isolate, &extension_conf, global_template);
|
v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr, global_template);
|
||||||
|
|
||||||
if (exts) {
|
|
||||||
v8js_free_ext_strarr(exts, exts_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If extensions have errors, context will be empty. (NOTE: This is V8 stuff, they expect the passed sources to compile :) */
|
|
||||||
if (context.IsEmpty()) {
|
if (context.IsEmpty()) {
|
||||||
zend_throw_exception(php_ce_v8js_exception,
|
zend_throw_exception(php_ce_v8js_exception, "Failed to create V8 context.", 0);
|
||||||
"Failed to create V8 context. "
|
|
||||||
"Check that registered extensions do not have errors.", 0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -784,69 +669,6 @@ static PHP_METHOD(V8Js, executeScript)
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ proto mixed V8Js::checkString(string script)
|
|
||||||
*/
|
|
||||||
static PHP_METHOD(V8Js, checkString)
|
|
||||||
{
|
|
||||||
zend_string *str = NULL;
|
|
||||||
zend_string *identifier = zend_string_init("V8Js::checkString()", 19, 0);
|
|
||||||
|
|
||||||
v8js_script *res = NULL;
|
|
||||||
|
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &str) == FAILURE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
v8js_compile_script(getThis(), str, identifier, &res);
|
|
||||||
zend_string_release(identifier);
|
|
||||||
|
|
||||||
if (!res) {
|
|
||||||
RETURN_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
v8js_script_free(res);
|
|
||||||
efree(res);
|
|
||||||
RETURN_TRUE;
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
/* {{{ proto mixed V8Js::getPendingException()
|
|
||||||
*/
|
|
||||||
static PHP_METHOD(V8Js, getPendingException)
|
|
||||||
{
|
|
||||||
v8js_ctx *c;
|
|
||||||
|
|
||||||
if (zend_parse_parameters_none() == FAILURE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = Z_V8JS_CTX_OBJ_P(getThis());
|
|
||||||
|
|
||||||
if (Z_TYPE(c->pending_exception) == IS_OBJECT) {
|
|
||||||
RETURN_ZVAL(&c->pending_exception, 1, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
/* {{{ proto void V8Js::clearPendingException()
|
|
||||||
*/
|
|
||||||
static PHP_METHOD(V8Js, clearPendingException)
|
|
||||||
{
|
|
||||||
v8js_ctx *c;
|
|
||||||
|
|
||||||
if (zend_parse_parameters_none() == FAILURE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = Z_V8JS_CTX_OBJ_P(getThis());
|
|
||||||
|
|
||||||
if (Z_TYPE(c->pending_exception) == IS_OBJECT) {
|
|
||||||
zval_ptr_dtor(&c->pending_exception);
|
|
||||||
ZVAL_NULL(&c->pending_exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
/* {{{ proto void V8Js::setModuleNormaliser(string base, string module_id)
|
/* {{{ proto void V8Js::setModuleNormaliser(string base, string module_id)
|
||||||
*/
|
*/
|
||||||
static PHP_METHOD(V8Js, setModuleNormaliser)
|
static PHP_METHOD(V8Js, setModuleNormaliser)
|
||||||
@ -1006,140 +828,10 @@ static void v8js_script_dtor(zend_resource *rsrc) /* {{{ */
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static int v8js_register_extension(zend_string *name, zend_string *source, zval *deps_arr, zend_bool auto_enable) /* {{{ */
|
|
||||||
{
|
|
||||||
v8js_jsext *jsext = NULL;
|
|
||||||
|
|
||||||
#ifdef ZTS
|
|
||||||
v8js_process_globals.lock.lock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
jsext = (v8js_jsext *) calloc(1, sizeof(v8js_jsext));
|
|
||||||
|
|
||||||
if (deps_arr) {
|
|
||||||
jsext->deps_count = zend_hash_num_elements(Z_ARRVAL_P(deps_arr));
|
|
||||||
|
|
||||||
if (v8js_create_ext_strarr(&jsext->deps, jsext->deps_count, Z_ARRVAL_P(deps_arr)) == FAILURE) {
|
|
||||||
php_error_docref(NULL, E_WARNING, "Invalid dependency array passed");
|
|
||||||
v8js_jsext_free_storage(jsext);
|
|
||||||
#ifdef ZTS
|
|
||||||
v8js_process_globals.lock.unlock();
|
|
||||||
#endif
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jsext->auto_enable = auto_enable;
|
|
||||||
// Allocate a persistent string which will survive until module shutdown on both ZTS(Persistent) and NTS(Not interned, those would be cleaned up)
|
|
||||||
// (zend_string_dup would return the original interned string, if interned, so we don't use that)
|
|
||||||
jsext->name = zend_string_init(ZSTR_VAL(name), ZSTR_LEN(name), 1);
|
|
||||||
jsext->source = zend_string_init(ZSTR_VAL(source), ZSTR_LEN(source), 1);
|
|
||||||
|
|
||||||
if (jsext->deps) {
|
|
||||||
jsext->deps_ht = (HashTable *) malloc(sizeof(HashTable));
|
|
||||||
zend_hash_init(jsext->deps_ht, jsext->deps_count, NULL, v8js_persistent_zval_dtor, 1);
|
|
||||||
zend_hash_copy(jsext->deps_ht, Z_ARRVAL_P(deps_arr), v8js_persistent_zval_ctor);
|
|
||||||
}
|
|
||||||
|
|
||||||
v8::Extension *extension = new v8::Extension(ZSTR_VAL(jsext->name), ZSTR_VAL(jsext->source), jsext->deps_count, jsext->deps);
|
|
||||||
|
|
||||||
if (!zend_hash_add_ptr(v8js_process_globals.extensions, jsext->name, jsext)) {
|
|
||||||
v8js_jsext_free_storage(jsext);
|
|
||||||
#ifdef ZTS
|
|
||||||
v8js_process_globals.lock.unlock();
|
|
||||||
#endif
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ZTS
|
|
||||||
v8js_process_globals.lock.unlock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extension->set_auto_enable(auto_enable ? true : false);
|
|
||||||
v8::RegisterExtension(std::unique_ptr<v8::Extension>(extension));
|
|
||||||
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ## Static methods ## */
|
/* ## Static methods ## */
|
||||||
|
|
||||||
/* {{{ proto bool V8Js::registerExtension(string ext_name, string script [, array deps [, bool auto_enable]])
|
|
||||||
*/
|
|
||||||
static PHP_METHOD(V8Js, registerExtension)
|
|
||||||
{
|
|
||||||
zend_string *ext_name, *script;
|
|
||||||
zval *deps_arr = NULL;
|
|
||||||
zend_bool auto_enable = 0;
|
|
||||||
|
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS|ab", &ext_name, &script, &deps_arr, &auto_enable) == FAILURE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ZSTR_LEN(ext_name)) {
|
|
||||||
php_error_docref(NULL, E_WARNING, "Extension name cannot be empty");
|
|
||||||
} else if (!ZSTR_LEN(script)) {
|
|
||||||
php_error_docref(NULL, E_WARNING, "Script cannot be empty");
|
|
||||||
} else if (v8js_register_extension(ext_name, script, deps_arr, auto_enable) == SUCCESS) {
|
|
||||||
RETURN_TRUE;
|
|
||||||
}
|
|
||||||
RETURN_FALSE;
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
/* {{{ proto array V8Js::getExtensions()
|
|
||||||
*/
|
|
||||||
static PHP_METHOD(V8Js, getExtensions)
|
|
||||||
{
|
|
||||||
v8js_jsext *jsext;
|
|
||||||
zend_string *key;
|
|
||||||
zval *val, ext;
|
|
||||||
|
|
||||||
if (zend_parse_parameters_none() == FAILURE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
array_init(return_value);
|
|
||||||
|
|
||||||
#ifdef ZTS
|
|
||||||
v8js_process_globals.lock.lock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (v8js_process_globals.extensions) {
|
|
||||||
ZEND_HASH_FOREACH_STR_KEY_VAL(v8js_process_globals.extensions, key, val) {
|
|
||||||
if (key) {
|
|
||||||
jsext = (v8js_jsext *) Z_PTR_P(val);
|
|
||||||
array_init(&ext);
|
|
||||||
add_assoc_bool_ex(&ext, ZEND_STRL("auto_enable"), jsext->auto_enable);
|
|
||||||
if (jsext->deps_ht) {
|
|
||||||
zval deps_arr;
|
|
||||||
array_init(&deps_arr);
|
|
||||||
zend_hash_copy(Z_ARRVAL_P(&deps_arr), jsext->deps_ht, (copy_ctor_func_t) zval_add_ref);
|
|
||||||
add_assoc_zval_ex(&ext, ZEND_STRL("deps"), &deps_arr);
|
|
||||||
}
|
|
||||||
add_assoc_zval_ex(return_value, ZSTR_VAL(key), ZSTR_LEN(key), &ext);
|
|
||||||
}
|
|
||||||
} ZEND_HASH_FOREACH_END();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ZTS
|
|
||||||
v8js_process_globals.lock.unlock();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
static v8::StartupData createSnapshotDataBlob(v8::SnapshotCreator *snapshot_creator, zend_string *str) /* {{{ */
|
static v8::StartupData createSnapshotDataBlob(v8::SnapshotCreator *snapshot_creator, zend_string *str) /* {{{ */
|
||||||
{
|
{
|
||||||
v8::Isolate *isolate = snapshot_creator->GetIsolate();
|
v8::Isolate *isolate = snapshot_creator->GetIsolate();
|
||||||
@ -1203,8 +895,6 @@ static PHP_METHOD(V8Js, createSnapshot)
|
|||||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_construct, 0, 0, 0)
|
ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_construct, 0, 0, 0)
|
||||||
ZEND_ARG_INFO(0, object_name)
|
ZEND_ARG_INFO(0, object_name)
|
||||||
ZEND_ARG_INFO(0, variables)
|
ZEND_ARG_INFO(0, variables)
|
||||||
ZEND_ARG_INFO(0, extensions)
|
|
||||||
ZEND_ARG_INFO(0, report_uncaught_exceptions)
|
|
||||||
ZEND_ARG_INFO(0, snapshot_blob)
|
ZEND_ARG_INFO(0, snapshot_blob)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
@ -1238,12 +928,6 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_checkstring, 0, 0, 1)
|
|||||||
ZEND_ARG_INFO(0, script)
|
ZEND_ARG_INFO(0, script)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO(arginfo_v8js_getpendingexception, 0)
|
|
||||||
ZEND_END_ARG_INFO()
|
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO(arginfo_v8js_clearpendingexception, 0)
|
|
||||||
ZEND_END_ARG_INFO()
|
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_setmodulenormaliser, 0, 0, 2)
|
ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_setmodulenormaliser, 0, 0, 2)
|
||||||
ZEND_ARG_INFO(0, base)
|
ZEND_ARG_INFO(0, base)
|
||||||
ZEND_ARG_INFO(0, module_id)
|
ZEND_ARG_INFO(0, module_id)
|
||||||
@ -1257,16 +941,6 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_setaverageobjectsize, 0, 0, 1)
|
|||||||
ZEND_ARG_INFO(0, average_object_size)
|
ZEND_ARG_INFO(0, average_object_size)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_registerextension, 0, 0, 2)
|
|
||||||
ZEND_ARG_INFO(0, extension_name)
|
|
||||||
ZEND_ARG_INFO(0, script)
|
|
||||||
ZEND_ARG_INFO(0, dependencies)
|
|
||||||
ZEND_ARG_INFO(0, auto_enable)
|
|
||||||
ZEND_END_ARG_INFO()
|
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO(arginfo_v8js_getextensions, 0)
|
|
||||||
ZEND_END_ARG_INFO()
|
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_createsnapshot, 0, 0, 1)
|
ZEND_BEGIN_ARG_INFO_EX(arginfo_v8js_createsnapshot, 0, 0, 1)
|
||||||
ZEND_ARG_INFO(0, script)
|
ZEND_ARG_INFO(0, script)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
@ -1287,16 +961,11 @@ const zend_function_entry v8js_methods[] = { /* {{{ */
|
|||||||
PHP_ME(V8Js, executeString, arginfo_v8js_executestring, ZEND_ACC_PUBLIC)
|
PHP_ME(V8Js, executeString, arginfo_v8js_executestring, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(V8Js, compileString, arginfo_v8js_compilestring, ZEND_ACC_PUBLIC)
|
PHP_ME(V8Js, compileString, arginfo_v8js_compilestring, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(V8Js, executeScript, arginfo_v8js_executescript, ZEND_ACC_PUBLIC)
|
PHP_ME(V8Js, executeScript, arginfo_v8js_executescript, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(V8Js, checkString, arginfo_v8js_checkstring, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED)
|
|
||||||
PHP_ME(V8Js, getPendingException, arginfo_v8js_getpendingexception, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED)
|
|
||||||
PHP_ME(V8Js, clearPendingException, arginfo_v8js_clearpendingexception, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED)
|
|
||||||
PHP_ME(V8Js, setModuleNormaliser, arginfo_v8js_setmodulenormaliser, ZEND_ACC_PUBLIC)
|
PHP_ME(V8Js, setModuleNormaliser, arginfo_v8js_setmodulenormaliser, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(V8Js, setModuleLoader, arginfo_v8js_setmoduleloader, ZEND_ACC_PUBLIC)
|
PHP_ME(V8Js, setModuleLoader, arginfo_v8js_setmoduleloader, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(V8Js, setTimeLimit, arginfo_v8js_settimelimit, ZEND_ACC_PUBLIC)
|
PHP_ME(V8Js, setTimeLimit, arginfo_v8js_settimelimit, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(V8Js, setMemoryLimit, arginfo_v8js_setmemorylimit, ZEND_ACC_PUBLIC)
|
PHP_ME(V8Js, setMemoryLimit, arginfo_v8js_setmemorylimit, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(V8Js, setAverageObjectSize, arginfo_v8js_setaverageobjectsize, ZEND_ACC_PUBLIC)
|
PHP_ME(V8Js, setAverageObjectSize, arginfo_v8js_setaverageobjectsize, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(V8Js, registerExtension, arginfo_v8js_registerextension, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_DEPRECATED)
|
|
||||||
PHP_ME(V8Js, getExtensions, arginfo_v8js_getextensions, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_DEPRECATED)
|
|
||||||
PHP_ME(V8Js, createSnapshot, arginfo_v8js_createsnapshot, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
|
PHP_ME(V8Js, createSnapshot, arginfo_v8js_createsnapshot, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
@ -37,8 +37,6 @@ struct cmp_str {
|
|||||||
struct v8js_ctx {
|
struct v8js_ctx {
|
||||||
v8::Persistent<v8::String> object_name;
|
v8::Persistent<v8::String> object_name;
|
||||||
v8::Persistent<v8::Context> context;
|
v8::Persistent<v8::Context> context;
|
||||||
zend_bool report_uncaught;
|
|
||||||
zval pending_exception;
|
|
||||||
int in_execution;
|
int in_execution;
|
||||||
v8::Isolate *isolate;
|
v8::Isolate *isolate;
|
||||||
|
|
||||||
|
@ -172,12 +172,6 @@ static PHP_MSHUTDOWN_FUNCTION(v8js)
|
|||||||
v8js_process_globals.v8_flags = NULL;
|
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;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
23
v8js_v8.cc
23
v8js_v8.cc
@ -224,31 +224,14 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There was pending exception left from earlier executions -> throw to PHP */
|
|
||||||
if (Z_TYPE(c->pending_exception) == IS_OBJECT) {
|
|
||||||
zend_throw_exception_object(&c->pending_exception);
|
|
||||||
ZVAL_NULL(&c->pending_exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle runtime JS exceptions */
|
/* Handle runtime JS exceptions */
|
||||||
if (try_catch.HasCaught()) {
|
if (try_catch.HasCaught()) {
|
||||||
|
|
||||||
/* Pending exceptions are set only in outer caller, inner caller exceptions are always rethrown */
|
/* Pending exceptions are set only in outer caller, inner caller exceptions are always rethrown */
|
||||||
if (c->in_execution < 1) {
|
if (c->in_execution < 1) {
|
||||||
|
v8js_throw_script_exception(c->isolate, &try_catch);
|
||||||
/* Report immediately if report_uncaught is true */
|
zval_ptr_dtor(&zv_v8inst);
|
||||||
if (c->report_uncaught) {
|
return;
|
||||||
v8js_throw_script_exception(c->isolate, &try_catch);
|
|
||||||
zval_ptr_dtor(&zv_v8inst);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Exception thrown from JS, preserve it for future execution */
|
|
||||||
if (result.IsEmpty()) {
|
|
||||||
v8js_create_script_exception(&c->pending_exception, c->isolate, &try_catch);
|
|
||||||
zval_ptr_dtor(&zv_v8inst);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rethrow back to JS */
|
/* Rethrow back to JS */
|
||||||
|
Loading…
Reference in New Issue
Block a user