Index: pbx/pbx_lua.c
===================================================================
--- pbx/pbx_lua.c	(revision 341805)
+++ pbx/pbx_lua.c	(revision 341809)
@@ -50,7 +50,11 @@
 static char *config = "extensions.lua";
 static char *registrar = "pbx_lua";
 
+#ifdef LOW_MEMORY
 #define LUA_EXT_DATA_SIZE 256
+#else
+#define LUA_EXT_DATA_SIZE 8192
+#endif
 #define LUA_BUF_SIZE 4096
 
 static char *lua_read_extensions_file(lua_State *L, long *size);
@@ -77,13 +81,14 @@
 static int lua_error_function(lua_State *L);
 
 static void lua_update_registry(lua_State *L, const char *context, const char *exten, int priority);
-static void lua_push_variable_table(lua_State *L, const char *name);
+static void lua_push_variable_table(lua_State *L);
 static void lua_create_app_table(lua_State *L);
 static void lua_create_channel_table(lua_State *L);
 static void lua_create_variable_metatable(lua_State *L);
 static void lua_create_application_metatable(lua_State *L);
 static void lua_create_autoservice_functions(lua_State *L);
 static void lua_create_hangup_function(lua_State *L);
+static void lua_concat_args(lua_State *L, int start, int nargs);
 
 static void lua_state_destroy(void *data);
 static void lua_datastore_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan);
@@ -177,15 +182,13 @@
 static int lua_pbx_exec(lua_State *L)
 {
 	int res, nargs = lua_gettop(L);
-	char data[LUA_EXT_DATA_SIZE] = "";
-	char *data_next = data, *app_name;
-	char *context, *exten;
+	const char *data = "";
+	char *app_name, *context, *exten;
 	char tmp[80], tmp2[80], tmp3[LUA_EXT_DATA_SIZE];
 	int priority, autoservice;
-	size_t data_left = sizeof(data);
 	struct ast_app *app;
 	struct ast_channel *chan;
-	
+
 	lua_getfield(L, 1, "name");
 	app_name = ast_strdupa(lua_tostring(L, -1));
 	lua_pop(L, 1);
@@ -216,21 +219,9 @@
 	priority = lua_tointeger(L, -1);
 	lua_pop(L, 1);
 
+	lua_concat_args(L, 2, nargs);
+	data = lua_tostring(L, -1);
 
-	if (nargs > 1) {
-		int i;
-
-		if (!lua_isnil(L, 2))
-			ast_build_string(&data_next, &data_left, "%s", luaL_checkstring(L, 2));
-
-		for (i = 3; i <= nargs; i++) {
-			if (lua_isnil(L, i))
-				ast_build_string(&data_next, &data_left, ",");
-			else
-				ast_build_string(&data_next, &data_left, ",%s", luaL_checkstring(L, i));
-		}
-	}
-	
 	ast_verb(3, "Executing [%s@%s:%d] %s(\"%s\", \"%s\")\n",
 			exten, context, priority,
 			term_color(tmp, app_name, COLOR_BRCYAN, 0, sizeof(tmp)),
@@ -245,7 +236,10 @@
 		ast_autoservice_stop(chan);
 
 	res = pbx_exec(chan, app, data);
-	
+
+	lua_pop(L, 1); /* pop data */
+	data = "";
+
 	if (autoservice)
 		ast_autoservice_start(chan);
 
@@ -389,16 +383,18 @@
  * \brief Push a 'variable' table on the stack for access the channel variable
  * with the given name.
  *
+ * The value on the top of the stack is popped and used as the name.
+ *
  * \param L the lua_State to use
  * \param name the name of the variable
  */
-static void lua_push_variable_table(lua_State *L, const char *name)
+static void lua_push_variable_table(lua_State *L)
 {
 	lua_newtable(L);
 	luaL_getmetatable(L, "variable");
 	lua_setmetatable(L, -2);
 
-	lua_pushstring(L, name);
+	lua_insert(L, -2); /* move the table after the name */
 	lua_setfield(L, -2, "name");
 	
 	lua_pushcfunction(L, &lua_get_variable_value);
@@ -527,7 +523,7 @@
 static int lua_get_variable(lua_State *L)
 {
 	struct ast_channel *chan;
-	char *name = ast_strdupa(luaL_checkstring(L, 2));
+	const char *name = luaL_checkstring(L, 2);
 	char *value = NULL;
 	char *workspace = alloca(LUA_BUF_SIZE);
 	workspace[0] = '\0';
@@ -536,7 +532,8 @@
 	chan = lua_touserdata(L, -1);
 	lua_pop(L, 1);
 
-	lua_push_variable_table(L, name);
+	lua_pushvalue(L, 2);
+	lua_push_variable_table(L);
 	
 	/* if this is not a request for a dialplan funciton attempt to retrieve
 	 * the value of the variable */
@@ -590,6 +587,38 @@
 }
 
 /*!
+ * \brief Concatenate a list of lua function arguments into a comma separated
+ * string.
+ * \param L the lua_State to use
+ * \param start the index of the first argument
+ * \param nargs the number of args
+ *
+ * The resulting string will be left on the top of the stack.
+ */
+static void lua_concat_args(lua_State *L, int start, int nargs) {
+	int concat = 0;
+	int i = start + 1;
+
+	if (start <= nargs && !lua_isnil(L, start)) {
+		lua_pushvalue(L, start);
+		concat += 1;
+	}
+
+	for (; i <= nargs; i++) {
+		if (lua_isnil(L, i)) {
+			lua_pushliteral(L, ",");
+			concat += 1;
+		} else {
+			lua_pushliteral(L, ",");
+			lua_pushvalue(L, i);
+			concat += 2;
+		}
+	}
+
+	lua_concat(L, concat);
+}
+
+/*!
  * \brief [lua_CFunction] Create a 'variable' object for accessing a dialplan
  * function (for access from lua, don't call directly)
  * 
@@ -608,34 +637,15 @@
 static int lua_func_read(lua_State *L)
 {
 	int nargs = lua_gettop(L);
-	char fullname[LUA_EXT_DATA_SIZE] = "";
-	char *fullname_next = fullname, *name;
-	size_t fullname_left = sizeof(fullname);
-	
+
+	/* build a string in the form of "func_name(arg1,arg2,arg3)" */
 	lua_getfield(L, 1, "name");
-	name = ast_strdupa(lua_tostring(L, -1));
-	lua_pop(L, 1);
+	lua_pushliteral(L, "(");
+	lua_concat_args(L, 2, nargs);
+	lua_pushliteral(L, ")");
+	lua_concat(L, 4);
 
-	ast_build_string(&fullname_next, &fullname_left, "%s(", name);
-	
-	if (nargs > 1) {
-		int i;
-
-		if (!lua_isnil(L, 2))
-			ast_build_string(&fullname_next, &fullname_left, "%s", luaL_checkstring(L, 2));
-
-		for (i = 3; i <= nargs; i++) {
-			if (lua_isnil(L, i))
-				ast_build_string(&fullname_next, &fullname_left, ",");
-			else
-				ast_build_string(&fullname_next, &fullname_left, ",%s", luaL_checkstring(L, i));
-		}
-	}
-
-	ast_build_string(&fullname_next, &fullname_left, ")");
-	
-	lua_push_variable_table(L, fullname);
-	
+	lua_push_variable_table(L);
 	return 1;
 }
 
