Argh...Version ID was messy
[phplua.git] / lua.c
blob5e08c2e23fe583a5fb02057b79645a3ef6ca4a26
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 getLuaY() ((php_lua_object*)zend_object_store_get_object(getThis() TSRMLS_CC))
55 #define getLua() getLuaZ(getThis())
57 static zend_object_handlers lua_handlers;
58 static zend_class_entry *lua_ce;
60 typedef struct _php_lua_object {
61 zend_object std;
62 lua_State *L;
63 zval* callbacks;
64 long callback_count;
65 } php_lua_object;
67 static const luaL_Reg php_lualibs[] = {
68 {"base", luaopen_base},
69 {LUA_LOADLIBNAME, luaopen_package},
70 {LUA_TABLIBNAME, luaopen_table},
71 {LUA_IOLIBNAME, luaopen_io},
72 {LUA_OSLIBNAME, luaopen_os},
73 {LUA_STRLIBNAME, luaopen_string},
74 {LUA_MATHLIBNAME, luaopen_math},
75 {LUA_DBLIBNAME, luaopen_debug},
76 {NULL, NULL}
79 static void php_lua_push_zval(lua_State *L, zval *val_p TSRMLS_DC);
80 static void php_lua_write_real_property(lua_State *L,int index,zval *prop, zval *value TSRMLS_DC);
82 static void *php_lua_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { /* {{{ */
83 if (nsize == 0) {
84 if (ptr) {
85 efree(ptr);
87 return NULL;
88 } else {
89 if (ptr) {
90 return erealloc(ptr, nsize);
91 } else {
92 return emalloc(nsize);
95 } /* }}} */
98 static void php_lua_push_array(lua_State *L, zval *array TSRMLS_DC) /* {{{ */
100 zval **data;
101 HashTable *arr_hash;
102 HashPosition pointer;
103 int array_count;
104 char *key;
105 int key_len;
106 long index;
107 int hash_key;
108 char *key_copy;
110 zval *zkey;
112 arr_hash = Z_ARRVAL_P(array);
113 array_count = zend_hash_num_elements(arr_hash);
115 lua_newtable(L);
117 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))
119 hash_key=zend_hash_get_current_key_ex(arr_hash, &key, &key_len, &index, 0, &pointer);
121 if (hash_key == HASH_KEY_IS_LONG && index == 0) {
122 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Trying to push array index %ld to lua which is unsupported in lua. Element has been discarded",index);
124 else {
125 ALLOC_INIT_ZVAL(zkey);
126 if (hash_key == HASH_KEY_IS_STRING) {
127 key_copy=estrndup(key,key_len-1);
128 Z_TYPE_P(zkey)=IS_STRING;
129 Z_STRVAL_P(zkey)=key_copy;
130 Z_STRLEN_P(zkey)=key_len-1;
132 else {
133 Z_TYPE_P(zkey)=IS_LONG;
134 Z_LVAL_P(zkey)=index;
137 php_lua_write_real_property(L,-3,zkey,*data TSRMLS_CC);
138 zval_ptr_dtor(&zkey);
141 } /* }}} */
146 static void php_lua_push_zval(lua_State *L, zval *val_p TSRMLS_DC) /* {{{ */
148 /* TODO: Use proper type for lua and separate only when needed */
150 /* push into lua stack properly */
151 switch (Z_TYPE_P(val_p)) {
152 case IS_STRING:
153 lua_pushlstring(L, Z_STRVAL_P(val_p), Z_STRLEN_P(val_p));
154 break;
156 case IS_NULL:
157 lua_pushnil(L);
158 break;
160 case IS_DOUBLE:
161 lua_pushnumber(L, Z_DVAL_P(val_p));
162 break;
164 case IS_LONG:
165 lua_pushnumber(L, Z_LVAL_P(val_p));
166 break;
168 case IS_BOOL:
169 lua_pushboolean(L, Z_BVAL_P(val_p));
170 break;
172 case IS_ARRAY:
173 php_lua_push_array(L,val_p TSRMLS_CC);
174 break;
176 default:
177 php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid type `%s' supported in lua", zend_zval_type_name(val_p));
178 lua_pushnil(L);
179 break;
182 } /* }}} */
184 static int php_lua_push_apply_func(void *pDest, void *argument TSRMLS_DC) /* {{{ */
186 php_lua_push_zval((lua_State*)argument, *(zval**)pDest TSRMLS_CC);
187 return ZEND_HASH_APPLY_KEEP;
188 } /* }}} */
190 static void php_lua_get_zval_from_stack(lua_State *L, int index, zval *ret TSRMLS_DC) /* {{{ */
192 const char *value;
193 size_t value_len;
195 switch (lua_type(L, index)) {
196 case LUA_TBOOLEAN:
197 ZVAL_BOOL(ret, lua_toboolean(L, index));
198 break;
200 case LUA_TNUMBER:
201 ZVAL_DOUBLE(ret, lua_tonumber(L, index));
202 break;
204 case LUA_TSTRING:
205 value = lua_tolstring(L, index, &value_len);
206 ZVAL_STRINGL(ret, (char*)value, value_len, 1);
207 break;
209 case LUA_TTABLE:
210 array_init(ret);
211 /* notify lua to traverse the table */
212 lua_pushnil(L);
214 zval *akey,*aval;
216 /* table has been moved by one because of the pushnil */
217 /* this will ONLY work with negative indices! */
218 while (lua_next(L, index-1) != 0)
220 ALLOC_INIT_ZVAL(akey);
221 ALLOC_INIT_ZVAL(aval);
223 /* `key' is at index -2 and `value' at index -1 */
224 php_lua_get_zval_from_stack(L,-2,akey);
225 php_lua_get_zval_from_stack(L,-1,aval);
227 switch(Z_TYPE_P(akey))
229 /* lua can't use (at least when i tried ;) ) floats as array keys so that should be safe */
230 case IS_DOUBLE:
231 add_index_zval(ret,(long)Z_DVAL_P(akey),aval);
232 break;
233 default:
234 add_assoc_zval(ret,Z_STRVAL_P(akey),aval);
235 break;
237 lua_pop(L, 1); /* removes `value'; keeps `key' for next iteration */
238 zval_ptr_dtor(&akey);
240 break;
243 case LUA_TFUNCTION:
244 /* TODO: Make this a PHP Function */
246 default:
247 php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid type `%i' passed from lua.", lua_type(L, index));
248 /* fall-through */
250 case LUA_TNIL:
251 ZVAL_NULL(ret);
252 break;
255 } /* }}} */
257 static int php_lua_print(lua_State *L) /* {{{ */
259 int i;
260 int n = lua_gettop(L);
262 for (i = 1; i <= n; i++) {
263 php_printf("%s", lua_tostring(L, i));
266 return 0;
267 } /* }}} */
269 static void php_lua_object_dtor(void *object, zend_object_handle handle TSRMLS_DC) /* {{{ */
271 php_lua_object *intern = (php_lua_object*)object;
272 zend_object_std_dtor(&(intern->std) TSRMLS_CC);
274 long i;
275 for (i=0;i<intern->callback_count;i++)
276 zval_dtor(&intern->callbacks[i]);
277 efree(intern->callbacks);
278 if (intern->L) {
279 lua_close(intern->L);
282 efree(intern);
283 } /* }}} */
285 static zval *php_lua_read_property(zval *obj, zval *prop, int type TSRMLS_DC) /* {{{ */
287 zval *retval;
288 lua_State *L = getLuaZ(obj);
290 LUA_STACK_START(L);
292 if (type != BP_VAR_R) {
293 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No write access using read_property.");
294 ALLOC_INIT_ZVAL(retval);
295 return retval;
298 if (Z_TYPE_P(prop) == IS_STRING) {
299 MAKE_STD_ZVAL(retval);
300 lua_getfield(L, LUA_GLOBALSINDEX, Z_STRVAL_P(prop) TSRMLS_CC);
301 php_lua_get_zval_from_stack(L, -1, retval TSRMLS_CC);
302 #if PHP_VERSION_ID>=50300
303 Z_DELREF_P(retval);
304 #else
305 retval->refcount--;
306 #endif
307 } else {
308 ALLOC_INIT_ZVAL(retval);
311 lua_pop(L, 1);
313 LUA_STACK_END(L);
315 return retval;
316 } /* }}} */
319 static void php_lua_write_real_property(lua_State *L,int index,zval *prop, zval *value TSRMLS_DC) /* {{{ */
321 LUA_STACK_START(L);
322 php_lua_push_zval(L, prop TSRMLS_CC);
323 php_lua_push_zval(L, value TSRMLS_CC);
325 lua_settable(L, index);
326 LUA_STACK_END(L);
327 } /* }}} */
331 static void php_lua_write_property(zval *obj, zval *prop, zval *value TSRMLS_DC) /* {{{ */
333 /* TODO: Use proper type for lua and separate only when needed */
334 lua_State *L = getLuaZ(obj);
336 php_lua_write_real_property(L,LUA_GLOBALSINDEX,prop,value TSRMLS_CC);
337 } /* }}} */
339 static int php_lua_atpanic(lua_State *L) { /* {{{ */
340 TSRMLS_FETCH();
341 php_error_docref(NULL TSRMLS_CC, E_WARNING, "lua panic (%s)", lua_tostring(L, 1));
342 lua_pop(L, 1);
343 zend_bailout();
344 return 0;
345 } /* }}} */
347 static zend_object_value php_lua_create_object(zend_class_entry *ce TSRMLS_DC) /* {{{ */
349 zval tmp;
350 zend_object_value retval;
351 php_lua_object *intern;
352 lua_State *L;
354 L = lua_newstate(php_lua_alloc, NULL);
355 lua_atpanic(L, php_lua_atpanic);
357 intern = ecalloc(1, sizeof(php_lua_object));
358 intern->L = L;
359 intern->callback_count=0;
360 intern->callbacks=emalloc(sizeof(zval*));
361 zend_object_std_init(&(intern->std), ce TSRMLS_CC);
362 zend_hash_copy(intern->std.properties,
363 &ce->default_properties, (copy_ctor_func_t) zval_add_ref,
364 (void *) &tmp, sizeof(zval *));
366 retval.handle = zend_objects_store_put(intern, php_lua_object_dtor, NULL, NULL TSRMLS_CC);
367 retval.handlers = &lua_handlers;
368 return retval;
369 } /* }}} */
371 static int php_lua_callback(lua_State *L) /* {{{ */
373 php_lua_object *object=(php_lua_object*)lua_topointer(L, lua_upvalueindex(1));
374 long selected_callback_index=(long)lua_tonumber(L, lua_upvalueindex(2));
375 zval *return_value;
377 ALLOC_INIT_ZVAL(return_value);
379 if (!zend_is_callable(&object->callbacks[selected_callback_index],0,NULL))
380 return;
382 zval **params;
383 int n = lua_gettop(L); /* number of arguments */
385 params=emalloc(n*sizeof(zval));
387 int i;
388 for (i = 1; i <= n; i++) {
389 ALLOC_INIT_ZVAL(params[i-1]);
390 /* php_lua_get_zval_from_stack won't work with positive indices */
391 php_lua_get_zval_from_stack(L,-n-1+i,params[i-1] TSRMLS_CC);
394 /* XXX no check - do we need one? :S */
395 /* johannes said i should use zend_call_method but this only allows up to 2 parameters?! */
396 call_user_function(EG(function_table),NULL,&object->callbacks[selected_callback_index],return_value,n,params TSRMLS_CC);
398 /* hmm...what if the result is NULL? should php return a return value (NULL) then or just return 0? :S */
399 php_lua_push_zval(L,return_value TSRMLS_CC);
401 for (i = 0; i < n; i++) {
402 zval_ptr_dtor(&params[i]);
404 efree(params);
406 zval_ptr_dtor(&return_value);
408 /* PHP doesn't support multiple return values so this will always be 1 */
409 return 1;
410 } /* }}} */
412 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) /* {{{ */
414 lua_getfield(L,table_index,function);
415 if (lua_type(L,lua_gettop(L)) != LUA_TFUNCTION) {
416 lua_pop(L, lua_gettop(L) - level);
417 php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid lua callback. '%s' is not a defined function",function);
418 return;
421 /* push the table on the stack as the first argument */
422 if (propagate_self)
423 lua_pushvalue(L,table_index + lua_gettop(L));
425 zend_hash_apply_with_argument(Z_ARRVAL_P(args), php_lua_push_apply_func, (void *)L TSRMLS_CC);
427 if (lua_pcall(L, zend_hash_num_elements(Z_ARRVAL_P(args)) + propagate_self, LUA_MULTRET, 0) != 0) {
428 php_error_docref(NULL TSRMLS_CC, E_WARNING, "error running lua function `%s': %s", function, lua_tostring(L, -1));
429 lua_pop(L, lua_gettop(L) - level);
430 return;
433 /* always return an array. otherwise we couldn't distinguish between a table return or a multi return */
434 array_init(return_value);
435 int retcount = lua_gettop(L) - level;
436 int i;
437 zval *val;
439 for (i = -retcount; i < 0; i++)
441 MAKE_STD_ZVAL(val);
442 php_lua_get_zval_from_stack(L, i, val TSRMLS_CC);
443 add_next_index_zval(return_value, val);
445 lua_pop(L, retcount);
447 return;
448 } /* }}} */
450 static void php_lua_call_table_function(INTERNAL_FUNCTION_PARAMETERS,int propagate_self) /* {{{ */
452 zval *callback,*args;
453 zval **lua_table,**lua_function;
454 int array_count,level;
455 lua_State *L;
457 L=getLua();
458 LUA_STACK_START(L);
460 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "za", &callback, &args) == FAILURE) {
461 return;
464 array_count=zend_hash_num_elements(Z_ARRVAL_P(callback));
465 if (array_count!=2) {
466 LUA_STACK_END(L);
467 php_error_docref(NULL TSRMLS_CC, E_WARNING, "invalid callback supplied. must contain exactly 2 elements");
468 return;
470 if (zend_hash_index_find(Z_ARRVAL_P(callback), 0, (void**)&lua_table) == FAILURE) {
471 php_error_docref(NULL TSRMLS_CC, E_WARNING, "callback index 0 is empty");
472 return;
474 if (zend_hash_index_find(Z_ARRVAL_P(callback), 1, (void**)&lua_function) == FAILURE) {
475 php_error_docref(NULL TSRMLS_CC, E_WARNING, "callback index 1 is empty");
476 return;
478 lua_getglobal(L,Z_STRVAL_PP(lua_table));
479 if (lua_type(L,lua_gettop(L)) != LUA_TTABLE) {
480 lua_pop(L, -1);
481 php_error_docref(NULL TSRMLS_CC, E_WARNING, "trying to call an invalid table '%s'",Z_STRVAL_PP(lua_table));
482 return;
484 level=lua_gettop(L);
486 php_lua_call_table_with_arguments(L,level,-1,Z_STRVAL_PP(lua_function),propagate_self,args,return_value);
488 /* remove the table which is still on top */
489 lua_pop(L,-1);
491 LUA_STACK_END(L);
492 } /* }}} */
494 /* {{{ */
495 static int php_lua_binary_zval_writer(lua_State* L, const void* p,size_t size, void* u)
497 Z_STRVAL_P((zval*)u)=erealloc(Z_STRVAL_P((zval*)u),(Z_STRLEN_P((zval*)u)+1+size)*sizeof(char));
498 memcpy(&Z_STRVAL_P((zval*)u)[Z_STRLEN_P((zval*)u)],p,size);
499 Z_STRLEN_P((zval*)u)=Z_STRLEN_P((zval*)u)+size;
500 Z_STRVAL_P((zval*)u)[Z_STRLEN_P((zval*)u)]='\0';
501 return 0;
503 /* }}} */
505 #define RETURN_STR "return %s"
508 /* {{{ lua::__construct()
509 Create new LUA instance */
510 PHP_METHOD(lua, __construct)
512 lua_State *L = getLua();
513 // mop: open standard libs if desired
514 if (lua_globals.load_standard_libs)
515 luaL_openlibs(L);
517 lua_register(L, "print", php_lua_print);
519 /* }}} */
521 /* {{{ lua::__call(string method, array args [, int nresults])
522 Call a lua function from within PHP */
523 PHP_METHOD(lua, __call)
525 int level, retcount;
526 char *function, *func;
527 int function_len;
528 zval *args;
529 long nresults = LUA_MULTRET;
530 lua_State *L = getLua();
532 LUA_STACK_START(L);
534 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa|l", &function, &function_len, &args, &nresults) == FAILURE) {
535 return;
538 level = lua_gettop(L);
540 spprintf(&func, sizeof(RETURN_STR)-2-1+function_len, RETURN_STR, function);
541 if (luaL_dostring(L, func)) {
542 efree(func);
543 php_error_docref(NULL TSRMLS_CC, E_WARNING, "error looking up lua function `%s': %s", function, lua_tostring(L, -1));
544 lua_pop(L, lua_gettop(L) - level);
545 LUA_STACK_END(L);
546 return;
548 efree(func);
550 zend_hash_apply_with_argument(Z_ARRVAL_P(args), php_lua_push_apply_func, (void *)L TSRMLS_CC);
552 if (lua_pcall(L, zend_hash_num_elements(Z_ARRVAL_P(args)), nresults, 0) != 0) {
553 php_error_docref(NULL TSRMLS_CC, E_WARNING, "error running lua function `%s': %s", function, lua_tostring(L, -1));
554 lua_pop(L, lua_gettop(L) - level);
555 LUA_STACK_END(L);
556 return;
559 retcount = lua_gettop(L) - level;
561 if (retcount == 0) {
562 /* No vlaue returned -> return null */
563 } else {
564 /* multiple return values -> build an array */
565 int i;
566 zval *val;
568 array_init(return_value);
569 for (i = -retcount; i < 0; i++)
571 MAKE_STD_ZVAL(val);
572 php_lua_get_zval_from_stack(L, i, val TSRMLS_CC);
573 add_next_index_zval(return_value, val);
575 lua_pop(L, retcount);
578 LUA_STACK_END(L);
579 return;
582 /* {{{ lua::call_function(string function, array args)
583 Call a lua function from within PHP */
584 PHP_METHOD(lua, call_function)
586 char *function;
587 int function_len;
588 zval *args;
589 lua_State *L;
590 int level;
592 L=getLua();
593 LUA_STACK_START(L);
595 level=lua_gettop(L);
597 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &function, &function_len, &args) == FAILURE) {
598 return;
601 php_lua_call_table_with_arguments(L,level,LUA_GLOBALSINDEX,function,0,args,return_value);
603 LUA_STACK_END(L);
606 /* {{{ lua::call_table(array lua_callback, array args)
607 Call a lua table from within PHP (lua_table.lua_function()) */
608 PHP_METHOD(lua, call_table)
610 php_lua_call_table_function(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
613 /* {{{ lua::call_table_self(array lua_callback, array args)
614 Call a lua table from within PHP and propagate self (lua_table:lua_function()) */
615 PHP_METHOD(lua, call_table_self)
617 php_lua_call_table_function(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
620 /* {{{ void lua::evaluate(string code)
621 Evaluates code with lua */
622 PHP_METHOD(lua, evaluate)
624 int error;
625 int code_len;
626 char *code;
627 lua_State *L = getLua();
629 LUA_STACK_START(L);
631 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &code, &code_len) == FAILURE) {
632 return;
635 error = luaL_loadbuffer(L, code, code_len, "line") || lua_pcall(L, 0, LUA_MULTRET, 0);
636 if (error) {
637 php_error_docref(NULL TSRMLS_CC, E_WARNING, "lua error: %s", lua_tostring(L, -1));
638 lua_pop(L, 1); /* pop error message from the stack */
641 /* always return an array. otherwise we couldn't distinguish between a table return or a multi return */
642 array_init(return_value);
643 int retcount = lua_gettop(L);
644 int i;
645 zval *val;
647 for (i = -retcount; i < 0; i++)
649 MAKE_STD_ZVAL(val);
650 php_lua_get_zval_from_stack(L, i, val TSRMLS_CC);
651 add_next_index_zval(return_value, val);
653 lua_pop(L, retcount);
655 LUA_STACK_END(L);
657 /* }}} */
659 /* {{{ void lua::evaluatefile(string file)
660 Evaluates a lua script */
661 PHP_METHOD(lua, evaluatefile)
663 int error;
664 int file_len;
665 char *file;
666 lua_State *L = getLua();
668 LUA_STACK_START(L);
670 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_len) == FAILURE) {
671 return;
674 if (php_check_open_basedir(file TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(file, "rb+", CHECKUID_CHECK_MODE_PARAM))) {
675 LUA_STACK_END(L);
676 RETURN_FALSE;
679 error = luaL_dofile(L, file);
681 if (error) {
682 php_error_docref(NULL TSRMLS_CC, E_WARNING, "lua error: %s", lua_tostring(L, -1));
683 lua_pop(L, 1);
686 array_init(return_value);
687 int retcount = lua_gettop(L);
688 int i;
689 zval *val;
691 for (i = -retcount; i < 0; i++)
693 MAKE_STD_ZVAL(val);
694 php_lua_get_zval_from_stack(L, i, val TSRMLS_CC);
695 add_next_index_zval(return_value, val);
697 lua_pop(L, retcount);
699 LUA_STACK_END(L);
701 /* }}} */
703 /* {{{ string lua::getVersion()
704 Return Lua's version */
705 PHP_METHOD(lua, getversion)
707 RETURN_STRING(LUA_RELEASE, 1);
709 /* }}} */
711 /* {{{ */
712 PHP_METHOD(lua,expose_function)
714 zval *callback;
715 char *lua_name;
716 int len;
718 php_lua_object *object=getLuaY();
719 lua_State *L = object->L;
721 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"sz",&lua_name,&len,&callback) == FAILURE)
722 return;
724 if (zend_is_callable(callback,0,NULL)) {
725 lua_pushlightuserdata(L,object);
726 lua_pushnumber(L,object->callback_count);
727 lua_pushcclosure(L, php_lua_callback,2);
728 lua_setglobal(L, lua_name);
730 /* hmm...out of memory check? */
731 object->callbacks=erealloc(object->callbacks,sizeof(zval)*(object->callback_count+1));
732 object->callbacks[object->callback_count] = *callback;
733 zval_copy_ctor(&object->callbacks[object->callback_count]);
734 object->callback_count++;
736 /* }}} */
738 /* {{{ */
739 PHP_METHOD(lua,compile)
741 char *chunk;
742 int len;
743 int error;
745 lua_State *L = lua_newstate(php_lua_alloc, NULL);
746 lua_atpanic(L, php_lua_atpanic);
748 LUA_STACK_START(L);
750 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"s",&chunk,&len) == FAILURE)
752 lua_close(L);
753 return;
756 error = luaL_loadbuffer(L, chunk, len, "line");
757 if (error) {
758 php_error_docref(NULL TSRMLS_CC, E_WARNING, "lua error: %s", lua_tostring(L, -1));
759 lua_pop(L, 1); /* pop error message from the stack */
760 lua_close(L);
761 return;
764 RETVAL_STRING("",1);
766 error=lua_dump(L,php_lua_binary_zval_writer,return_value);
767 lua_pop(L, 1); /* clean stack */
768 LUA_STACK_END(L);
769 lua_close(L);
770 if (error) {
771 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't dump code");
772 RETURN_NULL();
776 /* {{{ lua_functions[] */
777 zend_function_entry lua_functions[] = {
778 {NULL, NULL, NULL}
780 /* }}} */
782 /* {{{ ARG_INFO */
784 ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_call, 0, 0, 2)
785 ZEND_ARG_INFO(0, method)
786 ZEND_ARG_INFO(0, args)
787 ZEND_END_ARG_INFO()
789 ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_call_table, 0, 0, 2)
790 ZEND_ARG_INFO(0, callback)
791 ZEND_ARG_INFO(0, args)
792 ZEND_END_ARG_INFO()
794 ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_call_function, 0, 0, 2)
795 ZEND_ARG_INFO(0, function)
796 ZEND_ARG_INFO(0, args)
797 ZEND_END_ARG_INFO()
799 ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_evaluate, 0, 0, 1)
800 ZEND_ARG_INFO(0, code)
801 ZEND_END_ARG_INFO()
803 ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_evaluatefile, 0, 0, 1)
804 ZEND_ARG_INFO(0, file)
805 ZEND_END_ARG_INFO()
807 ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_expose_function, 0, 0, 1)
808 ZEND_ARG_INFO(0, callback)
809 ZEND_END_ARG_INFO()
811 ZEND_BEGIN_ARG_INFO_EX(arginfo_lua_compile, 0, 0, 1)
812 ZEND_ARG_INFO(0, chunk)
813 ZEND_END_ARG_INFO()
815 /* }}} */
817 /* {{{ lua_class_functions[] */
818 zend_function_entry lua_class_functions[] = {
819 PHP_ME(lua, __construct, NULL, ZEND_ACC_PUBLIC)
820 PHP_ME(lua, __call, arginfo_lua_call, ZEND_ACC_PUBLIC)
821 PHP_ME(lua, call_function, arginfo_lua_call_function, ZEND_ACC_PUBLIC)
822 PHP_ME(lua, call_table, arginfo_lua_call_table, ZEND_ACC_PUBLIC)
823 PHP_ME(lua, call_table_self, arginfo_lua_call_table, ZEND_ACC_PUBLIC)
824 PHP_ME(lua, evaluate, arginfo_lua_evaluate, ZEND_ACC_PUBLIC)
825 PHP_ME(lua, evaluatefile, arginfo_lua_evaluatefile, ZEND_ACC_PUBLIC)
826 PHP_ME(lua, getversion, NULL, ZEND_ACC_PUBLIC)
827 PHP_ME(lua, expose_function, arginfo_lua_expose_function, ZEND_ACC_PUBLIC)
828 PHP_ME(lua, compile, arginfo_lua_compile, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
829 {NULL, NULL, NULL}
831 /* }}} */
833 #ifdef COMPILE_DL_LUA
834 ZEND_GET_MODULE(lua)
835 #endif
837 /* {{{ PHP_INI
839 PHP_INI_BEGIN()
840 STD_PHP_INI_BOOLEAN("lua.load_standard_libs","1", PHP_INI_ALL, OnUpdateBool, load_standard_libs, zend_lua_globals, lua_globals)
841 PHP_INI_END()
842 /* }}} */
844 /* {{{ php_lua_init_globals
846 static void php_lua_init_globals(zend_lua_globals *lua_globals)
849 /* }}} */
851 /* {{{ PHP_MINIT_FUNCTION
853 PHP_MINIT_FUNCTION(lua)
855 REGISTER_INI_ENTRIES();
857 zend_class_entry ce;
858 INIT_CLASS_ENTRY(ce, "lua", lua_class_functions);
859 lua_ce = zend_register_internal_class(&ce TSRMLS_CC);
860 lua_ce->create_object = php_lua_create_object;
861 memcpy(&lua_handlers, zend_get_std_object_handlers(),
862 sizeof(zend_object_handlers));
863 lua_handlers.write_property = php_lua_write_property;
864 lua_handlers.read_property = php_lua_read_property;
865 lua_ce->ce_flags |= ZEND_ACC_FINAL;
867 zend_declare_class_constant_long(lua_ce, "MULTRET", sizeof("MULTRET")-1, LUA_MULTRET TSRMLS_CC);
869 ZEND_INIT_MODULE_GLOBALS(lua, php_lua_init_globals, NULL);
871 return SUCCESS;
873 /* }}} */
875 /* {{{ PHP_MSHUTDOWN_FUNCTION
877 PHP_MSHUTDOWN_FUNCTION(lua)
879 UNREGISTER_INI_ENTRIES();
880 return SUCCESS;
882 /* }}} */
884 /* {{{ PHP_RINIT_FUNCTION
886 PHP_RINIT_FUNCTION(lua)
888 return SUCCESS;
890 /* }}} */
892 /* {{{ PHP_RSHUTDOWN_FUNCTION
894 PHP_RSHUTDOWN_FUNCTION(lua)
896 return SUCCESS;
898 /* }}} */
900 /* {{{ PHP_MINFO_FUNCTION
902 PHP_MINFO_FUNCTION(lua)
904 php_info_print_table_start();
905 php_info_print_table_row(2, "lua support", "enabled");
906 php_info_print_table_row(2, "lua extension version", EXT_LUA_VERSION);
907 php_info_print_table_row(2, "lua release", LUA_RELEASE);
908 php_info_print_table_row(2, "lua copyright", LUA_COPYRIGHT);
909 php_info_print_table_row(2, "lua authors", LUA_AUTHORS);
910 php_info_print_table_end();
912 DISPLAY_INI_ENTRIES();
914 /* }}} */
916 /* {{{ lua_module_entry
918 zend_module_entry lua_module_entry = {
919 STANDARD_MODULE_HEADER,
920 "lua",
921 lua_functions,
922 PHP_MINIT(lua),
923 PHP_MSHUTDOWN(lua),
924 PHP_RINIT(lua),
925 PHP_RSHUTDOWN(lua),
926 PHP_MINFO(lua),
927 EXT_LUA_VERSION,
928 STANDARD_MODULE_PROPERTIES
930 /* }}} */
933 * Local variables:
934 * tab-width: 4
935 * c-basic-offset: 4
936 * vim: set noet sw=4 ts=4:
937 * vim600: noet sw=4 ts=4 fdm=marker:
938 * End: