remove pkg-config dependency. now uses good ole --with-lua[=DIR]
[phplua.git] / lua.c
blob5a375137282fda442a8708dd7f2570c86e71bde5
1 /*
2 +----------------------------------------------------------------------+
3 | LUA extension for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2007 Johannes Schlueter |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Author: Johannes Schlueter <johannes@php.net> |
16 | Marcelo Araujo <msaraujo@php.net> |
17 | Andreas Streichardt <andreas.streichardt@globalpark.com |
18 +----------------------------------------------------------------------+
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
25 #include "php.h"
26 #include "php_ini.h"
27 #include "ext/standard/info.h"
28 #include "php_lua.h"
30 #include "lua.h"
31 #include "lauxlib.h"
32 #include "lualib.h"
34 #define EXT_LUA_VERSION PHP_LUA_VERSION
36 #ifdef LUA_STACK_DEBUG
37 #define LUA_STACK_START(L) int __lua_old_top = lua_gettop(L)
38 #define LUA_STACK_END(L) \
39 if (__lua_old_top != lua_gettop(L)) { \
40 php_error_docref(NULL TSRMLS_CC, E_WARNING, "wrong stack size (%i before operation, %i now)", __lua_old_top, lua_gettop(L)); \
42 #else
43 #define LUA_STACK_START(L)
44 #define LUA_STACK_END(L)
45 #endif
47 #define LUA_POP_ZVAL(L, z) \
48 php_lua_get_zval_from_stack(L, -1, z); \
49 lua_pop(L, 1)
51 ZEND_DECLARE_MODULE_GLOBALS(lua)
53 #define getLuaZ(var) (((php_lua_object*)zend_object_store_get_object(var TSRMLS_CC))->L)
54 #define getLua() getLuaZ(getThis())
56 static zend_object_handlers lua_handlers;
57 static zend_class_entry *lua_ce;
59 typedef struct _php_lua_object {
60 zend_object std;
61 lua_State *L;
62 } php_lua_object;
64 static const luaL_Reg php_lualibs[] = {
65 {"base", luaopen_base},
66 {LUA_LOADLIBNAME, luaopen_package},
67 {LUA_TABLIBNAME, luaopen_table},
68 {LUA_IOLIBNAME, luaopen_io},
69 {LUA_OSLIBNAME, luaopen_os},
70 {LUA_STRLIBNAME, luaopen_string},
71 {LUA_MATHLIBNAME, luaopen_math},
72 {LUA_DBLIBNAME, luaopen_debug},
73 {NULL, NULL}
76 static void php_lua_push_zval(lua_State *L, zval *val_p TSRMLS_DC);
77 static void php_lua_write_real_property(lua_State *L,int index,zval *prop, zval *value TSRMLS_DC);
79 static void *php_lua_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { /* {{{ */
80 if (nsize == 0) {
81 if (ptr) {
82 efree(ptr);
84 return NULL;
85 } else {
86 if (ptr) {
87 return erealloc(ptr, nsize);
88 } else {
89 return emalloc(nsize);
92 } /* }}} */
95 static void php_lua_push_array(lua_State *L, zval *array TSRMLS_DC) /* {{{ */
97 zval **data;
98 HashTable *arr_hash;
99 HashPosition pointer;
100 int array_count;
101 char *key;
102 int key_len;
103 long index;
104 int hash_key;
105 char *key_copy;
107 zval *zkey;
109 arr_hash = Z_ARRVAL_P(array);
110 array_count = zend_hash_num_elements(arr_hash);
112 lua_newtable(L);
114 for(zend_hash_internal_pointer_reset_ex(arr_hash, &pointer); zend_hash_get_current_data_ex(arr_hash, (void**) &data, &pointer) == SUCCESS; zend_hash_move_forward_ex(arr_hash, &pointer))
116 hash_key=zend_hash_get_current_key_ex(arr_hash, &key, &key_len, &index, 0, &pointer);
118 if (hash_key == HASH_KEY_IS_LONG && index == 0) {
119 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Trying to push array index %d to lua which is unsupported in lua. Element has been discarded",index);
121 else {
122 ALLOC_INIT_ZVAL(zkey);
123 if (hash_key == HASH_KEY_IS_STRING) {
124 key_copy=estrndup(key,key_len-1);
125 Z_TYPE_P(zkey)=IS_STRING;
126 Z_STRVAL_P(zkey)=key_copy;
127 Z_STRLEN_P(zkey)=key_len-1;
129 else {
130 Z_TYPE_P(zkey)=IS_LONG;
131 Z_LVAL_P(zkey)=index;
134 php_lua_write_real_property(L,-3,zkey,*data TSRMLS_CC);
135 zval_ptr_dtor(&zkey);
138 } /* }}} */
143 static void php_lua_push_zval(lua_State *L, zval *val_p TSRMLS_DC) /* {{{ */
145 /* TODO: Use proper type for lua and separate only when needed */
147 /* push into lua stack properly */
148 switch (Z_TYPE_P(val_p)) {
149 case IS_STRING:
150 lua_pushlstring(L, Z_STRVAL_P(val_p), Z_STRLEN_P(val_p));
151 break;
153 case IS_NULL:
154 lua_pushnil(L);
155 break;
157 case IS_DOUBLE:
158 lua_pushnumber(L, Z_DVAL_P(val_p));
159 break;
161 case IS_LONG:
162 lua_pushnumber(L, Z_LVAL_P(val_p));
163 break;
165 case IS_BOOL:
166 lua_pushboolean(L, Z_BVAL_P(val_p));
167 break;
169 case IS_ARRAY:
170 php_lua_push_array(L,val_p TSRMLS_CC);
171 break;
173 default:
174 php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid type `%s' supported in lua", zend_zval_type_name(val_p));
175 lua_pushnil(L);
176 break;
179 } /* }}} */
181 static int php_lua_push_apply_func(void *pDest, void *argument TSRMLS_DC) /* {{{ */
183 php_lua_push_zval((lua_State*)argument, *(zval**)pDest TSRMLS_CC);
184 return ZEND_HASH_APPLY_KEEP;
185 } /* }}} */
187 static void php_lua_get_zval_from_stack(lua_State *L, int index, zval *ret TSRMLS_DC) /* {{{ */
189 const char *value;
190 size_t value_len;
192 switch (lua_type(L, index)) {
193 case LUA_TBOOLEAN:
194 ZVAL_BOOL(ret, lua_toboolean(L, index));
195 break;
197 case LUA_TNUMBER:
198 ZVAL_DOUBLE(ret, lua_tonumber(L, index));
199 break;
201 case LUA_TSTRING:
202 value = lua_tolstring(L, index, &value_len);
203 ZVAL_STRINGL(ret, (char*)value, value_len, 1);
204 break;
206 case LUA_TTABLE:
207 array_init(ret);
208 /* notify lua to traverse the table */
209 lua_pushnil(L);
211 zval *akey,*aval;
213 /* table has been moved by one because of the pushnil */
214 /* this will ONLY work with negative indices! */
215 while (lua_next(L, index-1) != 0)
217 ALLOC_INIT_ZVAL(akey);
218 ALLOC_INIT_ZVAL(aval);
220 /* `key' is at index -2 and `value' at index -1 */
221 php_lua_get_zval_from_stack(L,-2,akey);
222 php_lua_get_zval_from_stack(L,-1,aval);
224 switch(Z_TYPE_P(akey))
226 /* lua can't use (at least when i tried ;) ) floats as array keys so that should be safe */
227 case IS_DOUBLE:
228 add_index_zval(ret,(long)Z_DVAL_P(akey),aval);
229 break;
230 default:
231 add_assoc_zval(ret,Z_STRVAL_P(akey),aval);
232 break;
234 lua_pop(L, 1); /* removes `value'; keeps `key' for next iteration */
235 zval_ptr_dtor(&akey);
237 break;
240 case LUA_TFUNCTION:
241 /* TODO: Make this a PHP Function */
243 default:
244 php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid type `%i' passed from lua.", lua_type(L, index));
245 /* fall-through */
247 case LUA_TNIL:
248 ZVAL_NULL(ret);
249 break;
252 } /* }}} */
254 static int php_lua_print(lua_State *L) /* {{{ */
256 int i;
257 int n = lua_gettop(L);
259 for (i = 1; i <= n; i++) {
260 php_printf("%s", lua_tostring(L, i));
263 return 0;
264 } /* }}} */
266 static void php_lua_object_dtor(void *object, zend_object_handle handle TSRMLS_DC) /* {{{ */
268 php_lua_object *intern = (php_lua_object*)object;
269 zend_object_std_dtor(&(intern->std) TSRMLS_CC);
271 if (intern->L) {
272 lua_close(intern->L);
275 efree(intern);
276 } /* }}} */
278 static zval *php_lua_read_property(zval *obj, zval *prop, int type TSRMLS_DC) /* {{{ */
280 zval *retval;
281 lua_State *L = getLuaZ(obj);
283 LUA_STACK_START(L);
285 if (type != BP_VAR_R) {
286 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No write access using read_property.");
287 ALLOC_INIT_ZVAL(retval);
288 return retval;
291 if (Z_TYPE_P(prop) == IS_STRING) {
292 MAKE_STD_ZVAL(retval);
293 lua_getfield(L, LUA_GLOBALSINDEX, Z_STRVAL_P(prop) TSRMLS_CC);
294 php_lua_get_zval_from_stack(L, -1, retval TSRMLS_CC);
295 ZVAL_DELREF(retval);
296 } else {
297 ALLOC_INIT_ZVAL(retval);
300 lua_pop(L, 1);
302 LUA_STACK_END(L);
304 return retval;
305 } /* }}} */
308 static void php_lua_write_real_property(lua_State *L,int index,zval *prop, zval *value TSRMLS_DC) /* {{{ */
310 LUA_STACK_START(L);
311 php_lua_push_zval(L, prop TSRMLS_CC);
312 php_lua_push_zval(L, value TSRMLS_CC);
314 lua_settable(L, index);
315 LUA_STACK_END(L);
316 } /* }}} */
320 static void php_lua_write_property(zval *obj, zval *prop, zval *value TSRMLS_DC) /* {{{ */
322 /* TODO: Use proper type for lua and separate only when needed */
323 lua_State *L = getLuaZ(obj);
325 php_lua_write_real_property(L,LUA_GLOBALSINDEX,prop,value TSRMLS_CC);
326 } /* }}} */
328 static int php_lua_atpanic(lua_State *L) { /* {{{ */
329 TSRMLS_FETCH();
330 php_error_docref(NULL TSRMLS_CC, E_WARNING, "lua panic (%s)", lua_tostring(L, 1));
331 lua_pop(L, 1);
332 zend_bailout();
333 return 0;
334 } /* }}} */
336 static zend_object_value php_lua_create_object(zend_class_entry *ce TSRMLS_DC) /* {{{ */
338 zval tmp;
339 zend_object_value retval;
340 php_lua_object *intern;
341 lua_State *L;
343 L = lua_newstate(php_lua_alloc, NULL);
344 lua_atpanic(L, php_lua_atpanic);
346 intern = ecalloc(1, sizeof(php_lua_object));
347 intern->L = L;
348 zend_object_std_init(&(intern->std), ce TSRMLS_CC);
349 zend_hash_copy(intern->std.properties,
350 &ce->default_properties, (copy_ctor_func_t) zval_add_ref,
351 (void *) &tmp, sizeof(zval *));
353 retval.handle = zend_objects_store_put(intern, php_lua_object_dtor, NULL, NULL TSRMLS_CC);
354 retval.handlers = &lua_handlers;
355 return retval;
356 } /* }}} */
358 static int php_lua_callback(lua_State *L) /* {{{ */
360 int selected_callback_index=(int)lua_tonumber(L, lua_upvalueindex(1));
361 zval *return_value;
363 ALLOC_INIT_ZVAL(return_value);
365 if (!zend_is_callable(LUA_G(lua_callback)[selected_callback_index],0,NULL))
366 return;
368 zval **params;
369 int n = lua_gettop(L); /* number of arguments */
371 params=emalloc(n*sizeof(zval));
373 int i;
374 for (i = 1; i <= n; i++) {
375 ALLOC_INIT_ZVAL(params[i-1]);
376 /* php_lua_get_zval_from_stack won't work with positive indices */
377 php_lua_get_zval_from_stack(L,-n-1+i,params[i-1] TSRMLS_CC);
380 /* XXX no check - do we need one? :S */
381 /* johannes said i should use zend_call_method but this only allows up to 2 parameters?! */
382 call_user_function(EG(function_table),NULL,LUA_G(lua_callback)[selected_callback_index],return_value,n,params TSRMLS_CC);
384 /* hmm...what if the result is NULL? should php return a return value (NULL) then or just return 0? :S */
385 php_lua_push_zval(L,return_value TSRMLS_CC);
387 for (i = 0; i < n; i++) {
388 zval_ptr_dtor(&params[i]);
390 efree(params);
392 zval_ptr_dtor(&return_value);
394 /* PHP doesn't support multiple return values so this will always be 1 */
395 return 1;
396 } /* }}} */
398 static void php_lua_call_table_with_arguments(lua_State *L,int level,int table_index,char *function,int propagate_self,zval *args,zval *return_value) /* {{{ */
400 lua_getfield(L,table_index,function);
401 if (lua_type(L,lua_gettop(L)) != LUA_TFUNCTION) {
402 lua_pop(L, lua_gettop(L) - level);
403 php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid lua callback. '%s' is not a defined function",function);
404 return;
407 /* push the table on the stack as the first argument */
408 if (propagate_self)
409 lua_pushvalue(L,table_index + lua_gettop(L));
411 zend_hash_apply_with_argument(Z_ARRVAL_P(args), php_lua_push_apply_func, (void *)L TSRMLS_CC);
413 if (lua_pcall(L, zend_hash_num_elements(Z_ARRVAL_P(args)) + propagate_self, LUA_MULTRET, 0) != 0) {
414 php_error_docref(NULL TSRMLS_CC, E_WARNING, "error running lua function `%s': %s", function, lua_tostring(L, -1));
415 lua_pop(L, lua_gettop(L) - level);
416 return;
419 /* always return an array. otherwise we couldn't distinguish between a table return or a multi return */
420 array_init(return_value);
421 int retcount = lua_gettop(L) - level;
422 int i;
423 zval *val;
425 for (i = -retcount; i < 0; i++)
427 MAKE_STD_ZVAL(val);
428 php_lua_get_zval_from_stack(L, i, val TSRMLS_CC);
429 add_next_index_zval(return_value, val);
431 lua_pop(L, retcount);
433 return;
434 } /* }}} */
436 static void php_lua_call_table_function(INTERNAL_FUNCTION_PARAMETERS,int propagate_self) /* {{{ */
438 zval *callback,*args;
439 zval **lua_table,**lua_function;
440 int array_count,level;
441 lua_State *L;
443 L=getLua();
444 LUA_STACK_START(L);
446 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "za", &callback, &args) == FAILURE) {
447 return;
450 array_count=zend_hash_num_elements(Z_ARRVAL_P(callback));
451 if (array_count!=2) {
452 LUA_STACK_END(L);
453 php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid callback supplied. must contain exactly 2 elements");
454 return;
456 if (zend_hash_index_find(Z_ARRVAL_P(callback), 0, (void**)&lua_table) == FAILURE) {
457 php_error_docref(NULL TSRMLS_CC, E_WARNING, "callback index 0 is empty");
458 return;
460 if (zend_hash_index_find(Z_ARRVAL_P(callback), 1, (void**)&lua_function) == FAILURE) {
461 php_error_docref(NULL TSRMLS_CC, E_WARNING, "callback index 1 is empty");
462 return;
464 lua_getglobal(L,Z_STRVAL_PP(lua_table));
465 if (lua_type(L,lua_gettop(L)) != LUA_TTABLE) {
466 lua_pop(L, -1);
467 php_error_docref(NULL TSRMLS_CC, E_WARNING, "trying to call an invalid table '%s'",Z_STRVAL_PP(lua_table));
468 return;
470 level=lua_gettop(L);
472 php_lua_call_table_with_arguments(L,level,-1,Z_STRVAL_PP(lua_function),propagate_self,args,return_value);
474 /* remove the table which is still on top */
475 lua_pop(L,-1);
477 LUA_STACK_END(L);
478 } /* }}} */
480 /* {{{ */
481 static int php_lua_binary_zval_writer(lua_State* L, const void* p,size_t size, void* u)
483 Z_STRVAL_P((zval*)u)=erealloc(Z_STRVAL_P((zval*)u),(Z_STRLEN_P((zval*)u)+1+size)*sizeof(char));
484 memcpy(&Z_STRVAL_P((zval*)u)[Z_STRLEN_P((zval*)u)],p,size);
485 Z_STRLEN_P((zval*)u)=Z_STRLEN_P((zval*)u)+size;
486 Z_STRVAL_P((zval*)u)[Z_STRLEN_P((zval*)u)]='\0';
487 return 0;
489 /* }}} */
491 #define RETURN_STR "return %s"
494 /* {{{ lua::__construct()
495 Create new LUA instance */
496 PHP_METHOD(lua, __construct)
498 lua_State *L = getLua();
499 // mop: open standard libs if desired
500 if (lua_globals.load_standard_libs)
501 luaL_openlibs(L);
503 lua_register(L, "print", php_lua_print);
505 /* }}} */
507 /* {{{ lua::__call(string method, array args [, int nresults])
508 Call a lua function from within PHP */
509 PHP_METHOD(lua, __call)
511 int level, retcount;
512 char *function, *func;
513 long function_len;
514 zval *args;
515 int nresults = LUA_MULTRET;
516 lua_State *L = getLua();
518 LUA_STACK_START(L);
520 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|l", &function, &function_len, &args, &nresults) == FAILURE) {
521 return;
524 level = lua_gettop(L);
526 spprintf(&func, sizeof(RETURN_STR)-2-1+function_len, RETURN_STR, function);
527 if (luaL_dostring(L, func)) {
528 efree(func);
529 php_error_docref(NULL TSRMLS_CC, E_WARNING, "error looking up lua function `%s': %s", function, lua_tostring(L, -1));
530 lua_pop(L, lua_gettop(L) - level);
531 LUA_STACK_END(L);
532 return;
534 efree(func);
536 zend_hash_apply_with_argument(Z_ARRVAL_P(args), php_lua_push_apply_func, (void *)L TSRMLS_CC);
538 if (lua_pcall(L, zend_hash_num_elements(Z_ARRVAL_P(args)), nresults, 0) != 0) {
539 php_error_docref(NULL TSRMLS_CC, E_WARNING, "error running lua function `%s': %s", function, lua_tostring(L, -1));
540 lua_pop(L, lua_gettop(L) - level);
541 LUA_STACK_END(L);
542 return;
545 retcount = lua_gettop(L) - level;
547 if (retcount == 0) {
548 /* No vlaue returned -> return null */
549 } else {
550 /* multiple return values -> build an array */
551 int i;
552 zval *val;
554 array_init(return_value);
555 for (i = -retcount; i < 0; i++)
557 MAKE_STD_ZVAL(val);
558 php_lua_get_zval_from_stack(L, i, val TSRMLS_CC);
559 add_next_index_zval(return_value, val);
561 lua_pop(L, retcount);
564 LUA_STACK_END(L);
565 return;
568 /* {{{ lua::call_function(string function, array args)
569 Call a lua function from within PHP */
570 PHP_METHOD(lua, call_function)
572 char *function;
573 char *function_len;
574 zval *args;
575 lua_State *L;
576 int level;
578 L=getLua();
579 LUA_STACK_START(L);
581 level=lua_gettop(L);
583 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &function, &function_len, &args) == FAILURE) {
584 return;
587 php_lua_call_table_with_arguments(L,level,LUA_GLOBALSINDEX,function,0,args,return_value);
589 LUA_STACK_END(L);
592 /* {{{ lua::call_table(array lua_callback, array args)
593 Call a lua table from within PHP (lua_table.lua_function()) */
594 PHP_METHOD(lua, call_table)
596 php_lua_call_table_function(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
599 /* {{{ lua::call_table_self(array lua_callback, array args)
600 Call a lua table from within PHP and propagate self (lua_table:lua_function()) */
601 PHP_METHOD(lua, call_table_self)
603 php_lua_call_table_function(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
606 /* {{{ void lua::evaluate(string code)
607 Evaluates code with lua */
608 PHP_METHOD(lua, evaluate)
610 int error;
611 long code_len;
612 char *code;
613 lua_State *L = getLua();
615 LUA_STACK_START(L);
617 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &code, &code_len) == FAILURE) {
618 return;
621 error = luaL_loadbuffer(L, code, code_len, "line") || lua_pcall(L, 0, LUA_MULTRET, 0);
622 if (error) {
623 php_error_docref(NULL TSRMLS_CC, E_WARNING, "lua error: %s", lua_tostring(L, -1));
624 lua_pop(L, 1); /* pop error message from the stack */
627 /* always return an array. otherwise we couldn't distinguish between a table return or a multi return */
628 array_init(return_value);
629 int retcount = lua_gettop(L);
630 int i;
631 zval *val;
633 for (i = -retcount; i < 0; i++)
635 MAKE_STD_ZVAL(val);
636 php_lua_get_zval_from_stack(L, i, val TSRMLS_CC);
637 add_next_index_zval(return_value, val);
639 lua_pop(L, retcount);
641 LUA_STACK_END(L);
643 /* }}} */
645 /* {{{ void lua::evaluatefile(string file)
646 Evaluates a lua script */
647 PHP_METHOD(lua, evaluatefile)
649 int error;
650 long file_len;
651 char *file;
652 lua_State *L = getLua();
654 LUA_STACK_START(L);
656 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_len) == FAILURE) {
657 return;
660 if (php_check_open_basedir(file TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(file, "rb+", CHECKUID_CHECK_MODE_PARAM))) {
661 LUA_STACK_END(L);
662 RETURN_FALSE;
665 error = luaL_dofile(L, file);
667 if (error) {
668 php_error_docref(NULL TSRMLS_CC, E_WARNING, "lua error: %s", lua_tostring(L, -1));
669 lua_pop(L, 1);
672 array_init(return_value);
673 int retcount = lua_gettop(L);
674 int i;
675 zval *val;
677 for (i = -retcount; i < 0; i++)
679 MAKE_STD_ZVAL(val);
680 php_lua_get_zval_from_stack(L, i, val TSRMLS_CC);
681 add_next_index_zval(return_value, val);
683 lua_pop(L, retcount);
685 LUA_STACK_END(L);
687 /* }}} */
689 /* {{{ string lua::getVersion()
690 Return Lua's version */
691 PHP_METHOD(lua, getversion)
693 RETURN_STRING(LUA_RELEASE, 1);
695 /* }}} */
697 /* {{{ */
698 PHP_METHOD(lua,expose_function)
700 zval *callback;
701 char *lua_name;
702 long len;
704 lua_State *L = getLua();
706 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"sz",&lua_name,&len,&callback) == FAILURE)
707 return;
709 if (zend_is_callable(callback,0,NULL)) {
710 lua_pushnumber(L,LUA_G(lua_callback_count));
711 lua_pushcclosure(L, php_lua_callback,1);
712 lua_setglobal(L, lua_name);
714 /* hmm...out of memory check? */
715 LUA_G(lua_callback)=erealloc(LUA_G(lua_callback),sizeof(zval)*(LUA_G(lua_callback_count)+1));
717 ALLOC_INIT_ZVAL(LUA_G(lua_callback)[LUA_G(lua_callback_count)]);
718 *LUA_G(lua_callback)[LUA_G(lua_callback_count)] = *callback;
719 zval_copy_ctor(LUA_G(lua_callback)[LUA_G(lua_callback_count)]);
721 LUA_G(lua_callback_count)++;
723 /* }}} */
725 /* {{{ */
726 PHP_METHOD(lua,compile)
728 char *chunk;
729 long len;
730 int error;
732 lua_State *L = lua_newstate(php_lua_alloc, NULL);
733 lua_atpanic(L, php_lua_atpanic);
735 LUA_STACK_START(L);
737 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"s",&chunk,&len) == FAILURE)
739 lua_close(L);
740 return;
743 error = luaL_loadbuffer(L, chunk, len, "line");
744 if (error) {
745 php_error_docref(NULL TSRMLS_CC, E_WARNING, "lua error: %s", lua_tostring(L, -1));
746 lua_pop(L, 1); /* pop error message from the stack */
747 lua_close(L);
748 return;
751 RETVAL_STRING("",1);
753 error=lua_dump(L,php_lua_binary_zval_writer,return_value);
754 lua_pop(L, 1); /* clean stack */
755 LUA_STACK_END(L);
756 lua_close(L);
757 if (error) {
758 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't dump code");
759 RETURN_NULL();
763 /* {{{ lua_functions[] */
764 zend_function_entry lua_functions[] = {
765 {NULL, NULL, NULL}
767 /* }}} */
769 /* {{{ ARG_INFO */
771 ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_call, 0, 0, 2)
772 ZEND_ARG_INFO(0, method)
773 ZEND_ARG_INFO(0, args)
774 ZEND_END_ARG_INFO()
776 ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_call_table, 0, 0, 2)
777 ZEND_ARG_INFO(0, callback)
778 ZEND_ARG_INFO(0, args)
779 ZEND_END_ARG_INFO()
781 ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_call_function, 0, 0, 2)
782 ZEND_ARG_INFO(0, function)
783 ZEND_ARG_INFO(0, args)
784 ZEND_END_ARG_INFO()
786 ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_evaluate, 0, 0, 1)
787 ZEND_ARG_INFO(0, code)
788 ZEND_END_ARG_INFO()
790 ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_evaluatefile, 0, 0, 1)
791 ZEND_ARG_INFO(0, file)
792 ZEND_END_ARG_INFO()
794 ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_expose_function, 0, 0, 1)
795 ZEND_ARG_INFO(0, callback)
796 ZEND_END_ARG_INFO()
798 ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_compile, 0, 0, 1)
799 ZEND_ARG_INFO(0, chunk)
800 ZEND_END_ARG_INFO()
802 /* }}} */
804 /* {{{ lua_class_functions[] */
805 zend_function_entry lua_class_functions[] = {
806 PHP_ME(lua, __construct, NULL, ZEND_ACC_PUBLIC)
807 PHP_ME(lua, __call, arginfo_lua_call, ZEND_ACC_PUBLIC)
808 PHP_ME(lua, call_function, arginfo_lua_call_function, ZEND_ACC_PUBLIC)
809 PHP_ME(lua, call_table, arginfo_lua_call_table, ZEND_ACC_PUBLIC)
810 PHP_ME(lua, call_table_self, arginfo_lua_call_table, ZEND_ACC_PUBLIC)
811 PHP_ME(lua, evaluate, arginfo_lua_evaluate, ZEND_ACC_PUBLIC)
812 PHP_ME(lua, evaluatefile, arginfo_lua_evaluatefile, ZEND_ACC_PUBLIC)
813 PHP_ME(lua, getversion, NULL, ZEND_ACC_PUBLIC)
814 PHP_ME(lua, expose_function, arginfo_lua_expose_function, ZEND_ACC_PUBLIC)
815 PHP_ME(lua, compile, arginfo_lua_compile, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
816 {NULL, NULL, NULL}
818 /* }}} */
820 #ifdef COMPILE_DL_LUA
821 ZEND_GET_MODULE(lua)
822 #endif
824 /* {{{ PHP_INI
826 PHP_INI_BEGIN()
827 STD_PHP_INI_BOOLEAN("lua.load_standard_libs","1", PHP_INI_ALL, OnUpdateBool, load_standard_libs, zend_lua_globals, lua_globals)
828 PHP_INI_END()
829 /* }}} */
831 /* {{{ php_lua_init_globals
833 static void php_lua_init_globals(zend_lua_globals *lua_globals)
836 /* }}} */
838 /* {{{ PHP_MINIT_FUNCTION
840 PHP_MINIT_FUNCTION(lua)
842 REGISTER_INI_ENTRIES();
844 zend_class_entry ce;
845 INIT_CLASS_ENTRY(ce, "lua", lua_class_functions);
846 lua_ce = zend_register_internal_class(&ce TSRMLS_CC);
847 lua_ce->create_object = php_lua_create_object;
848 memcpy(&lua_handlers, zend_get_std_object_handlers(),
849 sizeof(zend_object_handlers));
850 lua_handlers.write_property = php_lua_write_property;
851 lua_handlers.read_property = php_lua_read_property;
852 lua_ce->ce_flags |= ZEND_ACC_FINAL;
854 zend_declare_class_constant_long(lua_ce, "MULTRET", sizeof("MULTRET")-1, LUA_MULTRET TSRMLS_CC);
856 ZEND_INIT_MODULE_GLOBALS(lua, php_lua_init_globals, NULL);
858 return SUCCESS;
860 /* }}} */
862 /* {{{ PHP_MSHUTDOWN_FUNCTION
864 PHP_MSHUTDOWN_FUNCTION(lua)
866 UNREGISTER_INI_ENTRIES();
867 return SUCCESS;
869 /* }}} */
871 /* {{{ PHP_RINIT_FUNCTION
873 PHP_RINIT_FUNCTION(lua)
875 LUA_G(lua_callback_count)=0;
876 LUA_G(lua_callback)=emalloc(sizeof(zval*));
877 return SUCCESS;
879 /* }}} */
881 /* {{{ PHP_RSHUTDOWN_FUNCTION
883 PHP_RSHUTDOWN_FUNCTION(lua)
885 long i;
886 for (i=0;i<LUA_G(lua_callback_count);i++)
887 efree(LUA_G(lua_callback)[i]);
888 efree(LUA_G(lua_callback));
889 return SUCCESS;
891 /* }}} */
893 /* {{{ PHP_MINFO_FUNCTION
895 PHP_MINFO_FUNCTION(lua)
897 php_info_print_table_start();
898 php_info_print_table_row(2, "lua support", "enabled");
899 php_info_print_table_row(2, "lua extension version", EXT_LUA_VERSION);
900 php_info_print_table_row(2, "lua release", LUA_RELEASE);
901 php_info_print_table_row(2, "lua copyright", LUA_COPYRIGHT);
902 php_info_print_table_row(2, "lua authors", LUA_AUTHORS);
903 php_info_print_table_end();
905 DISPLAY_INI_ENTRIES();
907 /* }}} */
909 /* {{{ lua_module_entry
911 zend_module_entry lua_module_entry = {
912 STANDARD_MODULE_HEADER,
913 "lua",
914 lua_functions,
915 PHP_MINIT(lua),
916 PHP_MSHUTDOWN(lua),
917 PHP_RINIT(lua),
918 PHP_RSHUTDOWN(lua),
919 PHP_MINFO(lua),
920 EXT_LUA_VERSION,
921 STANDARD_MODULE_PROPERTIES
923 /* }}} */
926 * Local variables:
927 * tab-width: 4
928 * c-basic-offset: 4
929 * vim: set noet sw=4 ts=4:
930 * vim600: noet sw=4 ts=4 fdm=marker:
931 * End: