70 Commits

Author SHA1 Message Date
Xinchen Hui
15f58c43fb releasing 2.0.5 2017-12-31 12:33:16 +08:00
Xinchen Hui
c4c61f05bf Revert the last merge 2017-10-18 13:05:38 +08:00
Xinchen Hui
9ef044896a Merge pull request #31 from sgolemon/callback.refcount
Explicitly release held references to PHP callbacks
2017-10-18 12:56:28 +08:00
Xinchen Hui
feb39efa86 Merge pull request #32 from sgolemon/gitignore
Add a .gitignore to disregard build artifacts
2017-10-18 12:56:02 +08:00
Xinchen Hui
4438a88e85 Merge pull request #33 from sgolemon/object.alloc
Fix allocation of lua object.
2017-10-18 12:55:49 +08:00
Xinchen Hui
0c6a60d21b Merge pull request #34 from sgolemon/php_printf
Prefer php_printf() over printf()
2017-10-18 12:55:26 +08:00
Xinchen Hui
db95520d2f Merge pull request #35 from sgolemon/non-string.accessor
Fix non-string member access in read/write prop.
2017-10-18 12:55:10 +08:00
Xinchen Hui
8afc555bce Merge pull request #36 from sgolemon/closure.refactor
Refactor LuaClosure
2017-10-18 12:53:50 +08:00
Sara Golemon
486de80ebf Refactor LuaClosure
Use proper internal object storage rather than private props.
Favor NULL clone_obj handler over empty private __clone method.
Favor free_obj handler over __destruct() method.
2017-10-03 10:09:53 -04:00
Sara Golemon
1813b36307 Fix non-string member access in read/write prop.
These both have a null pointer deref waiting to happen
and are coincidentally more complex than they need to be.

zval_get_string() will incref any IS_STRING zval,
or copy/convert any non-string zval.

zend_string_release() will then decref or free as appropriate.
2017-10-03 08:51:02 -04:00
Sara Golemon
a2be2c935b Prefer php_printf() over printf()
On CLI the distinction doesn't matter, but in a web sapi this
will ensure the output goes to the right place.
2017-10-03 08:37:13 -04:00
Sara Golemon
6690ee0c70 Fix allocation of lua object.
Size the malloc using zend's helper.
Use ecalloc over emalloc to make sure uninit'd structs are clear.
No need to check return value as e*alloc() funcs can't fail.
2017-10-03 08:32:51 -04:00
Sara Golemon
f64a8d6d27 Add a .gitignore to disregard build artifacts 2017-10-02 19:01:00 -04:00
Sara Golemon
d6c7850afa Explicitly release held references to PHP callbacks 2017-10-02 18:52:01 -04:00
Xinchen Hui
257d46c1e4 back to dev 2017-07-12 11:42:28 +08:00
Xinchen Hui
e350b425f4 release 2.0.4 2017-07-12 11:42:06 +08:00
Xinchen Hui
527f927ead Fixed bug #73964 (Segmentation fault (11)) 2017-02-12 10:53:36 +08:00
Xinchen Hui
9be57325c6 back to dev 2017-02-10 19:14:10 +08:00
Xinchen Hui
1ff1eb10c9 releaseing 2.0.3 2017-02-10 19:13:44 +08:00
Xinchen Hui
cbe65b9ad6 Fixed issue #20 (PHP 7: Lua::eval(): unsupported type `unknown' for lua) 2016-05-30 11:44:12 +08:00
Xinchen Hui
04f7106631 back to dev 2016-05-26 17:42:59 +08:00
Xinchen Hui
7406b07f2c Prepare for 2.0.2 2016-05-26 17:42:22 +08:00
Xinchen Hui
17cbba8b77 Fixed issue #22 (Boolean FALSE is always TRUE) 2016-05-20 11:54:37 +08:00
Xinchen Hui
7cdb287c33 back to dev 2016-04-11 10:55:22 +08:00
Xinchen Hui
f3d6dca1a0 Prepareing for 2.0.1 2016-04-11 10:54:41 +08:00
Xinchen Hui
f177b21ff1 Added tests for bug #71997 2016-04-11 10:51:15 +08:00
Xinchen Hui
c7d9844cf1 Fixed default searching in centOS 2016-04-11 10:50:28 +08:00
Xinchen Hui
12c53f28eb Fixed nApplyCount checking 2016-04-11 10:37:11 +08:00
Xinchen Hui
86cb62e0b8 Merge pull request #19 from tony2001/php7_fixes
fix send_zval_to_lua()
2016-04-07 19:14:59 +08:00
Antony Dovgal
dc226c345d fix send_zval_to_lua() 2016-03-31 12:56:15 +03:00
Xinchen Hui
2d23b565e5 Merge branch 'master' into php7
Conflicts:
	README.md
2015-10-26 21:11:38 -07:00
Xinchen Hui
6a2bf0e8af Update README 2015-10-26 21:11:12 -07:00
Xinchen Hui
230a8af900 Update README 2015-10-26 21:10:51 -07:00
Xinchen Hui
468203ce7c Merge branch 'master' into php7 2015-10-26 21:05:54 -07:00
Xinchen Hui
aaf49be301 trigger triavis 2015-10-26 21:05:41 -07:00
Xinchen Hui
1bd4adf039 No valgrind is valiable 2015-10-26 20:59:34 -07:00
Xinchen Hui
18e2bb493d enable full test 2015-10-26 20:56:56 -07:00
Xinchen Hui
0b28ef4f55 Merge branch 'master' into php7
Conflicts:
	.travis.yml
	travis/compile.sh
2015-10-26 20:56:19 -07:00
Xinchen Hui
d3323aa9fe enable travis 2015-10-26 20:54:55 -07:00
Xinchen Hui
f6a2f09b19 User hjanuschka doesn't exists? 2015-10-27 11:16:04 +08:00
Xinchen Hui
6c2a37f99c back to dev 2015-10-27 11:14:10 +08:00
Xinchen Hui
65764e0777 release lua for PHP7 2015-10-27 11:13:39 +08:00
Xinchen Hui
cf3f69b274 Cleanup 2015-02-26 12:10:34 +08:00
Xinchen Hui
49b95a64f3 All tests passed 2015-02-26 12:05:45 +08:00
Xinchen Hui
ca8cf30759 Only for PHP7 2015-02-26 00:16:38 +08:00
Xinchen Hui
8bccbdc5db clean up (not finish yet) 2015-02-26 00:11:42 +08:00
Xinchen Hui
50d32564d2 Master is only for PHP5.X now 2015-02-25 22:23:05 +08:00
Xinchen Hui
a55478e449 Merge pull request #17 from tony2001/suffix_fix
several config fixes
2015-02-25 20:52:52 +08:00
Antony Dovgal
adb5146954 fix include dir 2015-02-25 15:46:46 +03:00
Antony Dovgal
b95ae16c6f also fix "no" suffix 2015-02-25 15:44:29 +03:00
Antony Dovgal
c3b50a5645 fix libluaYES suffix 2015-02-25 15:26:31 +03:00
Xinchen Hui
bcc3bb67f8 Merge pull request #16 from hjanuschka/hj
Memleaks
2015-02-04 21:56:56 +08:00
Helmut Januschka
5e5fefcdbf * this fixes memleak in php_lua_call_callback
* no more outstanding memory leaks
2015-02-04 12:56:41 +00:00
Xinchen Hui
dea4f594e4 Merge pull request #14 from hjanuschka/hj
add me to authors 👍
2015-02-02 23:21:06 +08:00
Helmut Januschka
6205c5c4ff add me to authors 👍 2015-02-02 15:06:46 +00:00
Xinchen Hui
a2e9c435c4 Merge pull request #13 from hjanuschka/hj
fix for latest php7 head
2015-02-02 22:09:42 +08:00
Helmut Januschka
061f22aac0 fix for latest php7 head 2015-02-02 13:27:33 +00:00
Xinchen Hui
0c265c5e7d Merge pull request #7 from remicollet/issue-php533
Fix build against PHP 5.3.3
2013-11-29 10:15:57 -08:00
Remi Collet
d893cd58c2 zval_copy_property_ctor have been added in 5.3.4 (so not in 5.3.3) 2013-11-06 14:11:45 +01:00
Xinchen Hui
96d77a1c7a Merge pull request #6 from remicollet/issue-110
Various fix for 1.1.0
2013-10-24 00:36:17 -07:00
Remi Collet
99e95d1bf5 fix [-Wpointer-sign] 2013-10-24 08:27:36 +02:00
Remi Collet
10b0cf59cd skip test if json not enabled (or build as shared and so not loaded during make test) 2013-10-24 08:22:57 +02:00
Remi Collet
561f632f62 fix test for 5.1, error string have changed 2013-10-24 08:22:01 +02:00
Remi Collet
22d5b508e7 LUA_ERRGCMM is 5.2 only 2013-10-24 08:19:02 +02:00
Remi Collet
4c8fff9af5 LUA_OK is 5.2 2013-10-24 08:17:43 +02:00
Remi Collet
bef3b82b47 quick fix to allow build against shared system library 2013-10-24 08:16:46 +02:00
Remi Collet
5489007dc8 missing test 2013-10-24 08:12:32 +02:00
Remi Collet
c4f51f3b43 fix role for doc 2013-10-24 08:12:05 +02:00
Remi Collet
b56130d45b drop package2.xml, no more supported 2013-10-24 08:11:15 +02:00
Xinchen Hui
098a5ef470 back to dev(1.1.1-dev) 2013-10-23 12:21:30 +08:00
20 changed files with 855 additions and 732 deletions

37
.gitignore vendored Normal file
View File

@@ -0,0 +1,37 @@
*.lo
*.la
.*.swp
.deps
.libs/
include/
tests/*.diff
tests/*.exp
tests/*.log
tests/*.php
tests/*.out
tests/*.sh
Makefile
Makefile.fragments
Makefile.global
Makefile.objects
acinclude.m4
aclocal.m4
autom4te.cache/
build/
config.guess
config.h
config.h.in
config.log
config.nice
config.status
config.sub
configure
configure.ac
configure.in
install-sh
libtool
ltmain.sh
missing
mkinstalldirs
modules/
run-tests.php

23
.travis.yml Normal file
View File

@@ -0,0 +1,23 @@
language: php
addons:
apt:
packages:
- liblua5.2-dev
php:
- 7.0
notifications:
email: false
irc: "irc.efnet.org#php.yaf"
env:
- REPORT_EXIT_STATUS=1 NO_INTERACTION=1
#Compile
before_script:
- ./travis/compile.sh
# Run PHPs run-tests.php
script: TEST_PHP_ARGS="--show-diff" make test

View File

@@ -2,3 +2,4 @@ lua
Johannes Schlueter Johannes Schlueter
Marcelo Araujo Marcelo Araujo
Xinchen Hui Xinchen Hui
Helmut Januschka

View File

@@ -1,2 +1,6 @@
"Lua is a powerful, fast, light-weight, embeddable scripting language." # PHP Lua
[![Build Status](https://secure.travis-ci.org/laruence/php-lua.png)](https://travis-ci.org/laruence/php-lua)
This extension embeds the lua interpreter and offers an OO-API to lua variables and functions. This extension embeds the lua interpreter and offers an OO-API to lua variables and functions.
"Lua is a powerful, fast, light-weight, embeddable scripting language."

41
config.m4 Normal file → Executable file
View File

@@ -1,34 +1,57 @@
dnl $Id: config.m4 321796 2012-01-05 17:23:48Z laruence $ dnl $Id: config.m4 321796 2012-01-05 17:23:48Z laruence $
PHP_ARG_WITH(lua, for lua support, PHP_ARG_WITH(lua, for lua support,
[ --with-lua=[DIR] Include php lua support]) [ --with-lua=[DIR] Include php lua support])
PHP_ARG_WITH(lua-version, to specify a custom lua version, [ --with-lua-version=[VERSION]] Use the specified lua version.)
PHP_ARG_WITH(lua-version, to specify a custom lua version, [ --with-lua-version=[VERSION]] Use the specified lua version.)
if test "$PHP_LUA" != "no"; then if test "$PHP_LUA" != "no"; then
if test -r $PHP_LUA/include/lua.h; then if test -r $PHP_LUA/include/lua.h; then
LUA_DIR=$PHP_LUA LUA_INCLUDE_DIR=$PHP_LUA/include
else else
AC_MSG_CHECKING(for lua in default path) AC_MSG_CHECKING(for lua in default path)
for i in /usr/local /usr; do for i in /usr/local /usr; do
if test -r $i/include/lua/lua.h; then if test -r $i/include/lua/lua.h; then
LUA_DIR=$i LUA_INCLUDE_DIR=$i/include/lua
AC_MSG_RESULT(found in $i) AC_MSG_RESULT(found in $i)
break break
fi fi
if test -r $i/include/lua.h; then
LUA_INCLUDE_DIR=$i/include
AC_MSG_RESULT(found in $i)
break
fi
if test "$PHP_LUA_VERSION" != "yes"; then
if test -r $i/include/lua$PHP_LUA_VERSION/lua.h; then
LUA_INCLUDE_DIR=$i/include/lua$PHP_LUA_VERSION
AC_MSG_RESULT(found in a version-specific subdirectory of $i)
break
fi
fi
done done
fi fi
if test -z "$LUA_DIR"; then if test -z "$LUA_INCLUDE_DIR"; then
AC_MSG_RESULT(not found) AC_MSG_RESULT(not found)
AC_MSG_ERROR(Please reinstall the lua distribution - lua.h should be in <lua-dir>/include/) AC_MSG_ERROR(Please reinstall the lua distribution - lua.h should be in <lua-dir>/include/)
fi fi
LUA_LIB_NAME=liblua.a if test "$PHP_LUA_VERSION" != "yes" -a "$PHP_LUA_VERSION" != "no"; then
LUA_LIB_SUFFIX=lua$PHP_LUA_VERSION
else
LUA_LIB_SUFFIX=lua
fi
if test -r $PHP_LUA/$PHP_LIBDIR/${LUA_LIB_NAME}; then LUA_LIB_NAME=lib$LUA_LIB_SUFFIX
if test -r $PHP_LUA/$PHP_LIBDIR/${LUA_LIB_NAME}.${SHLIB_SUFFIX_NAME} -o -r $PHP_LUA/$PHP_LIBDIR/${LUA_LIB_NAME}.a; then
LUA_LIB_DIR=$PHP_LUA/$PHP_LIBDIR LUA_LIB_DIR=$PHP_LUA/$PHP_LIBDIR
else else
AC_MSG_CHECKING(for lua library in default path) AC_MSG_CHECKING(for lua library in default path)
for i in /usr/lib /usr/lib64; do for i in /usr/$PHP_LIBDIR /usr/lib /usr/lib64 /usr/lib/x86_64-linux-gnu; do
if test -r $i/${LUA_LIB_NAME}; then if test -r $i/${LUA_LIB_NAME}.${SHLIB_SUFFIX_NAME} -o -r $i/${LUA_LIB_NAME}.a; then
LUA_LIB_DIR=$i LUA_LIB_DIR=$i
AC_MSG_RESULT(found in $i) AC_MSG_RESULT(found in $i)
break break
@@ -41,8 +64,8 @@ if test "$PHP_LUA" != "no"; then
AC_MSG_ERROR(Please reinstall the lua distribution - lua library should be in <lua-dir>/lib/) AC_MSG_ERROR(Please reinstall the lua distribution - lua library should be in <lua-dir>/lib/)
fi fi
PHP_ADD_INCLUDE($LUA_DIR/include) PHP_ADD_INCLUDE($LUA_INCLUDE_DIR)
PHP_ADD_LIBRARY_WITH_PATH(lua, $LUA_LIB_DIR, LUA_SHARED_LIBADD) PHP_ADD_LIBRARY_WITH_PATH($LUA_LIB_SUFFIX, $LUA_LIB_DIR, LUA_SHARED_LIBADD)
PHP_SUBST(LUA_SHARED_LIBADD) PHP_SUBST(LUA_SHARED_LIBADD)
PHP_NEW_EXTENSION(lua, lua.c lua_closure.c, $ext_shared) PHP_NEW_EXTENSION(lua, lua.c lua_closure.c, $ext_shared)
fi fi

579
lua.c Normal file → Executable file
View File

@@ -13,9 +13,9 @@
| Author : Johannes Schlueter <johannes@php.net> | | Author : Johannes Schlueter <johannes@php.net> |
| Xinchen Hui <laruence@php.net> | | Xinchen Hui <laruence@php.net> |
| Marcelo Araujo <msaraujo@php.net> | | Marcelo Araujo <msaraujo@php.net> |
| Helmut Januschka <helmut@januschka.com> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
$Id: lua.c 324348 2012-03-19 03:12:15Z laruence $ */
*/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
@@ -90,45 +90,42 @@ ZEND_GET_MODULE(lua)
/** {{{ static void php_lua_stack_dump(lua_State* L) /** {{{ static void php_lua_stack_dump(lua_State* L)
* just for debug * just for debug
*/ */
#ifdef PHP_LUA_DEBUG
static void php_lua_stack_dump(lua_State* L) { static void php_lua_stack_dump(lua_State* L) {
int i = 1; int i = 1;
int n = lua_gettop(L); int n = lua_gettop(L);
printf("The Length of stack is %d\n", n); php_printf("The Length of stack is %d\n", n);
for (; i <= n; ++i) { for (; i <= n; ++i) {
int t = lua_type(L, i); int t = lua_type(L, i);
printf("%s:", lua_typename(L, t)); php_printf("%s:", lua_typename(L, t));
switch(t) { switch(t) {
case LUA_TNUMBER: case LUA_TNUMBER:
printf("%f", lua_tonumber(L, i)); php_printf("%f", lua_tonumber(L, i));
break; break;
case LUA_TSTRING: case LUA_TSTRING:
printf("%s", lua_tostring(L, i)); php_printf("%s", lua_tostring(L, i));
break; break;
case LUA_TTABLE: case LUA_TTABLE:
break; break;
case LUA_TFUNCTION: case LUA_TFUNCTION:
break; break;
case LUA_TNIL: case LUA_TNIL:
printf("NULL"); php_printf("NULL");
break; break;
case LUA_TBOOLEAN: case LUA_TBOOLEAN:
printf("%s", lua_toboolean(L, i) ? "TRUE" : "FALSE"); php_printf("%s", lua_toboolean(L, i) ? "TRUE" : "FALSE");
break; break;
default: default:
break; break;
} }
printf("\n"); php_printf("\n");
} }
} }
#endif
/* }}} */ /* }}} */
/** {{{ static int php_lua_atpanic(lua_State *L) /** {{{ static int php_lua_atpanic(lua_State *L)
*/ */
static int php_lua_atpanic(lua_State *L) { static int php_lua_atpanic(lua_State *L) {
TSRMLS_FETCH(); php_error_docref(NULL, E_ERROR, "lua panic (%s)", lua_tostring(L, 1));
php_error_docref(NULL TSRMLS_CC, E_ERROR, "lua panic (%s)", lua_tostring(L, 1));
lua_pop(L, 1); lua_pop(L, 1);
zend_bailout(); zend_bailout();
return 0; return 0;
@@ -138,13 +135,14 @@ static int php_lua_atpanic(lua_State *L) {
/** {{{ static int php_lua_print(lua_State *L) /** {{{ static int php_lua_print(lua_State *L)
*/ */
static int php_lua_print(lua_State *L) { static int php_lua_print(lua_State *L) {
zval rv;
int i = 0; int i = 0;
int nargs = lua_gettop(L);
TSRMLS_FETCH(); for (i = 1; i <= nargs; ++i) {
for (i = -lua_gettop(L) ; i<0; i++) { php_lua_get_zval_from_lua(L, i, NULL, &rv);
zval *tmp = php_lua_get_zval_from_lua(L, i, NULL TSRMLS_CC); zend_print_zval_r(&rv, 1);
zend_print_zval_r(tmp, 1 TSRMLS_CC); zval_ptr_dtor(&rv);
zval_ptr_dtor(&tmp);
} }
return 0; return 0;
} }
@@ -172,147 +170,87 @@ static void * php_lua_alloc_function(void *ud, void *ptr, size_t osize, size_t n
} }
/* }}} */ /* }}} */
/** {{{ static void php_lua_dtor_object(void *object, zend_object_handle handle TSRMLS_DC) static void php_lua_dtor_object(zend_object *object) /* {{{ */ {
* the dtor function for lua object php_lua_object *lua_obj = php_lua_obj_from_obj(object);
*/
static void php_lua_dtor_object(void *object, zend_object_handle handle TSRMLS_DC) {
php_lua_object *lua_obj = (php_lua_object *)object;
zend_object_std_dtor(&(lua_obj->obj) TSRMLS_CC); zend_object_std_dtor(&(lua_obj->obj));
}
/* }}} */
static void php_lua_free_object(zend_object *object) /* {{{ */ {
php_lua_object *lua_obj = php_lua_obj_from_obj(object);
if (lua_obj->L) { if (lua_obj->L) {
lua_close(lua_obj->L); lua_close(lua_obj->L);
} }
efree(lua_obj);
} }
/* }}} */ /* }}} */
/** {{{ static zend_object_value php_lua_create_object(zend_class_entry *ce TSRMLS_DC) /** {{{ static zend_object_value php_lua_create_object(zend_class_entry *ce)
*
* the create object handler for lua
*/ */
static zend_object_value php_lua_create_object(zend_class_entry *ce TSRMLS_DC) { zend_object *php_lua_create_object(zend_class_entry *ce)
zend_object_value obj = {0}; {
php_lua_object *lua_obj = NULL; php_lua_object* intern;
lua_State *L = NULL; lua_State *L;
L = lua_newstate(php_lua_alloc_function, NULL); L = luaL_newstate();
lua_atpanic(L, php_lua_atpanic); lua_atpanic(L, php_lua_atpanic);
lua_obj = emalloc(sizeof(php_lua_object)); intern = ecalloc(1, sizeof(php_lua_object) + zend_object_properties_size(ce));
intern->L = L;
if (!lua_obj) { zend_object_std_init(&intern->obj, ce);
php_error_docref(NULL TSRMLS_CC, E_ERROR, "alloc memory for lua object failed"); object_properties_init(&intern->obj, ce);
}
lua_obj->L = L; intern->obj.handlers = &lua_object_handlers;
zend_object_std_init(&(lua_obj->obj), ce TSRMLS_CC);
#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4) return &intern->obj;
zend_hash_copy(lua_obj->obj.properties, &ce->default_properties,
#if (PHP_MINOR_VERSION < 3)
(copy_ctor_func_t) zval_add_ref,
#else
zval_copy_property_ctor(ce),
#endif
(void *)0, sizeof(zval *));
#elif (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 3)
object_properties_init(&(lua_obj->obj), ce);
#endif
obj.handle = zend_objects_store_put(lua_obj, php_lua_dtor_object, NULL, NULL TSRMLS_CC);
obj.handlers = &lua_object_handlers;
return obj;
} }
/* }}} */ /* }}} */
/** {{{ static zval * php_lua_read_property(zval *object, zval *member, int type TSRMLS_DC) /** {{{ static zval * php_lua_read_property(zval *object, zval *member, int type)
*/ */
#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4)) || (PHP_MAJOR_VERSION < 5) zval *php_lua_read_property(zval *object, zval *member, int type, void **cache_slot, zval *rv){
static zval * php_lua_read_property(zval *object, zval *member, int type TSRMLS_DC) { lua_State *L = (Z_LUAVAL_P(object))->L;
#else zend_string *str_member;
static zval * php_lua_read_property(zval *object, zval *member, int type, const struct _zend_literal *key TSRMLS_DC) {
#endif
zval *retval = NULL;
lua_State *L = NULL;
zval *tmp_member = NULL;
#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 3))
(void)key;
#endif
if (type != BP_VAR_R) { if (type != BP_VAR_R) {
MAKE_STD_ZVAL(retval); ZVAL_NULL(rv);
ZVAL_NULL(retval); return rv;
return retval;
} }
if (Z_TYPE_P(member) != IS_STRING) { str_member = zval_get_string(member);
ALLOC_ZVAL(tmp_member);
*tmp_member = *member;
INIT_PZVAL(tmp_member);
zval_copy_ctor(tmp_member);
convert_to_string(tmp_member);
member = tmp_member;
}
L = Z_LUAVAL_P(object);
#if (LUA_VERSION_NUM < 502) #if (LUA_VERSION_NUM < 502)
lua_getfield(L, LUA_GLOBALSINDEX, Z_STRVAL_P(member)); lua_getfield(L, LUA_GLOBALSINDEX, ZSTR_VAL(str_member));
#else #else
lua_getglobal(L, Z_STRVAL_P(member)); lua_getglobal(L, ZSTR_VAL(str_member));
#endif #endif
retval = php_lua_get_zval_from_lua(L, -1, object TSRMLS_CC); zend_string_release(str_member);
Z_DELREF_P(retval);
php_lua_get_zval_from_lua(L, -1, object, rv);
lua_pop(L, 1); lua_pop(L, 1);
return rv;
if (tmp_member) {
zval_ptr_dtor(&tmp_member);
}
return retval;
} }
/* }}} */ /* }}} */
/** {{{ static void php_lua_write_property(zval *object, zval *member, zval *value TSRMLS_DC) /** {{{ static void php_lua_write_property(zval *object, zval *member, zval *value)
*/ */
#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4)) || (PHP_MAJOR_VERSION < 5) static void php_lua_write_property(zval *object, zval *member, zval *value, void ** key) {
static void php_lua_write_property(zval *object, zval *member, zval *value TSRMLS_DC) { lua_State *L = (Z_LUAVAL_P(object))->L;
#else zend_string *str_member = zval_get_string(member);
static void php_lua_write_property(zval *object, zval *member, zval *value, const struct _zend_literal *key TSRMLS_DC) {
#endif
lua_State *L = NULL;
zval *tmp_member = NULL;
#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 3))
(void)key;
#endif
if (Z_TYPE_P(member) != IS_STRING) {
ALLOC_ZVAL(tmp_member);
*tmp_member = *member;
INIT_PZVAL(tmp_member);
zval_copy_ctor(tmp_member);
convert_to_string(tmp_member);
member = tmp_member;
}
L = Z_LUAVAL_P(object);
#if (LUA_VERSION_NUM < 502) #if (LUA_VERSION_NUM < 502)
php_lua_send_zval_to_lua(L, member TSRMLS_CC); php_lua_send_zval_to_lua(L, member);
php_lua_send_zval_to_lua(L, value TSRMLS_CC); php_lua_send_zval_to_lua(L, value);
lua_settable(L, LUA_GLOBALSINDEX); lua_settable(L, LUA_GLOBALSINDEX);
#else #else
php_lua_send_zval_to_lua(L, value TSRMLS_CC); php_lua_send_zval_to_lua(L, value);
lua_setglobal(L, Z_STRVAL_P(member)); lua_setglobal(L, Z_STRVAL_P(member));
#endif #endif
if (tmp_member) { zend_string_release(str_member);
zval_ptr_dtor(&tmp_member);
}
} }
/* }}} */ /* }}} */
@@ -320,72 +258,57 @@ static void php_lua_write_property(zval *object, zval *member, zval *value, cons
*/ */
static int php_lua_call_callback(lua_State *L) { static int php_lua_call_callback(lua_State *L) {
int order = 0; int order = 0;
zval *return_value = NULL; zval retval;
zval **func = NULL; zval *func = NULL;
zval *callbacks = NULL; zval *callbacks = NULL;
TSRMLS_FETCH();
order = lua_tonumber(L, lua_upvalueindex(1)); order = lua_tonumber(L, lua_upvalueindex(1));
callbacks = zend_read_static_property(lua_ce, ZEND_STRL("_callbacks"), 1 TSRMLS_CC); callbacks = zend_read_static_property(lua_ce, ZEND_STRL("_callbacks"), 1);
if (ZVAL_IS_NULL(callbacks)) { if (ZVAL_IS_NULL(callbacks)) {
return 0; return 0;
} }
MAKE_STD_ZVAL(return_value); func = zend_hash_index_find(Z_ARRVAL_P(callbacks), order);
if (zend_hash_index_find(Z_ARRVAL_P(callbacks), order, (void **)&func) == FAILURE) { if (!zend_is_callable(func, 0, NULL)) {
return 0;
}
if (!zend_is_callable(*func, 0, NULL TSRMLS_CC)) {
return 0; return 0;
} else { } else {
zval **params = NULL; zval *params;
int i = 0; int i = 0;
int arg_num = lua_gettop(L); int arg_num = lua_gettop(L);
params = ecalloc(arg_num, sizeof(zval)); params = safe_emalloc(sizeof(zval), arg_num, 0);
for (i = 0; i < arg_num; i++) {
for (; i<arg_num; i++) { php_lua_get_zval_from_lua(L, -(arg_num - i), NULL, &params[i]);
params[i] = php_lua_get_zval_from_lua(L, -(arg_num-i), NULL TSRMLS_CC);
} }
call_user_function(EG(function_table), NULL, *func, return_value, arg_num, params TSRMLS_CC); call_user_function(EG(function_table), NULL, func, &retval, arg_num, params);
php_lua_send_zval_to_lua(L, &retval);
php_lua_send_zval_to_lua(L, return_value TSRMLS_CC); for (i = 0; i<arg_num; i++) {
for (i=0; i<arg_num; i++) {
zval_ptr_dtor(&params[i]); zval_ptr_dtor(&params[i]);
} }
efree(params); efree(params);
zval_ptr_dtor(&return_value); zval_ptr_dtor(&retval);
return 1; return 1;
} }
} }
/* }}} */ /* }}} */
/** {{{ zval * php_lua_get_zval_from_lua(lua_State *L, int index, zval *lua_obj TSRMLS_DC) zval *php_lua_get_zval_from_lua(lua_State *L, int index, zval *lua_obj, zval *rv) /* {{{ */ {
*/
zval * php_lua_get_zval_from_lua(lua_State *L, int index, zval *lua_obj TSRMLS_DC) {
zval *retval;
MAKE_STD_ZVAL(retval);
ZVAL_NULL(retval);
switch (lua_type(L, index)) { switch (lua_type(L, index)) {
case LUA_TNIL: case LUA_TNIL:
ZVAL_NULL(retval); ZVAL_NULL(rv);
break; break;
case LUA_TBOOLEAN: case LUA_TBOOLEAN:
ZVAL_BOOL(retval, lua_toboolean(L, index)); ZVAL_BOOL(rv, lua_toboolean(L, index));
break; break;
case LUA_TNUMBER: case LUA_TNUMBER:
ZVAL_DOUBLE(retval, lua_tonumber(L, index)); ZVAL_DOUBLE(rv, lua_tonumber(L, index));
break; break;
case LUA_TSTRING: case LUA_TSTRING:
{ {
@@ -393,32 +316,33 @@ zval * php_lua_get_zval_from_lua(lua_State *L, int index, zval *lua_obj TSRMLS_D
size_t len = 0; size_t len = 0;
val = (char *)lua_tolstring(L, index, &len); val = (char *)lua_tolstring(L, index, &len);
ZVAL_STRINGL(retval, val, len, 1); ZVAL_STRINGL(rv, val, len);
} }
break; break;
case LUA_TTABLE: case LUA_TTABLE:
array_init(retval); array_init(rv);
lua_pushnil(L); /* first key */ lua_pushnil(L); /* first key */
while (lua_next(L, index-1) != 0) { while (lua_next(L, index-1) != 0) {
zval *key = NULL; zval key, val;
zval *val = NULL;
/* uses 'key' (at index -2) and 'value' (at index -1) */ /* uses 'key' (at index -2) and 'value' (at index -1) */
key = php_lua_get_zval_from_lua(L, -2, lua_obj TSRMLS_CC); if (!php_lua_get_zval_from_lua(L, -2, lua_obj, &key)) {
val = php_lua_get_zval_from_lua(L, -1, lua_obj TSRMLS_CC); break;
}
if (!key || !val) { if (!php_lua_get_zval_from_lua(L, -1, lua_obj, &val)) {
zval_ptr_dtor(&key);
/* there is a warning already in php_lua_get_zval_from_lua */ /* there is a warning already in php_lua_get_zval_from_lua */
break; break;
} }
switch(Z_TYPE_P(key)) { switch (Z_TYPE(key)) {
case IS_DOUBLE: case IS_DOUBLE:
case IS_LONG: case IS_LONG:
add_index_zval(retval, Z_DVAL_P(key), val); add_index_zval(rv, Z_DVAL(key), &val);
break; break;
case IS_STRING: case IS_STRING:
add_assoc_zval(retval, Z_STRVAL_P(key), val); add_assoc_zval(rv, Z_STRVAL(key), &val);
zval_ptr_dtor(&key);
break; break;
case IS_ARRAY: case IS_ARRAY:
case IS_OBJECT: case IS_OBJECT:
@@ -426,22 +350,23 @@ zval * php_lua_get_zval_from_lua(lua_State *L, int index, zval *lua_obj TSRMLS_D
break; break;
} }
lua_pop(L, 1); lua_pop(L, 1);
zval_ptr_dtor(&key);
} }
break; break;
case LUA_TFUNCTION: case LUA_TFUNCTION:
{ {
long ref_id = 0; long ref_id = 0;
if (!lua_obj) { if (!lua_obj) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "corrupted Lua object"); php_error_docref(NULL, E_WARNING, "corrupted Lua object");
break; break;
} }
lua_pushvalue(L, index); lua_pushvalue(L, index);
ref_id = luaL_ref(L, LUA_REGISTRYINDEX); ref_id = luaL_ref(L, LUA_REGISTRYINDEX);
if (!php_lua_closure_instance(retval, ref_id, lua_obj TSRMLS_CC)) { if (!php_lua_closure_instance(rv, ref_id, lua_obj)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to initialize closure object"); php_error_docref(NULL, E_WARNING, "failed to initialize closure object");
ZVAL_NULL(rv);
return NULL;
} }
} }
break; break;
@@ -449,22 +374,26 @@ zval * php_lua_get_zval_from_lua(lua_State *L, int index, zval *lua_obj TSRMLS_D
case LUA_TTHREAD: case LUA_TTHREAD:
case LUA_TLIGHTUSERDATA: case LUA_TLIGHTUSERDATA:
default: default:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unsupported type '%s' for php", php_error_docref(NULL, E_WARNING, "unsupported type '%s' for php",
lua_typename(L, lua_type(L, index))); lua_typename(L, lua_type(L, index)));
ZVAL_NULL(rv);
return NULL;
} }
return rv;
return retval;
} }
/* }}} */ /* }}} */
/** {{{ int php_lua_send_zval_to_lua(lua_State *L, zval *val TSRMLS_DC) int php_lua_send_zval_to_lua(lua_State *L, zval *val) /* {{{ */ {
*/
int php_lua_send_zval_to_lua(lua_State *L, zval *val TSRMLS_DC) {
try_again:
switch (Z_TYPE_P(val)) { switch (Z_TYPE_P(val)) {
case IS_BOOL: case IS_TRUE:
lua_pushboolean(L, Z_BVAL_P(val)); lua_pushboolean(L, 1);
break; break;
case IS_FALSE:
lua_pushboolean(L, 0);
break;
case IS_UNDEF:
case IS_NULL: case IS_NULL:
lua_pushnil(L); lua_pushnil(L);
break; break;
@@ -480,10 +409,10 @@ int php_lua_send_zval_to_lua(lua_State *L, zval *val TSRMLS_DC) {
case IS_OBJECT: case IS_OBJECT:
case IS_ARRAY: case IS_ARRAY:
{ {
if (zend_is_callable(val, 0, NULL TSRMLS_CC)) { if (zend_is_callable(val, 0, NULL)) {
zval* callbacks = NULL; zval *callbacks;
callbacks = zend_read_static_property(lua_ce, ZEND_STRL("_callbacks"), 1 TSRMLS_CC); callbacks = zend_read_static_property(lua_ce, ZEND_STRL("_callbacks"), 1);
if (ZVAL_IS_NULL(callbacks)) { if (ZVAL_IS_NULL(callbacks)) {
array_init(callbacks); array_init(callbacks);
@@ -492,57 +421,53 @@ int php_lua_send_zval_to_lua(lua_State *L, zval *val TSRMLS_DC) {
lua_pushnumber(L, zend_hash_num_elements(Z_ARRVAL_P(callbacks))); lua_pushnumber(L, zend_hash_num_elements(Z_ARRVAL_P(callbacks)));
lua_pushcclosure(L, php_lua_call_callback, 1); lua_pushcclosure(L, php_lua_call_callback, 1);
zval_add_ref(&val); zval_add_ref(val);
add_next_index_zval(callbacks, val); add_next_index_zval(callbacks, val);
} else { } else {
HashTable *ht = NULL; zval *v;
zval **ppzval = NULL; ulong longkey;
zend_string *key;
zval zkey;
ht = HASH_OF(val); HashTable *ht = HASH_OF(val);
if (ZEND_HASH_APPLY_PROTECTION(ht)) {
if (++ht->nApplyCount > 1) { ZEND_HASH_INC_APPLY_COUNT(ht);
php_error_docref(NULL TSRMLS_CC, E_ERROR, "recursion found"); if (ZEND_HASH_GET_APPLY_COUNT(ht) > 1) {
--ht->nApplyCount; php_error_docref(NULL, E_ERROR, "recursion found");
break; ZEND_HASH_DEC_APPLY_COUNT(ht);
break;
}
} }
lua_newtable(L); 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)) { ZEND_HASH_FOREACH_KEY_VAL_IND(ht, longkey, key, v) {
case HASH_KEY_IS_STRING : if (key) {
MAKE_STD_ZVAL(zkey); ZVAL_STR(&zkey, key);
ZVAL_STRINGL(zkey, key, len - 1, 1); } else {
break; ZVAL_LONG(&zkey, longkey);
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);
php_lua_send_zval_to_lua(L, zkey TSRMLS_CC); php_lua_send_zval_to_lua(L, v);
php_lua_send_zval_to_lua(L, *ppzval TSRMLS_CC);
lua_settable(L, -3); lua_settable(L, -3);
} ZEND_HASH_FOREACH_END();
zval_ptr_dtor(&zkey); if (ZEND_HASH_APPLY_PROTECTION(ht)) {
ZEND_HASH_DEC_APPLY_COUNT(ht);
} }
--ht->nApplyCount;
} }
} }
break; break;
case IS_REFERENCE:
ZVAL_DEREF(val);
goto try_again;
break;
case IS_INDIRECT:
val = Z_INDIRECT_P(val);
goto try_again;
break;
default: default:
php_error_docref(NULL TSRMLS_CC, E_ERROR, "unsupported type `%s' for lua" php_error_docref(NULL, E_ERROR, "unsupported type `%s' for lua", zend_zval_type_name(val));
, zend_zval_type_name(val));
lua_pushnil(L); lua_pushnil(L);
return 1; return 1;
} }
@@ -551,52 +476,49 @@ int php_lua_send_zval_to_lua(lua_State *L, zval *val TSRMLS_DC) {
} }
/* }}} */ /* }}} */
/*** {{{ static int php_lua_arg_apply_func(void *data, void *L TSRMLS_DC) /*** {{{ static int php_lua_arg_apply_func(void *data, void *L)
*/ */
static int php_lua_arg_apply_func(void *data, void *L TSRMLS_DC) { static int php_lua_arg_apply_func(void *data, void *L) {
php_lua_send_zval_to_lua((lua_State*)L, *(zval**)data TSRMLS_CC); php_lua_send_zval_to_lua((lua_State*)L, (zval*)data);
return ZEND_HASH_APPLY_KEEP; return ZEND_HASH_APPLY_KEEP;
} /* }}} */ } /* }}} */
/** {{{ static zval * php_lua_call_lua_function(zval *lua_obj, zval *func, zval *args, int use_self TSRMLS_DC) static zval *php_lua_call_lua_function(zval *lua_obj, zval *func, zval *args, int use_self, zval *retval) /* {{{ */ {
*/ int bp = 0;
static zval * php_lua_call_lua_function(zval *lua_obj, zval *func, zval *args, int use_self TSRMLS_DC) { int sp = 0;
int bp = 0;
int sp = 0;
int arg_num = 0; int arg_num = 0;
zval *ret = NULL; zval rv;
lua_State *L = NULL; lua_State *L;
L = Z_LUAVAL_P(lua_obj); L = (Z_LUAVAL_P(lua_obj))->L;
if (IS_ARRAY == Z_TYPE_P(func)) { if (IS_ARRAY == Z_TYPE_P(func)) {
zval **t = NULL; zval *t, *f;
zval **f = NULL; if ((t = zend_hash_index_find(Z_ARRVAL_P(func), 0)) == NULL || Z_TYPE_P(t) != IS_STRING
if (zend_hash_index_find(Z_ARRVAL_P(func), 0, (void **)&t) == FAILURE || Z_TYPE_PP(t) != IS_STRING || (f = zend_hash_index_find(Z_ARRVAL_P(func), 1)) == NULL || Z_TYPE_P(f) != IS_STRING) {
|| zend_hash_index_find(Z_ARRVAL_P(func), 1, (void **)&f) == FAILURE || Z_TYPE_PP(f) != IS_STRING) {
/* as johannes suggesting use exceptioni to distinguish the error from a lua function return false /* as johannes suggesting use exceptioni to distinguish the error from a lua function return false
php_error_docref(NULL TSRMLS_CC, E_WARNING, php_error_docref(NULL, E_WARNING,
"invalid lua function, argument must be an array which contain two elements: array('table', 'method')"); "invalid lua function, argument must be an array which contain two elements: array('table', 'method')");
*/ */
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, zend_throw_exception_ex(lua_exception_ce, 0,
"invalid lua function, argument must be an array which contain two elements: array('table', 'method')"); "invalid lua function, argument must be an array which contain two elements: array('table', 'method')");
return NULL; return NULL;
} }
#if (LUA_VERSION_NUM < 502) #if (LUA_VERSION_NUM < 502)
lua_getfield(L, LUA_GLOBALSINDEX, Z_STRVAL_PP(t)); lua_getfield(L, LUA_GLOBALSINDEX, Z_STRVAL_P(t));
#else #else
lua_getglobal(L, Z_STRVAL_PP(t)); lua_getglobal(L, Z_STRVAL_P(t));
#endif #endif
if (LUA_TTABLE != lua_type(L, lua_gettop(L))) { if (LUA_TTABLE != lua_type(L, lua_gettop(L))) {
lua_pop(L, -1); lua_pop(L, -1);
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "invalid lua table '%s'", Z_STRVAL_PP(t)); zend_throw_exception_ex(lua_exception_ce, 0, "invalid lua table '%s'", Z_STRVAL_P(t));
return NULL; return NULL;
} }
bp = lua_gettop(L); bp = lua_gettop(L);
lua_getfield(L, -1, Z_STRVAL_PP(f)); lua_getfield(L, -1, Z_STRVAL_P(f));
if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) { if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) {
lua_pop(L, -2); lua_pop(L, -2);
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "invalid lua table function '%s'.%s", Z_STRVAL_PP(t), Z_STRVAL_PP(f)); zend_throw_exception_ex(lua_exception_ce, 0, "invalid lua table function '%s'.%s", Z_STRVAL_P(t), Z_STRVAL_P(f));
return NULL; return NULL;
} }
} else if (IS_STRING == Z_TYPE_P(func)) { } else if (IS_STRING == Z_TYPE_P(func)) {
@@ -608,21 +530,17 @@ static zval * php_lua_call_lua_function(zval *lua_obj, zval *func, zval *args, i
#endif #endif
if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) { if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) {
lua_pop(L, -1); lua_pop(L, -1);
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "invalid lua function '%s'", Z_STRVAL_P(func)); zend_throw_exception_ex(lua_exception_ce, 0, "invalid lua function '%s'", Z_STRVAL_P(func));
return NULL; return NULL;
} }
} else if (IS_OBJECT == Z_TYPE_P(func) } else if (IS_OBJECT == Z_TYPE_P(func)
&& instanceof_function(Z_OBJCE_P(func), php_lua_get_closure_ce() TSRMLS_CC)) { && instanceof_function(Z_OBJCE_P(func), php_lua_get_closure_ce())) {
zval *closure = zend_read_property(php_lua_get_closure_ce(), func, ZEND_STRL("_closure"), 1 TSRMLS_CC); lua_closure_object *closure_obj = php_lua_closure_object_from_zend_object(Z_OBJ_P(func));
if (!Z_LVAL_P(closure)) {
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "invalid lua closure");
return NULL;
}
bp = lua_gettop(L); bp = lua_gettop(L);
lua_rawgeti(L, LUA_REGISTRYINDEX, Z_LVAL_P(closure)); lua_rawgeti(L, LUA_REGISTRYINDEX, closure_obj->closure);
if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) { if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) {
lua_pop(L, -1); lua_pop(L, -1);
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "call to lua closure failed"); zend_throw_exception_ex(lua_exception_ce, 0, "call to lua closure failed");
return NULL; return NULL;
} }
} }
@@ -635,11 +553,11 @@ static zval * php_lua_call_lua_function(zval *lua_obj, zval *func, zval *args, i
if (args) { if (args) {
arg_num += zend_hash_num_elements(Z_ARRVAL_P(args)); arg_num += zend_hash_num_elements(Z_ARRVAL_P(args));
zend_hash_apply_with_argument(Z_ARRVAL_P(args), php_lua_arg_apply_func, (void *)L TSRMLS_CC); zend_hash_apply_with_argument(Z_ARRVAL_P(args), (apply_func_arg_t)php_lua_arg_apply_func, (void *)L);
} }
if (lua_pcall(L, arg_num, LUA_MULTRET, 0) != LUA_OK) { if (lua_pcall(L, arg_num, LUA_MULTRET, 0) != LUA_OK) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, php_error_docref(NULL, E_WARNING,
"call to lua function %s failed", lua_tostring(L, -1)); "call to lua function %s failed", lua_tostring(L, -1));
lua_pop(L, lua_gettop(L) - bp); lua_pop(L, lua_gettop(L) - bp);
return NULL; return NULL;
@@ -648,17 +566,16 @@ static zval * php_lua_call_lua_function(zval *lua_obj, zval *func, zval *args, i
sp = lua_gettop(L) - bp; sp = lua_gettop(L) - bp;
if (!sp) { if (!sp) {
MAKE_STD_ZVAL(ret); ZVAL_NULL(retval);
ZVAL_NULL(ret);
} else if (sp == 1) { } else if (sp == 1) {
ret = php_lua_get_zval_from_lua(L, -1, lua_obj TSRMLS_CC); php_lua_get_zval_from_lua(L, -1, lua_obj, retval);
} else { } else {
zval rv;
int i = 0; int i = 0;
MAKE_STD_ZVAL(ret); array_init(retval);
array_init(ret);
for (i = -sp; i < 0; i++) { for (i = -sp; i < 0; i++) {
zval *tmp = php_lua_get_zval_from_lua(L, i, lua_obj TSRMLS_CC); php_lua_get_zval_from_lua(L, i, lua_obj, &rv);
add_next_index_zval(ret, tmp); add_next_index_zval(retval, &rv);
} }
} }
@@ -668,43 +585,43 @@ static zval * php_lua_call_lua_function(zval *lua_obj, zval *func, zval *args, i
lua_pop(L, -1); lua_pop(L, -1);
} }
return ret; return retval;
} /* }}} */ } /* }}} */
/** {{{ proto Lua::eval(string $lua_chunk) /** {{{ proto Lua::eval(string $lua_chunk)
* eval a lua chunk * eval a lua chunk
*/ */
PHP_METHOD(lua, eval) { PHP_METHOD(lua, eval) {
lua_State *L = NULL; lua_State *L;
char *statements = NULL; char *statements;
long bp, len = 0; long bp, len;
int ret; int ret;
L = Z_LUAVAL_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &statements, &len) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &statements, &len) == FAILURE) {
return; return;
} }
L = (Z_LUAVAL_P(getThis()))->L;
bp = lua_gettop(L); bp = lua_gettop(L);
if ((ret = luaL_loadbuffer(L, statements, len, "line")) != LUA_OK || (ret = lua_pcall(L, 0, LUA_MULTRET, 0) != LUA_OK)) { if ((ret = luaL_loadbuffer(L, statements, len, "line")) != LUA_OK || (ret = lua_pcall(L, 0, LUA_MULTRET, 0) != LUA_OK)) {
zend_throw_exception_ex(lua_exception_ce, ret TSRMLS_CC, "%s", lua_tostring(L, -1)); zend_throw_exception_ex(lua_exception_ce, ret, "%s", lua_tostring(L, -1));
lua_pop(L, 1); lua_pop(L, 1);
RETURN_FALSE; RETURN_FALSE;
} else { } else {
zval *tmp = NULL; int ret_count;
int ret_count = 0;
int i = 0;
ret_count = lua_gettop(L) - bp; ret_count = lua_gettop(L) - bp;
if (ret_count > 1) { if (ret_count > 1) {
zval rv;
int i = 0;
array_init(return_value); array_init(return_value);
for (i = -ret_count; i<0; i++) { for (i = -ret_count; i<0; i++) {
tmp = php_lua_get_zval_from_lua(L, i, getThis() TSRMLS_CC); php_lua_get_zval_from_lua(L, i, getThis(), &rv);
add_next_index_zval(return_value, tmp); add_next_index_zval(return_value, &rv);
} }
} else if (ret_count) { } else if (ret_count) {
zval *tmp = php_lua_get_zval_from_lua(L, -1, getThis() TSRMLS_CC); php_lua_get_zval_from_lua(L, -1, getThis(), return_value);
RETURN_ZVAL(tmp, 1, 1);
} }
lua_pop(L, ret_count); lua_pop(L, ret_count);
} }
@@ -715,50 +632,41 @@ PHP_METHOD(lua, eval) {
* run a lua script file * run a lua script file
*/ */
PHP_METHOD(lua, include) { PHP_METHOD(lua, include) {
lua_State *L = NULL; lua_State *L;
char *file = NULL; char *file;
long bp, len = 0; size_t bp, len;
int ret; int ret;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &len) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &file, &len) == FAILURE) {
return; return;
} }
if (php_check_open_basedir(file TSRMLS_CC) if (php_check_open_basedir(file)) {
#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4)) || (PHP_MAJOR_VERSION < 5)
|| (PG(safe_mode)
&& !php_checkuid(file, "rb+", CHECKUID_CHECK_MODE_PARAM))
#endif
) {
RETURN_FALSE; RETURN_FALSE;
} }
L = Z_LUAVAL_P(getThis()); L = (Z_LUAVAL_P(getThis()))->L;
bp = lua_gettop(L); bp = lua_gettop(L);
if ((ret = luaL_loadfile(L, file)) != LUA_OK || (ret = lua_pcall(L, 0, LUA_MULTRET, 0) != LUA_OK)) { if ((ret = luaL_loadfile(L, file)) != LUA_OK || (ret = lua_pcall(L, 0, LUA_MULTRET, 0) != LUA_OK)) {
zend_throw_exception_ex(lua_exception_ce, ret TSRMLS_CC, "%s", lua_tostring(L, -1)); zend_throw_exception_ex(lua_exception_ce, ret, "%s", lua_tostring(L, -1));
lua_pop(L, 1); lua_pop(L, 1);
RETURN_FALSE; RETURN_FALSE;
} else { } else {
zval *tmp = NULL; int ret_count;
int ret_count = 0;
int i = 0;
ret_count = lua_gettop(L) - bp; ret_count = lua_gettop(L) - bp;
if (ret_count > 1) { if (ret_count > 1) {
zval rv;
int i = 0;
array_init(return_value); array_init(return_value);
for (i = -ret_count; i<0; i++) { for (i = -ret_count; i<0; i++) {
tmp = php_lua_get_zval_from_lua(L, i, getThis() TSRMLS_CC); php_lua_get_zval_from_lua(L, i, getThis(), &rv);
add_next_index_zval(return_value, tmp); add_next_index_zval(return_value, &rv);
} }
} else if (ret_count) { } else if (ret_count) {
zval *tmp = php_lua_get_zval_from_lua(L, -1, getThis() TSRMLS_CC); php_lua_get_zval_from_lua(L, -1, getThis(), return_value);
RETURN_ZVAL(tmp, 1, 1);
} }
lua_pop(L, ret_count); lua_pop(L, ret_count);
} }
} }
@@ -768,41 +676,37 @@ PHP_METHOD(lua, include) {
*/ */
PHP_METHOD(lua, call) { PHP_METHOD(lua, call) {
long u_self = 0; long u_self = 0;
zval *func;
zval *args = NULL; zval *args = NULL;
zval *func = NULL;
zval *ret = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|al", &func, &args, &u_self) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|al", &func, &args, &u_self) == FAILURE) {
return; return;
} }
if ((ret = php_lua_call_lua_function(getThis(), func, args, u_self TSRMLS_CC))) { if (!(php_lua_call_lua_function(getThis(), func, args, u_self, return_value))) {
RETURN_ZVAL(ret, 1, 1); RETURN_FALSE;
} }
RETURN_FALSE;
} }
/* }}} */ /* }}} */
/** {{{ proto Lua::assign(string $name, mix $value) /** {{{ proto Lua::assign(string $name, mix $value)
*/ */
PHP_METHOD(lua, assign) { PHP_METHOD(lua, assign) {
char *name = NULL; zval *name;
zval *value = NULL; zval *value;
lua_State *L = NULL; lua_State *L;
int len = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &len, &value) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &name, &value) == FAILURE) {
return; return;
} }
L = Z_LUAVAL_P(getThis()); L = (Z_LUAVAL_P(getThis()))->L;
php_lua_send_zval_to_lua(L, value TSRMLS_CC); php_lua_send_zval_to_lua(L, value);
#if (LUA_VERSION_NUM < 502) #if (LUA_VERSION_NUM < 502)
lua_setfield(L, LUA_GLOBALSINDEX, name); lua_setfield(L, LUA_GLOBALSINDEX, Z_STRVAL_P(name));
#else #else
lua_setglobal(L, name); lua_setglobal(L, Z_STRVAL_P(name));
#endif #endif
RETURN_ZVAL(getThis(), 1, 0); RETURN_ZVAL(getThis(), 1, 0);
@@ -812,33 +716,34 @@ PHP_METHOD(lua, assign) {
/** {{{ proto Lua::registerCallback(string $name, mix $value) /** {{{ proto Lua::registerCallback(string $name, mix $value)
*/ */
PHP_METHOD(lua, registerCallback) { PHP_METHOD(lua, registerCallback) {
char *name = NULL; char *name;
long len = 0; size_t len;
zval *func = NULL; zval *func;
lua_State *L = NULL; lua_State *L;
zval* callbacks = NULL; zval* callbacks;
L = Z_LUAVAL_P(getThis());
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"sz", &name, &len, &func) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(),"sz", &name, &len, &func) == FAILURE) {
return; return;
} }
callbacks = zend_read_static_property(lua_ce, ZEND_STRL("_callbacks"), 1 TSRMLS_CC); L = (Z_LUAVAL_P(getThis()))->L;
callbacks = zend_read_static_property(lua_ce, ZEND_STRL("_callbacks"), 1);
if (ZVAL_IS_NULL(callbacks)) { if (ZVAL_IS_NULL(callbacks)) {
array_init(callbacks); array_init(callbacks);
} }
if (zend_is_callable(func, 0, NULL TSRMLS_CC)) { if (zend_is_callable(func, 0, NULL)) {
lua_pushnumber(L, zend_hash_num_elements(Z_ARRVAL_P(callbacks))); lua_pushnumber(L, zend_hash_num_elements(Z_ARRVAL_P(callbacks)));
lua_pushcclosure(L, php_lua_call_callback, 1); lua_pushcclosure(L, php_lua_call_callback, 1);
lua_setglobal(L, name); lua_setglobal(L, name);
} else { } else {
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "invalid php callback"); zend_throw_exception_ex(lua_exception_ce, 0, "invalid php callback");
RETURN_FALSE; RETURN_FALSE;
} }
zval_add_ref(&func); zval_add_ref(func);
add_next_index_zval(callbacks, func); add_next_index_zval(callbacks, func);
RETURN_ZVAL(getThis(), 1, 0); RETURN_ZVAL(getThis(), 1, 0);
@@ -848,14 +753,15 @@ PHP_METHOD(lua, registerCallback) {
/** {{{ proto Lua::getVersion() /** {{{ proto Lua::getVersion()
*/ */
PHP_METHOD(lua, getVersion) { PHP_METHOD(lua, getVersion) {
RETURN_STRING(LUA_RELEASE, 1); RETURN_STRING(LUA_RELEASE);
} }
/* }}} */ /* }}} */
/** {{{ proto Lua::__construct() /** {{{ proto Lua::__construct()
*/ */
PHP_METHOD(lua, __construct) { PHP_METHOD(lua, __construct) {
lua_State *L = Z_LUAVAL_P(getThis()); lua_State * L = (Z_LUAVAL_P(getThis()))->L;
luaL_openlibs(L); luaL_openlibs(L);
lua_register(L, "print", php_lua_print); lua_register(L, "print", php_lua_print);
if (ZEND_NUM_ARGS()) { if (ZEND_NUM_ARGS()) {
@@ -876,7 +782,7 @@ zend_function_entry lua_class_methods[] = {
PHP_ME(lua, getVersion, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC) PHP_ME(lua, getVersion, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
PHP_ME(lua, registerCallback, arginfo_lua_register, ZEND_ACC_PUBLIC) PHP_ME(lua, registerCallback, arginfo_lua_register, ZEND_ACC_PUBLIC)
PHP_MALIAS(lua, __call, call, arginfo_lua_call, ZEND_ACC_PUBLIC) PHP_MALIAS(lua, __call, call, arginfo_lua_call, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL} PHP_FE_END
}; };
/* }}} */ /* }}} */
@@ -892,33 +798,34 @@ PHP_MINIT_FUNCTION(lua) {
REGISTER_LONG_CONSTANT("LUA_ERRRUN", LUA_ERRRUN, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("LUA_ERRRUN", LUA_ERRRUN, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("LUA_ERRSYNTAX", LUA_ERRSYNTAX, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("LUA_ERRSYNTAX", LUA_ERRSYNTAX, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("LUA_ERRMEM", LUA_ERRMEM, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("LUA_ERRMEM", LUA_ERRMEM, CONST_PERSISTENT | CONST_CS);
#ifdef LUA_ERRGCMM
REGISTER_LONG_CONSTANT("LUA_ERRGCMM", LUA_ERRGCMM, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("LUA_ERRGCMM", LUA_ERRGCMM, CONST_PERSISTENT | CONST_CS);
#endif
REGISTER_LONG_CONSTANT("LUA_ERRERR", LUA_ERRERR, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("LUA_ERRERR", LUA_ERRERR, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("LUA_ERRFILE", LUA_ERRFILE, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("LUA_ERRFILE", LUA_ERRFILE, CONST_PERSISTENT | CONST_CS);
lua_ce = zend_register_internal_class(&ce TSRMLS_CC); lua_ce = zend_register_internal_class(&ce);
lua_ce->create_object = php_lua_create_object; lua_ce->create_object = php_lua_create_object;
memcpy(&lua_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); memcpy(&lua_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
lua_object_handlers.offset = XtOffsetOf(php_lua_object, obj);
lua_object_handlers.dtor_obj = php_lua_dtor_object;
lua_object_handlers.free_obj = php_lua_free_object;
lua_object_handlers.clone_obj = NULL;
lua_object_handlers.write_property = php_lua_write_property; lua_object_handlers.write_property = php_lua_write_property;
lua_object_handlers.read_property = php_lua_read_property; lua_object_handlers.read_property = php_lua_read_property;
lua_ce->ce_flags |= ZEND_ACC_FINAL; lua_ce->ce_flags |= ZEND_ACC_FINAL;
zend_declare_property_null(lua_ce, ZEND_STRL("_callbacks"), ZEND_ACC_STATIC|ZEND_ACC_PRIVATE TSRMLS_CC); zend_declare_property_null(lua_ce, ZEND_STRL("_callbacks"), ZEND_ACC_STATIC|ZEND_ACC_PRIVATE);
zend_declare_class_constant_string(lua_ce, ZEND_STRL("LUA_VERSION"), LUA_RELEASE TSRMLS_CC); zend_declare_class_constant_string(lua_ce, ZEND_STRL("LUA_VERSION"), LUA_RELEASE);
php_lua_closure_register(TSRMLS_C); php_lua_closure_register();
INIT_CLASS_ENTRY(ce, "LuaException", NULL); INIT_CLASS_ENTRY(ce, "LuaException", NULL);
lua_exception_ce = zend_register_internal_class_ex(&ce,
#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 2) lua_exception_ce = zend_register_internal_class_ex(&ce, zend_exception_get_default());
zend_exception_get_default(),
#else
zend_exception_get_default(TSRMLS_C),
#endif
NULL TSRMLS_CC);
return SUCCESS; return SUCCESS;
} }

View File

@@ -11,10 +11,10 @@
| license@php.net so we can mail you a copy immediately. | | license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Author : Johannes Schlueter <johannes@php.net> | | Author : Johannes Schlueter <johannes@php.net> |
| Xinchen Hui <laruence@php.net> | | Xinchen Hui <laruence@php.net> |
| Marcelo Araujo <msaraujo@php.net> | | Marcelo Araujo <msaraujo@php.net> |
| Helmut Januschka <helmut@januschka.com> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
$Id: lua_closure.c 319740 2011-11-24 08:06:48Z laruence $
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@@ -25,6 +25,7 @@
#include "Zend/zend_exceptions.h" #include "Zend/zend_exceptions.h"
#include "lua.h" #include "lua.h"
#include "lua_closure.h"
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
@@ -33,6 +34,7 @@
static zend_class_entry *lua_closure_ce; static zend_class_entry *lua_closure_ce;
extern zend_class_entry *lua_ce; extern zend_class_entry *lua_ce;
extern zend_class_entry *lua_exception_ce; extern zend_class_entry *lua_exception_ce;
static zend_object_handlers lua_closure_handlers;
/** {{{ ARG_INFO /** {{{ ARG_INFO
* *
@@ -43,12 +45,15 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_invoke, 0, 0, 1)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
/* }}} */ /* }}} */
/** {{{ zval * php_lua_closure_instance(zval *instance, long ref_id, zval *lua_obj TSRMLS_DC) /** {{{ zval * php_lua_closure_instance(zval *instance, long ref_id, zval *lua_obj)
*/ */
zval * php_lua_closure_instance(zval *instance, long ref_id, zval *lua_obj TSRMLS_DC) { zval* php_lua_closure_instance(zval *instance, long ref_id, zval *lua_obj) {
lua_closure_object *objval;
object_init_ex(instance, lua_closure_ce); object_init_ex(instance, lua_closure_ce);
zend_update_property_long(lua_closure_ce, instance, ZEND_STRL("_closure"), ref_id TSRMLS_CC); objval = php_lua_closure_object_from_zend_object(Z_OBJ_P(instance));
zend_update_property(lua_closure_ce, instance, ZEND_STRL("_lua_object"), lua_obj TSRMLS_CC); objval->closure = ref_id;
ZVAL_ZVAL(&(objval->lua), lua_obj, 1, 0);
return instance; return instance;
} }
@@ -60,74 +65,44 @@ PHP_METHOD(lua_closure, __construct) {
} }
/* }}} */ /* }}} */
/** {{{ proto LuaClosure::__destruct()
*/
PHP_METHOD(lua_closure, __destruct) {
zval *lua_obj, *closure;
lua_obj = zend_read_property(lua_closure_ce, getThis(), ZEND_STRL("_lua_object"), 1 TSRMLS_CC);
if (ZVAL_IS_NULL(lua_obj)
|| Z_TYPE_P(lua_obj) != IS_OBJECT
|| !instanceof_function(Z_OBJCE_P(lua_obj), lua_ce TSRMLS_CC)) {
RETURN_FALSE;
}
closure = zend_read_property(lua_closure_ce, getThis(), ZEND_STRL("_closure"), 1 TSRMLS_CC);
if (!Z_LVAL_P(closure)) {
RETURN_FALSE;
}
luaL_unref(Z_LUAVAL_P(lua_obj), LUA_REGISTRYINDEX, Z_LVAL_P(closure));
}
/* }}} */
/** {{{ proto LuaClosure::invoke(mxied $args) /** {{{ proto LuaClosure::invoke(mxied $args)
*/ */
PHP_METHOD(lua_closure, invoke) { PHP_METHOD(lua_closure, invoke) {
lua_closure_object *objval = php_lua_closure_object_from_zend_object(Z_OBJ_P(getThis()));
int bp, sp; int bp, sp;
zval ***arguments = NULL; zval *arguments = NULL;
zval *lua_obj = NULL;
lua_State *L = NULL; lua_State *L = NULL;
zval *closure = NULL; zval rv;
if (ZEND_NUM_ARGS()) { if (ZEND_NUM_ARGS()) {
arguments = emalloc(sizeof(zval**) * ZEND_NUM_ARGS()); arguments = emalloc(sizeof(zval*) * ZEND_NUM_ARGS());
if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), arguments) == FAILURE) { if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), arguments) == FAILURE) {
efree(arguments); efree(arguments);
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "cannot get arguments for calling closure"); zend_throw_exception_ex(NULL, 0, "cannot get arguments for calling closure");
return; return;
} }
} }
lua_obj = zend_read_property(lua_closure_ce, getThis(), ZEND_STRL("_lua_object"), 1 TSRMLS_CC); if (Z_TYPE(objval->lua) != IS_OBJECT
|| !instanceof_function(Z_OBJCE(objval->lua), lua_ce)) {
if (ZVAL_IS_NULL(lua_obj) zend_throw_exception_ex(NULL, 0, "corrupted Lua object");
|| Z_TYPE_P(lua_obj) != IS_OBJECT
|| !instanceof_function(Z_OBJCE_P(lua_obj), lua_ce TSRMLS_CC)) {
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "corrupted Lua object");
return; return;
} }
closure = zend_read_property(lua_closure_ce, getThis(), ZEND_STRL("_closure"), 1 TSRMLS_CC); L = (Z_LUAVAL(objval->lua))->L;
if (!Z_LVAL_P(closure)) {
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "invalid lua closure");
return;
}
L = Z_LUAVAL_P(lua_obj);
bp = lua_gettop(L); bp = lua_gettop(L);
lua_rawgeti(L, LUA_REGISTRYINDEX, Z_LVAL_P(closure)); lua_rawgeti(L, LUA_REGISTRYINDEX, objval->closure);
if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) { if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) {
lua_pop(L, -1); lua_pop(L, -1);
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "call to lua closure failed"); zend_throw_exception_ex(NULL, 0, "call to lua closure failed");
return; return;
} }
if (ZEND_NUM_ARGS()) { if (ZEND_NUM_ARGS()) {
int i = 0; int i = 0;
for(;i<ZEND_NUM_ARGS();i++) { for(;i<ZEND_NUM_ARGS();i++) {
php_lua_send_zval_to_lua(L, *(arguments[i]) TSRMLS_CC); php_lua_send_zval_to_lua(L, &arguments[i]);
} }
} }
@@ -136,7 +111,7 @@ PHP_METHOD(lua_closure, invoke) {
efree(arguments); efree(arguments);
} }
lua_pop(L, lua_gettop(L) - bp); lua_pop(L, lua_gettop(L) - bp);
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, zend_throw_exception_ex(NULL, 0,
"call to lua function %s failed", lua_tostring(L, -1)); "call to lua function %s failed", lua_tostring(L, -1));
return; return;
} }
@@ -146,14 +121,14 @@ PHP_METHOD(lua_closure, invoke) {
if (!sp) { if (!sp) {
RETURN_NULL(); RETURN_NULL();
} else if (sp == 1) { } else if (sp == 1) {
zval *tmp = php_lua_get_zval_from_lua(L, -1, lua_obj TSRMLS_CC); php_lua_get_zval_from_lua(L, -1, &(objval->lua), return_value);
RETURN_ZVAL(tmp, 0, 0);
} else { } else {
zval rv;
int i = 0; int i = 0;
array_init(return_value); array_init(return_value);
for (i = -sp; i < 0; i++) { for (i = -sp; i < 0; i++) {
zval *tmp = php_lua_get_zval_from_lua(L, i, lua_obj TSRMLS_CC); php_lua_get_zval_from_lua(L, i, &(objval->lua), &rv);
add_next_index_zval(return_value, tmp); add_next_index_zval(return_value, &rv);
} }
} }
@@ -165,73 +140,52 @@ PHP_METHOD(lua_closure, invoke) {
} }
/* }}} */ /* }}} */
/** {{{ proto LuaClosure::__clone()
*/
PHP_METHOD(lua_closure, __clone) {
}
/* }}} */
/* {{{ lua_class_methods[] /* {{{ lua_class_methods[]
*
*/ */
zend_function_entry lua_closure_methods[] = { zend_function_entry lua_closure_methods[] = {
PHP_ME(lua_closure, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR) PHP_ME(lua_closure, __construct, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_CTOR)
PHP_ME(lua_closure, __destruct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DTOR)
PHP_ME(lua_closure, __clone, NULL, ZEND_ACC_PRIVATE)
PHP_ME(lua_closure, invoke, arginfo_lua_invoke, ZEND_ACC_PUBLIC) PHP_ME(lua_closure, invoke, arginfo_lua_invoke, ZEND_ACC_PUBLIC)
PHP_MALIAS(lua_closure, __invoke, invoke, arginfo_lua_invoke, ZEND_ACC_PUBLIC) PHP_MALIAS(lua_closure, __invoke, invoke, arginfo_lua_invoke, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL} PHP_FE_END
}; };
/* }}} */ /* }}} */
static void php_lua_closure_dtor_object(void *object, zend_object_handle handle TSRMLS_DC) /* {{{ */ static void php_lua_closure_free_obj(zend_object *zobj) /* {{{ */
{ {
zend_object *obj = (zend_object*)object; lua_closure_object *objval = php_lua_closure_object_from_zend_object(zobj);
zend_object_std_dtor(obj TSRMLS_CC); if ((Z_TYPE(objval->lua) == IS_OBJECT) &&
instanceof_function(Z_OBJCE(objval->lua), lua_ce)) {
efree(obj); luaL_unref((Z_LUAVAL(objval->lua))->L, LUA_REGISTRYINDEX, objval->closure);
}
zval_dtor(&(objval->lua));
zend_object_std_dtor(zobj);
} /* }}} */ } /* }}} */
static zend_object_value php_lua_closure_create_object(zend_class_entry *ce TSRMLS_DC) /* {{{ */ zend_object *php_lua_closure_create_object(zend_class_entry *ce) /* {{{ */
{ {
zend_object_value obj = {0}; lua_closure_object *objval = ecalloc(1, sizeof(lua_closure_object) + zend_object_properties_size(ce));
zend_object *lua_closure_obj = NULL; zend_object *zobj = &(objval->std);
lua_closure_obj = emalloc(sizeof(zend_object)); zend_object_std_init(zobj, ce);
zobj->handlers = &lua_closure_handlers;
zend_object_std_init(lua_closure_obj, ce TSRMLS_CC); return zobj;
#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4)
zend_hash_copy(lua_closure_obj->properties, &ce->default_properties,
#if (PHP_MINOR_VERSION < 3)
(copy_ctor_func_t) zval_add_ref,
#else
zval_copy_property_ctor(ce),
#endif
(void *)0, sizeof(zval *));
#elif (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION > 3)
object_properties_init(lua_closure_obj, ce);
#endif
obj.handle = zend_objects_store_put(lua_closure_obj, php_lua_closure_dtor_object, NULL, NULL TSRMLS_CC);
obj.handlers = zend_get_std_object_handlers();
return obj;
} /* }}} */ } /* }}} */
void php_lua_closure_register(TSRMLS_D) /* {{{ */ void php_lua_closure_register() /* {{{ */
{ {
zend_class_entry ce; zend_class_entry ce;
INIT_CLASS_ENTRY(ce, "LuaClosure", lua_closure_methods); INIT_CLASS_ENTRY(ce, "LuaClosure", lua_closure_methods);
lua_closure_ce = zend_register_internal_class(&ce TSRMLS_CC); lua_closure_ce = zend_register_internal_class(&ce);
lua_closure_ce->create_object = php_lua_closure_create_object; lua_closure_ce->create_object = php_lua_closure_create_object;
lua_closure_ce->ce_flags |= ZEND_ACC_FINAL; lua_closure_ce->ce_flags |= ZEND_ACC_FINAL;
zend_declare_property_long(lua_closure_ce, ZEND_STRL("_closure"), 0, ZEND_ACC_PRIVATE TSRMLS_CC); memcpy(&lua_closure_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
zend_declare_property_null(lua_closure_ce, ZEND_STRL("_lua_object"), ZEND_ACC_PRIVATE TSRMLS_CC); lua_closure_handlers.offset = XtOffsetOf(lua_closure_object, std);
lua_closure_handlers.clone_obj = NULL;
lua_closure_handlers.free_obj = php_lua_closure_free_obj;
} /* }}} */ } /* }}} */
zend_class_entry *php_lua_get_closure_ce() /* {{{ */ zend_class_entry *php_lua_get_closure_ce() /* {{{ */

View File

@@ -11,15 +11,29 @@
| license@php.net so we can mail you a copy immediately. | | license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
| Author : Johannes Schlueter <johannes@php.net> | | Author : Johannes Schlueter <johannes@php.net> |
| Xinchen Hui <laruence@php.net> | | Xinchen Hui <laruence@php.net> |
| Marcelo Araujo <msaraujo@php.net> | | Marcelo Araujo <msaraujo@php.net> |
| Helmut Januschka <helmut@januschka.com> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
$Id: lua_closure.h 319733 2011-11-24 07:13:56Z laruence $
*/ */
void php_lua_closure_register(TSRMLS_D); #ifndef LUA_CLOSURE_H
#define LUA_CLOSURE_H
typedef struct _lua_closure_object {
long closure;
zval lua;
zend_object std;
} lua_closure_object;
static inline lua_closure_object* php_lua_closure_object_from_zend_object(zend_object *zobj) {
return ((lua_closure_object*)(zobj + 1)) - 1;
}
void php_lua_closure_register();
zend_class_entry *php_lua_get_closure_ce(); zend_class_entry *php_lua_get_closure_ce();
zval * php_lua_closure_instance(zval *instance, long ref_id, zval *lua_obj TSRMLS_DC); zval * php_lua_closure_instance(zval *instance, long ref_id, zval *lua_obj);
#endif
/* /*
* Local variables: * Local variables:

View File

@@ -1,68 +1,297 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/package-1.0"> <package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.4.7" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
<package version="1.0" packagerversion="1.9.4">
<name>lua</name> <name>lua</name>
<channel>pecl.php.net</channel>
<summary>Embedded lua interpreter</summary> <summary>Embedded lua interpreter</summary>
<description>&quot;Lua is a powerful, fast, light-weight, embeddable scripting language.&quot; <description>"Lua is a powerful, fast, light-weight, embeddable scripting language."
This extension embeds the lua interpreter and offers an OO-API to lua variables and functions. This extension embeds the lua interpreter and offers an OO-API to lua variables and functions.</description>
</description> <lead>
<maintainers> <name>Johannes Schlüter</name>
<maintainer> <user>johannes</user>
<user>johannes</user> <email>johannes@php.net</email>
<name>Johannes Schlüter</name> <active>yes</active>
<email>johannes@php.net</email> </lead>
<role>lead</role> <lead>
</maintainer> <name>Xinchen Hui</name>
<maintainer> <user>laruence</user>
<user>laruence</user> <email>laruence@php.net</email>
<name>Xinchen Hui</name> <active>yes</active>
<email>laruence@php.net</email> </lead>
<role>lead</role> <developer>
</maintainer> <name>Marcelo Araujo</name>
<maintainer> <user>msaraujo</user>
<user>msaraujo</user> <email>msaraujo@php.net</email>
<name>Marcelo Araujo</name> <active>yes</active>
<email>msaraujo@php.net</email> </developer>
<role>developer</role> <date>2017-12-31</date>
</maintainer> <time>19:15:00</time>
</maintainers> <version>
<release> <release>2.0.5</release>
<version>0.9.5</version> <api>2.0.5</api>
<date>2013-10-23</date> </version>
<license>PHP</license> <stability>
<state>beta</state> <release>stable</release>
<notes>- Fixed #65097 (nApplyCount release missing) (emptyhua at gmail dot com) <api>stable</api>
- Trigger E_STRICT when pass an array with index &apos;0&apos; to lua instead of ignoring it </stability>
- added support for callable functions and closures as values returned injected into lua engine (harald at octris dot org) <license uri="http://www.php.net/license">PHP</license>
</notes> <notes>
<deps> - Refactor LuaClosure. (SaraG)
<dep type="php" rel="ge" version="5.1.0"/> - Fix non-string member access in read/write prop. (SaraG)
</deps> - Fix allocation of lua object. (SaraG)
<filelist> </notes>
<contents>
<dir name="/">
<file name="config.m4" role="src" />
<file name="php_lua.h" role="src" />
<file name="lua.c" role="src" />
<file name="lua_closure.h" role="src" />
<file name="lua_closure.c" role="src" />
<file name="config.w32" role="src" />
<file name="CREDITS" role="doc" />
<file name="EXPERIMENTAL" role="doc" />
<file name="LICENSE" role="doc" />
<dir name="tests"> <dir name="tests">
<file role="test" name="001.phpt"/> <file name="001.phpt" role="test" />
<file role="test" name="002.phpt"/> <file name="002.phpt" role="test" />
<file role="test" name="003.phpt"/> <file name="003.phpt" role="test" />
<file role="test" name="004.phpt"/> <file name="004.phpt" role="test" />
<file role="test" name="005.phpt"/> <file name="005.phpt" role="test" />
<file role="test" name="006.phpt"/> <file name="006.phpt" role="test" />
<file role="test" name="007.phpt"/> <file name="007.phpt" role="test" />
<file role="test" name="008.phpt"/> <file name="008.phpt" role="test" />
<file role="test" name="009.phpt"/> <file name="009.phpt" role="test" />
<file role="test" name="010.phpt"/> <file name="010.phpt" role="test" />
<file role="test" name="011.phpt"/> <file name="011.phpt" role="test" />
<file role="test" name="012.phpt"/> <file name="012.phpt" role="test" />
<file role="test" name="013.phpt"/> <file name="013.phpt" role="test" />
</dir> <!-- /tests --> <file name="issue012.phpt" role="test" />
<file role="src" name="config.m4"/> <file name="bug65097.phpt" role="test" />
<file role="src" name="config.w32"/> <file name="bug71997.phpt" role="test" />
<file role="src" name="CREDITS"/> <file name="bug73964.phpt" role="test" />
<file role="src" name="EXPERIMENTAL"/> </dir>
<file role="src" name="LICENSE"/> </dir>
<file role="src" name="lua.c"/> </contents>
<file role="src" name="lua_closure.c"/> <dependencies>
<file role="src" name="lua_closure.h"/> <required>
<file role="src" name="php_lua.h"/> <php>
</filelist> <min>7.0.0</min>
</release> </php>
<pearinstaller>
<min>1.4.0</min>
</pearinstaller>
</required>
</dependencies>
<providesextension>lua</providesextension>
<extsrcrelease />
<changelog>
<release>
<date>2017-12-31</date>
<version>
<release>2.0.5</release>
<api>2.0.5</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Refactor LuaClosure. (SaraG)
- Fix non-string member access in read/write prop. (SaraG)
- Fix allocation of lua object. (SaraG)
</notes>
</release>
<release>
<date>2017-07-12</date>
<version>
<release>2.0.4</release>
<api>2.0.4</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Fixed bug #73964 (Segmentation fault)
</notes>
</release>
<release>
<date>2017-02-10</date>
<version>
<release>2.0.3</release>
<api>2.0.3</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Fixed issue #20 (PHP 7: Lua::eval(): unsupported type `unknown' for lua)
</notes>
</release>
<release>
<date>2016-05-26</date>
<version>
<release>2.0.2</release>
<api>2.0.2</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Fixed issue #22 (Boolean FALSE is always TRUE)
</notes>
</release>
<release>
<date>2016-04-11</date>
<version>
<release>2.0.1</release>
<api>2.0.1</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Fixed bug #71997 (One-Dimensional arrays cause segmentation faults)
</notes>
</release>
<release>
<date>2015-10-27</date>
<version>
<release>2.0.0</release>
<api>2.0.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Release lua for PHP7
</notes>
</release>
<release>
<date>2012-10-23</date>
<version>
<release>1.1.0</release>
<api>1.1.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Fixed #65097 (nApplyCount release missing) (emptyhua at gmail dot com)
- Trigger E_STRICT when pass an array with index '0' to lua instead of ignoring it
- added support for callable functions and closures as values returned injected into lua engine (harald at octris dot org)
</notes>
</release>
<release>
<date>2012-06-24</date>
<version>
<release>1.0.0</release>
<api>1.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Release stable version
</notes>
</release>
<release>
<date>2012-03-19</date>
<version>
<release>0.9.4</release>
<api>0.9.4</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Compatible with lua 5.2
</notes>
</release>
<release>
<date>2012-01-12</date>
<version>
<release>0.9.3</release>
<api>0.9.3</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Fix build on windows
- Fix build when building lua with static
</notes>
</release>
<release>
<date>2012-01-06</date>
<version>
<release>0.9.2</release>
<api>0.9.2</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Fixed bug #60641 PECL install lua with lua5.1 packages
</notes>
</release>
<release>
<date>2011-11-24</date>
<version>
<release>0.9.1</release>
<api>0.9.1</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Compatible with PHP5.3+
- Fix ZTS build
- Fix mem leak when get value from lua
</notes>
</release>
<release>
<date>2011-08-03</date>
<version>
<release>0.9.0</release>
<api>0.9.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Merge Plua into Lua
- Api changes
- Add supporting for LUA_TFUNCTION
</notes>
</release>
</changelog>
</package> </package>
<!--
vim:et:ts=1:sw=1
-->

View File

@@ -1,200 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.4.7" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
<name>lua</name>
<channel>pecl.php.net</channel>
<summary>Embedded lua interpreter</summary>
<description>"Lua is a powerful, fast, light-weight, embeddable scripting language."
This extension embeds the lua interpreter and offers an OO-API to lua variables and functions.</description>
<lead>
<name>Johannes Schlüter</name>
<user>johannes</user>
<email>johannes@php.net</email>
<active>yes</active>
</lead>
<lead>
<name>Xinchen Hui</name>
<user>laruence</user>
<email>laruence@php.net</email>
<active>yes</active>
</lead>
<developer>
<name>Marcelo Araujo</name>
<user>msaraujo</user>
<email>msaraujo@php.net</email>
<active>yes</active>
</developer>
<date>2013-10-23</date>
<time>12:04:27</time>
<version>
<release>1.1.0</release>
<api>1.1.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP</license>
<notes>
- Fixed #65097 (nApplyCount release missing) (emptyhua at gmail dot com)
- Trigger E_STRICT when pass an array with index '0' to lua instead of ignoring it
- added support for callable functions and closures as values returned injected into lua engine (harald at octris dot org)
</notes>
<contents>
<dir name="/">
<file name="config.m4" role="src" />
<file name="php_lua.h" role="src" />
<file name="lua.c" role="src" />
<file name="lua_closure.h" role="src" />
<file name="lua_closure.c" role="src" />
<file name="config.w32" role="src" />
<file name="CREDITS" role="src" />
<file name="EXPERIMENTAL" role="src" />
<file name="LICENSE" role="src" />
<dir name="tests">
<file name="001.phpt" role="test" />
<file name="002.phpt" role="test" />
<file name="003.phpt" role="test" />
<file name="004.phpt" role="test" />
<file name="005.phpt" role="test" />
<file name="006.phpt" role="test" />
<file name="007.phpt" role="test" />
<file name="008.phpt" role="test" />
<file name="009.phpt" role="test" />
<file name="010.phpt" role="test" />
<file name="011.phpt" role="test" />
<file name="012.phpt" role="test" />
<file name="013.phpt" role="test" />
</dir>
</dir>
</contents>
<dependencies>
<required>
<php>
<min>5.1.0</min>
</php>
<pearinstaller>
<min>1.4.0</min>
</pearinstaller>
</required>
</dependencies>
<providesextension>lua</providesextension>
<extsrcrelease />
<changelog>
<release>
<date>2012-10-23</date>
<version>
<release>1.1.0</release>
<api>1.1.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Fixed #65097 (nApplyCount release missing) (emptyhua at gmail dot com)
- Trigger E_STRICT when pass an array with index '0' to lua instead of ignoring it
- added support for callable functions and closures as values returned injected into lua engine (harald at octris dot org)
</notes>
</release>
<release>
<date>2012-06-24</date>
<version>
<release>1.0.0</release>
<api>1.0.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Release stable version
</notes>
</release>
<release>
<date>2012-03-19</date>
<version>
<release>0.9.4</release>
<api>0.9.4</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Compatible with lua 5.2
</notes>
</release>
<release>
<date>2012-01-12</date>
<version>
<release>0.9.3</release>
<api>0.9.3</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Fix build on windows
- Fix build when building lua with static
</notes>
</release>
<release>
<date>2012-01-06</date>
<version>
<release>0.9.2</release>
<api>0.9.2</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Fixed bug #60641 PECL install lua with lua5.1 packages
</notes>
</release>
<release>
<date>2011-11-24</date>
<version>
<release>0.9.1</release>
<api>0.9.1</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Compatible with PHP5.3+
- Fix ZTS build
- Fix mem leak when get value from lua
</notes>
</release>
<release>
<date>2011-08-03</date>
<version>
<release>0.9.0</release>
<api>0.9.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<license uri="http://www.php.net/license">PHP License</license>
<notes>
- Merge Plua into Lua
- Api changes
- Add supporting for LUA_TFUNCTION
</notes>
</release>
</changelog>
</package>
<!--
vim:et:ts=1:sw=1
-->

View File

@@ -13,8 +13,8 @@
| Author : Johannes Schlueter <johannes@php.net> | | Author : Johannes Schlueter <johannes@php.net> |
| Xinchen Hui <laruence@php.net> | | Xinchen Hui <laruence@php.net> |
| Marcelo Araujo <msaraujo@php.net> | | Marcelo Araujo <msaraujo@php.net> |
| Helmut Januschka <helmut@januschka.com> |
+----------------------------------------------------------------------+ +----------------------------------------------------------------------+
$Id: php_lua.h 324349 2012-03-19 03:17:15Z laruence $
*/ */
#ifndef PHP_LUA_H #ifndef PHP_LUA_H
@@ -24,6 +24,11 @@
#include "lauxlib.h" #include "lauxlib.h"
#include "lualib.h" #include "lualib.h"
/* LUA_OK is defined sinc 5.2 */
#ifndef LUA_OK
#define LUA_OK 0
#endif
extern zend_module_entry lua_module_entry; extern zend_module_entry lua_module_entry;
#define phpext_lua_ptr &lua_module_entry #define phpext_lua_ptr &lua_module_entry
@@ -43,24 +48,24 @@ extern zend_module_entry lua_module_entry;
#define LUA_G(v) (lua_globals.v) #define LUA_G(v) (lua_globals.v)
#endif #endif
#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 3)) || (PHP_MAJOR_VERSION < 5) #define PHP_LUA_VERSION "2.0.5"
#define Z_ADDREF_P ZVAL_ADDREF
#define Z_REFCOUNT_P ZVAL_REFCOUNT
#define Z_DELREF_P ZVAL_DELREF
#endif
#define PHP_LUA_VERSION "1.1.0"
#define Z_LUAVAL_P(obj) ((php_lua_object*)(zend_object_store_get_object(obj TSRMLS_CC)))->L
struct _php_lua_object { struct _php_lua_object {
zend_object obj; lua_State *L;
lua_State *L; zend_object obj;
}; };
typedef struct _php_lua_object php_lua_object; typedef struct _php_lua_object php_lua_object;
zval * php_lua_get_zval_from_lua(lua_State *L, int index, zval *lua_obj TSRMLS_DC); static inline php_lua_object *php_lua_obj_from_obj(zend_object *obj) {
int php_lua_send_zval_to_lua(lua_State *L, zval *val TSRMLS_DC); return (php_lua_object*)((char*)(obj)-XtOffsetOf(php_lua_object, obj));
}
#define Z_LUAVAL(obj) php_lua_obj_from_obj(Z_OBJ((obj)))
#define Z_LUAVAL_P(obj) php_lua_obj_from_obj(Z_OBJ_P((obj)))
zval *php_lua_get_zval_from_lua(lua_State *L, int index, zval *lua_obj, zval *rv);
int php_lua_send_zval_to_lua(lua_State *L, zval *val);
PHP_MINIT_FUNCTION(lua); PHP_MINIT_FUNCTION(lua);
PHP_MSHUTDOWN_FUNCTION(lua); PHP_MSHUTDOWN_FUNCTION(lua);
@@ -69,8 +74,8 @@ PHP_MINFO_FUNCTION(lua);
PHP_METHOD(lua, __construct); PHP_METHOD(lua, __construct);
PHP_METHOD(lua, eval); PHP_METHOD(lua, eval);
PHP_METHOD(lua, require); PHP_METHOD(lua, require);
#endif /* PHP_LUA_H */
#endif /* PHP_LUA_H */
/* /*
* Local variables: * Local variables:

4
tests/001.phpt Normal file → Executable file
View File

@@ -15,7 +15,9 @@ try {
assert($e->getCode() == LUA_ERRSYNTAX); assert($e->getCode() == LUA_ERRSYNTAX);
echo "\n", $e->getMessage(); echo "\n", $e->getMessage();
} }
?>
--EXPECTF-- --EXPECTF--
12 12
-0.53657291800043 -0.53657291800043
[string "line"]:1: syntax error near 'code' [string "line"]:1: %s near 'code'

30
tests/0014.phpt Normal file
View File

@@ -0,0 +1,30 @@
--TEST--
Check for Table Pass vic-a-verse
--SKIPIF--
<?php if (!extension_loaded("lua")) print "skip"; ?>
--FILE--
<?php
$l = new lua();
$l->eval(<<<CODE
function test(a)
lua_fcn(a)
end
CODE
);
$l->registerCallback("lua_fcn", function($a) {
ksort($a);
var_dump($a);
});
$l->test(array("key1"=>"v1",
"key2"=>"v2"));
--EXPECT--
array(2) {
["key1"]=>
string(2) "v1"
["key2"]=>
string(2) "v2"
}

View File

@@ -32,7 +32,7 @@ Testing fine
Hello PHP Hello PHP
Testing broken Testing broken
%s:%d: syntax error near 'fdrg' %s:%d: %s near 'fdrg'
Testing return Testing return
Array Array
( (

View File

@@ -1,7 +1,10 @@
--TEST-- --TEST--
Bug #65097 (nApplyCount release missing) Bug #65097 (nApplyCount release missing)
--SKIPIF-- --SKIPIF--
<?php if (!extension_loaded("lua")) print "skip"; ?> <?php
if (!extension_loaded("lua")) print "skip lua extension missing";
if (!extension_loaded("json")) print "skip json extension missing";
?>
--INI-- --INI--
error_reporting=E_ALL&~E_STRICT error_reporting=E_ALL&~E_STRICT
--FILE-- --FILE--

22
tests/bug71997.phpt Normal file
View File

@@ -0,0 +1,22 @@
--TEST--
Bug #71997 (One-Dimensional arrays cause segmentation faults)
--SKIPIF--
<?php
if (!extension_loaded("lua")) print "skip lua extension missing";
?>
--FILE--
<?php
$mylua = new \lua();
$mylua->eval(<<<CODE
function nicefunction(args)
print(args[1])
return args[1]
end
CODE
);
echo $mylua->call("nicefunction", array(array('hello', 'world')));
?>
done
--EXPECT--
worldworlddone

45
tests/bug73964.phpt Normal file
View File

@@ -0,0 +1,45 @@
--TEST--
Bug #73964 (Segmentation fault (11))
--SKIPIF--
<?php
if (!extension_loaded("lua")) print "skip lua extension missing";
?>
--FILE--
<?php
class LuaTest
{
function __construct()
{
$this->lua = new Lua();
$this->lua->registerCallback("log", array($this, "API_LuaLog"));
}
function API_LuaLog( $entry)
{
echo("from lua: $entry");
}
public function RunTest()
{
$this->lua->eval(<<<CODE
function TestFunc(str)
log(str)
end
CODE
);
$GamePackage = $this->lua->RootTable;
$this->lua->call("TestFunc", array("okey"));
}
}
$a = new LuaTest();
$a->runtest();
?>
--EXPECT--
from lua: okey

15
tests/issue012.phpt Normal file
View File

@@ -0,0 +1,15 @@
--TEST--
ISSUE #022 (Boolean FALSE is always TRUE)
--SKIPIF--
<?php
if (!extension_loaded("lua")) print "skip lua extension missing";
?>
--FILE--
<?php
$lua = new Lua();
$lua->assign('TEST', false);
$result = $lua->eval('return TEST');
var_dump($result)
?>
--EXPECT--
bool(false)

7
travis/build_check.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
#exit 1 on error
echo "all ok ";
ls ./modules/bartlby.so
exit $?

2
travis/compile.sh Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
phpize && ./configure --with-lua-version=5.2 && make