mirror of
https://github.com/php-win-ext/php-lua.git
synced 2026-03-24 00:52:12 +01:00
initial commit
This commit is contained in:
2
EXPERIMENTAL
Normal file
2
EXPERIMENTAL
Normal file
@@ -0,0 +1,2 @@
|
||||
This extension embeds lua interpreter into PHP. We should emphasize that is
|
||||
still under development and is completely experimental.
|
||||
2
README
Normal file
2
README
Normal file
@@ -0,0 +1,2 @@
|
||||
"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.
|
||||
48
config.m4
Normal file
48
config.m4
Normal file
@@ -0,0 +1,48 @@
|
||||
dnl $Id: config.m4 315592 2011-08-27 00:58:41Z johannes $
|
||||
PHP_ARG_WITH(lua, for lua support,
|
||||
[ --with-lua=[DIR] Include php lua support])
|
||||
|
||||
if test "$PHP_LUA" != "no"; then
|
||||
if test -r $PHP_LUA/include/lua.h; then
|
||||
LUA_DIR=$PHP_LUA
|
||||
else
|
||||
AC_MSG_CHECKING(for lua in default path)
|
||||
for i in /usr/local /usr; do
|
||||
if test -r $i/include/lua/include.h; then
|
||||
LUA_DIR=$i
|
||||
AC_MSG_RESULT(found in $i)
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if test -z "$LUA_DIR"; then
|
||||
AC_MSG_RESULT(not found)
|
||||
AC_MSG_ERROR(Please reinstall the lua distribution - lua.h should be in <lua-dir>/include/)
|
||||
fi
|
||||
|
||||
LUA_LIB_NAME=lua
|
||||
|
||||
if test -r $PHP_LUA/$PHP_LIBDIR/lib${LUA_LIB_NAME}.a; then
|
||||
LUA_LIB_DIR=$PHP_LUA/$PHP_LIBDIR
|
||||
else
|
||||
AC_MSG_CHECKING(for lua library in default path)
|
||||
for i in /usr/lib /usr/lib64; do
|
||||
if test -r $i/$PHP_LIBDIR/${LUA_LIB_DIR}.a; then
|
||||
LUA_LIB_DIR=$i
|
||||
AC_MSG_RESULT(found in $i)
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if test -z "$LUA_LIB_DIR"; then
|
||||
AC_MSG_RESULT(not found)
|
||||
AC_MSG_ERROR(Please reinstall the lua distribution - lua library should be in <lua-dir>/lib/)
|
||||
fi
|
||||
|
||||
PHP_ADD_INCLUDE($LUA_DIR/include)
|
||||
PHP_ADD_LIBRARY_WITH_PATH(lua, $LUA_LIB_DIR, LUA_SHARED_LIBADD)
|
||||
PHP_SUBST(LUA_SHARED_LIBADD)
|
||||
PHP_NEW_EXTENSION(lua, lua.c lua_closure.c, $ext_shared)
|
||||
fi
|
||||
15
config.w32
Normal file
15
config.w32
Normal file
@@ -0,0 +1,15 @@
|
||||
// $Id: config.w32 314169 2011-08-03 14:05:16Z laruence $
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_WITH("lua", "lua support", "no");
|
||||
|
||||
if (PHP_LUA != "no") {
|
||||
if (CHECK_LIB("liblua.lib", "lua", PHP_LUA) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("lua.h", "CFLAGS_LUA",
|
||||
PHP_LUA + "\\include;" + PHP_PHP_BUILD + "\\include\\lua;" + PHP_LUA)) {
|
||||
EXTENSION("lua", "lua.c");
|
||||
AC_DEFINE('HAVE_LUA', 1, 'Have LUA library');
|
||||
} else {
|
||||
WARNING("lua not enabled; libraries and headers not found");
|
||||
}
|
||||
}
|
||||
908
lua.c
Normal file
908
lua.c
Normal file
@@ -0,0 +1,908 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Lua |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author : Johannes Schlueter <johannes@php.net> |
|
||||
| Xinchen Hui <laruence@php.net> |
|
||||
| Marcelo Araujo <msaraujo@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
$Id: lua.c 319740 2011-11-24 08:06:48Z laruence $
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "php_ini.h"
|
||||
#include "ext/standard/info.h"
|
||||
#include "Zend/zend_exceptions.h"
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
#include "php_lua.h"
|
||||
#include "lua_closure.h"
|
||||
|
||||
zend_class_entry *lua_ce;
|
||||
zend_class_entry *lua_exception_ce;
|
||||
static zend_object_handlers lua_object_handlers;
|
||||
|
||||
/** {{{ ARG_INFO
|
||||
*
|
||||
*/
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_call, 0, 0, 2)
|
||||
ZEND_ARG_INFO(0, method)
|
||||
ZEND_ARG_INFO(0, args)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_assign, 0, 0, 2)
|
||||
ZEND_ARG_INFO(0, name)
|
||||
ZEND_ARG_INFO(0, value)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_register, 0, 0, 2)
|
||||
ZEND_ARG_INFO(0, name)
|
||||
ZEND_ARG_INFO(0, function)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_include, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, file)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_eval, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, statements)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_free, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, closure)
|
||||
ZEND_END_ARG_INFO()
|
||||
/* }}} */
|
||||
|
||||
/* {{{ lua_module_entry
|
||||
*/
|
||||
zend_module_entry lua_module_entry = {
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
STANDARD_MODULE_HEADER,
|
||||
#endif
|
||||
"lua",
|
||||
NULL,
|
||||
PHP_MINIT(lua),
|
||||
PHP_MSHUTDOWN(lua),
|
||||
NULL,
|
||||
NULL,
|
||||
PHP_MINFO(lua),
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
PHP_LUA_VERSION,
|
||||
#endif
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
#ifdef COMPILE_DL_LUA
|
||||
ZEND_GET_MODULE(lua)
|
||||
#endif
|
||||
|
||||
/** {{{ static void php_lua_stack_dump(lua_State* L)
|
||||
* just for debug
|
||||
*/
|
||||
#ifdef PHP_LUA_DEBUG
|
||||
static void php_lua_stack_dump(lua_State* L) {
|
||||
int i = 1;
|
||||
int n = lua_gettop(L);
|
||||
printf("The Length of stack is %d\n", n);
|
||||
for (; i <= n; ++i) {
|
||||
int t = lua_type(L, i);
|
||||
printf("%s:", lua_typename(L, t));
|
||||
switch(t) {
|
||||
case LUA_TNUMBER:
|
||||
printf("%f", lua_tonumber(L, i));
|
||||
break;
|
||||
case LUA_TSTRING:
|
||||
printf("%s", lua_tostring(L, i));
|
||||
break;
|
||||
case LUA_TTABLE:
|
||||
break;
|
||||
case LUA_TFUNCTION:
|
||||
break;
|
||||
case LUA_TNIL:
|
||||
printf("NULL");
|
||||
break;
|
||||
case LUA_TBOOLEAN:
|
||||
printf("%s", lua_toboolean(L, i) ? "TRUE" : "FALSE");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
/** {{{ static int php_lua_atpanic(lua_State *L)
|
||||
*/
|
||||
static int php_lua_atpanic(lua_State *L) {
|
||||
TSRMLS_FETCH();
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "lua panic (%s)", lua_tostring(L, 1));
|
||||
lua_pop(L, 1);
|
||||
zend_bailout();
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/** {{{ static int php_lua_print(lua_State *L)
|
||||
*/
|
||||
static int php_lua_print(lua_State *L) {
|
||||
int i = 0;
|
||||
|
||||
TSRMLS_FETCH();
|
||||
for (i = -lua_gettop(L) ; i<0; i++) {
|
||||
zval *tmp = php_lua_get_zval_from_lua(L, i, NULL TSRMLS_CC);
|
||||
zend_print_zval_r(tmp, 1 TSRMLS_CC);
|
||||
zval_ptr_dtor(&tmp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/** {{{ static void * php_lua_alloc_function(void *ud, void *ptr, size_t osize, size_t nsize)
|
||||
* the memory-allocation function used by Lua states.
|
||||
*/
|
||||
static void * php_lua_alloc_function(void *ud, void *ptr, size_t osize, size_t nsize) {
|
||||
(void) osize;
|
||||
(void) nsize;
|
||||
|
||||
if (nsize) {
|
||||
if (ptr) {
|
||||
return erealloc(ptr, nsize);
|
||||
}
|
||||
return emalloc(nsize);
|
||||
} else {
|
||||
if (ptr) {
|
||||
efree(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/** {{{ static void php_lua_dtor_object(void *object, zend_object_handle handle TSRMLS_DC)
|
||||
* the dtor function for lua 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);
|
||||
|
||||
if (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)
|
||||
*
|
||||
* the create object handler for lua
|
||||
*/
|
||||
static zend_object_value php_lua_create_object(zend_class_entry *ce TSRMLS_DC) {
|
||||
zend_object_value obj = {0};
|
||||
php_lua_object *lua_obj = NULL;
|
||||
lua_State *L = NULL;
|
||||
|
||||
L = lua_newstate(php_lua_alloc_function, NULL);
|
||||
|
||||
lua_atpanic(L, php_lua_atpanic);
|
||||
|
||||
lua_obj = emalloc(sizeof(php_lua_object));
|
||||
|
||||
if (!lua_obj) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "alloc memory for lua object failed");
|
||||
}
|
||||
|
||||
lua_obj->L = L;
|
||||
zend_object_std_init(&(lua_obj->obj), ce TSRMLS_CC);
|
||||
|
||||
#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4)
|
||||
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)
|
||||
*/
|
||||
#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 4)) || (PHP_MAJOR_VERSION < 5)
|
||||
static zval * php_lua_read_property(zval *object, zval *member, int type TSRMLS_DC) {
|
||||
#else
|
||||
static zval * php_lua_read_property(zval *object, zval *member, int type, const struct _zend_literal *key TSRMLS_DC) {
|
||||
(void)key;
|
||||
#endif
|
||||
zval *retval = NULL;
|
||||
lua_State *L = NULL;
|
||||
zval *tmp_member = NULL;
|
||||
|
||||
if (type != BP_VAR_R) {
|
||||
MAKE_STD_ZVAL(retval);
|
||||
ZVAL_NULL(retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
lua_getfield(L, LUA_GLOBALSINDEX, Z_STRVAL_P(member));
|
||||
retval = php_lua_get_zval_from_lua(L, -1, object TSRMLS_CC);
|
||||
Z_DELREF_P(retval);
|
||||
lua_pop(L, 1);
|
||||
|
||||
if (tmp_member) {
|
||||
zval_ptr_dtor(&tmp_member);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/** {{{ static void php_lua_write_property(zval *object, zval *member, zval *value TSRMLS_DC)
|
||||
*/
|
||||
#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 TSRMLS_DC) {
|
||||
#else
|
||||
static void php_lua_write_property(zval *object, zval *member, zval *value, const struct _zend_literal *key TSRMLS_DC) {
|
||||
(void)key;
|
||||
#endif
|
||||
lua_State *L = NULL;
|
||||
zval *tmp_member = NULL;
|
||||
|
||||
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);
|
||||
|
||||
php_lua_send_zval_to_lua(L, member TSRMLS_CC);
|
||||
php_lua_send_zval_to_lua(L, value TSRMLS_CC);
|
||||
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
|
||||
if (tmp_member) {
|
||||
zval_ptr_dtor(&tmp_member);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/** {{{ 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 TSRMLS_DC) {
|
||||
zval *retval;
|
||||
|
||||
MAKE_STD_ZVAL(retval);
|
||||
ZVAL_NULL(retval);
|
||||
|
||||
switch (lua_type(L, index)) {
|
||||
case LUA_TNIL:
|
||||
ZVAL_NULL(retval);
|
||||
break;
|
||||
case LUA_TBOOLEAN:
|
||||
ZVAL_BOOL(retval, lua_toboolean(L, index));
|
||||
break;
|
||||
case LUA_TNUMBER:
|
||||
ZVAL_DOUBLE(retval, lua_tonumber(L, index));
|
||||
break;
|
||||
case LUA_TSTRING:
|
||||
{
|
||||
char *val = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
val = (char *)lua_tolstring(L, index, &len);
|
||||
ZVAL_STRINGL(retval, val, len, 1);
|
||||
}
|
||||
break;
|
||||
case LUA_TTABLE:
|
||||
array_init(retval);
|
||||
lua_pushnil(L); /* first key */
|
||||
while (lua_next(L, index-1) != 0) {
|
||||
zval *key = NULL;
|
||||
zval *val = NULL;
|
||||
|
||||
/* uses 'key' (at index -2) and 'value' (at index -1) */
|
||||
key = php_lua_get_zval_from_lua(L, -2, lua_obj TSRMLS_CC);
|
||||
val = php_lua_get_zval_from_lua(L, -1, lua_obj TSRMLS_CC);
|
||||
|
||||
if (!key || !val) {
|
||||
/* there is a warning already in php_lua_get_zval_from_lua */
|
||||
break;
|
||||
}
|
||||
|
||||
switch(Z_TYPE_P(key)) {
|
||||
case IS_DOUBLE:
|
||||
case IS_LONG:
|
||||
add_index_zval(retval, Z_DVAL_P(key), val);
|
||||
break;
|
||||
case IS_STRING:
|
||||
add_assoc_zval(retval, Z_STRVAL_P(key), val);
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
case IS_OBJECT:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
zval_ptr_dtor(&key);
|
||||
}
|
||||
break;
|
||||
case LUA_TFUNCTION:
|
||||
{
|
||||
long ref_id = 0;
|
||||
if (!lua_obj) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "corrupted Lua object");
|
||||
break;
|
||||
}
|
||||
|
||||
lua_pushvalue(L, index);
|
||||
ref_id = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
|
||||
if (!php_lua_closure_instance(retval, ref_id, lua_obj TSRMLS_CC)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to initialize closure object");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LUA_TUSERDATA:
|
||||
case LUA_TTHREAD:
|
||||
case LUA_TLIGHTUSERDATA:
|
||||
default:
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unsupported type '%s' for php",
|
||||
lua_typename(L, lua_type(L, index)));
|
||||
}
|
||||
|
||||
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 TSRMLS_DC) {
|
||||
|
||||
switch (Z_TYPE_P(val)) {
|
||||
case IS_BOOL:
|
||||
lua_pushboolean(L, Z_BVAL_P(val));
|
||||
break;
|
||||
case IS_NULL:
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
case IS_DOUBLE:
|
||||
lua_pushnumber(L, Z_DVAL_P(val));
|
||||
break;
|
||||
case IS_LONG:
|
||||
lua_pushnumber(L, Z_LVAL_P(val));
|
||||
break;
|
||||
case IS_STRING:
|
||||
lua_pushlstring(L, Z_STRVAL_P(val), Z_STRLEN_P(val));
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
case IS_ARRAY:
|
||||
{
|
||||
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_NOTICE
|
||||
, "attempt to pass an array index begin with 0 to lua, the index 0 will be discarded");
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
php_error_docref(NULL TSRMLS_CC, E_ERROR, "unsupported type `%s' for lua"
|
||||
, zend_zval_type_name(val));
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*** {{{ static int php_lua_arg_apply_func(void *data, void *L TSRMLS_DC)
|
||||
*/
|
||||
static int php_lua_arg_apply_func(void *data, void *L TSRMLS_DC) {
|
||||
php_lua_send_zval_to_lua((lua_State*)L, *(zval**)data TSRMLS_CC);
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
} /* }}} */
|
||||
|
||||
/** {{{ static int php_lua_call_callback(lua_State *L)
|
||||
*/
|
||||
static int php_lua_call_callback(lua_State *L) {
|
||||
int order = 0;
|
||||
zval *return_value = NULL;
|
||||
zval **func = NULL;
|
||||
zval *callbacks = NULL;
|
||||
order = lua_tonumber(L, lua_upvalueindex(1));
|
||||
|
||||
TSRMLS_FETCH();
|
||||
callbacks = zend_read_static_property(lua_ce, ZEND_STRL("_callbacks"), 1 TSRMLS_CC);
|
||||
|
||||
if (ZVAL_IS_NULL(callbacks)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
MAKE_STD_ZVAL(return_value);
|
||||
|
||||
if (zend_hash_index_find(Z_ARRVAL_P(callbacks), order, (void **)&func) == FAILURE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!zend_is_callable(*func, 0, NULL TSRMLS_CC)) {
|
||||
return 0;
|
||||
} else {
|
||||
zval **params = NULL;
|
||||
int i = 0;
|
||||
int arg_num = lua_gettop(L);
|
||||
|
||||
params = ecalloc(arg_num, sizeof(zval));
|
||||
|
||||
for (; i<arg_num; 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);
|
||||
|
||||
php_lua_send_zval_to_lua(L, return_value TSRMLS_CC);
|
||||
|
||||
for (i=0; i<arg_num; i++) {
|
||||
zval_ptr_dtor(¶ms[i]);
|
||||
}
|
||||
|
||||
efree(params);
|
||||
zval_ptr_dtor(&return_value);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/** {{{ 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 TSRMLS_DC) {
|
||||
int bp = 0;
|
||||
int sp = 0;
|
||||
int arg_num = 0;
|
||||
zval *ret = NULL;
|
||||
lua_State *L = NULL;
|
||||
|
||||
L = Z_LUAVAL_P(lua_obj);
|
||||
|
||||
if (IS_ARRAY == Z_TYPE_P(func)) {
|
||||
zval **t = NULL;
|
||||
zval **f = NULL;
|
||||
if (zend_hash_index_find(Z_ARRVAL_P(func), 0, (void **)&t) == FAILURE || Z_TYPE_PP(t) != 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
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
"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,
|
||||
"invalid lua function, argument must be an array which contain two elements: array('table', 'method')");
|
||||
return NULL;
|
||||
}
|
||||
lua_getfield(L, LUA_GLOBALSINDEX, Z_STRVAL_PP(t));
|
||||
if (LUA_TTABLE != lua_type(L, lua_gettop(L))) {
|
||||
lua_pop(L, -1);
|
||||
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "invalid lua table '%s'", Z_STRVAL_PP(t));
|
||||
return NULL;
|
||||
}
|
||||
bp = lua_gettop(L);
|
||||
lua_getfield(L, -1, Z_STRVAL_PP(f));
|
||||
if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) {
|
||||
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));
|
||||
return NULL;
|
||||
}
|
||||
} else if (IS_STRING == Z_TYPE_P(func)) {
|
||||
bp = lua_gettop(L);
|
||||
lua_getfield(L, LUA_GLOBALSINDEX, Z_STRVAL_P(func));
|
||||
if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) {
|
||||
lua_pop(L, -1);
|
||||
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "invalid lua function '%s'", Z_STRVAL_P(func));
|
||||
return NULL;
|
||||
}
|
||||
} else if (IS_OBJECT == Z_TYPE_P(func)
|
||||
&& instanceof_function(Z_OBJCE_P(func), php_lua_get_closure_ce() TSRMLS_CC)) {
|
||||
zval *closure = zend_read_property(php_lua_get_closure_ce(), func, ZEND_STRL("_closure"), 1 TSRMLS_CC);
|
||||
if (!Z_LVAL_P(closure)) {
|
||||
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "invalid lua closure");
|
||||
return NULL;
|
||||
}
|
||||
bp = lua_gettop(L);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, Z_LVAL_P(closure));
|
||||
if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) {
|
||||
lua_pop(L, -1);
|
||||
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "call to lua closure failed");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (use_self) {
|
||||
lua_pushvalue(L, -2);
|
||||
lua_remove(L, -2);
|
||||
arg_num++;
|
||||
}
|
||||
|
||||
if (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);
|
||||
}
|
||||
|
||||
if (lua_pcall(L, arg_num, LUA_MULTRET, 0) != 0) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
"call to lua function %s failed", lua_tostring(L, -1));
|
||||
lua_pop(L, lua_gettop(L) - bp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sp = lua_gettop(L) - bp;
|
||||
|
||||
if (!sp) {
|
||||
MAKE_STD_ZVAL(ret);
|
||||
ZVAL_NULL(ret);
|
||||
} else if (sp == 1) {
|
||||
ret = php_lua_get_zval_from_lua(L, -1, lua_obj TSRMLS_CC);
|
||||
} else {
|
||||
int i = 0;
|
||||
MAKE_STD_ZVAL(ret);
|
||||
array_init(ret);
|
||||
for (i = -sp; i < 0; i++) {
|
||||
zval *tmp = php_lua_get_zval_from_lua(L, i, lua_obj TSRMLS_CC);
|
||||
add_next_index_zval(ret, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
lua_pop(L, sp);
|
||||
|
||||
if (IS_ARRAY == Z_TYPE_P(func)) {
|
||||
lua_pop(L, -1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
} /* }}} */
|
||||
|
||||
/** {{{ proto Lua::eval(string $lua_chunk)
|
||||
* eval a lua chunk
|
||||
*/
|
||||
PHP_METHOD(lua, eval) {
|
||||
lua_State *L = NULL;
|
||||
char *statements = NULL;
|
||||
long bp, len = 0;
|
||||
|
||||
L = Z_LUAVAL_P(getThis());
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &statements, &len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
bp = lua_gettop(L);
|
||||
if (luaL_loadbuffer(L, statements, len, "line") || lua_pcall(L, 0, LUA_MULTRET, 0)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
"lua error: %s", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
RETURN_FALSE;
|
||||
} else {
|
||||
zval *tmp = NULL;
|
||||
int ret_count = 0;
|
||||
int i = 0;
|
||||
|
||||
ret_count = lua_gettop(L) - bp;
|
||||
if (ret_count > 1) {
|
||||
array_init(return_value);
|
||||
for (i = -ret_count; i<0; i++) {
|
||||
tmp = php_lua_get_zval_from_lua(L, i, getThis() TSRMLS_CC);
|
||||
add_next_index_zval(return_value, tmp);
|
||||
}
|
||||
} else if (ret_count) {
|
||||
zval *tmp = php_lua_get_zval_from_lua(L, -1, getThis() TSRMLS_CC);
|
||||
RETURN_ZVAL(tmp, 1, 1);
|
||||
}
|
||||
lua_pop(L, ret_count);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/** {{{ proto Lua::include(string $file)
|
||||
* run a lua script file
|
||||
*/
|
||||
PHP_METHOD(lua, include) {
|
||||
lua_State *L = NULL;
|
||||
char *file = NULL;
|
||||
long bp, len = 0;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (php_check_open_basedir(file TSRMLS_CC)
|
||||
#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;
|
||||
}
|
||||
|
||||
L = Z_LUAVAL_P(getThis());
|
||||
|
||||
bp = lua_gettop(L);
|
||||
if (luaL_dofile(L, file)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING,
|
||||
"lua error: %s", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
RETURN_FALSE;
|
||||
} else {
|
||||
zval *tmp = NULL;
|
||||
int ret_count = 0;
|
||||
int i = 0;
|
||||
|
||||
ret_count = lua_gettop(L) - bp;
|
||||
if (ret_count > 1) {
|
||||
array_init(return_value);
|
||||
|
||||
for (i = -ret_count; i<0; i++) {
|
||||
tmp = php_lua_get_zval_from_lua(L, i, getThis() TSRMLS_CC);
|
||||
add_next_index_zval(return_value, tmp);
|
||||
}
|
||||
|
||||
} else if (ret_count) {
|
||||
zval *tmp = php_lua_get_zval_from_lua(L, -1, getThis() TSRMLS_CC);
|
||||
RETURN_ZVAL(tmp, 1, 1);
|
||||
}
|
||||
|
||||
lua_pop(L, ret_count);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/** {{{ proto Lua::call(mixed $function, array $args, bool $use_self)
|
||||
*/
|
||||
PHP_METHOD(lua, call) {
|
||||
long u_self = 0;
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ret = php_lua_call_lua_function(getThis(), func, args, u_self TSRMLS_CC))) {
|
||||
RETURN_ZVAL(ret, 1, 1);
|
||||
}
|
||||
|
||||
RETURN_FALSE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/** {{{ proto Lua::assign(string $name, mix $value)
|
||||
*/
|
||||
PHP_METHOD(lua, assign) {
|
||||
char *name = NULL;
|
||||
zval *value = NULL;
|
||||
lua_State *L = NULL;
|
||||
int len = 0;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &len, &value) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
L = Z_LUAVAL_P(getThis());
|
||||
|
||||
php_lua_send_zval_to_lua(L, value TSRMLS_CC);
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, name);
|
||||
|
||||
RETURN_ZVAL(getThis(), 1, 0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/** {{{ proto Lua::registerCallback(string $name, mix $value)
|
||||
*/
|
||||
PHP_METHOD(lua, registerCallback) {
|
||||
char *name = NULL;
|
||||
long len = 0;
|
||||
zval *func = NULL;
|
||||
lua_State *L = NULL;
|
||||
zval* callbacks = NULL;
|
||||
L = Z_LUAVAL_P(getThis());
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"sz", &name, &len, &func) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
callbacks = zend_read_static_property(lua_ce, ZEND_STRL("_callbacks"), 1 TSRMLS_CC);
|
||||
|
||||
if (ZVAL_IS_NULL(callbacks)) {
|
||||
array_init(callbacks);
|
||||
}
|
||||
|
||||
if (zend_is_callable(func, 0, NULL TSRMLS_CC)) {
|
||||
lua_pushnumber(L, zend_hash_num_elements(Z_ARRVAL_P(callbacks)));
|
||||
lua_pushcclosure(L, php_lua_call_callback, 1);
|
||||
lua_setglobal(L, name);
|
||||
} else {
|
||||
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "invalid php callback");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
zval_add_ref(&func);
|
||||
add_next_index_zval(callbacks, func);
|
||||
|
||||
RETURN_ZVAL(getThis(), 1, 0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/** {{{ proto Lua::getVersion()
|
||||
*/
|
||||
PHP_METHOD(lua, getVersion) {
|
||||
RETURN_STRING(LUA_RELEASE, 1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/** {{{ proto Lua::__construct()
|
||||
*/
|
||||
PHP_METHOD(lua, __construct) {
|
||||
lua_State *L = Z_LUAVAL_P(getThis());
|
||||
luaL_openlibs(L);
|
||||
lua_register(L, "print", php_lua_print);
|
||||
if (ZEND_NUM_ARGS()) {
|
||||
PHP_MN(lua_include)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ lua_class_methods[]
|
||||
*
|
||||
*/
|
||||
zend_function_entry lua_class_methods[] = {
|
||||
PHP_ME(lua, __construct, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
|
||||
PHP_ME(lua, eval, arginfo_lua_eval, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(lua, include, arginfo_lua_include, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(lua, call, arginfo_lua_call, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(lua, assign, arginfo_lua_assign, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(lua, getVersion, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_ALLOW_STATIC)
|
||||
PHP_ME(lua, registerCallback, arginfo_lua_register, ZEND_ACC_PUBLIC)
|
||||
PHP_MALIAS(lua, __call, call, arginfo_lua_call, ZEND_ACC_PUBLIC)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINIT_FUNCTION
|
||||
*/
|
||||
PHP_MINIT_FUNCTION(lua) {
|
||||
zend_class_entry ce;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "Lua", lua_class_methods);
|
||||
|
||||
lua_ce = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
lua_ce->create_object = php_lua_create_object;
|
||||
memcpy(&lua_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
|
||||
|
||||
lua_object_handlers.write_property = php_lua_write_property;
|
||||
lua_object_handlers.read_property = php_lua_read_property;
|
||||
|
||||
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_class_constant_string(lua_ce, ZEND_STRL("LUA_VERSION"), LUA_RELEASE TSRMLS_CC);
|
||||
|
||||
php_lua_closure_register(TSRMLS_C);
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "LuaException", NULL);
|
||||
lua_exception_ce = zend_register_internal_class_ex(&ce,
|
||||
#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 2)
|
||||
zend_exception_get_default(),
|
||||
#else
|
||||
zend_exception_get_default(TSRMLS_C),
|
||||
#endif
|
||||
NULL TSRMLS_CC);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MSHUTDOWN_FUNCTION
|
||||
*/
|
||||
PHP_MSHUTDOWN_FUNCTION(lua)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ PHP_MINFO_FUNCTION
|
||||
*/
|
||||
PHP_MINFO_FUNCTION(lua)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "lua support", "enabled");
|
||||
php_info_print_table_row(2, "lua extension version", PHP_LUA_VERSION);
|
||||
php_info_print_table_row(2, "lua release", LUA_RELEASE);
|
||||
php_info_print_table_row(2, "lua copyright", LUA_COPYRIGHT);
|
||||
php_info_print_table_row(2, "lua authors", LUA_AUTHORS);
|
||||
php_info_print_table_end();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
21
lua.php
Normal file
21
lua.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
$br = (php_sapi_name() == "cli")? "":"<br>";
|
||||
|
||||
if(!extension_loaded('lua')) {
|
||||
dl('lua.' . PHP_SHLIB_SUFFIX);
|
||||
}
|
||||
$module = 'lua';
|
||||
$functions = get_extension_funcs($module);
|
||||
echo "Functions available in the test extension:$br\n";
|
||||
foreach($functions as $func) {
|
||||
echo $func."$br\n";
|
||||
}
|
||||
echo "$br\n";
|
||||
$function = 'confirm_' . $module . '_compiled';
|
||||
if (extension_loaded($module)) {
|
||||
$str = $function($module);
|
||||
} else {
|
||||
$str = "Module $module is not compiled into PHP";
|
||||
}
|
||||
echo "$str\n";
|
||||
?>
|
||||
249
lua_closure.c
Normal file
249
lua_closure.c
Normal file
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Lua |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author : Johannes Schlueter <johannes@php.net> |
|
||||
| Xinchen Hui <laruence@php.net> |
|
||||
| Marcelo Araujo <msaraujo@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
$Id: lua_closure.c 319740 2011-11-24 08:06:48Z laruence $
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "php.h"
|
||||
#include "Zend/zend_exceptions.h"
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
|
||||
#include "php_lua.h"
|
||||
|
||||
static zend_class_entry *lua_closure_ce;
|
||||
extern zend_class_entry *lua_ce;
|
||||
extern zend_class_entry *lua_exception_ce;
|
||||
|
||||
/** {{{ ARG_INFO
|
||||
*
|
||||
*/
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_invoke, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, arg)
|
||||
ZEND_ARG_INFO(0, ...)
|
||||
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 TSRMLS_DC) {
|
||||
object_init_ex(instance, lua_closure_ce);
|
||||
zend_update_property_long(lua_closure_ce, instance, ZEND_STRL("_closure"), ref_id TSRMLS_CC);
|
||||
zend_update_property(lua_closure_ce, instance, ZEND_STRL("_lua_object"), lua_obj TSRMLS_CC);
|
||||
|
||||
return instance;
|
||||
}
|
||||
/** }}} */
|
||||
|
||||
/** {{{ proto LuaClosure::__construct()
|
||||
*/
|
||||
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)
|
||||
*/
|
||||
PHP_METHOD(lua_closure, invoke) {
|
||||
int bp, sp;
|
||||
zval ***arguments = NULL;
|
||||
zval *lua_obj = NULL;
|
||||
lua_State *L = NULL;
|
||||
zval *closure = NULL;
|
||||
|
||||
if (ZEND_NUM_ARGS()) {
|
||||
arguments = emalloc(sizeof(zval**) * ZEND_NUM_ARGS());
|
||||
if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), arguments) == FAILURE) {
|
||||
efree(arguments);
|
||||
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "cannot get arguments for calling closure");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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)) {
|
||||
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "corrupted Lua object");
|
||||
return;
|
||||
}
|
||||
|
||||
closure = zend_read_property(lua_closure_ce, getThis(), ZEND_STRL("_closure"), 1 TSRMLS_CC);
|
||||
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);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, Z_LVAL_P(closure));
|
||||
if (LUA_TFUNCTION != lua_type(L, lua_gettop(L))) {
|
||||
lua_pop(L, -1);
|
||||
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC, "call to lua closure failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ZEND_NUM_ARGS()) {
|
||||
int i = 0;
|
||||
for(;i<ZEND_NUM_ARGS();i++) {
|
||||
php_lua_send_zval_to_lua(L, *(arguments[i]) TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
|
||||
if (lua_pcall(L, ZEND_NUM_ARGS(), LUA_MULTRET, 0) != 0) {
|
||||
if (arguments) {
|
||||
efree(arguments);
|
||||
}
|
||||
lua_pop(L, lua_gettop(L) - bp);
|
||||
zend_throw_exception_ex(lua_exception_ce, 0 TSRMLS_CC,
|
||||
"call to lua function %s failed", lua_tostring(L, -1));
|
||||
return;
|
||||
}
|
||||
|
||||
sp = lua_gettop(L) - bp;
|
||||
|
||||
if (!sp) {
|
||||
RETURN_NULL();
|
||||
} else if (sp == 1) {
|
||||
zval *tmp = php_lua_get_zval_from_lua(L, -1, lua_obj TSRMLS_CC);
|
||||
RETURN_ZVAL(tmp, 0, 0);
|
||||
} else {
|
||||
int i = 0;
|
||||
array_init(return_value);
|
||||
for (i = -sp; i < 0; i++) {
|
||||
zval *tmp = php_lua_get_zval_from_lua(L, i, lua_obj TSRMLS_CC);
|
||||
add_next_index_zval(return_value, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
lua_pop(L, sp);
|
||||
|
||||
if (arguments) {
|
||||
efree(arguments);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/** {{{ proto LuaClosure::__clone()
|
||||
*/
|
||||
PHP_METHOD(lua_closure, __clone) {
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ lua_class_methods[]
|
||||
*
|
||||
*/
|
||||
zend_function_entry lua_closure_methods[] = {
|
||||
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_MALIAS(lua_closure, __invoke, invoke, arginfo_lua_invoke, ZEND_ACC_PUBLIC)
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
/* }}} */
|
||||
|
||||
static void php_lua_closure_dtor_object(void *object, zend_object_handle handle TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_object *obj = (zend_object*)object;
|
||||
|
||||
zend_object_std_dtor(obj TSRMLS_CC);
|
||||
|
||||
efree(obj);
|
||||
} /* }}} */
|
||||
|
||||
static zend_object_value php_lua_closure_create_object(zend_class_entry *ce TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_object_value obj = {0};
|
||||
zend_object *lua_closure_obj = NULL;
|
||||
|
||||
lua_closure_obj = emalloc(sizeof(zend_object));
|
||||
|
||||
zend_object_std_init(lua_closure_obj, ce TSRMLS_CC);
|
||||
#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) /* {{{ */
|
||||
{
|
||||
zend_class_entry ce;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "LuaClosure", lua_closure_methods);
|
||||
lua_closure_ce = zend_register_internal_class(&ce TSRMLS_CC);
|
||||
lua_closure_ce->create_object = php_lua_closure_create_object;
|
||||
lua_closure_ce->ce_flags |= ZEND_ACC_FINAL;
|
||||
|
||||
zend_declare_property_long(lua_closure_ce, ZEND_STRL("_closure"), 0, ZEND_ACC_PRIVATE TSRMLS_CC);
|
||||
zend_declare_property_null(lua_closure_ce, ZEND_STRL("_lua_object"), ZEND_ACC_PRIVATE TSRMLS_CC);
|
||||
|
||||
|
||||
} /* }}} */
|
||||
|
||||
zend_class_entry *php_lua_get_closure_ce() /* {{{ */
|
||||
{
|
||||
return lua_closure_ce;
|
||||
} /* }}} */
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
31
lua_closure.h
Normal file
31
lua_closure.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Lua |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author : Johannes Schlueter <johannes@php.net> |
|
||||
| Xinchen Hui <laruence@php.net> |
|
||||
| Marcelo Araujo <msaraujo@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
$Id: lua_closure.h 319733 2011-11-24 07:13:56Z laruence $
|
||||
*/
|
||||
|
||||
void php_lua_closure_register(TSRMLS_D);
|
||||
zend_class_entry *php_lua_get_closure_ce();
|
||||
zval * php_lua_closure_instance(zval *instance, long ref_id, zval *lua_obj TSRMLS_DC);
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
66
package.xml
Normal file
66
package.xml
Normal file
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE package SYSTEM "http://pear.php.net/dtd/package-1.0">
|
||||
<package version="1.0" packagerversion="1.9.2">
|
||||
<name>lua</name>
|
||||
<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>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>johannes</user>
|
||||
<name>Johannes Schlüter</name>
|
||||
<email>johannes@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<user>laruence</user>
|
||||
<name>Xinchen Hui</name>
|
||||
<email>laruence@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<user>msaraujo</user>
|
||||
<name>Marcelo Araujo</name>
|
||||
<email>msaraujo@php.net</email>
|
||||
<role>developer</role>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
<release>
|
||||
<version>0.9.1</version>
|
||||
<date>2011-11-24</date>
|
||||
<license>PHP</license>
|
||||
<state>beta</state>
|
||||
<notes>- Compatible with PHP5.3+
|
||||
- Fix ZTS build
|
||||
- Fix mem leak when get value from lua
|
||||
</notes>
|
||||
<deps>
|
||||
<dep type="php" rel="ge" version="5.1.0"/>
|
||||
<dep type="php" rel="le" version="5.4.0"/>
|
||||
</deps>
|
||||
<filelist>
|
||||
<dir name="tests">
|
||||
<file role="test" name="001.phpt"/>
|
||||
<file role="test" name="002.phpt"/>
|
||||
<file role="test" name="003.phpt"/>
|
||||
<file role="test" name="004.phpt"/>
|
||||
<file role="test" name="005.phpt"/>
|
||||
<file role="test" name="006.phpt"/>
|
||||
<file role="test" name="007.phpt"/>
|
||||
<file role="test" name="008.phpt"/>
|
||||
<file role="test" name="009.phpt"/>
|
||||
<file role="test" name="010.phpt"/>
|
||||
<file role="test" name="011.phpt"/>
|
||||
</dir> <!-- /tests -->
|
||||
<file role="src" name="config.m4"/>
|
||||
<file role="src" name="config.w32"/>
|
||||
<file role="src" name="CREDITS"/>
|
||||
<file role="src" name="EXPERIMENTAL"/>
|
||||
<file role="src" name="lua.c"/>
|
||||
<file role="src" name="lua_closure.c"/>
|
||||
<file role="src" name="lua_closure.h"/>
|
||||
<file role="src" name="php_lua.h"/>
|
||||
</filelist>
|
||||
</release>
|
||||
</package>
|
||||
119
package2.xml
Normal file
119
package2.xml
Normal file
@@ -0,0 +1,119 @@
|
||||
<?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>2011-11-24</date>
|
||||
<time>15:17:25</time>
|
||||
<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>
|
||||
<notes>
|
||||
- Compatible with PHP5.3+
|
||||
- Fix ZTS build
|
||||
- Fix mem leak when get value from lua
|
||||
</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" />
|
||||
<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" />
|
||||
</dir>
|
||||
</dir>
|
||||
</contents>
|
||||
<dependencies>
|
||||
<required>
|
||||
<php>
|
||||
<min>5.1.0</min>
|
||||
<max>5.4.0</max>
|
||||
</php>
|
||||
<pearinstaller>
|
||||
<min>1.4.0</min>
|
||||
</pearinstaller>
|
||||
</required>
|
||||
</dependencies>
|
||||
<providesextension>lua</providesextension>
|
||||
<extsrcrelease />
|
||||
<changelog>
|
||||
<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
|
||||
-->
|
||||
78
php_lua.h
Normal file
78
php_lua.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Lua |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author : Johannes Schlueter <johannes@php.net> |
|
||||
| Xinchen Hui <laruence@php.net> |
|
||||
| Marcelo Araujo <msaraujo@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
$Id: php_lua.h 319733 2011-11-24 07:13:56Z laruence $
|
||||
*/
|
||||
|
||||
#ifndef PHP_LUA_H
|
||||
#define PHP_LUA_H
|
||||
|
||||
extern zend_module_entry lua_module_entry;
|
||||
#define phpext_lua_ptr &lua_module_entry
|
||||
|
||||
#ifdef PHP_WIN32
|
||||
#define PHP_LUA_API __declspec(dllexport)
|
||||
#else
|
||||
#define PHP_LUA_API
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#include "TSRM.h"
|
||||
#endif
|
||||
|
||||
#ifdef ZTS
|
||||
#define LUA_G(v) TSRMG(lua_globals_id, zend_lua_globals *, v)
|
||||
#else
|
||||
#define LUA_G(v) (lua_globals.v)
|
||||
#endif
|
||||
|
||||
#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 3)) || (PHP_MAJOR_VERSION < 5)
|
||||
#define Z_ADDREF_P ZVAL_ADDREF
|
||||
#define Z_REFCOUNT_P ZVAL_REFCOUNT
|
||||
#define Z_DELREF_P ZVAL_DELREF
|
||||
#endif
|
||||
|
||||
#define PHP_LUA_VERSION "0.9.0"
|
||||
#define Z_LUAVAL_P(obj) ((php_lua_object*)(zend_object_store_get_object(obj TSRMLS_CC)))->L
|
||||
|
||||
struct _php_lua_object {
|
||||
zend_object obj;
|
||||
lua_State *L;
|
||||
};
|
||||
|
||||
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);
|
||||
int php_lua_send_zval_to_lua(lua_State *L, zval *val TSRMLS_DC);
|
||||
|
||||
PHP_MINIT_FUNCTION(lua);
|
||||
PHP_MSHUTDOWN_FUNCTION(lua);
|
||||
PHP_MINFO_FUNCTION(lua);
|
||||
|
||||
PHP_METHOD(lua, __construct);
|
||||
PHP_METHOD(lua, eval);
|
||||
PHP_METHOD(lua, require);
|
||||
#endif /* PHP_LUA_H */
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
16
tests/001.phpt
Normal file
16
tests/001.phpt
Normal file
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Basic lua check
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("lua")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$l = new lua();
|
||||
$l->assign("b", 12);
|
||||
$l->eval("print(b)");
|
||||
$l->eval('print("\n")');
|
||||
$l->eval("print(math.sin(b))");
|
||||
$l->eval("invalid code");
|
||||
--EXPECTF--
|
||||
12
|
||||
-0.53657291800043
|
||||
Warning: Lua::eval(): lua error: [string "line"]:1: '=' expected near 'code' in %s on line %d
|
||||
19
tests/002.phpt
Normal file
19
tests/002.phpt
Normal file
@@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Set and read properties
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("lua")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$l = new lua();
|
||||
$l->a = "foobar";
|
||||
$l->b = 12;
|
||||
var_dump($l->b);
|
||||
var_dump($l->a);
|
||||
|
||||
$l->b = null;
|
||||
var_dump($l->b);
|
||||
?>
|
||||
--EXPECT--
|
||||
float(12)
|
||||
string(6) "foobar"
|
||||
NULL
|
||||
95
tests/003.phpt
Normal file
95
tests/003.phpt
Normal file
@@ -0,0 +1,95 @@
|
||||
--TEST--
|
||||
Call lua functions
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("lua")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$l = new lua();
|
||||
$l->eval(<<<CODE
|
||||
function phptest_no_param()
|
||||
print("No parameters!\\n")
|
||||
end
|
||||
|
||||
function phptest_1_param(param)
|
||||
print("Parameter: `", param, "'!\\n")
|
||||
end
|
||||
|
||||
function phptest_2_params(param1, param2)
|
||||
print("Parameter 1: `", param1, "', Parameter 2: `", param2, "'!\\n")
|
||||
end
|
||||
|
||||
function multiret()
|
||||
return "a", "b", "c"
|
||||
end
|
||||
CODE
|
||||
);
|
||||
|
||||
$l->print("Hello world!\n");
|
||||
$l->phptest_no_param();
|
||||
|
||||
$l->phptest_1_param();
|
||||
$l->phptest_1_param("foobar");
|
||||
|
||||
$l->phptest_2_params();
|
||||
$l->phptest_2_params("foo");
|
||||
$l->phptest_2_params("foo", "bar");
|
||||
|
||||
echo "\n";
|
||||
|
||||
var_dump($l->call(array("math", "sin"), array(3/2*pi())));
|
||||
var_dump($l->call(array("math", "cos"), array(pi())));
|
||||
|
||||
echo "\n";
|
||||
|
||||
try {
|
||||
$l->notexisting(2423);
|
||||
$l->call(array("math", "sin", "function"), array(432, 342));
|
||||
|
||||
} catch (LuaException $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
|
||||
echo "\n";
|
||||
|
||||
var_dump($l->type("fobar"));
|
||||
var_dump($l->multiret());
|
||||
|
||||
echo "\n";
|
||||
|
||||
var_dump($l->__call("multiret", array()));
|
||||
|
||||
$l->__call("print");
|
||||
$l->__call("print", array("foo"));
|
||||
?>
|
||||
--EXPECTF--
|
||||
Hello world!
|
||||
No parameters!
|
||||
Parameter: `'!
|
||||
Parameter: `foobar'!
|
||||
Parameter 1: `', Parameter 2: `'!
|
||||
Parameter 1: `foo', Parameter 2: `'!
|
||||
Parameter 1: `foo', Parameter 2: `bar'!
|
||||
|
||||
float(-1)
|
||||
float(-1)
|
||||
|
||||
invalid lua function 'notexisting'
|
||||
string(6) "string"
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(1) "a"
|
||||
[1]=>
|
||||
string(1) "b"
|
||||
[2]=>
|
||||
string(1) "c"
|
||||
}
|
||||
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(1) "a"
|
||||
[1]=>
|
||||
string(1) "b"
|
||||
[2]=>
|
||||
string(1) "c"
|
||||
}
|
||||
foo
|
||||
35
tests/004.phpt
Normal file
35
tests/004.phpt
Normal file
@@ -0,0 +1,35 @@
|
||||
--TEST--
|
||||
Type conversion from lua to PHP
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("lua")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$l = new lua();
|
||||
|
||||
$l->eval(<<<CODE
|
||||
a = nil
|
||||
b = false
|
||||
c = 23
|
||||
d = -432
|
||||
e = 432.432
|
||||
f = 0
|
||||
g = 14.3e24
|
||||
h = "foobar"
|
||||
i = ""
|
||||
CODE
|
||||
);
|
||||
|
||||
for ($i = 'a'; $i < 'j'; $i++) {
|
||||
var_dump($l->{$i});
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
NULL
|
||||
bool(false)
|
||||
float(23)
|
||||
float(-432)
|
||||
float(432.432)
|
||||
float(0)
|
||||
float(1.43E+25)
|
||||
string(6) "foobar"
|
||||
string(0) ""
|
||||
17
tests/005.phpt
Normal file
17
tests/005.phpt
Normal file
@@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
Lua phpinfo() block
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("lua")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$r = new ReflectionExtension('lua');
|
||||
$r->info();
|
||||
?>
|
||||
--EXPECTF--
|
||||
lua
|
||||
|
||||
lua support => enabled
|
||||
lua extension version => %s
|
||||
lua release => %s
|
||||
lua copyright => %s
|
||||
lua authors => %s
|
||||
39
tests/006.phpt
Normal file
39
tests/006.phpt
Normal file
@@ -0,0 +1,39 @@
|
||||
--TEST--
|
||||
Lua::include()
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("lua")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$filename = __FILE__.'.tmp';
|
||||
|
||||
$code = array(
|
||||
'fine' => 'print "Hello PHP"',
|
||||
'broken' => 'dgdr fdrg erb rxdgre tews< df hxfdxgfc gsdgxvrsgrg.ve4w',
|
||||
'return' => 'return "php", "lua", "extension"',
|
||||
);
|
||||
|
||||
$l = new lua();
|
||||
|
||||
foreach ($code as $n => $c) {
|
||||
echo "\nTesting $n\n";
|
||||
file_put_contents($filename, $c);
|
||||
$ret = $l->include($filename);
|
||||
if ($ret) print_r($ret);
|
||||
@unlink($filename);
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
|
||||
Testing fine
|
||||
Hello PHP
|
||||
Testing broken
|
||||
|
||||
Warning: Lua::include(): lua error: %s '=' expected near 'fdrg' in %s on line %d
|
||||
|
||||
Testing return
|
||||
Array
|
||||
(
|
||||
[0] => php
|
||||
[1] => lua
|
||||
[2] => extension
|
||||
)
|
||||
30
tests/007.phpt
Normal file
30
tests/007.phpt
Normal file
@@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
Lua return function
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("lua")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$l = new lua();
|
||||
|
||||
$l->eval(<<<CODE
|
||||
function closure ()
|
||||
local from = "lua";
|
||||
return (function ()
|
||||
print(from);
|
||||
end);
|
||||
end
|
||||
CODE
|
||||
);
|
||||
|
||||
$func = $l->closure();
|
||||
|
||||
$l->call($func);
|
||||
unset($func);
|
||||
$func = $l->closure();
|
||||
|
||||
$l->call($func);
|
||||
unset($func);
|
||||
?>
|
||||
--EXPECTF--
|
||||
lualua
|
||||
41
tests/008.phpt
Normal file
41
tests/008.phpt
Normal file
@@ -0,0 +1,41 @@
|
||||
--TEST--
|
||||
register php function to lua
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("lua")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$l = new lua();
|
||||
|
||||
class A {
|
||||
public static function intro($foo, $bar) {
|
||||
echo $foo, $bar;
|
||||
}
|
||||
}
|
||||
|
||||
$l->registerCallback("callphp", array("A", "intro"));
|
||||
|
||||
$l->eval(<<<CODE
|
||||
callphp("foo", "bar");
|
||||
CODE
|
||||
);
|
||||
|
||||
Class B {
|
||||
public function intro(array $bar) {
|
||||
echo join(",", $bar);
|
||||
}
|
||||
}
|
||||
|
||||
$l->registerCallback("callphp2", array(new B, "intro"));
|
||||
|
||||
|
||||
$l->registerCallback("echo", "var_dump");
|
||||
|
||||
$l->eval(<<<CODE
|
||||
callphp2({"foo", "bar"});
|
||||
echo("maybe");
|
||||
CODE
|
||||
);
|
||||
?>
|
||||
--EXPECTF--
|
||||
foobarfoo,barstring(5) "maybe"
|
||||
45
tests/009.phpt
Normal file
45
tests/009.phpt
Normal file
@@ -0,0 +1,45 @@
|
||||
--TEST--
|
||||
Bug (eval and include compute wrong return value number)
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("lua")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$l = new lua();
|
||||
|
||||
$l->eval(<<<CODE
|
||||
function closure ()
|
||||
local from = "lua";
|
||||
return (function ()
|
||||
print(from);
|
||||
end);
|
||||
end
|
||||
CODE
|
||||
);
|
||||
|
||||
$func = $l->closure();
|
||||
|
||||
$arr = $l->eval(<<<CODE
|
||||
return 2, 3, 4, 5, 6
|
||||
CODE
|
||||
);
|
||||
|
||||
print_r($arr);
|
||||
|
||||
$l->call($func);
|
||||
unset($func);
|
||||
$func = $l->closure();
|
||||
|
||||
$l->call($func);
|
||||
unset($func);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Array
|
||||
(
|
||||
[0] => 2
|
||||
[1] => 3
|
||||
[2] => 4
|
||||
[3] => 5
|
||||
[4] => 6
|
||||
)
|
||||
lualua
|
||||
34
tests/010.phpt
Normal file
34
tests/010.phpt
Normal file
@@ -0,0 +1,34 @@
|
||||
--TEST--
|
||||
LuaClosure exception
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("lua")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$l = new lua();
|
||||
|
||||
$l->eval(<<<CODE
|
||||
function closure ()
|
||||
local from = "lua";
|
||||
return (function ()
|
||||
print(from);
|
||||
end);
|
||||
end
|
||||
CODE
|
||||
);
|
||||
|
||||
$func = $l->closure();
|
||||
|
||||
try {
|
||||
$l->call($func);
|
||||
if (version_compare(PHP_VERSION, "5.3.0") >= 0) {
|
||||
$func();
|
||||
} else {
|
||||
$func->invoke();
|
||||
}
|
||||
} catch (LuaException $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
lualua
|
||||
18
tests/011.phpt
Normal file
18
tests/011.phpt
Normal file
@@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
register invalid php callback to lua
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("lua")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$l = new lua();
|
||||
|
||||
try {
|
||||
$l->registerCallback("callphp", "print");
|
||||
echo "okey";
|
||||
} catch (Exception $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
|
||||
--EXPECT--
|
||||
invalid php callback
|
||||
Reference in New Issue
Block a user