mirror of
https://github.com/phpv8/v8js.git
synced 2024-12-22 15:11:53 +00:00
Remove support for V8 extensions
This commit is contained in:
parent
2b3e904dab
commit
fa4babb307
34
README.md
34
README.md
@ -78,11 +78,10 @@ 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 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 = [], $report_uncaught_exceptions = TRUE, $snapshot_blob = NULL)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -177,30 +176,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 +330,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
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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(), true, $snap);
|
||||||
$v8->executeString('var_dump(doublify(23));');
|
$v8->executeString('var_dump(doublify(23));');
|
||||||
?>
|
?>
|
||||||
===EOF===
|
===EOF===
|
||||||
|
@ -5,7 +5,7 @@ Test V8::executeString() : Exception clearing test
|
|||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
$v8 = new V8Js(null, array(), array(), false);
|
$v8 = new V8Js(null, array(), false);
|
||||||
|
|
||||||
var_dump($v8->getPendingException());
|
var_dump($v8->getPendingException());
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ class Foo {
|
|||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->v8 = new V8Js(null, array(), array(), false);
|
$this->v8 = new V8Js(null, array(), false);
|
||||||
$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());
|
||||||
|
@ -10,7 +10,7 @@ class Foo {
|
|||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->v8 = new V8Js(null, array(), array(), false);
|
$this->v8 = new V8Js(null, array(), false);
|
||||||
$this->v8->foo = $this;
|
$this->v8->foo = $this;
|
||||||
$this->v8->executeString('function foobar() { throw new SyntaxError(); }', 'throw_1');
|
$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 { foobar(); } catch (e) { print(e + " caught in JS!\n"); }', 'trycatch1');
|
||||||
|
@ -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
|
|
@ -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(), true, $snapshot);
|
||||||
|
|
||||||
# insert unicode via php var
|
# insert unicode via php var
|
||||||
$jscript->unicode = $unicode;
|
$jscript->unicode = $unicode;
|
||||||
|
260
v8js_class.cc
260
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:
|
||||||
@ -247,73 +236,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 +250,13 @@ 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 [, bool report_uncaught_exceptions [, 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;
|
zend_bool report_uncaught = 1;
|
||||||
zval *vars_arr = NULL, *exts_arr = NULL;
|
zval *vars_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 +266,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!abz", &object_name, &vars_arr, &report_uncaught, &snapshot_blob) == FAILURE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,26 +321,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 +342,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1006,140 +899,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,7 +966,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, report_uncaught_exceptions)
|
||||||
ZEND_ARG_INFO(0, snapshot_blob)
|
ZEND_ARG_INFO(0, snapshot_blob)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
@ -1257,16 +1019,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()
|
||||||
@ -1295,8 +1047,6 @@ const zend_function_entry v8js_methods[] = { /* {{{ */
|
|||||||
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}
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
Loading…
Reference in New Issue
Block a user