mirror of
https://github.com/phpv8/v8js.git
synced 2024-12-22 14:01:53 +00:00
Merge pull request #201 from stesie/generator-php-to-v8
Generator object passing from PHP to JS
This commit is contained in:
commit
b4b6a8a1a3
@ -180,6 +180,7 @@ int main ()
|
|||||||
v8js_commonjs.cc \
|
v8js_commonjs.cc \
|
||||||
v8js_convert.cc \
|
v8js_convert.cc \
|
||||||
v8js_exceptions.cc \
|
v8js_exceptions.cc \
|
||||||
|
v8js_generator_export.cc \
|
||||||
v8js_methods.cc \
|
v8js_methods.cc \
|
||||||
v8js_object_export.cc \
|
v8js_object_export.cc \
|
||||||
v8js_timer.cc \
|
v8js_timer.cc \
|
||||||
@ -190,3 +191,10 @@ int main ()
|
|||||||
|
|
||||||
PHP_ADD_MAKEFILE_FRAGMENT
|
PHP_ADD_MAKEFILE_FRAGMENT
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl Local variables:
|
||||||
|
dnl tab-width: 4
|
||||||
|
dnl c-basic-offset: 4
|
||||||
|
dnl End:
|
||||||
|
dnl vim600: noet sw=4 ts=4 fdm=marker
|
||||||
|
dnl vim<600: noet sw=4 ts=4
|
||||||
|
@ -17,11 +17,10 @@ if (PHP_V8JS != "no") {
|
|||||||
AC_DEFINE("PHP_V8_API_VERSION", "4007075", "", false);
|
AC_DEFINE("PHP_V8_API_VERSION", "4007075", "", false);
|
||||||
AC_DEFINE("PHP_V8_VERSION", "4.7.75", "", true);
|
AC_DEFINE("PHP_V8_VERSION", "4.7.75", "", true);
|
||||||
|
|
||||||
EXTENSION("v8js", "v8js_array_access.cc v8js.cc v8js_class.cc v8js_commonjs.cc v8js_convert.cc v8js_exceptions.cc v8js_methods.cc v8js_object_export.cc v8js_timer.cc v8js_v8.cc v8js_v8object_class.cc v8js_variables.cc", "yes");
|
EXTENSION("v8js", "v8js_array_access.cc v8js.cc v8js_class.cc v8js_commonjs.cc v8js_convert.cc v8js_exceptions.cc v8js_generator_export.cc v8js_methods.cc v8js_object_export.cc v8js_timer.cc v8js_v8.cc v8js_v8object_class.cc v8js_variables.cc", "yes");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
WARNING("v8js not enabled, headers or libs not found");
|
WARNING("v8js not enabled, headers or libs not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +63,7 @@ extern "C" {
|
|||||||
|
|
||||||
#if PHP_V8_API_VERSION >= 3030000
|
#if PHP_V8_API_VERSION >= 3030000
|
||||||
#define V8JS_V8GENERATOR_SUPPORT 1
|
#define V8JS_V8GENERATOR_SUPPORT 1
|
||||||
|
#define V8JS_GENERATOR_EXPORT_SUPPORT 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* method signatures of zend_update_property and zend_read_property were
|
/* method signatures of zend_update_property and zend_read_property were
|
||||||
|
38
tests/generators_to_v8_001.phpt
Normal file
38
tests/generators_to_v8_001.phpt
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : Generators PHP -> V8 (instantite in JS)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
require_once(dirname(__FILE__) . '/skipif.inc');
|
||||||
|
|
||||||
|
// Actually this check is a bit bad as it tests import, but currently
|
||||||
|
// there is no flag we can check for export
|
||||||
|
if (!class_exists('V8Generator')) {
|
||||||
|
die("skip Installed V8 version doesn't support generators");
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$js = <<<EOJS
|
||||||
|
for(var i of PHP.Gen()) {
|
||||||
|
var_dump(i);
|
||||||
|
}
|
||||||
|
EOJS;
|
||||||
|
|
||||||
|
$v8 = new V8Js();
|
||||||
|
$v8->Gen = function() {
|
||||||
|
for($i = 0; $i < 4; $i ++) {
|
||||||
|
yield $i;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$v8->executeString($js);
|
||||||
|
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECTF--
|
||||||
|
int(0)
|
||||||
|
int(1)
|
||||||
|
int(2)
|
||||||
|
int(3)
|
||||||
|
===EOF===
|
36
tests/generators_to_v8_002.phpt
Normal file
36
tests/generators_to_v8_002.phpt
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : Generators PHP -> V8 (instantiate in JS, iterate in PHP)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
require_once(dirname(__FILE__) . '/skipif.inc');
|
||||||
|
|
||||||
|
// Actually this check is a bit bad as it tests import, but currently
|
||||||
|
// there is no flag we can check for export
|
||||||
|
if (!class_exists('V8Generator')) {
|
||||||
|
die("skip Installed V8 version doesn't support generators");
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$v8 = new V8Js();
|
||||||
|
$v8->Gen = function() {
|
||||||
|
for($i = 0; $i < 4; $i ++) {
|
||||||
|
yield $i;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$gen = $v8->executeString('(PHP.Gen())');
|
||||||
|
|
||||||
|
foreach($gen as $i) {
|
||||||
|
var_dump($i);
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECTF--
|
||||||
|
int(0)
|
||||||
|
int(1)
|
||||||
|
int(2)
|
||||||
|
int(3)
|
||||||
|
===EOF===
|
55
tests/generators_to_v8_003.phpt
Normal file
55
tests/generators_to_v8_003.phpt
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : Generators PHP -> V8 (instantiate in JS, iterate in PHP)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
require_once(dirname(__FILE__) . '/skipif.inc');
|
||||||
|
|
||||||
|
// Actually this check is a bit bad as it tests import, but currently
|
||||||
|
// there is no flag we can check for export
|
||||||
|
if (!class_exists('V8Generator')) {
|
||||||
|
die("skip Installed V8 version doesn't support generators");
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$v8 = new V8Js();
|
||||||
|
$v8->Gen = function() {
|
||||||
|
for($i = 0; $i < 6; $i ++) {
|
||||||
|
yield $i;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$JS = <<<EOJS
|
||||||
|
var g = PHP.Gen();
|
||||||
|
var_dump(g.next());
|
||||||
|
var_dump(g.next());
|
||||||
|
(g);
|
||||||
|
EOJS;
|
||||||
|
|
||||||
|
$gen = $v8->executeString($JS);
|
||||||
|
|
||||||
|
foreach($gen as $i) {
|
||||||
|
var_dump($i);
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECTF--
|
||||||
|
object(Object)#%d (2) {
|
||||||
|
["value"] =>
|
||||||
|
int(0)
|
||||||
|
["done"] =>
|
||||||
|
bool(false)
|
||||||
|
}
|
||||||
|
object(Object)#%d (2) {
|
||||||
|
["value"] =>
|
||||||
|
int(1)
|
||||||
|
["done"] =>
|
||||||
|
bool(false)
|
||||||
|
}
|
||||||
|
int(2)
|
||||||
|
int(3)
|
||||||
|
int(4)
|
||||||
|
int(5)
|
||||||
|
===EOF===
|
56
tests/generators_to_v8_004.phpt
Normal file
56
tests/generators_to_v8_004.phpt
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : Generators PHP -> V8 (yield from)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
require_once(dirname(__FILE__) . '/skipif.inc');
|
||||||
|
|
||||||
|
// Actually this check is a bit bad as it tests import, but currently
|
||||||
|
// there is no flag we can check for export
|
||||||
|
if (!class_exists('V8Generator')) {
|
||||||
|
die("skip Installed V8 version doesn't support generators");
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function FibonacciGenerator()
|
||||||
|
{
|
||||||
|
$i = 0;
|
||||||
|
$j = 1;
|
||||||
|
for(;;) {
|
||||||
|
yield $j;
|
||||||
|
list($i, $j) = array($j, $i + $j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$v8 = new V8Js();
|
||||||
|
$v8->fibs = FibonacciGenerator();
|
||||||
|
|
||||||
|
$JS = <<<EOJS
|
||||||
|
function* prefixer() {
|
||||||
|
yield* arguments;
|
||||||
|
yield* PHP.fibs;
|
||||||
|
}
|
||||||
|
|
||||||
|
var gen = prefixer(23, 42);
|
||||||
|
|
||||||
|
for(var i = 0; i < 10; i ++) {
|
||||||
|
var_dump(gen.next().value);
|
||||||
|
}
|
||||||
|
EOJS;
|
||||||
|
|
||||||
|
$v8->executeString($JS);
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECT--
|
||||||
|
int(23)
|
||||||
|
int(42)
|
||||||
|
int(1)
|
||||||
|
int(1)
|
||||||
|
int(2)
|
||||||
|
int(3)
|
||||||
|
int(5)
|
||||||
|
int(8)
|
||||||
|
int(13)
|
||||||
|
int(21)
|
||||||
|
===EOF===
|
49
tests/generators_to_v8_basic.phpt
Normal file
49
tests/generators_to_v8_basic.phpt
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
--TEST--
|
||||||
|
Test V8::executeString() : Generators PHP -> V8
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
require_once(dirname(__FILE__) . '/skipif.inc');
|
||||||
|
|
||||||
|
// Actually this check is a bit bad as it tests import, but currently
|
||||||
|
// there is no flag we can check for export
|
||||||
|
if (!class_exists('V8Generator')) {
|
||||||
|
die("skip Installed V8 version doesn't support generators");
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function TheGenerator()
|
||||||
|
{
|
||||||
|
for($i = 0; $i < 4; $i ++) {
|
||||||
|
yield $i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(TheGenerator() as $i) {
|
||||||
|
var_dump($i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$js = <<<EOJS
|
||||||
|
for(var i of PHP.gen) {
|
||||||
|
var_dump(i);
|
||||||
|
}
|
||||||
|
EOJS;
|
||||||
|
|
||||||
|
$v8 = new V8Js();
|
||||||
|
$v8->gen = TheGenerator();
|
||||||
|
$gen = $v8->executeString($js);
|
||||||
|
|
||||||
|
?>
|
||||||
|
===EOF===
|
||||||
|
--EXPECTF--
|
||||||
|
int(0)
|
||||||
|
int(1)
|
||||||
|
int(2)
|
||||||
|
int(3)
|
||||||
|
int(0)
|
||||||
|
int(1)
|
||||||
|
int(2)
|
||||||
|
int(3)
|
||||||
|
===EOF===
|
76
v8js_generator_export.cc
Normal file
76
v8js_generator_export.cc
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
| PHP Version 7 |
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
| Copyright (c) 2016 The PHP Group |
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
| http://www.opensource.org/licenses/mit-license.php MIT License |
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
| Author: Stefan Siegl <stesie@php.net> |
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include "php_v8js_macros.h"
|
||||||
|
|
||||||
|
#ifdef V8JS_GENERATOR_EXPORT_SUPPORT
|
||||||
|
|
||||||
|
v8::Local<v8::Value> v8js_wrap_generator(v8::Isolate *isolate, v8::Local<v8::Value> wrapped_object) /* {{{ */
|
||||||
|
{
|
||||||
|
v8::Local<v8::Value> result;
|
||||||
|
|
||||||
|
assert(!wrapped_object.IsEmpty());
|
||||||
|
assert(wrapped_object->IsObject());
|
||||||
|
|
||||||
|
v8::TryCatch try_catch;
|
||||||
|
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, "(\
|
||||||
|
function(wrapped_object) { \
|
||||||
|
return (function*() { \
|
||||||
|
for(;;) { \
|
||||||
|
if(!wrapped_object.valid()) { \
|
||||||
|
return; \
|
||||||
|
} \
|
||||||
|
yield wrapped_object.current(); \
|
||||||
|
wrapped_object.next(); \
|
||||||
|
} \
|
||||||
|
})(); \
|
||||||
|
})");
|
||||||
|
v8::Local<v8::Script> script = v8::Script::Compile(source);
|
||||||
|
|
||||||
|
if(script.IsEmpty()) {
|
||||||
|
zend_error(E_ERROR, "Failed to compile Generator object wrapper");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Local<v8::Value> wrapper_fn_val = script->Run();
|
||||||
|
|
||||||
|
if(wrapper_fn_val.IsEmpty() || !wrapper_fn_val->IsFunction()) {
|
||||||
|
zend_error(E_ERROR, "Failed to create Generator object wrapper function");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
v8::Local<v8::Function> wrapper_fn = v8::Local<v8::Function>::Cast(wrapper_fn_val);
|
||||||
|
v8::Local<v8::Value> *jsArgv = static_cast<v8::Local<v8::Value> *>(alloca(sizeof(v8::Local<v8::Value>)));
|
||||||
|
|
||||||
|
new(&jsArgv[0]) v8::Local<v8::Value>;
|
||||||
|
jsArgv[0] = v8::Local<v8::Value>::New(isolate, wrapped_object);
|
||||||
|
|
||||||
|
result = wrapper_fn->Call(V8JS_GLOBAL(isolate), 1, jsArgv);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
#endif /* V8JS_GENERATOR_EXPORT_SUPPORT */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local variables:
|
||||||
|
* tab-width: 4
|
||||||
|
* c-basic-offset: 4
|
||||||
|
* End:
|
||||||
|
* vim600: noet sw=4 ts=4 fdm=marker
|
||||||
|
* vim<600: noet sw=4 ts=4
|
||||||
|
*/
|
32
v8js_generator_export.h
Normal file
32
v8js_generator_export.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
| PHP Version 7 |
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
| Copyright (c) 2016 The PHP Group |
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
| http://www.opensource.org/licenses/mit-license.php MIT License |
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
| Author: Stefan Siegl <stesie@php.net> |
|
||||||
|
+----------------------------------------------------------------------+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef V8JS_GENERATOR_EXPORT_H
|
||||||
|
#define V8JS_GENERATOR_EXPORT_H
|
||||||
|
|
||||||
|
#ifdef V8JS_GENERATOR_EXPORT_SUPPORT
|
||||||
|
|
||||||
|
v8::Local<v8::Value> v8js_wrap_generator(v8::Isolate *isolate, v8::Local<v8::Value> wrapped_object);
|
||||||
|
|
||||||
|
#endif /* V8JS_GENERATOR_EXPORT_SUPPORT */
|
||||||
|
|
||||||
|
#endif /* V8JS_GENERATOR_EXPORT_H */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local variables:
|
||||||
|
* mode: c++
|
||||||
|
* tab-width: 4
|
||||||
|
* c-basic-offset: 4
|
||||||
|
* End:
|
||||||
|
* vim600: noet sw=4 ts=4 fdm=marker
|
||||||
|
* vim<600: noet sw=4 ts=4
|
||||||
|
*/
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "php_v8js_macros.h"
|
#include "php_v8js_macros.h"
|
||||||
#include "v8js_array_access.h"
|
#include "v8js_array_access.h"
|
||||||
|
#include "v8js_generator_export.h"
|
||||||
#include "v8js_object_export.h"
|
#include "v8js_object_export.h"
|
||||||
#include "v8js_v8object_class.h"
|
#include "v8js_v8object_class.h"
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ extern "C" {
|
|||||||
#include "zend_interfaces.h"
|
#include "zend_interfaces.h"
|
||||||
#include "zend_closures.h"
|
#include "zend_closures.h"
|
||||||
#include "zend_exceptions.h"
|
#include "zend_exceptions.h"
|
||||||
|
#include "zend_generators.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
static void v8js_weak_object_callback(const v8::WeakCallbackData<v8::Object, zend_object> &data);
|
static void v8js_weak_object_callback(const v8::WeakCallbackData<v8::Object, zend_object> &data);
|
||||||
@ -955,7 +957,17 @@ v8::Handle<v8::Value> v8js_hash_to_jsobj(zval *value, v8::Isolate *isolate TSRML
|
|||||||
|
|
||||||
/* If it's a PHP object, wrap it */
|
/* If it's a PHP object, wrap it */
|
||||||
if (ce) {
|
if (ce) {
|
||||||
return v8js_wrap_object(isolate, ce, value TSRMLS_CC);
|
v8::Local<v8::Value> wrapped_object = v8js_wrap_object(isolate, ce, value TSRMLS_CC);
|
||||||
|
|
||||||
|
#ifdef V8JS_GENERATOR_EXPORT_SUPPORT
|
||||||
|
if (ce == zend_ce_generator) {
|
||||||
|
/* Wrap PHP Generator object in a wrapper function that provides
|
||||||
|
* ES6 style behaviour. */
|
||||||
|
wrapped_object = v8js_wrap_generator(isolate, wrapped_object);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return wrapped_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Associative PHP arrays cannot be wrapped to JS arrays, convert them to
|
/* Associative PHP arrays cannot be wrapped to JS arrays, convert them to
|
||||||
|
Loading…
Reference in New Issue
Block a user