0
0
mirror of https://github.com/phpv8/v8js.git synced 2024-12-23 03:51:51 +00:00

Implement direct iteration on JS generators

This commit is contained in:
Stefan Siegl 2016-01-07 22:41:13 +01:00
parent 2c7a7ab87d
commit e686603b89
2 changed files with 104 additions and 15 deletions

View File

@ -0,0 +1,57 @@
--TEST--
Test V8::executeString() : Generators V8 -> PHP (direct)
--SKIPIF--
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
--FILE--
<?php
$js = <<<EOJS
function* TheGen() {
for(var i = 0; i < 4; i ++) {
yield i;
}
}
TheGen();
EOJS;
$v8 = new V8Js();
$gen = $v8->executeString($js);
var_dump($gen->current());
// JS generators don't have the key concept (-> just "false")
var_dump($gen->key());
// fetching multiple times shouldn't leak
var_dump($gen->current());
var_dump($gen->current());
$gen->next(); // 1
var_dump($gen->current());
$gen->next(); // 2
var_dump($gen->current());
$gen->next(); // 3
var_dump($gen->current());
var_dump($gen->valid());
$gen->next(); // undef
var_dump($gen->current());
var_dump($gen->valid());
?>
===EOF===
--EXPECTF--
int(0)
bool(false)
int(0)
int(0)
int(1)
int(2)
int(3)
bool(true)
NULL
bool(false)
===EOF===

View File

@ -479,14 +479,14 @@ static void v8js_v8generator_free_storage(zend_object *object) /* {{{ */
static zend_object *v8js_v8generator_new(zend_class_entry *ce) /* {{{ */ static zend_object *v8js_v8generator_new(zend_class_entry *ce) /* {{{ */
{ {
v8js_v8object *c; v8js_v8generator *c;
c = (v8js_v8object *) ecalloc(1, sizeof(v8js_v8generator) + zend_object_properties_size(ce)); c = (v8js_v8generator *) ecalloc(1, sizeof(v8js_v8generator) + zend_object_properties_size(ce));
zend_object_std_init(&c->std, ce); zend_object_std_init(&c->v8obj.std, ce);
c->std.handlers = &v8js_v8object_handlers; c->v8obj.std.handlers = &v8js_v8generator_handlers;
new(&c->v8obj) v8::Persistent<v8::Value>(); new(&c->v8obj.v8obj) v8::Persistent<v8::Value>();
return &c->std; return &c->v8obj.std;
} }
/* }}} */ /* }}} */
@ -539,6 +539,17 @@ static void v8js_v8generator_next(v8js_v8generator *g) /* {{{ */
} }
/* }}} */ /* }}} */
static zend_function *v8js_v8generator_get_method(zend_object **object_ptr, zend_string *method, const zval *key) /* {{{ */
{
zend_function *result = std_object_handlers.get_method(object_ptr, method, key);
if(!result) {
result = v8js_v8object_get_method(object_ptr, method, key);
}
return result;
}
/* }}} */
/* {{{ proto V8Generator::__construct() /* {{{ proto V8Generator::__construct()
*/ */
@ -575,6 +586,11 @@ PHP_METHOD(V8Generator, __wakeup)
PHP_METHOD(V8Generator, current) PHP_METHOD(V8Generator, current)
{ {
v8js_v8generator *g = Z_V8JS_V8GENERATOR_OBJ_P(getThis()); v8js_v8generator *g = Z_V8JS_V8GENERATOR_OBJ_P(getThis());
if(!g->primed) {
v8js_v8generator_next(g);
}
RETVAL_ZVAL(&g->value, 1, 0); RETVAL_ZVAL(&g->value, 1, 0);
} }
/* }}} */ /* }}} */
@ -660,16 +676,31 @@ static const zend_function_entry v8js_v8function_methods[] = { /* {{{ */
}; };
/* }}} */ /* }}} */
ZEND_BEGIN_ARG_INFO(arginfo_v8generator_current, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_v8generator_key, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_v8generator_next, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_v8generator_rewind, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_v8generator_valid, 0)
ZEND_END_ARG_INFO()
static const zend_function_entry v8js_v8generator_methods[] = { /* {{{ */ static const zend_function_entry v8js_v8generator_methods[] = { /* {{{ */
PHP_ME(V8Generator, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) PHP_ME(V8Generator, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
PHP_ME(V8Generator, __sleep, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(V8Generator, __sleep, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(V8Generator, __wakeup, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(V8Generator, __wakeup, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(V8Generator, current, NULL, ZEND_ACC_PUBLIC) PHP_ME(V8Generator, current, arginfo_v8generator_current, ZEND_ACC_PUBLIC)
PHP_ME(V8Generator, key, NULL, ZEND_ACC_PUBLIC) PHP_ME(V8Generator, key, arginfo_v8generator_key, ZEND_ACC_PUBLIC)
PHP_ME(V8Generator, next, NULL, ZEND_ACC_PUBLIC) PHP_ME(V8Generator, next, arginfo_v8generator_next, ZEND_ACC_PUBLIC)
PHP_ME(V8Generator, rewind, NULL, ZEND_ACC_PUBLIC) PHP_ME(V8Generator, rewind, arginfo_v8generator_rewind, ZEND_ACC_PUBLIC)
PHP_ME(V8Generator, valid, NULL, ZEND_ACC_PUBLIC) PHP_ME(V8Generator, valid, arginfo_v8generator_valid, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL} {NULL, NULL, NULL}
}; };
@ -720,6 +751,7 @@ PHP_MINIT_FUNCTION(v8js_v8object_class) /* {{{ */
/* V8Generator handlers */ /* V8Generator handlers */
memcpy(&v8js_v8generator_handlers, &v8js_v8object_handlers, sizeof(zend_object_handlers)); memcpy(&v8js_v8generator_handlers, &v8js_v8object_handlers, sizeof(zend_object_handlers));
v8js_v8generator_handlers.get_method = v8js_v8generator_get_method;
v8js_v8generator_handlers.offset = XtOffsetOf(struct v8js_v8generator, v8obj.std); v8js_v8generator_handlers.offset = XtOffsetOf(struct v8js_v8generator, v8obj.std);
v8js_v8generator_handlers.free_obj = v8js_v8generator_free_storage; v8js_v8generator_handlers.free_obj = v8js_v8generator_free_storage;