added support for callable functions and closures as values returned / injected into lua engine

This commit is contained in:
Harald Lapp
2013-08-26 15:28:16 +02:00
parent d9238bdd53
commit f6c6a7fb9e

88
lua.c
View File

@@ -480,48 +480,64 @@ int php_lua_send_zval_to_lua(lua_State *L, zval *val TSRMLS_DC) {
case IS_OBJECT:
case IS_ARRAY:
{
HashTable *ht = NULL;
zval **ppzval = NULL;
if (zend_is_callable(val, 0, NULL TSRMLS_CC)) {
zval* callbacks = NULL;
ht = HASH_OF(val);
callbacks = zend_read_static_property(lua_ce, ZEND_STRL("_callbacks"), 1 TSRMLS_CC);
if (++ht->nApplyCount > 1) {
php_error_docref(NULL TSRMLS_CC, E_ERROR, "recursion found");
--ht->nApplyCount;
break;
}
lua_newtable(L);
for(zend_hash_internal_pointer_reset(ht);
zend_hash_get_current_data(ht, (void **)&ppzval) == SUCCESS;
zend_hash_move_forward(ht)) {
char *key = NULL;
int len = 0;
long idx = 0;
zval *zkey= NULL;
switch(zend_hash_get_current_key_ex(ht, &key, &len, &idx, 0, NULL)) {
case HASH_KEY_IS_STRING :
MAKE_STD_ZVAL(zkey);
ZVAL_STRINGL(zkey, key, len - 1, 1);
break;
case HASH_KEY_IS_LONG:
if (idx == 0) {
php_error_docref(NULL TSRMLS_CC, E_STRICT,
"attempt to pass an array index begin with 0 to lua");
}
MAKE_STD_ZVAL(zkey);
ZVAL_LONG(zkey, idx);
break;
if (ZVAL_IS_NULL(callbacks)) {
array_init(callbacks);
}
php_lua_send_zval_to_lua(L, zkey TSRMLS_CC);
php_lua_send_zval_to_lua(L, *ppzval TSRMLS_CC);
lua_settable(L, -3);
lua_pushnumber(L, zend_hash_num_elements(Z_ARRVAL_P(callbacks)));
lua_pushcclosure(L, php_lua_call_callback, 1);
zval_ptr_dtor(&zkey);
zval_add_ref(&val);
add_next_index_zval(callbacks, val);
} else {
HashTable *ht = NULL;
zval **ppzval = NULL;
ht = HASH_OF(val);
if (++ht->nApplyCount > 1) {
php_error_docref(NULL TSRMLS_CC, E_ERROR, "recursion found");
--ht->nApplyCount;
break;
}
lua_newtable(L);
for(zend_hash_internal_pointer_reset(ht);
zend_hash_get_current_data(ht, (void **)&ppzval) == SUCCESS;
zend_hash_move_forward(ht)) {
char *key = NULL;
int len = 0;
long idx = 0;
zval *zkey= NULL;
switch(zend_hash_get_current_key_ex(ht, &key, &len, &idx, 0, NULL)) {
case HASH_KEY_IS_STRING :
MAKE_STD_ZVAL(zkey);
ZVAL_STRINGL(zkey, key, len - 1, 1);
break;
case HASH_KEY_IS_LONG:
if (idx == 0) {
php_error_docref(NULL TSRMLS_CC, E_STRICT,
"attempt to pass an array index begin with 0 to lua");
}
MAKE_STD_ZVAL(zkey);
ZVAL_LONG(zkey, idx);
break;
}
php_lua_send_zval_to_lua(L, zkey TSRMLS_CC);
php_lua_send_zval_to_lua(L, *ppzval TSRMLS_CC);
lua_settable(L, -3);
zval_ptr_dtor(&zkey);
}
--ht->nApplyCount;
}
--ht->nApplyCount;
}
break;
default: