ngx_int_t
ngx_http_lua_header_filter_by_chunk(lua_State *L, ngx_http_request_t *r)
{
    int              old_exit_code = 0;
    ngx_int_t        rc;
    u_char          *err_msg;
    size_t           len;
#if (NGX_PCRE)
    ngx_pool_t      *old_pool;
#endif
    ngx_http_lua_ctx_t          *ctx;

    ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
    if (ctx->exited) {
        old_exit_code = ctx->exit_code;
    }

    /*  initialize nginx context in Lua VM, code chunk at stack top    sp = 1 */
    ngx_http_lua_header_filter_by_lua_env(L, r);

#if (NGX_PCRE)
    /* XXX: work-around to nginx regex subsystem */
    old_pool = ngx_http_lua_pcre_malloc_init(r->pool);
#endif

    lua_pushcfunction(L, ngx_http_lua_traceback);
    lua_insert(L, 1);  /* put it under chunk and args */

    /*  protected call user code */
    rc = lua_pcall(L, 0, 1, 1);

    lua_remove(L, 1);  /* remove traceback function */

#if (NGX_PCRE)
    /* XXX: work-around to nginx regex subsystem */
    ngx_http_lua_pcre_malloc_done(old_pool);
#endif

    dd("rc == %d", (int) rc);

    if (rc != 0) {
        /*  error occured when running loaded code */
        err_msg = (u_char *) lua_tolstring(L, -1, &len);

        if (err_msg == NULL) {
            err_msg = (u_char *) "unknown reason";
            len = sizeof("unknown reason") - 1;
        }

        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "failed to run header_filter_by_lua*: %*s", len, err_msg);

        lua_settop(L, 0); /*  clear remaining elems on stack */

        return NGX_ERROR;
    }

    dd("exited: %d, exit code: %d, old exit code: %d",
       (int) ctx->exited, (int) ctx->exit_code, (int) old_exit_code);

    if (ctx->exited && ctx->exit_code != old_exit_code) {
        if (ctx->exit_code == NGX_ERROR) {
            return NGX_ERROR;
        }

        dd("finalize request with %d", (int) ctx->exit_code);

        rc = ngx_http_filter_finalize_request(r, &ngx_http_lua_module,
                                              ctx->exit_code);
        if (rc == NGX_ERROR || rc == NGX_AGAIN) {
            return rc;
        }

        return NGX_DECLINED;
    }

    /*  clear Lua stack */
    lua_settop(L, 0);

    return NGX_OK;
}
Beispiel #2
0
int w_World_getContactFilter(lua_State *L)
{
	World *t = luax_checkworld(L, 1);
	lua_remove(L, 1);
	return t->getContactFilter(L);
}
Beispiel #3
0
void _pklua_lua_socket_free_buffer(lua_State* L, int stack_pos)
{
  lua_remove(L, stack_pos);
}
Beispiel #4
0
void LuaSerializer::pickle(lua_State *l, int idx, std::string &out, const char *key = NULL)
{
	static char buf[256];

	LUA_DEBUG_START(l);

	idx = (idx < 0) ? lua_gettop(l)+idx+1 : idx;

	if (lua_getmetatable(l, idx)) {
		lua_getfield(l, -1, "class");
		if (lua_isnil(l, -1))
			lua_pop(l, 2);

		else {
			const char *cl = lua_tostring(l, -1);
			snprintf(buf, sizeof(buf), "o%s\n", cl);

			lua_getfield(l, LUA_GLOBALSINDEX, cl);
			if (lua_isnil(l, -1))
				luaL_error(l, "No Serialize method found for class '%s'\n", cl);

			lua_getfield(l, -1, "Serialize");
			if (lua_isnil(l, -1))
				luaL_error(l, "No Serialize method found for class '%s'\n", cl);

			lua_pushvalue(l, idx);
			pi_lua_protected_call(l, 1, 1);

			lua_remove(l, idx);
			lua_insert(l, idx);

			lua_pop(l, 3);

			if (lua_isnil(l, idx)) {
				LUA_DEBUG_END(l, 0);
				return;
			}

			out += buf;
		}
	}

	switch (lua_type(l, idx)) {
		case LUA_TNIL:
			break;

		case LUA_TNUMBER: {
			snprintf(buf, sizeof(buf), "f%f\n", lua_tonumber(l, idx));
			out += buf;
			break;
		}

		case LUA_TBOOLEAN: {
			snprintf(buf, sizeof(buf), "b%d", lua_toboolean(l, idx) ? 1 : 0);
			out += buf;
			break;
		}

		case LUA_TSTRING: {
			lua_pushvalue(l, idx);
			const char *str = lua_tostring(l, -1);
			snprintf(buf, sizeof(buf), "s" SIZET_FMT "\n", strlen(str));
			out += buf;
			out += str;
			lua_pop(l, 1);
			break;
		}

		case LUA_TTABLE: {
			lua_pushinteger(l, lua_Integer(lua_topointer(l, idx)));         // ptr

			lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");    // ptr reftable
			lua_pushvalue(l, -2);                                           // ptr reftable ptr
			lua_rawget(l, -2);                                              // ptr reftable ???

			if (!lua_isnil(l, -1)) {
				out += "r";
				pickle(l, -3, out, key);
				lua_pop(l, 3);                                              // [empty]
			}

			else {
				out += "t";

				lua_pushvalue(l, -3);                                       // ptr reftable nil ptr
				lua_pushvalue(l, idx);                                      // ptr reftable nil ptr table
				lua_rawset(l, -4);                                          // ptr reftable nil
				pickle(l, -3, out, key);
				lua_pop(l, 3);                                              // [empty]

				lua_pushvalue(l, idx);
				lua_pushnil(l);
				while (lua_next(l, -2)) {
					if (key) {
						pickle(l, -2, out, key);
						pickle(l, -1, out, key);
					}
					else {
						lua_pushvalue(l, -2);
						const char *k = lua_tostring(l, -1);
						pickle(l, -3, out, k);
						pickle(l, -2, out, k);
						lua_pop(l, 1);
					}
					lua_pop(l, 1);
				}
				lua_pop(l, 1);
				out += "n";
			}

			break;
		}

		case LUA_TUSERDATA: {
			out += "u";
			lid *idp = static_cast<lid*>(lua_touserdata(l, idx));
			LuaObjectBase *lo = LuaObjectBase::Lookup(*idp);
			if (!lo)
				Error("Lua serializer '%s' tried to serialize object with id 0x%08x, but it no longer exists", key, *idp);

			// XXX object wrappers should really have Serialize/Unserialize
			// methods to deal with this
			if (lo->Isa("SystemPath")) {
				SystemPath *sbp = dynamic_cast<SystemPath*>(lo->m_object);
				snprintf(buf, sizeof(buf), "SystemPath\n%d\n%d\n%d\n%d\n%d\n",
					sbp->sectorX, sbp->sectorY, sbp->sectorZ, sbp->systemIndex, sbp->bodyIndex);
				out += buf;
				break;
			}

			if (lo->Isa("Body")) {
				Body *b = dynamic_cast<Body*>(lo->m_object);
				snprintf(buf, sizeof(buf), "Body\n%d\n", Pi::game->GetSpace()->GetIndexForBody(b));
				out += buf;
				break;
			}

			Error("Lua serializer '%s' tried to serialize unsupported userdata value", key);
			break;
		}

		default:
			Error("Lua serializer '%s' tried to serialize %s value", key, lua_typename(l, lua_type(l, idx)));
			break;
	}

	LUA_DEBUG_END(l, 0);
}
Beispiel #5
0
int w_World_queryBoundingBox(lua_State *L)
{
	World *t = luax_checkworld(L, 1);
	lua_remove(L, 1);
	return t->queryBoundingBox(L);
}
Beispiel #6
0
/* 
 * error, data, read_len = port:read(max_read_len [[, timeout_ms], forced])
 *
 * if forced > 0 then read() blocks until 'timeout_ms' or there's 'max_read_len'
 * bytes available
 */
static int lua_port_read(lua_State *L)
{
	int ret = 0;
	int argc = 0;
	int forced = 0;
	unsigned int timeout = 0;
	unsigned int len = 0;
	unsigned int bytes_read = 0;
	unsigned char *data = NULL;
	struct rs232_port_t *p = NULL;

	p = (struct rs232_port_t*) luaL_checkudata(L, 1, MODULE_NAMESPACE);
	lua_remove(L, 1);

	if (p == NULL || !rs232_port_open(p)) {
		lua_pushinteger(L, RS232_ERR_PORT_CLOSED);
		lua_pushnil(L);
		lua_pushinteger(L, 0);
		return 3;
	}

	argc = lua_gettop(L);
	switch (argc) {
	case 1:
		len = (unsigned int) luaL_checkinteger(L, 1);
		data = (unsigned char*) malloc(len * sizeof(unsigned char *));
		memset(data, 0, len);
		ret = rs232_read(p, data, len, &bytes_read);
		break;
	case 2:
	case 3:
		len = (unsigned int) luaL_checknumber(L, 1);
		data = (unsigned char*) malloc(len * sizeof(unsigned char *));
		memset(data, 0, len);
		timeout = (unsigned int) luaL_checknumber(L, 2);
		forced = luaL_optint(L, 3, 0);
		if (forced > 0)
			ret = rs232_read_timeout_forced(p, data, len, &bytes_read, timeout);
		else
			ret = rs232_read_timeout(p, data, len, &bytes_read, timeout);
		break;
	default:
		lua_pushinteger(L, RS232_ERR_UNKNOWN);
		lua_pushnil(L);
		lua_pushinteger(L, 0);
		return 3;
	}

	DBG("ret=%d hex='%s' bytes_read=%d\n",
	    ret, rs232_hex_dump(data, bytes_read), bytes_read);

	lua_pushinteger(L, RS232_ERR_NOERROR);
	if (bytes_read > 0)
		lua_pushlstring(L, (char *) data, bytes_read);
	else
		lua_pushnil(L);

	if (data)
		free(data);

	lua_pushinteger(L, bytes_read);
	return 3;
}
static int
ngx_http_lua_ngx_location_capture_multi(lua_State *L)
{
    ngx_http_request_t              *r;
    ngx_http_request_t              *sr = NULL; /* subrequest object */
    ngx_http_post_subrequest_t      *psr;
    ngx_http_lua_ctx_t              *sr_ctx;
    ngx_http_lua_ctx_t              *ctx;
    ngx_array_t                     *extra_vars;
    ngx_str_t                        uri;
    ngx_str_t                        args;
    ngx_str_t                        extra_args;
    ngx_uint_t                       flags;
    u_char                          *p;
    u_char                          *q;
    size_t                           len;
    size_t                           nargs;
    int                              rc;
    int                              n;
    int                              always_forward_body = 0;
    ngx_uint_t                       method;
    ngx_http_request_body_t         *body;
    int                              type;
    ngx_buf_t                       *b;
    unsigned                         vars_action;
    ngx_uint_t                       nsubreqs;
    ngx_uint_t                       index;
    size_t                           sr_statuses_len;
    size_t                           sr_headers_len;
    size_t                           sr_bodies_len;
    size_t                           sr_flags_len;
    size_t                           ofs1, ofs2;
    unsigned                         custom_ctx;
    ngx_http_lua_co_ctx_t           *coctx;

    ngx_http_lua_post_subrequest_data_t      *psr_data;

    n = lua_gettop(L);
    if (n != 1) {
        return luaL_error(L, "only one argument is expected, but got %d", n);
    }

    luaL_checktype(L, 1, LUA_TTABLE);

    nsubreqs = lua_objlen(L, 1);
    if (nsubreqs == 0) {
        return luaL_error(L, "at least one subrequest should be specified");
    }

    r = ngx_http_lua_get_req(L);
    if (r == NULL) {
        return luaL_error(L, "no request object found");
    }

    ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
    if (ctx == NULL) {
        return luaL_error(L, "no ctx found");
    }

    ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE
                               | NGX_HTTP_LUA_CONTEXT_ACCESS
                               | NGX_HTTP_LUA_CONTEXT_CONTENT);

    coctx = ctx->cur_co_ctx;
    if (coctx == NULL) {
        return luaL_error(L, "no co ctx found");
    }

    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "lua location capture, uri:\"%V\" c:%ud", &r->uri,
                   r->main->count);

    sr_statuses_len = nsubreqs * sizeof(ngx_int_t);
    sr_headers_len  = nsubreqs * sizeof(ngx_http_headers_out_t *);
    sr_bodies_len   = nsubreqs * sizeof(ngx_str_t);
    sr_flags_len    = nsubreqs * sizeof(uint8_t);

    p = ngx_pcalloc(r->pool, sr_statuses_len + sr_headers_len +
                    sr_bodies_len + sr_flags_len);

    if (p == NULL) {
        return luaL_error(L, "no memory");
    }

    coctx->sr_statuses = (void *) p;
    p += sr_statuses_len;

    coctx->sr_headers = (void *) p;
    p += sr_headers_len;

    coctx->sr_bodies = (void *) p;
    p += sr_bodies_len;

    coctx->sr_flags = (void *) p;

    coctx->nsubreqs = nsubreqs;

    coctx->pending_subreqs = 0;

    extra_vars = NULL;

    for (index = 0; index < nsubreqs; index++) {
        coctx->pending_subreqs++;

        lua_rawgeti(L, 1, index + 1);
        if (lua_isnil(L, -1)) {
            return luaL_error(L, "only array-like tables are allowed");
        }

        dd("queries query: top %d", lua_gettop(L));

        if (lua_type(L, -1) != LUA_TTABLE) {
            return luaL_error(L, "the query argument %d is not a table, "
                              "but a %s",
                              index, lua_typename(L, lua_type(L, -1)));
        }

        nargs = lua_objlen(L, -1);

        if (nargs != 1 && nargs != 2) {
            return luaL_error(L, "query argument %d expecting one or "
                              "two arguments", index);
        }

        lua_rawgeti(L, 2, 1); /* queries query uri */

        dd("queries query uri: %d", lua_gettop(L));

        dd("first arg in first query: %s", lua_typename(L, lua_type(L, -1)));

        body = NULL;

        ngx_str_null(&extra_args);

        if (extra_vars != NULL) {
            /* flush out existing elements in the array */
            extra_vars->nelts = 0;
        }

        vars_action = 0;

        custom_ctx = 0;

        if (nargs == 2) {
            /* check out the options table */

            lua_rawgeti(L, 2, 2); /* queries query uri opts */

            dd("queries query uri opts: %d", lua_gettop(L));

            if (lua_type(L, 4) != LUA_TTABLE) {
                return luaL_error(L, "expecting table as the 2nd argument for "
                                  "subrequest %d, but got %s", index,
                                  luaL_typename(L, 4));
            }

            dd("queries query uri opts: %d", lua_gettop(L));

            /* check the args option */

            lua_getfield(L, 4, "args");

            type = lua_type(L, -1);

            switch (type) {
            case LUA_TTABLE:
                ngx_http_lua_process_args_option(r, L, -1, &extra_args);
                break;

            case LUA_TNIL:
                /* do nothing */
                break;

            case LUA_TNUMBER:
            case LUA_TSTRING:
                extra_args.data = (u_char *) lua_tolstring(L, -1, &len);
                extra_args.len = len;

                break;

            default:
                return luaL_error(L, "Bad args option value");
            }

            lua_pop(L, 1);

            dd("queries query uri opts: %d", lua_gettop(L));

            /* check the vars option */

            lua_getfield(L, 4, "vars");

            switch (lua_type(L, -1)) {
            case LUA_TTABLE:
                ngx_http_lua_process_vars_option(r, L, -1, &extra_vars);

                dd("post process vars top: %d", lua_gettop(L));
                break;

            case LUA_TNIL:
                /* do nothing */
                break;

            default:
                return luaL_error(L, "Bad vars option value");
            }

            lua_pop(L, 1);

            dd("queries query uri opts: %d", lua_gettop(L));

            /* check the share_all_vars option */

            lua_getfield(L, 4, "share_all_vars");

            switch (lua_type(L, -1)) {
            case LUA_TNIL:
                /* do nothing */
                break;

            case LUA_TBOOLEAN:
                if (lua_toboolean(L, -1)) {
                    vars_action |= NGX_HTTP_LUA_SHARE_ALL_VARS;
                }
                break;

            default:
                return luaL_error(L, "Bad share_all_vars option value");
            }

            lua_pop(L, 1);

            dd("queries query uri opts: %d", lua_gettop(L));

            /* check the copy_all_vars option */

            lua_getfield(L, 4, "copy_all_vars");

            switch (lua_type(L, -1)) {
            case LUA_TNIL:
                /* do nothing */
                break;

            case LUA_TBOOLEAN:
                if (lua_toboolean(L, -1)) {
                    vars_action |= NGX_HTTP_LUA_COPY_ALL_VARS;
                }
                break;

            default:
                return luaL_error(L, "Bad copy_all_vars option value");
            }

            lua_pop(L, 1);

            dd("queries query uri opts: %d", lua_gettop(L));

            /* check the "forward_body" option */

            lua_getfield(L, 4, "always_forward_body");
            always_forward_body = lua_toboolean(L, -1);
            lua_pop(L, 1);

            dd("always foward body: %d", always_forward_body);

            /* check the "method" option */

            lua_getfield(L, 4, "method");

            type = lua_type(L, -1);

            if (type == LUA_TNIL) {
                method = NGX_HTTP_GET;

            } else {
                if (type != LUA_TNUMBER) {
                    return luaL_error(L, "Bad http request method");
                }

                method = (ngx_uint_t) lua_tonumber(L, -1);
            }

            lua_pop(L, 1);

            dd("queries query uri opts: %d", lua_gettop(L));

            /* check the "ctx" option */

            lua_getfield(L, 4, "ctx");

            type = lua_type(L, -1);

            if (type != LUA_TNIL) {
                if (type != LUA_TTABLE) {
                    return luaL_error(L, "Bad ctx option value type %s, "
                                      "expected a Lua table",
                                      lua_typename(L, type));
                }

                custom_ctx = 1;

            } else {
                lua_pop(L, 1);
            }

            dd("queries query uri opts ctx?: %d", lua_gettop(L));

            /* check the "body" option */

            lua_getfield(L, 4, "body");

            type = lua_type(L, -1);

            if (type != LUA_TNIL) {
                if (type != LUA_TSTRING && type != LUA_TNUMBER) {
                    return luaL_error(L, "Bad http request body");
                }

                body = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));

                if (body == NULL) {
                    return luaL_error(L, "no memory");
                }

                q = (u_char *) lua_tolstring(L, -1, &len);

                dd("request body: [%.*s]", (int) len, q);

                if (len) {
                    b = ngx_create_temp_buf(r->pool, len);
                    if (b == NULL) {
                        return luaL_error(L, "no memory");
                    }

                    b->last = ngx_copy(b->last, q, len);

                    body->bufs = ngx_alloc_chain_link(r->pool);
                    if (body->bufs == NULL) {
                        return luaL_error(L, "no memory");
                    }

                    body->bufs->buf = b;
                    body->bufs->next = NULL;

                    body->buf = b;
                }
            }

            lua_pop(L, 1); /* pop the body */

            /* stack: queries query uri opts ctx? */

            lua_remove(L, 4);

            /* stack: queries query uri ctx? */

            dd("queries query uri ctx?: %d", lua_gettop(L));

        } else {
            method = NGX_HTTP_GET;
        }

        /* stack: queries query uri ctx? */

        p = (u_char *) luaL_checklstring(L, 3, &len);

        uri.data = ngx_palloc(r->pool, len);
        if (uri.data == NULL) {
            return luaL_error(L, "memory allocation error");
        }

        ngx_memcpy(uri.data, p, len);

        uri.len = len;

        ngx_str_null(&args);

        flags = 0;

        rc = ngx_http_parse_unsafe_uri(r, &uri, &args, &flags);
        if (rc != NGX_OK) {
            dd("rc = %d", (int) rc);

            return luaL_error(L, "unsafe uri in argument #1: %s", p);
        }

        if (args.len == 0) {
            if (extra_args.len) {
                p = ngx_palloc(r->pool, extra_args.len);
                if (p == NULL) {
                    return luaL_error(L, "no memory");
                }

                ngx_memcpy(p, extra_args.data, extra_args.len);

                args.data = p;
                args.len = extra_args.len;
            }

        } else if (extra_args.len) {
            /* concatenate the two parts of args together */
            len = args.len + (sizeof("&") - 1) + extra_args.len;

            p = ngx_palloc(r->pool, len);
            if (p == NULL) {
                return luaL_error(L, "no memory");
            }

            q = ngx_copy(p, args.data, args.len);
            *q++ = '&';
            ngx_memcpy(q, extra_args.data, extra_args.len);

            args.data = p;
            args.len = len;
        }

        ofs1 = ngx_align(sizeof(ngx_http_post_subrequest_t), sizeof(void *));
        ofs2 = ngx_align(sizeof(ngx_http_lua_ctx_t), sizeof(void *));

        p = ngx_palloc(r->pool, ofs1 + ofs2
                       + sizeof(ngx_http_lua_post_subrequest_data_t));
        if (p == NULL) {
            return luaL_error(L, "no memory");
        }

        psr = (ngx_http_post_subrequest_t *) p;

        p += ofs1;

        sr_ctx = (ngx_http_lua_ctx_t *) p;

        ngx_http_lua_assert((void *) sr_ctx == ngx_align_ptr(sr_ctx,
                                                             sizeof(void *)));

        p += ofs2;

        psr_data = (ngx_http_lua_post_subrequest_data_t *) p;

        ngx_http_lua_assert((void *) psr_data == ngx_align_ptr(psr_data,
                                                               sizeof(void *)));

        ngx_memzero(sr_ctx, sizeof(ngx_http_lua_ctx_t));

        /* set by ngx_memzero:
         *      sr_ctx->run_post_subrequest = 0
         *      sr_ctx->free = NULL
         *      sr_ctx->body = NULL
         */

        psr_data->ctx = sr_ctx;
        psr_data->pr_co_ctx = coctx;

        psr->handler = ngx_http_lua_post_subrequest;
        psr->data = psr_data;

        rc = ngx_http_lua_subrequest(r, &uri, &args, &sr, psr, 0);

        if (rc != NGX_OK) {
            return luaL_error(L, "failed to issue subrequest: %d", (int) rc);
        }

        ngx_http_lua_init_ctx(sr, sr_ctx);

        sr_ctx->capture = 1;
        sr_ctx->index = index;
        sr_ctx->last_body = &sr_ctx->body;
        sr_ctx->vm_state = ctx->vm_state;

        ngx_http_set_ctx(sr, sr_ctx, ngx_http_lua_module);

        rc = ngx_http_lua_adjust_subrequest(sr, method, always_forward_body,
                                            body, vars_action, extra_vars);

        if (rc != NGX_OK) {
            ngx_http_lua_cancel_subreq(sr);
            return luaL_error(L, "failed to adjust the subrequest: %d",
                              (int) rc);
        }

        dd("queries query uri opts ctx? %d", lua_gettop(L));

        /* stack: queries query uri ctx? */

        if (custom_ctx) {
            ngx_http_lua_ngx_set_ctx_helper(L, sr, sr_ctx, -1);
            lua_pop(L, 3);

        } else {
            lua_pop(L, 2);
        }

        /* stack: queries */
    }

    if (extra_vars) {
        ngx_array_destroy(extra_vars);
    }

    ctx->no_abort = 1;

    return lua_yield(L, 0);
}
Beispiel #8
0
void lua_removef(lua_State *L, int index) { lua_remove(L, index); }
Beispiel #9
0
int Xml_eval(lua_State *L) {
	char* str = 0;
	size_t str_size=0;
	if(lua_isuserdata(L,1))
		str = (char*)lua_touserdata(L,1);
	else {
		const char * sTmp = luaL_checklstring(L,1,&str_size);
		str = (char*)malloc(str_size+1);
		memcpy(str, sTmp, str_size);
		str[str_size]=0;
	}
	Tokenizer* tok = Tokenizer_new(str, str_size ? str_size : strlen(str));
	lua_settop(L,0);
	const char* token=0;
	int firstStatement = 1;
	while((token=Tokenizer_next(tok))!=0) if(token[0]==OPN) { // new tag found
		if(lua_gettop(L)) {
			int newIndex=lua_rawlen(L,-1)+1;
			lua_pushnumber(L,newIndex);
			lua_newtable(L);
			lua_settable(L, -3);
			lua_pushnumber(L,newIndex);
			lua_gettable(L,-2);
		}
		else {
			if (firstStatement) {
				lua_newtable(L);
				firstStatement = 0;
			}
			else return lua_gettop(L);
		}
		// set metatable:
		lua_newtable(L);
		lua_pushliteral(L, "__index");
		lua_getglobal(L, "xml");
		lua_settable(L, -3);

		lua_pushliteral(L, "__tostring"); // set __tostring metamethod
		lua_getglobal(L, "xml");
		lua_pushliteral(L,"str");
		lua_gettable(L, -2);
		lua_remove(L, -2);
		lua_settable(L, -3);
		lua_setmetatable(L, -2);

		// parse tag and content:
		lua_pushnumber(L,0); // use index 0 for storing the tag
		lua_pushstring(L, Tokenizer_next(tok));
		lua_settable(L, -3);

		while(((token = Tokenizer_next(tok))!=0)&&(token[0]!=CLS)&&(token[0]!=ESC)) { // parse tag header
			size_t sepPos=find(token, "=", 0);
			if(token[sepPos]) { // regular attribute
				const char* aVal =token+sepPos+2;
				lua_pushlstring(L, token, sepPos);
				size_t lenVal = strlen(aVal)-1;
				if(!lenVal) Xml_pushDecode(L, "", 0);
				else Xml_pushDecode(L, aVal, lenVal);
				lua_settable(L, -3);
			}
		}
		if(!token||(token[0]==ESC)) {
			if(lua_gettop(L)>1) lua_settop(L,-2); // this tag has no content, only attributes
			else break;
		}
	}
	else if(token[0]==ESC) { // previous tag is over
		if(lua_gettop(L)>1) lua_settop(L,-2); // pop current table
		else break;
	}
	else { // read elements
		lua_pushnumber(L,lua_rawlen(L,-1)+1);
		Xml_pushDecode(L, token, 0);
		lua_settable(L, -3);
	}
	Tokenizer_delete(tok);
	free(str);
	return lua_gettop(L);
}
Beispiel #10
0
static void mar_decode_value
    (lua_State *L, const char *buf, size_t len, const char **p, size_t *idx)
{
    size_t l;
    char val_type = **p;
    mar_incr_ptr(MAR_CHR);
    switch (val_type) {
    case LUA_TBOOLEAN:
        lua_pushboolean(L, *(char*)*p);
        mar_incr_ptr(MAR_CHR);
        break;
    case LUA_TNUMBER:
        lua_pushnumber(L, *(lua_Number*)*p);
        mar_incr_ptr(MAR_I64);
        break;
    case MAR_TINT:
        lua_pushinteger(L, *(lua_Integer*)*p);
        mar_incr_ptr(MAR_I64);
        break;
    case LUA_TSTRING:
        mar_next_len(l, uint32_t);
        lua_pushlstring(L, *p, l);
        mar_incr_ptr(l);
        break;
    case LUA_TTABLE: {
        char tag = *(char*)*p;
        mar_incr_ptr(MAR_CHR);
        if (tag == MAR_TREF) {
            int ref;
            mar_next_len(ref, int);
            lua_rawgeti(L, SEEN_IDX, ref);
        }
        else if (tag == MAR_TVAL) {
            mar_next_len(l, uint32_t);
            lua_newtable(L);
            lua_pushvalue(L, -1);
            lua_rawseti(L, SEEN_IDX, (*idx)++);
            mar_decode_table(L, *p, l, idx);
            mar_incr_ptr(l);
        }
        else if (tag == MAR_TUSR) {
            mar_next_len(l, uint32_t);
            lua_newtable(L);
            mar_decode_table(L, *p, l, idx);
            lua_rawgeti(L, -1, 1);
            lua_call(L, 0, 1);
            lua_remove(L, -2);
            lua_pushvalue(L, -1);
            lua_rawseti(L, SEEN_IDX, (*idx)++);
            mar_incr_ptr(l);
        }
        else {
            luaL_error(L, "bad encoded data");
        }
        break;
    }
    case LUA_TFUNCTION: {
        unsigned int nups;
        unsigned int i;
        mar_Buffer dec_buf;
        char tag = *(char*)*p;
        mar_incr_ptr(1);
        if (tag == MAR_TREF) {
            int ref;
            mar_next_len(ref, int);
            lua_rawgeti(L, SEEN_IDX, ref);
        }
        else {
            mar_next_len(l, uint32_t);
            dec_buf.data = (char*)*p;
            dec_buf.size = l;
            dec_buf.head = l;
            dec_buf.seek = 0;
            lua_load(L, (lua_Reader)buf_read, &dec_buf, "=marshal", NULL);
            mar_incr_ptr(l);

            lua_pushvalue(L, -1);
            lua_rawseti(L, SEEN_IDX, (*idx)++);

            mar_next_len(l, uint32_t);
            lua_newtable(L);
            mar_decode_table(L, *p, l, idx);

            lua_pushstring(L, MAR_ENV_IDX_KEY);
            lua_rawget(L, -2);
            if (lua_isnumber(L, -1)) {
                lua_pushglobaltable(L);
                lua_rawset(L, -3);
            }
            else {
                lua_pop(L, 1);
            }

            lua_pushstring(L, MAR_NUPS_IDX_KEY);
            lua_rawget(L, -2);
            nups = luaL_checknumber(L, -1);
            lua_pop(L, 1);

            for (i = 1; i <= nups; i++) {
                lua_rawgeti(L, -1, i);
                lua_setupvalue(L, -3, i);
            }

            lua_pop(L, 1);
            mar_incr_ptr(l);
        }
        break;
    }
    case LUA_TUSERDATA: {
        char tag = *(char*)*p;
        mar_incr_ptr(MAR_CHR);
        if (tag == MAR_TREF) {
            int ref;
            mar_next_len(ref, int);
            lua_rawgeti(L, SEEN_IDX, ref);
        }
        else if (tag == MAR_TUSR) {
            mar_next_len(l, uint32_t);
            lua_newtable(L);
            mar_decode_table(L, *p, l, idx);
            lua_rawgeti(L, -1, 1);
            lua_call(L, 0, 1);
            lua_remove(L, -2);
            lua_pushvalue(L, -1);
            lua_rawseti(L, SEEN_IDX, (*idx)++);
            mar_incr_ptr(l);
        }
        else { /* tag == MAR_TVAL */
            lua_pushnil(L);
        }
        break;
    }
    case LUA_TNIL:
    case LUA_TTHREAD:
        lua_pushnil(L);
        break;
    default:
        luaL_error(L, "bad code");
    }
}
// Don't whine bout my gotos, lua api is a bitch, i had to!
int CLuaClassDefs::Index ( lua_State* luaVM )
{
    lua_pushvalue ( luaVM, lua_upvalueindex ( 1 ) ); // ud, k, mt

    // First we look for a function
    lua_pushstring ( luaVM, "__class" ); // ud, k, mt, "__class"
    lua_rawget ( luaVM, -2 ); // ud, k, mt, __class table

    if ( !lua_istable ( luaVM, -1 ) )
    {
        lua_pop ( luaVM, 1 ); // ud, k, mt
        goto searchparent;
    }

    lua_pushvalue ( luaVM, 2 ); // ud, k, mt, __class table, k
    lua_rawget ( luaVM, -2 ); // ud, k, mt, __class table, function
    lua_remove ( luaVM, -2 ); // ud, k, mt, function

    if ( lua_isfunction ( luaVM, -1 ) )
    { // Found the function, clean up and return
        lua_remove ( luaVM, -2 ); // ud, k, function
        return 1;
    }
    lua_pop ( luaVM, 1 ); // ud, k, mt

    // Function not found, look for property
    lua_pushstring ( luaVM, "__get" ); // ud, k, mt, "__get"
    lua_rawget ( luaVM, -2 ); // ud, k, mt, __get table

    if ( !lua_istable ( luaVM, -1 ) )
    {
        lua_pop ( luaVM, 1 ); // ud, k, mt
        goto searchparent;
    }

    lua_pushvalue ( luaVM, 2 ); // ud, k, mt, __get table, k
    lua_rawget ( luaVM, -2 ); // ud, k, mt, __get table, function
    lua_remove ( luaVM, -2 ); // ud, k, mt, function

    if ( lua_isfunction ( luaVM, -1 ) )
    { // Found the property,
        lua_remove ( luaVM, -2 ); // ud, k, function

        lua_pushvalue ( luaVM, 1 ); // ud, k, function, ud
        lua_call ( luaVM, 1, 1 ); // ud, k, result

        return 1;
    }
    lua_pop ( luaVM, 1 ); // ud, k, mt

searchparent:
    lua_pushstring ( luaVM, "__parent" ); // ud, k, mt, "__parent"
    lua_rawget ( luaVM, -2 ); // ud, k, mt, __parent table
    if ( lua_istable ( luaVM, -1 ) )
    {
        lua_pushstring ( luaVM, "__index" ); // ud, k, mt, __parent table, "__index"
        lua_rawget ( luaVM, -2 ); // ud, k, mt, __parent table, function
        if ( lua_isfunction ( luaVM, -1 ) )
        {
            lua_pushvalue ( luaVM, 1 ); // ud, k, mt, __parent table, function, ud
            lua_pushvalue ( luaVM, 2 ); // ud, k, mt, __parent table, function, ud, k

            lua_call ( luaVM, 2, 1 ); // ud, k, mt, __parent table, result

            lua_replace ( luaVM, -3 ); // ud, k, result, __parent table
            lua_pop ( luaVM, 1 ); // ud, k, result
            return 1;
        }
        lua_pop ( luaVM, 1 ); // ud, k, mt, __parent table
    }
    lua_pop ( luaVM, 2 ); // ud, k

    lua_pushnil ( luaVM );
    return 1;
}
Beispiel #12
0
static void mar_encode_value(lua_State *L, mar_Buffer *buf, int val, size_t *idx)
{
    size_t l;
    int val_type = lua_type(L, val);
    if (lua_isinteger(L, val))
        val_type = MAR_TINT;
    lua_pushvalue(L, val);

    buf_write(L, (const char*)&val_type, MAR_CHR, buf);
    switch (val_type) {
    case LUA_TBOOLEAN: {
        int int_val = lua_toboolean(L, -1);
        buf_write(L, (const char*)&int_val, MAR_CHR, buf);
        break;
    }
    case LUA_TSTRING: {
        const char *str_val = lua_tolstring(L, -1, &l);
        buf_write(L, (const char*)&l, MAR_I32, buf);
        buf_write(L, str_val, l, buf);
        break;
    }
    case LUA_TNUMBER: {
        lua_Number num_val = lua_tonumber(L, -1);
        buf_write(L, (const char*)&num_val, MAR_I64, buf);
        break;
    }
    case MAR_TINT: {
        lua_Integer num_val = lua_tointeger(L, -1);
        buf_write(L, (const char*)&num_val, MAR_I64, buf);
        break;
    }
    case LUA_TTABLE: {
        int tag, ref;
        lua_pushvalue(L, -1);
        lua_rawget(L, SEEN_IDX);
        if (!lua_isnil(L, -1)) {
            ref = lua_tointeger(L, -1);
            tag = MAR_TREF;
            buf_write(L, (const char*)&tag, MAR_CHR, buf);
            buf_write(L, (const char*)&ref, MAR_I32, buf);
            lua_pop(L, 1);
        }
        else {
            mar_Buffer rec_buf;
            lua_pop(L, 1); /* pop nil */
            if (luaL_getmetafield(L, -1, "__persist")) {
                tag = MAR_TUSR;

                lua_pushvalue(L, -2); /* self */
                lua_call(L, 1, 1);
                if (!lua_isfunction(L, -1)) {
                    luaL_error(L, "__persist must return a function");
                }

                lua_remove(L, -2); /* __persist */

                lua_newtable(L);
                lua_pushvalue(L, -2); /* callback */
                lua_rawseti(L, -2, 1);

                buf_init(L, &rec_buf);
                mar_encode_table(L, &rec_buf, idx);

                buf_write(L, (const char*)&tag, MAR_CHR, buf);
                buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf);
                buf_write(L, rec_buf.data, rec_buf.head, buf);
                buf_done(L, &rec_buf);
                lua_pop(L, 1);
            }
            else {
                tag = MAR_TVAL;

                lua_pushvalue(L, -1);
                lua_pushinteger(L, (*idx)++);
                lua_rawset(L, SEEN_IDX);

                lua_pushvalue(L, -1);
                buf_init(L, &rec_buf);
                mar_encode_table(L, &rec_buf, idx);
                lua_pop(L, 1);

                buf_write(L, (const char*)&tag, MAR_CHR, buf);
                buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf);
                buf_write(L, rec_buf.data,rec_buf.head, buf);
                buf_done(L, &rec_buf);
            }
        }
        break;
    }
    case LUA_TFUNCTION: {
        int tag, ref;
        lua_pushvalue(L, -1);
        lua_rawget(L, SEEN_IDX);
        if (!lua_isnil(L, -1)) {
            ref = lua_tointeger(L, -1);
            tag = MAR_TREF;
            buf_write(L, (const char*)&tag, MAR_CHR, buf);
            buf_write(L, (const char*)&ref, MAR_I32, buf);
            lua_pop(L, 1);
        }
        else {
            mar_Buffer rec_buf;
            unsigned int i;
            lua_Debug ar;
            lua_pop(L, 1); /* pop nil */

            lua_pushvalue(L, -1);
            lua_getinfo(L, ">nuS", &ar);
            if (ar.what[0] != 'L') {
                luaL_error(L, "attempt to persist a C function '%s'", ar.name);
            }
            tag = MAR_TVAL;
            lua_pushvalue(L, -1);
            lua_pushinteger(L, (*idx)++);
            lua_rawset(L, SEEN_IDX);

            lua_pushvalue(L, -1);
            buf_init(L, &rec_buf);
            lua_dump(L, (lua_Writer)buf_write, &rec_buf, true);

            buf_write(L, (const char*)&tag, MAR_CHR, buf);
            buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf);
            buf_write(L, rec_buf.data, rec_buf.head, buf);
            buf_done(L, &rec_buf);
            lua_pop(L, 1);

            lua_createtable(L, ar.nups, 0);
            for (i = 1; i <= ar.nups; i++) {
                const char* upvalue_name = lua_getupvalue(L, -2, i);
                if (strcmp("_ENV", upvalue_name) == 0) {
                    lua_pop(L, 1);
                    // Mark where _ENV is expected.
                    lua_pushstring(L, MAR_ENV_IDX_KEY);
                    lua_pushinteger(L, i);
                    lua_rawset(L, -3);
                }
                else {
                    lua_rawseti(L, -2, i);
                }
            }
            lua_pushstring(L, MAR_NUPS_IDX_KEY);
            lua_pushnumber(L, ar.nups);
            lua_rawset(L, -3);

            buf_init(L, &rec_buf);
            mar_encode_table(L, &rec_buf, idx);

            buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf);
            buf_write(L, rec_buf.data, rec_buf.head, buf);
            buf_done(L, &rec_buf);
            lua_pop(L, 1);
        }

        break;
    }
    case LUA_TUSERDATA: {
        int tag, ref;
        lua_pushvalue(L, -1);
        lua_rawget(L, SEEN_IDX);
        if (!lua_isnil(L, -1)) {
            ref = lua_tointeger(L, -1);
            tag = MAR_TREF;
            buf_write(L, (const char*)&tag, MAR_CHR, buf);
            buf_write(L, (const char*)&ref, MAR_I32, buf);
            lua_pop(L, 1);
        }
        else {
            mar_Buffer rec_buf;
            lua_pop(L, 1); /* pop nil */
            if (luaL_getmetafield(L, -1, "__persist")) {
                tag = MAR_TUSR;

                lua_pushvalue(L, -2);
                lua_pushinteger(L, (*idx)++);
                lua_rawset(L, SEEN_IDX);

                lua_pushvalue(L, -2);
                lua_call(L, 1, 1);
                if (!lua_isfunction(L, -1)) {
                    luaL_error(L, "__persist must return a function");
                }
                lua_newtable(L);
                lua_pushvalue(L, -2);
                lua_rawseti(L, -2, 1);
                lua_remove(L, -2);

                buf_init(L, &rec_buf);
                mar_encode_table(L, &rec_buf, idx);

                buf_write(L, (const char*)&tag, MAR_CHR, buf);
                buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf);
		        buf_write(L, rec_buf.data, rec_buf.head, buf);
		        buf_done(L, &rec_buf);
            }
            else {
                luaL_error(L, "attempt to encode userdata (no __persist hook)");
            }
            lua_pop(L, 1);
        }
        break;
    }
    case LUA_TNIL: break;
    default:
        luaL_error(L, "invalid value type (%s)", lua_typename(L, val_type));
    }
    lua_pop(L, 1);
}
Beispiel #13
0
int cLuaState::CallFunctionWithForeignParams(
	const AString & a_FunctionName,
	cLuaState & a_SrcLuaState,
	int a_SrcParamStart,
	int a_SrcParamEnd
)
{
	ASSERT(IsValid());
	ASSERT(a_SrcLuaState.IsValid());
	
	// Store the stack position before any changes
	int OldTop = lua_gettop(m_LuaState);
	
	// Push the function to call, including the error handler:
	if (!PushFunction(a_FunctionName.c_str()))
	{
		LOGWARNING("Function '%s' not found", a_FunctionName.c_str());
		lua_pop(m_LuaState, 2);
		return -1;
	}

	// Copy the function parameters to the target state
	if (CopyStackFrom(a_SrcLuaState, a_SrcParamStart, a_SrcParamEnd) < 0)
	{
		// Something went wrong, fix the stack and exit
		lua_pop(m_LuaState, 2);
		m_NumCurrentFunctionArgs = -1;
		m_CurrentFunctionName.clear();
		return -1;
	}
	
	// Call the function, with an error handler:
	int s = lua_pcall(m_LuaState, a_SrcParamEnd - a_SrcParamStart + 1, LUA_MULTRET, OldTop + 1);
	if (ReportErrors(s))
	{
		LOGWARN("Error while calling function '%s' in '%s'", a_FunctionName.c_str(), m_SubsystemName.c_str());
		// Fix the stack.
		// We don't know how many values have been pushed, so just get rid of any that weren't there initially
		int CurTop = lua_gettop(m_LuaState);
		if (CurTop > OldTop)
		{
			lua_pop(m_LuaState, CurTop - OldTop);
		}
		
		// Reset the internal checking mechanisms:
		m_NumCurrentFunctionArgs = -1;
		m_CurrentFunctionName.clear();
		
		// Make Lua think everything is okay and return 0 values, so that plugins continue executing.
		// The failure is indicated by the zero return values.
		return 0;
	}
	
	// Reset the internal checking mechanisms:
	m_NumCurrentFunctionArgs = -1;
	m_CurrentFunctionName.clear();
	
	// Remove the error handler from the stack:
	lua_remove(m_LuaState, OldTop + 1);
	
	// Return the number of return values:
	return lua_gettop(m_LuaState) - OldTop;
}
Beispiel #14
0
	void dispatchEvent(int type, void *event)
	{
        luaL_rawgetptr(L, LUA_REGISTRYINDEX, &keyWeak);
        luaL_rawgetptr(L, -1, this);
        if (lua_isnil(L, -1))
        {
            lua_pop(L, 2);
            return;
        }
        
        lua_getfield(L, -1, "dispatchEvent");
		
        lua_pushvalue(L, -2);
        
        lua_getglobal(L, "Event");
        lua_getfield(L, -1, "new");
        lua_remove(L, -2);
        
        switch (type)
        {
			case GHID_KEY_DOWN_EVENT:
                lua_pushstring(L, KEY_DOWN);
                break;
			case GHID_KEY_UP_EVENT:
                lua_pushstring(L, KEY_UP);
                break;
			case GHID_RIGHT_JOYSTICK_EVENT:
                lua_pushstring(L, RIGHT_JOYSTICK);
                break;
			case GHID_LEFT_JOYSTICK_EVENT:
                lua_pushstring(L, LEFT_JOYSTICK);
                break;
			case GHID_RIGHT_TRIGGER_EVENT:
                lua_pushstring(L, RIGHT_TRIGGER);
                break;
			case GHID_LEFT_TRIGGER_EVENT:
                lua_pushstring(L, LEFT_TRIGGER);
                break;
            case GHID_AXIS_JOYSTICK_EVENT:
                lua_pushstring(L, AXIS_JOYSTICK);
                break;
			case GHID_CONNECTED_EVENT:
                lua_pushstring(L, CONNECTED);
                break;
			case GHID_DISCONNECTED_EVENT:
                lua_pushstring(L, DISCONNECTED);
                break;
        }

        lua_call(L, 1, 1);
		
		if (type == GHID_KEY_DOWN_EVENT || type == GHID_KEY_UP_EVENT)
        {
            ghid_KeyEvent *event2 = (ghid_KeyEvent*)event;
            
			lua_pushnumber(L, event2->keyCode);
			lua_setfield(L, -2, "keyCode");

            lua_pushnumber(L, event2->realCode);
            lua_setfield(L, -2, "realCode");

			lua_pushnumber(L, event2->playerId);
			lua_setfield(L, -2, "playerId");
        }
		else if (type == GHID_RIGHT_JOYSTICK_EVENT || type == GHID_LEFT_JOYSTICK_EVENT)
        {
            ghid_JoystickEvent *event2 = (ghid_JoystickEvent*)event;
			
			lua_pushnumber(L, event2->x);
			lua_setfield(L, -2, "x");
			
			lua_pushnumber(L, event2->y);
			lua_setfield(L, -2, "y");
			
			lua_pushnumber(L, event2->angle);
			lua_setfield(L, -2, "angle");
			
			lua_pushnumber(L, event2->strength);
			lua_setfield(L, -2, "strength");
			
			lua_pushnumber(L, event2->playerId);
			lua_setfield(L, -2, "playerId");
        }
		else if (type == GHID_RIGHT_TRIGGER_EVENT || type == GHID_LEFT_TRIGGER_EVENT)
        {
            ghid_TriggerEvent *event2 = (ghid_TriggerEvent*)event;
			
			lua_pushnumber(L, event2->strength);
			lua_setfield(L, -2, "strength");
			
			lua_pushnumber(L, event2->playerId);
			lua_setfield(L, -2, "playerId");
        }
        else if (type == GHID_AXIS_JOYSTICK_EVENT)
        {
            ghid_JoystickEvent *event2 = (ghid_JoystickEvent*)event;

            lua_pushnumber(L, event2->playerId);
            lua_setfield(L, -2, "playerId");

            lua_pushnumber(L, event2->strength);
            lua_setfield(L, -2, "strength");

            lua_pushnumber(L, event2->angle);
            lua_setfield(L, -2, "axis");
        }
		else if (type == GHID_CONNECTED_EVENT || type == GHID_DISCONNECTED_EVENT)
        {
            ghid_DeviceEvent *event2 = (ghid_DeviceEvent*)event;
			
			lua_pushnumber(L, event2->playerId);
            lua_setfield(L, -2, "playerId");
        }

		lua_call(L, 2, 0);
		
		lua_pop(L, 2);
	}
static int l_signal(lua_State *L)
{
  int args = lua_gettop(L);
  int t, sig; /* type, signal */

  /* get type of signal */
  luaL_checkany(L, 1);
  t = lua_type(L, 1);
  if (t == LUA_TNUMBER)
    sig = (int) lua_tonumber(L, 1);
  else if (t == LUA_TSTRING)
  {
    lua_pushstring(L, LUA_SIGNAL);
    lua_gettable(L, LUA_REGISTRYINDEX);
    lua_pushvalue(L, 1);
    lua_gettable(L, -2);
    if (!lua_isnumber(L, -1))
      luaL_error(L, "invalid signal string");
    sig = (int) lua_tonumber(L, -1);
    lua_pop(L, 1); /* get rid of number we pushed */
  } else
    luaL_checknumber(L, 1); /* will always error, with good error msg */

  /* set handler */
  if (args == 1 || lua_isnil(L, 2)) /* clear handler */
  {
    lua_pushstring(L, LUA_SIGNAL);
    lua_gettable(L, LUA_REGISTRYINDEX);
    lua_pushnumber(L, sig);
    lua_gettable(L, -2); /* return old handler */
    lua_pushnumber(L, sig);
    lua_pushnil(L);
    lua_settable(L, -4);
    lua_remove(L, -2); /* remove LUA_SIGNAL table */
    signal(sig, SIG_DFL);
  } else
  {
    luaL_checktype(L, 2, LUA_TFUNCTION);

    lua_pushstring(L, LUA_SIGNAL);
    lua_gettable(L, LUA_REGISTRYINDEX);

    lua_pushnumber(L, sig);
    lua_pushvalue(L, 2);
    lua_settable(L, -3);

    /* Set the state for the handler */
    Lsig = L;

    if (lua_toboolean(L, 3)) /* c hook? */
    {
      if (signal(sig, handle) == SIG_ERR)
        lua_pushboolean(L, 0);
      else
        lua_pushboolean(L, 1);
    } else /* lua_hook */
    {
      if (signal(sig, handle) == SIG_ERR)
        lua_pushboolean(L, 0);
      else
        lua_pushboolean(L, 1);
    }
  }
  return 1;
}
Beispiel #16
0
/* Class index function
    * If the object is a userdata (ie, an object), it searches the field in
    * the alternative table stored in the corresponding "ubox" table.
*/
static int class_index_event (lua_State* L)
{
    int t = lua_type(L,1);
    if (t == LUA_TUSERDATA)
    {
        /* Access alternative table */
#ifdef LUA_VERSION_NUM /* new macro on version 5.1 */
        lua_getfenv(L,1);
        if (!lua_rawequal(L, -1, TOLUA_NOPEER)) {
            lua_pushvalue(L, 2); /* key */
            lua_gettable(L, -2); /* on lua 5.1, we trade the "tolua_peers" lookup for a gettable call */
            if (!lua_isnil(L, -1))
                return 1;
        };
#else
        lua_pushstring(L,"tolua_peers");
        lua_rawget(L,LUA_REGISTRYINDEX);        /* stack: obj key ubox */
        lua_pushvalue(L,1);
        lua_rawget(L,-2);                       /* stack: obj key ubox ubox[u] */
        if (lua_istable(L,-1))
        {
            lua_pushvalue(L,2);  /* key */
            lua_rawget(L,-2);                      /* stack: obj key ubox ubox[u] value */
            if (!lua_isnil(L,-1))
                return 1;
        }
#endif
        lua_settop(L,2);                        /* stack: obj key */
        /* Try metatables */
        lua_pushvalue(L,1);                     /* stack: obj key obj */
        while (lua_getmetatable(L,-1))
        {   /* stack: obj key obj mt */
            lua_remove(L,-2);                      /* stack: obj key mt */
            if (lua_isnumber(L,2))                 /* check if key is a numeric value */
            {
                /* try operator[] */
                lua_pushstring(L,".geti");
                lua_rawget(L,-2);                      /* stack: obj key mt func */
                if (lua_isfunction(L,-1))
                {
                    lua_pushvalue(L,1);
                    lua_pushvalue(L,2);
                    lua_call(L,2,1);
                    return 1;
                }
            }
            else
            {
                lua_pushvalue(L,2);                    /* stack: obj key mt key */
                lua_rawget(L,-2);                      /* stack: obj key mt value */
                if (!lua_isnil(L,-1))
                    return 1;
                else
                    lua_pop(L,1);
                /* try C/C++ variable */
                lua_pushstring(L,".get");
                lua_rawget(L,-2);                      /* stack: obj key mt tget */
                if (lua_istable(L,-1))
                {
                    lua_pushvalue(L,2);
                    lua_rawget(L,-2);                      /* stack: obj key mt value */
                    if (lua_iscfunction(L,-1))
                    {
                        lua_pushvalue(L,1);
                        lua_pushvalue(L,2);
                        lua_call(L,2,1);
                        return 1;
                    }
                    else if (lua_istable(L,-1))
                    {
                        /* deal with array: create table to be returned and cache it in ubox */
                        void* u = *((void**)lua_touserdata(L,1));
                        lua_newtable(L);                /* stack: obj key mt value table */
                        lua_pushstring(L,".self");
                        lua_pushlightuserdata(L,u);
                        lua_rawset(L,-3);               /* store usertype in ".self" */
                        lua_insert(L,-2);               /* stack: obj key mt table value */
                        lua_setmetatable(L,-2);         /* set stored value as metatable */
                        lua_pushvalue(L,-1);            /* stack: obj key met table table */
                        lua_pushvalue(L,2);             /* stack: obj key mt table table key */
                        lua_insert(L,-2);               /*  stack: obj key mt table key table */
                        storeatubox(L,1);               /* stack: obj key mt table */
                        return 1;
                    }
                }
            }
            lua_settop(L,3);
        }
        lua_pushnil(L);
        return 1;
    }
    else if (t== LUA_TTABLE)
    {
        lua_pushvalue(L,1);
        class_table_get_index(L);
        return 1;
    }
    lua_pushnil(L);
    return 1;
}
Beispiel #17
0
void ReadScriptDescriptor::ClearStack(uint32 levels_to_clear)
{
    _open_tables.clear();
    for(uint32 i = 0; i < levels_to_clear; ++i)
        lua_remove(_lstack, 0);
}
Beispiel #18
0
/* Newindex function
    * It first searches for a C/C++ varaible to be set.
    * Then, it either stores it in the alternative ubox table (in the case it is
    * an object) or in the own table (that represents the class or module).
*/
static int class_newindex_event (lua_State* L)
{
    int t = lua_type(L,1);
    if (t == LUA_TUSERDATA)
    {
        /* Try accessing a C/C++ variable to be set */
        lua_getmetatable(L,1);
        while (lua_istable(L,-1))                /* stack: t k v mt */
        {
            if (lua_isnumber(L,2))                 /* check if key is a numeric value */
            {
                /* try operator[] */
                lua_pushstring(L,".seti");
                lua_rawget(L,-2);                      /* stack: obj key mt func */
                if (lua_isfunction(L,-1))
                {
                    lua_pushvalue(L,1);
                    lua_pushvalue(L,2);
                    lua_pushvalue(L,3);
                    lua_call(L,3,0);
                    return 0;
                }
            }
            else
            {
                lua_pushstring(L,".set");
                lua_rawget(L,-2);                      /* stack: t k v mt tset */
                if (lua_istable(L,-1))
                {
                    lua_pushvalue(L,2);
                    lua_rawget(L,-2);                     /* stack: t k v mt tset func */
                    if (lua_iscfunction(L,-1))
                    {
                        lua_pushvalue(L,1);
                        lua_pushvalue(L,3);
                        lua_call(L,2,0);
                        return 0;
                    }
                    lua_pop(L,1);                          /* stack: t k v mt tset */
                }
                lua_pop(L,1);                           /* stack: t k v mt */
                if (!lua_getmetatable(L,-1))            /* stack: t k v mt mt */
                    lua_pushnil(L);
                lua_remove(L,-2);                       /* stack: t k v mt */
            }
        }
        lua_settop(L,3);                          /* stack: t k v */

        /* then, store as a new field */
        storeatubox(L,1);
    }
    else if (t== LUA_TTABLE)
    {
        lua_getmetatable(L,1);  /* stack: t k v mt */
        lua_pushstring(L,".set");
        lua_rawget(L,-2);       /* stack: t k v mt tset */
        if (lua_istable(L,-1)) {
            lua_pushvalue(L,2);  /* stack: t k v mt tset k */
            lua_rawget(L,-2);
            if (lua_iscfunction(L,-1)) {  /* ... func */
                lua_pushvalue(L,1); /* ... func t */
                lua_pushvalue(L,3); /* ... func t v */
                lua_call(L,2,0);
                return 0;
            }
        }
		lua_settop(L,3);
        class_backup_before_newindex(L);
		lua_settop(L,3);
        lua_getmetatable(L,1);  /* stack: t k v mt */
        lua_replace(L, 1);      /* stack: mt k v */
		lua_rawset(L,1);
    }
    return 0;
}
Beispiel #19
0
static int
luaA_sysctl_get(lua_State *L)
{
	int	nlen;
	int	i;
	int	oid[CTL_MAXNAME];
	int	ctltype;
	u_int	kind;
	size_t	len;
	size_t	intlen;
	uintmax_t umv;
	intmax_t mv;
	char	fmt[BUFSIZ];
	char	buf[BUFSIZ];
	char	*val, *oval, *p;
	int (*func)(lua_State *, int, void *);

	bzero(fmt, BUFSIZ);
	bzero(buf, BUFSIZ);

	/* get first argument from lua */
	len = strlcpy(buf, luaL_checkstring(L, 1), sizeof(buf));
	if (len >= sizeof(buf))
		return (luaL_error(L, "oid too long"));

	nlen = name2oid(buf, oid);
	if (nlen < 0)
		return (luaL_error(L, "%s: unknown iod", buf));
	if (oidfmt(oid, nlen, fmt, sizeof(fmt), &kind) != 0)
		return (luaL_error(L, "couldn't find format of oid '%s'", buf));
	if ((kind & CTLTYPE) == CTLTYPE_NODE)
		return (luaL_error(L, "can't handle CTLTYPE_NODE"));

	/* find an estimate of how much we need for this var */
	len = 0;
	(void)sysctl(oid, nlen, NULL, &len, NULL, 0);
	len += len; /* we want to be sure :-) */
	val = oval = malloc(len + 1);
	if (val == NULL)
		return (luaL_error(L, "malloc failed"));

	i = sysctl(oid, nlen, val, &len, NULL, 0);
	if (i || !len) {
		free(oval);
		return (luaL_error(L, "sysctl failed"));
	}
	val[len] = '\0';

	p = val;
	ctltype = (kind & CTLTYPE);
	intlen = ctl_size[ctltype];

	switch (ctltype) {
	case CTLTYPE_STRING:
		lua_pushstring(L, p);
		break;
	case CTLTYPE_INT:    /* FALLTHROUGH */
	case CTLTYPE_UINT:   /* FALLTHROUGH */
	case CTLTYPE_LONG:   /* FALLTHROUGH */
	case CTLTYPE_ULONG:  /* FALLTHROUGH */
#if __FreeBSD_version < 900000
	case CTLTYPE_QUAD:
#else
	case CTLTYPE_S64:    /* FALLTHROUGH */
	case CTLTYPE_U64:
#endif
		/* an intlen of 0 or less will make us loop indefinitely */
		if (intlen <= 0) {
			free(oval);
			return (luaL_error(L, "sysctl error (intlen == %zd)", intlen));
		}
		i = 0;
		lua_newtable(L);
		while (len >= intlen) {
			i++;
			switch (ctltype) {
			case CTLTYPE_INT:  /* FALLTHROUGH */
			case CTLTYPE_UINT:
				umv = *(u_int *)p;
				mv = *(int *)p;
				break;
			case CTLTYPE_LONG:   /* FALLTHROUGH */
			case CTLTYPE_ULONG:
				umv = *(u_long *)p;
				mv = *(long *)p;
				break;
#if __FreeBSD_version < 900000
			case CTLTYPE_QUAD:
				umv = *(u_quad_t *)p;
				mv = *(quad_t *)p;
#else
			case CTLTYPE_S64: /* FALLTHROUGH */
			case CTLTYPE_U64:
				umv = *(uint64_t *)p;
				mv = *(int64_t *)p;
#endif
				break;
			default:
				return (luaL_error(L, "sysctl error (bug)"));
			  	/* NOTREACHED */
			}
			lua_pushinteger(L, i);
			switch (ctltype) {
			case CTLTYPE_INT:  /* FALLTHROUGH */
			case CTLTYPE_LONG:
				lua_pushinteger(L, mv);
				break;
			case CTLTYPE_UINT: /* FALLTHROUGH */
			case CTLTYPE_ULONG:
				lua_pushinteger(L, umv);
				break;
#if __FreeBSD_version < 900000
			case CTLTYPE_QUAD:
				lua_pushnumber(L, mv);
				break;
#else
			case CTLTYPE_S64:
				lua_pushnumber(L, mv);
				break;
			case CTLTYPE_U64:
				lua_pushnumber(L, umv);
				break;
#endif
			default:
				return (luaL_error(L, "sysctl error (bug)"));
			  	/* NOTREACHED */
			}
			lua_settable(L, -3);
			len -= intlen;
			p += intlen;
		}
		if (i == 1) {
			lua_pushinteger(L, i);
			lua_gettable(L, -2);
			lua_remove(L, lua_gettop(L) - 1); /* remove table */
		}
		break;
	case CTLTYPE_OPAQUE:
		if (strcmp(fmt, "S,clockinfo") == 0)
			func = S_clockinfo;
		else if (strcmp(fmt, "S,loadavg") == 0)
			func = S_loadavg;
		else if (strcmp(fmt, "S,timeval") == 0)
			func = S_timeval;
		else if (strcmp(fmt, "S,vmtotal") == 0)
			func = S_vmtotal;
		else if (strcmp(fmt, "T,dev_t") == 0)
			func = T_dev_t;
		else
			func = NULL;

		if (func) {
			(*func)(L, len, val);
			break;
		}
		/* FALLTHROUGH */
	default:
		free(oval);
		return (luaL_error(L, "unknown CTLTYPE: fmt=%s ctltype=%d",
		    fmt, ctltype));
	}
	free(oval);
	lua_pushstring(L, fmt);
	return (2); /* two returned value */
}
Beispiel #20
0
	void LuaInstance::Remove(int index) const
	{
		lua_remove(m_state, index);
	}
Beispiel #21
0
void siplua_register_watch_cclosures(lua_State *L)
{
  lua_pushvalue(L, LUA_GLOBALSINDEX);
  luaL_openlib(L, NULL, siplua_watch_mylib, 0);
  lua_remove(L, -1);
}
Beispiel #22
0
/**
 * Set the premake.path variable, pulling from the --scripts argument
 * and PREMAKE_PATH environment variable if present.
 */
static void build_premake_path(lua_State* L)
{
	int top;
	const char* value;

	lua_getglobal(L, "premake");
	top = lua_gettop(L);

	/* Start by searching the current working directory */
	lua_pushstring(L, ".");

	/* The --scripts argument goes next, if present */
	if (scripts_path) {
		lua_pushstring(L, ";");
		lua_pushstring(L, scripts_path);
	}

	/* Then the PREMAKE_PATH environment variable */
	value = getenv("PREMAKE_PATH");
	if (value) {
		lua_pushstring(L, ";");
		lua_pushstring(L, value);
	}

	/* Then in ~/.premake */
	lua_pushstring(L, ";");
	lua_getglobal(L, "_USER_HOME_DIR");
	lua_pushstring(L, "/.premake");

	/* In the user's Application Support folder */
#if defined(PLATFORM_MACOSX)
	lua_pushstring(L, ";");
	lua_getglobal(L, "_USER_HOME_DIR");
	lua_pushstring(L, "/Library/Application Support/Premake");
#endif

	/* In the /usr tree */
	lua_pushstring(L, ";/usr/local/share/premake;/usr/share/premake");

	/* Put it all together */
	lua_concat(L, lua_gettop(L) - top);

	/* Match Lua's package.path; use semicolon separators */
#if !defined(PLATFORM_WINDOWS)
	lua_getglobal(L, "string");
	lua_getfield(L, -1, "gsub");
	lua_pushvalue(L, -3);
	lua_pushstring(L, ":");
	lua_pushstring(L, ";");
	lua_call(L, 3, 1);
	/* remove the string global table */
	lua_remove(L, -2);
	/* remove the previously concatonated result */
	lua_remove(L, -2);
#endif

	/* Store it in premake.path */
	lua_setfield(L, -2, "path");

	/* Remove the premake namespace table */
	lua_pop(L, 1);
}
Beispiel #23
0
LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
  lua_State *L = B->L;
  lua_pushlstring(L, B->b, B->n);
  if (buffonstack(B))
    lua_remove(L, -2);  /* remove old buffer */
}
void LuaUtils::PushCurrentFuncEnv(lua_State* L, const char* caller)
{
	PushCurrentFunc(L, caller);
	PushFunctionEnv(L, caller, -1);
	lua_remove(L, -2); // remove the function
}
Beispiel #25
0
int w_World_getCallbacks(lua_State *L)
{
	World *t = luax_checkworld(L, 1);
	lua_remove(L, 1);
	return t->getCallbacks(L);
}
Beispiel #26
0
static int errfile (lua_State *L, int fnameindex) {
  const char *filename = lua_tostring(L, fnameindex) + 1;
  lua_pushfstring(L, "cannot read %s: %s", filename, strerror(errno));
  lua_remove(L, fnameindex);
  return LUA_ERRFILE;
}
Beispiel #27
0
int w_World_getGravity(lua_State *L)
{
	World *t = luax_checkworld(L, 1);
	lua_remove(L, 1);
	return t->getGravity(L);
}
Beispiel #28
0
int script_func_exec(const char *func, const char *sig, ...)
{
    int lev = 1; /* `func` is global function */
    int err = 0;
    size_t tok_len = 0;
    const char *cur_mod = func,  *mod;
    char module[MAX_MODULE_NAME_LENGTH];

    lua_getglobal(L, "_G");
    if (!lua_istable(L, -1)) {
        lua_pop(L, lev);
        LOG_ERROR("script", "%s", "Global table is NOT available.");
        return SCRIPT_RC_ERROR;
    }
    while ((mod = strchr(cur_mod, '.'))) {
        tok_len = mod - cur_mod;
        strncpy(module, cur_mod, tok_len);
        module[tok_len] = '\0';
        cur_mod = mod + 1;
        lua_getfield(L, -1, module);
        ++lev;
        if (!lua_istable(L, -1)) {
            lua_pop(L, lev);
            LOG_ERROR("script", "`%s()` is NOT recognized as a Lua function.",
                func);
            return SCRIPT_RC_ERROR;
        }
    }
    lua_getfield(L, -1, cur_mod); /* function */
    if (!lua_isfunction(L, -1)) {
        lua_pop(L, lev + 1);
        LOG_ERROR("script", "`%s()` is NOT recognized as a Lua function.",
            func);
        return SCRIPT_RC_ERROR;
    }

    va_list args;
    va_start(args, sig);
    int argc = 0;

    /* parse input arguments */
    for (; sig && *sig && *sig != '>'; ++sig, ++argc) {
        switch (*sig) {
        case 'i': /* integer */
            lua_pushnumber(L, va_arg(args, int));
            break;
        case 's': /* string */
            lua_pushstring(L, va_arg(args, char *));
            break;
        case 'f': /* double */
            lua_pushnumber(L, va_arg(args, double));
            break;
        default: /* double */
            LOG_ERROR("script", "invalid option (%c)", *sig);
            lua_pop(L, lev + argc);
            return SCRIPT_RC_ERROR;
        }
    }

    int handler = lua_gettop(L) - argc;

    lua_pushcfunction(L, script_traceback);
    lua_insert(L, handler);
    err = lua_pcall(L, argc, LUA_MULTRET, handler);
    lua_remove(L, handler);
    va_end(args);
    if (err) {
        return script_error(L);
    }
    lua_pop(L, lev);
    return SCRIPT_RC_OK;
}
Beispiel #29
0
int pklua_lua_pkm_get_metrics(lua_State* L)
{
  struct pk_global_state* state = &pk_state;

  pk_log(PK_LOG_LUA_DEBUG, "pklua_lua_pkm_get_metrics(%p)", L);
  int n = lua_gettop(L);
  if (n != 1 || !lua_istable(L, 1)) {
    lua_pushstring(L, "Incorrect arguments in get_metrics");
    return lua_error(L);
  }

  lua_getfield(L, 1, "_pkm");
  if (!lua_islightuserdata(L, -1)) {
    lua_pushstring(L, "Incorrect arguments in get_metrics (2)");
    return lua_error(L);
  }
  struct pk_manager* manager = lua_touserdata(L, -1);
  lua_remove(L, -1);

  lua_newtable(L);
  int metrics = lua_gettop(L); /* Relatives offsets would break below */

  lua_pushstring(L, PK_VERSION);
  lua_setfield(L, metrics, "libpagekite_version");
  #define PKM_INT(s, n) lua_pushinteger(L, s->n);\
                        lua_setfield(L, metrics, #s"_"#n)
  #define PKM_STR(s, n) lua_pushstring(L, (s->n == NULL) ? "(null)" : s->n);\
                        lua_setfield(L, metrics, #s"_"#n)
  PKM_INT(manager, status);
  PKM_INT(manager, last_world_update);
  PKM_INT(manager, next_tick);
  PKM_INT(manager, enable_timer);
  PKM_INT(manager, last_dns_update);
  PKM_INT(manager, kite_max);
  PKM_INT(manager, tunnel_max);
  PKM_INT(manager, be_conn_max);
  PKM_INT(manager, fancy_pagekite_net_rejection);
  PKM_INT(manager, enable_watchdog);
  PKM_INT(manager, want_spare_frontends);
  PKM_INT(manager, housekeeping_interval_min);
  PKM_INT(manager, housekeeping_interval_max);
  PKM_INT(manager, check_world_interval);
  PKM_STR(manager, dynamic_dns_url);
  PKM_INT(state, live_streams);
  PKM_INT(state, live_tunnels);
  PKM_INT(state, live_listeners);
  PKM_STR(state, app_id_short);
  PKM_STR(state, app_id_long);
  PKM_INT(state, quota_days);
  PKM_INT(state, quota_conns);
  PKM_INT(state, quota_mb);

  /* Copy Lua metrics from master Lua context */
  pk_lua_t* mgr_lua;
  if ((mgr_lua = pklua_lock_lua(manager->lua)) != NULL) {

    lua_State* ML = mgr_lua->lua;
    lua_getfield(ML, LUA_GLOBALSINDEX, "pklua");
    lua_getfield(ML, -1, "metrics");
    /* ML stack: -1=metrics, -2=pklua */

    lua_pushnil(ML);
    while (lua_next(ML, -2)) {
      /* copy key and value so lua_tostring doesn't corrupt */
      lua_pushvalue(ML, -2);
      lua_pushvalue(ML, -2);
      /* ML stack: -1=value copy, -2=key copy, -3=value, -4=key, -5=metrics */

      lua_pushinteger(L, lua_tointeger(ML, -1));
      lua_setfield(L, metrics, lua_tostring(ML, -2));

      lua_pop(ML, 3);
      /* ML stack: -1=key, -2=metrics */
    }

    lua_remove(ML, -1);
    lua_remove(ML, -1);
    pklua_unlock_lua(mgr_lua);
  }

  /* L stack: -1 = new table */
  return 1;
}
Beispiel #30
0
int
get_pgfunc(lua_State *L)
{
	Lua_pgfunc *lf;
	Pgfunc_options opt;
	MemoryContext m;
	const char* reg_name = NULL;
	HeapTuple proctup;
	Form_pg_proc proc;
	int luasrc = 0;
	Oid funcid = 0;

	BEGINLUA;

	opt.only_internal = true;
	opt.throwable = true;

	if (lua_gettop(L) == 2){
		luaL_checktype(L, 2, LUA_TTABLE);
		parse_options(L, &opt);
	}else if (lua_gettop(L) != 1){
		return luaL_error(L, "pgfunc(text): wrong arguments");
	}
	if(lua_type(L, 1) == LUA_TSTRING){
		reg_name = luaL_checkstring(L, 1);
		m = MemoryContextSwitchTo(tmpcontext);
		PG_TRY();
		{
			funcid = DatumGetObjectId(DirectFunctionCall1(regprocedurein, CStringGetDatum(reg_name)));
		}
		PG_CATCH();{}
		PG_END_TRY();
		MemoryContextSwitchTo(m);
		MemoryContextReset(tmpcontext);
	}else if (lua_type(L, 1) == LUA_TNUMBER){
		funcid = luaL_checkinteger(L, 1);
	}

	if (!OidIsValid(funcid)){
		if (reg_name)
			return luaL_error(L,"failed to register %s", reg_name);
		return luaL_error(L,"failed to register function with oid %d", funcid);
	}

	proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
	if (!HeapTupleIsValid(proctup)){
		return luaL_error(L,"cache lookup failed for function %d", funcid);
	}

	proc = (Form_pg_proc) GETSTRUCT(proctup);

	luasrc = ((proc->prolang == get_pllua_oid())
		  || (proc->prolang == get_plluau_oid()));
	if ( opt.only_internal
			&&(proc->prolang != INTERNALlanguageId)
			&&(!luasrc) ){
		ReleaseSysCache(proctup);
		return luaL_error(L, "supported only SQL/internal functions");
	}


	lf = (Lua_pgfunc *)lua_newuserdata(L, sizeof(Lua_pgfunc));

	/*make it g/collected*/
	luaP_getfield(L, pg_func_type_name);
	lua_setmetatable(L, -2);


	lf->prorettype = proc->prorettype;
	lf->funcid = funcid;
	lf->options = opt;

	{
		Oid *argtypes;
		char **argnames;
		char *argmodes;
		int argc;
		MemoryContext cur = CurrentMemoryContext;

		MemoryContextSwitchTo(tmpcontext);

		argc = get_func_arg_info(proctup,
					 &argtypes, &argnames, &argmodes);

		MemoryContextSwitchTo(get_common_ctx());

		lf->numargs = argc;
		lf->argtypes = (Oid*)palloc(argc * sizeof(Oid));
		memcpy(lf->argtypes, argtypes, argc * sizeof(Oid));
		MemoryContextSwitchTo(cur);
		MemoryContextReset(tmpcontext);
	}

	if (luasrc){
		bool isnull;
		text *t;
		const char *s;
		luaL_Buffer b;
		int pcall_result;
		Datum prosrc;

		if((lf->numargs != 1)
				|| (lf->argtypes[0] != INTERNALOID)
				|| (lf->prorettype != INTERNALOID)){
			luaL_error(L, "pgfunc accepts only 'internal' pllua/u functions with internal argument");
		}

		prosrc = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_prosrc, &isnull);
		if (isnull) elog(ERROR, "[pgfunc]: null lua prosrc");
		luaL_buffinit(L, &b);

		luaL_addstring(&b,"do ");
		t = DatumGetTextP(prosrc);
		luaL_addlstring(&b, VARDATA(t), VARSIZE(t) - VARHDRSZ);
		luaL_addstring(&b, " end");
		luaL_pushresult(&b);
		s = lua_tostring(L, -1);

		ReleaseSysCache(proctup);
		clean_pgfuncinfo(lf);

		if (luaL_loadbuffer(L, s, strlen(s), "pgfunc chunk"))
			luaL_error(L, "compile");

		lua_remove(L, -2); /*delete source element*/

		pcall_result = lua_pcall(L, 0, 1, 0);
		lua_remove(L, -2); /*delete chunk*/
		if(pcall_result == 0){
			ENDLUAV(1);
			return 1;
		}

		if( pcall_result == LUA_ERRRUN)
			luaL_error(L,"%s %s","Runtime error:",lua_tostring(L, -1));
		else if(pcall_result == LUA_ERRMEM)
			luaL_error(L,"%s %s","Memory error:",lua_tostring(L, -1));
		else if(pcall_result == LUA_ERRERR)
			luaL_error(L,"%s %s","Error:",lua_tostring(L, -1));

		return luaL_error(L, "pgfunc unknown error");
	}

	if(proc->proretset) {
		lua_pushcclosure(L, pgfunc_rows, 1);
	} else {
		fmgr_info(funcid, &lf->fi);
		lua_pushcclosure(L, pg_callable_func, 1);
	}



	ReleaseSysCache(proctup);

	ENDLUAV(1);
	return 1;
}