pkg/lua: Provide better integration with RIOT
- Remove file related functions from loader. * All packages must be builtin. - Remove os.tmpname. - Interface with TLSF. - Don't abort() when out of memory.
This commit is contained in:
parent
32e823acb2
commit
ed4411602c
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 FU Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Basic lua example application
|
||||
*
|
||||
* @author Daniel Petry <daniel.petry@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
|
||||
#include "main.lua.h"
|
||||
|
||||
int lua_run_script(const char *buffer, size_t buffer_len)
|
||||
{
|
||||
|
||||
lua_State *L = luaL_newstate();
|
||||
|
||||
if (L == NULL) {
|
||||
puts("cannot create state: not enough memory");
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
luaL_openlibs(L);
|
||||
luaL_loadbuffer(L, buffer, buffer_len, "lua input script");
|
||||
|
||||
if (lua_pcall(L, 0, 0, 0) != LUA_OK){
|
||||
puts("Lua script running failed");
|
||||
return EINTR;
|
||||
}
|
||||
|
||||
lua_close(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
puts("Lua RIOT build");
|
||||
lua_run_script(main_lua, main_lua_len);
|
||||
return 0;
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
APPLICATION = lua
|
||||
APPLICATION = lua_basic
|
||||
|
||||
# If no BOARD is found in the environment, use this default:
|
||||
BOARD ?= native
|
||||
@ -29,12 +29,10 @@ DEVELHELP ?= 1
|
||||
# Change this to 0 show compiler invocation lines by default:
|
||||
QUIET ?= 1
|
||||
|
||||
USEMODULE += ps
|
||||
|
||||
ifneq ($(BOARD),native)
|
||||
# This stack size is large enough to run Lua print() functions of
|
||||
# various lengths. Other functions untested.
|
||||
CFLAGS += -DTHREAD_STACKSIZE_MAIN=4096
|
||||
CFLAGS += -DTHREAD_STACKSIZE_MAIN='(THREAD_STACKSIZE_DEFAULT+2048)'
|
||||
endif
|
||||
|
||||
USEPKG += lua
|
||||
@ -61,6 +59,6 @@ $(LUA_PATH)/:
|
||||
$(LUA_H): | $(LUA_PATH)/
|
||||
$(LUA_H): $(LUA_PATH)/%.lua.h: %.lua
|
||||
|
||||
xxd -i $< | sed 's/^unsigned/const/g' > $@
|
||||
xxd -i $< | sed 's/^unsigned/const unsigned/g' > $@
|
||||
|
||||
$(RIOTBUILD_CONFIG_HEADER_C): $(LUA_H)
|
||||
61
examples/lua_basic/main.c
Normal file
61
examples/lua_basic/main.c
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2018 FU Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Basic lua example application
|
||||
*
|
||||
* @author Daniel Petry <daniel.petry@fu-berlin.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
#include "lua_run.h"
|
||||
|
||||
#include "main.lua.h"
|
||||
|
||||
#define LUA_MEM_SIZE (11000)
|
||||
static char lua_mem[LUA_MEM_SIZE] __attribute__ ((aligned(__BIGGEST_ALIGNMENT__)));
|
||||
|
||||
int lua_run_script(const uint8_t *buffer, size_t buffer_len)
|
||||
{
|
||||
lua_State *L = lua_riot_newstate(lua_mem, sizeof(lua_mem), NULL);
|
||||
|
||||
if (L == NULL) {
|
||||
puts("cannot create state: not enough memory");
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
lua_riot_openlibs(L, LUAR_LOAD_BASE);
|
||||
luaL_loadbuffer(L, (const char *)buffer, buffer_len, "lua input script");
|
||||
|
||||
if (lua_pcall(L, 0, 0, 0) != LUA_OK) {
|
||||
puts("Lua script running failed");
|
||||
return EINTR;
|
||||
}
|
||||
|
||||
lua_close(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
puts("Lua RIOT build");
|
||||
lua_run_script(main_lua, main_lua_len);
|
||||
puts("Lua interpreter exited");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,11 +1,12 @@
|
||||
PKG_NAME=lua
|
||||
PKG_URL=https://github.com/lua/lua.git
|
||||
# tag: v5-3-4
|
||||
PKG_VERSION=e354c6355e7f48e087678ec49e340ca0696725b1
|
||||
PKG_LICENSE=MIT
|
||||
|
||||
.PHONY: all
|
||||
|
||||
all:
|
||||
all: Makefile.lua
|
||||
@cp Makefile.lua $(PKG_BUILDDIR)
|
||||
"$(MAKE)" -C $(PKG_BUILDDIR) -f Makefile.lua
|
||||
|
||||
|
||||
3
pkg/lua/Makefile.dep
Normal file
3
pkg/lua/Makefile.dep
Normal file
@ -0,0 +1,3 @@
|
||||
USEPKG += tlsf
|
||||
USEMODULE += lua-contrib
|
||||
USEMODULE += printf_float
|
||||
@ -1 +1,3 @@
|
||||
INCLUDES += -I$(PKGDIRBASE)/lua
|
||||
INCLUDES += -I$(RIOTPKG)/lua/include
|
||||
DIRS += $(RIOTPKG)/lua/contrib
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
SRC := $(filter-out lua.c luac.c,$(wildcard *.c))
|
||||
SRC := $(filter-out loadlib.c lua.c luac.c,$(wildcard *.c))
|
||||
|
||||
# This builds for native using POSIX system calls and some extra libraries, and
|
||||
# removes a compiler warning that warns against using tmpnam().
|
||||
ifeq ($(BOARD),native)
|
||||
CFLAGS += -DLUA_USE_LINUX
|
||||
endif
|
||||
CFLAGS += -fstack-usage -fconserve-stack \
|
||||
-DLUA_MAXCAPTURES=16 \
|
||||
-DL_MAXLENNUM=50
|
||||
# Enable these options to debug stack usage
|
||||
# -Wstack-usage=128 -Wno-error=stack-usage=128
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
||||
3
pkg/lua/contrib/Makefile
Normal file
3
pkg/lua/contrib/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = lua-contrib
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
51
pkg/lua/contrib/binsearch.c
Normal file
51
pkg/lua/contrib/binsearch.c
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief Generic binary search for tables containing strings.
|
||||
* @author Juan Carrano <j.carrano@fu-berlin.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "binsearch.h"
|
||||
|
||||
int binsearch_str(const void *start, size_t offset, size_t stride, size_t nmemb,
|
||||
const char *str, size_t n)
|
||||
{
|
||||
const uint8_t *cstart = (((const uint8_t *)start) + offset);
|
||||
size_t lo = 0, hi = nmemb;
|
||||
|
||||
while (lo < hi) {
|
||||
size_t mid = (lo + hi) / 2;
|
||||
const char *target = *((const char *const *)(cstart + mid * stride));
|
||||
int cmp = strncmp(str, target, n);
|
||||
|
||||
if (cmp == 0) {
|
||||
return mid;
|
||||
}
|
||||
else if (cmp < 0) {
|
||||
hi = mid;
|
||||
}
|
||||
else { /* (cmp > 0) */
|
||||
lo = mid + 1;
|
||||
}
|
||||
}
|
||||
return (-ENOENT);
|
||||
}
|
||||
|
||||
const void *binsearch_str_p(const void *start, size_t offset, size_t stride,
|
||||
size_t nmemb, const char *str, size_t n)
|
||||
{
|
||||
int ix = binsearch_str(start, offset, stride, nmemb, str, n);
|
||||
|
||||
return (ix == (-ENOENT)) ? NULL : (const uint8_t *)start + ix * stride;
|
||||
}
|
||||
139
pkg/lua/contrib/binsearch.h
Normal file
139
pkg/lua/contrib/binsearch.h
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @{
|
||||
* @file
|
||||
*
|
||||
* @brief Generic binary search for tables containing strings.
|
||||
* @author Juan Carrano <j.carrano@fu-berlin.de>
|
||||
*
|
||||
* It is often the case that one has an array of structs, where one of the
|
||||
* members of the struct is a string pointer containing a key that must be
|
||||
* searched. If the array is sorted by this key and of known length, a binary
|
||||
* search can be performed.
|
||||
*
|
||||
* To make the code generic we must reinterpret the structure array
|
||||
* as an array of pointers to string with a stride (separation in bytes between
|
||||
* elements) and offset (position of the first element relative to the start of
|
||||
* the array) given by the struct definition.
|
||||
*
|
||||
* For example, given the following struct and array definitions and assuming
|
||||
* a 32 bit platform with strict aligment:
|
||||
* struct s1 {
|
||||
* int a; // Takes up 4 bytes
|
||||
* char *name; // Takes up 4 bytes
|
||||
* char m; // Takes up 1 byte
|
||||
* };
|
||||
* struct s1 my_table[] = {......};
|
||||
*
|
||||
* Then each element of my_table will be aligned to 12 bytes. The address of the
|
||||
* "name" field of the first elements will be 4 bytes more than the address of
|
||||
* "my_table". With this two numbers we can compute the address of the i-th
|
||||
* "name" field as:
|
||||
* [address of my_table] + offset + i*stride
|
||||
* Where stride=12 bytes and offset = 4 bytes.
|
||||
*/
|
||||
|
||||
#ifndef BINSEARCH_H
|
||||
#define BINSEARCH_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Produce a compiler error if x is not an lvalue.
|
||||
*/
|
||||
#define _ENSURE_LVALUE(x) ((void)sizeof(&(x)))
|
||||
|
||||
/**
|
||||
* UNSAFE MACRO: Difference in bytes between the addresses of two consecutive
|
||||
* array elements.
|
||||
*/
|
||||
#define _ARRAY_STRIDE(arr) ((size_t)((uint8_t *)((arr) + 1) - (uint8_t *)(arr)))
|
||||
|
||||
/**
|
||||
* UNSAFE MACRO: Offset in bytes from the start of the array to member "member"
|
||||
* of the first element.
|
||||
*/
|
||||
#define _ARRAY_MEMBER_OFFS(arr, member) \
|
||||
((size_t)((uint8_t *)(&((arr)->member)) - (uint8_t *)(arr)))
|
||||
|
||||
/**
|
||||
* Find the index of the array element that contains "str" in
|
||||
* member "member".
|
||||
*
|
||||
* A compile-time error will be raised if arr is not an lvalue. This ensures the
|
||||
* macro is safe.
|
||||
*
|
||||
* @return Index of the array element containing the string.
|
||||
* @return (-ENOENT) if it is not found.
|
||||
*/
|
||||
#define BINSEARCH_STR(arr, nmemb, member, str, n) \
|
||||
(_ENSURE_LVALUE(arr), \
|
||||
(binsearch_str((arr), _ARRAY_MEMBER_OFFS(arr, member), _ARRAY_STRIDE(arr), \
|
||||
(nmemb), (str), (n))) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Find a pointer of the array element that contains "str" in
|
||||
* member "member".
|
||||
*
|
||||
* @return Address of the element containing the string (as a void pointer).
|
||||
* @return Null if it is not found.
|
||||
*/
|
||||
#define BINSEARCH_STR_P(arr, nmemb, member, str, n) \
|
||||
(_ENSURE_LVALUE(arr), \
|
||||
(binsearch_str_p((arr), _ARRAY_MEMBER_OFFS(arr, member), _ARRAY_STRIDE(arr), \
|
||||
(nmemb), (str), (n))) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Search for an array element containing a string.
|
||||
*
|
||||
* This does NOT check for NULL pointers, though start can be NULL of the size
|
||||
* (nmemb) is zero.
|
||||
*
|
||||
* @param start Pointer to start of array. The array must be ordered
|
||||
* according to the search string.
|
||||
* @param offset Offset of member containing string within structure. This
|
||||
* can be determined using offsetof.
|
||||
* @param stride Difference in bytes between the addresses of two consecutive
|
||||
* array elements.
|
||||
* @param nmemb Number of elements in the array.
|
||||
* @param str String that will be compared against.
|
||||
* @param n Compare up to n characters (see strncmp())
|
||||
*
|
||||
* @return Index of the array element containing the string.
|
||||
* @return (-ENOENT) if it is not found.
|
||||
*/
|
||||
int binsearch_str(const void *start, size_t offset, size_t stride, size_t nmemb,
|
||||
const char *str, size_t n);
|
||||
|
||||
/**
|
||||
* Like binsearch_str but returns the pointer to the element.
|
||||
*
|
||||
* @return Address of the element containing the string.
|
||||
* @return Null if it is not found.
|
||||
*/
|
||||
const void *binsearch_str_p(const void *start, size_t offset, size_t stride,
|
||||
size_t nmemb, const char *str, size_t n);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* BINSEARCH_H */
|
||||
263
pkg/lua/contrib/lua_loadlib.c
Normal file
263
pkg/lua/contrib/lua_loadlib.c
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (C) 1994-2017 Lua.org, PUC-Rio.
|
||||
* Copyright (C) 2018 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
/**
|
||||
* @ingroup pkg_lua
|
||||
* @{
|
||||
* @file
|
||||
*
|
||||
* @brief Replacement for the lua "package" module.
|
||||
* @author Juan Carrano <j.carrano@fu-berlin.de>
|
||||
* @author Roberto Ierusalimschy
|
||||
*
|
||||
* This file replaces the loadlib.c that comes with lua. It removes support
|
||||
* for files (both lua files and c shared objects) and dynamic loading since
|
||||
* none of these are present in RIOT.
|
||||
*
|
||||
* Instead, modules are searched in statically defined tables. In the case
|
||||
* of C modules, the table contains pointers to C functions that act as module
|
||||
* loaders. For pure Lua modules, the source code must be given as a string
|
||||
* embedded in the application binary.
|
||||
*
|
||||
*/
|
||||
|
||||
#define loadlib_c
|
||||
#define LUA_LIB
|
||||
|
||||
#include "lprefix.h"
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
|
||||
#include "binsearch.h"
|
||||
|
||||
#include "lua_builtin.h"
|
||||
#include "lua_loadlib.h"
|
||||
|
||||
/* ======================== 'searchers' functions =========================== */
|
||||
|
||||
static int _ll_searcher_builtin_lua(lua_State *L, const char *name)
|
||||
{
|
||||
const struct lua_riot_builtin_lua *lmodule =
|
||||
BINSEARCH_STR_P(lua_riot_builtin_lua_table,
|
||||
lua_riot_builtin_lua_table_len,
|
||||
name, name, LUAR_MAX_MODULE_NAME);
|
||||
|
||||
if (lmodule != NULL) {
|
||||
int load_result = luaL_loadbuffer(L, (const char *)lmodule->code,
|
||||
lmodule->code_size,
|
||||
lmodule->name);
|
||||
if (load_result == LUA_OK) {
|
||||
lua_pushstring(L, name); /* will be 2nd argument to module */
|
||||
}
|
||||
|
||||
return load_result;
|
||||
}
|
||||
else {
|
||||
return LUAR_MODULE_NOTFOUND;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search in the list of pure lua modules.
|
||||
*
|
||||
* If the module is found, the source code is compiled and the compiled chunk
|
||||
* is placed on the lua stack, followed by the module name (as a string).
|
||||
*/
|
||||
static int searcher_builtin_lua(lua_State *L)
|
||||
{
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
int load_result = _ll_searcher_builtin_lua(L, name);
|
||||
|
||||
switch (load_result) {
|
||||
case LUA_OK:
|
||||
return 2; /* there are two elements in the stack */
|
||||
case LUAR_MODULE_NOTFOUND:
|
||||
return luaL_error(L, "Module '%s' not found in Lua-builtins",
|
||||
lua_tostring(L, 1));
|
||||
default:
|
||||
return luaL_error(L, "error loading module '%s' from Lua-builtins: \n%s",
|
||||
lua_tostring(L, 1), lua_tostring(L, 2));
|
||||
}
|
||||
}
|
||||
|
||||
static int _ll_searcher_builtin_c(lua_State *L, const char *name)
|
||||
{
|
||||
const struct lua_riot_builtin_c *cmodule =
|
||||
BINSEARCH_STR_P(lua_riot_builtin_c_table,
|
||||
lua_riot_builtin_c_table_len,
|
||||
name, name, LUAR_MAX_MODULE_NAME);
|
||||
|
||||
if (cmodule != NULL) {
|
||||
lua_pushcfunction(L, cmodule->luaopen);
|
||||
lua_pushstring(L, name); /* will be 2nd argument to module */
|
||||
return LUA_OK;
|
||||
}
|
||||
else {
|
||||
return LUAR_MODULE_NOTFOUND;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search in the list of C lua modules.
|
||||
*
|
||||
* If the module is found, the loader function is loaded with lua_pushcfunction
|
||||
* and is returned.
|
||||
*/
|
||||
static int searcher_builtin_c(lua_State *L)
|
||||
{
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
int load_result = _ll_searcher_builtin_c(L, name);
|
||||
|
||||
if (load_result == LUA_OK) {
|
||||
return 2;
|
||||
}
|
||||
else {
|
||||
return luaL_error(L, "Module '%s' not found in C-builtins",
|
||||
lua_tostring(L, 1));
|
||||
}
|
||||
}
|
||||
|
||||
int lua_riot_getloader(lua_State *L, const char *name)
|
||||
{
|
||||
int load_result;
|
||||
|
||||
load_result = _ll_searcher_builtin_lua(L, name);
|
||||
|
||||
if (load_result == LUAR_MODULE_NOTFOUND) {
|
||||
load_result = _ll_searcher_builtin_c(L, name);
|
||||
}
|
||||
|
||||
return load_result;
|
||||
}
|
||||
|
||||
/* ======================== 'require' function ============================= */
|
||||
|
||||
static int searcher_preload(lua_State *L)
|
||||
{
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
|
||||
if (lua_getfield(L, -1, name) == LUA_TNIL) { /* not found? */
|
||||
lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void findloader(lua_State *L, const char *name)
|
||||
{
|
||||
int i;
|
||||
luaL_Buffer msg; /* to build error message */
|
||||
|
||||
luaL_buffinit(L, &msg);
|
||||
/* push 'package.searchers' to index 3 in the stack */
|
||||
if (lua_getfield(L, lua_upvalueindex(1), "searchers") != LUA_TTABLE) {
|
||||
luaL_error(L, "'package.searchers' must be a table");
|
||||
}
|
||||
/* iterate over available searchers to find a loader */
|
||||
for (i = 1;; i++) {
|
||||
if (lua_rawgeti(L, 3, i) == LUA_TNIL) { /* no more searchers? */
|
||||
lua_pop(L, 1); /* remove nil */
|
||||
luaL_pushresult(&msg); /* create error message */
|
||||
luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1));
|
||||
}
|
||||
lua_pushstring(L, name);
|
||||
lua_call(L, 1, 2); /* call it */
|
||||
if (lua_isfunction(L, -2)) { /* did it find a loader? */
|
||||
return; /* module loader found */
|
||||
}
|
||||
else if (lua_isstring(L, -2)) { /* searcher returned error message? */
|
||||
lua_pop(L, 1); /* remove extra return */
|
||||
luaL_addvalue(&msg); /* concatenate error message */
|
||||
}
|
||||
else {
|
||||
lua_pop(L, 2); /* remove both returns */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int ll_require(lua_State *L)
|
||||
{
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
|
||||
lua_settop(L, 1); /* LOADED table will be at index 2 */
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
|
||||
lua_getfield(L, 2, name); /* LOADED[name] */
|
||||
if (lua_toboolean(L, -1)) { /* is it there? */
|
||||
return 1; /* package is already loaded */
|
||||
}
|
||||
/* else must load package */
|
||||
lua_pop(L, 1); /* remove 'getfield' result */
|
||||
findloader(L, name);
|
||||
lua_pushstring(L, name); /* pass name as argument to module loader */
|
||||
lua_insert(L, -2); /* name is 1st argument (before search data) */
|
||||
lua_call(L, 2, 1); /* run loader to load module */
|
||||
if (!lua_isnil(L, -1)) { /* non-nil return? */
|
||||
lua_setfield(L, 2, name); /* LOADED[name] = returned value */
|
||||
}
|
||||
if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */
|
||||
lua_pushboolean(L, 1); /* use true as result */
|
||||
lua_pushvalue(L, -1); /* extra copy to be returned */
|
||||
lua_setfield(L, 2, name); /* LOADED[name] = true */
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ====================== 'package' module loader =========================== */
|
||||
|
||||
static const luaL_Reg pk_funcs[] = {
|
||||
/* placeholders */
|
||||
{ "preload", NULL },
|
||||
{ "searchers", NULL },
|
||||
{ "loaded", NULL },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
static const luaL_Reg ll_funcs[] = {
|
||||
{ "require", ll_require },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
LUAMOD_API int luaopen_package(lua_State *L)
|
||||
{
|
||||
static const lua_CFunction searchers[] =
|
||||
{ searcher_preload, searcher_builtin_lua, searcher_builtin_c, NULL };
|
||||
int i;
|
||||
|
||||
luaL_newlib(L, pk_funcs); /* create 'package' table */
|
||||
|
||||
/* create 'searchers' table */
|
||||
lua_createtable(L, sizeof(searchers) / sizeof(searchers[0]) - 1, 0);
|
||||
/* fill it with predefined searchers */
|
||||
for (i = 0; searchers[i] != NULL; i++) {
|
||||
lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */
|
||||
lua_pushcclosure(L, searchers[i], 1);
|
||||
lua_rawseti(L, -2, i + 1);
|
||||
}
|
||||
|
||||
lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */
|
||||
|
||||
/* set field 'loaded' */
|
||||
luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
|
||||
lua_setfield(L, -2, "loaded");
|
||||
|
||||
/* set field 'preload' */
|
||||
luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
|
||||
lua_setfield(L, -2, "preload");
|
||||
|
||||
|
||||
lua_pushglobaltable(L);
|
||||
lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */
|
||||
luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */
|
||||
lua_pop(L, 1); /* pop global table */
|
||||
return 1; /* return 'package' table */
|
||||
}
|
||||
|
||||
/** @} */
|
||||
283
pkg/lua/contrib/lua_run.c
Normal file
283
pkg/lua/contrib/lua_run.c
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
/**
|
||||
* @ingroup pkg_lua
|
||||
* @{
|
||||
* @file
|
||||
*
|
||||
* @brief Convenience functions for running Lua code.
|
||||
* @author Juan Carrano <j.carrano@fu-berlin.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#define LUA_LIB
|
||||
|
||||
#include "lprefix.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "kernel_defines.h"
|
||||
#include "tlsf.h"
|
||||
|
||||
#include "lua.h"
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
#include "lua_run.h"
|
||||
#include "lua_loadlib.h"
|
||||
|
||||
const char *lua_riot_str_errors[] = {
|
||||
"No errors",
|
||||
"Error setting up the interpreter",
|
||||
"Error while loading a builtin library",
|
||||
"Cannot find the specified module",
|
||||
"Compilation / syntax error",
|
||||
"Unprotected error (uncaught exception)",
|
||||
"Out of memory",
|
||||
"Internal interpreter error",
|
||||
"Unknown error"
|
||||
};
|
||||
|
||||
/* The lua docs state the behavior in these cases:
|
||||
*
|
||||
* 1. ptr=?, size=0 -> free(ptr)
|
||||
therefore ptr=NULL, size=0 -> NOP
|
||||
* 2. ptr=? , size!=0 -> realloc(ptr, size)
|
||||
*
|
||||
* The TLSF code for realloc says:
|
||||
* / * Zero-size requests are treated as free. * /
|
||||
* if (ptr && size == 0)
|
||||
* {
|
||||
* tlsf_free(tlsf, ptr);
|
||||
* }
|
||||
* / * Requests with NULL pointers are treated as malloc. * /
|
||||
* else if (!ptr)
|
||||
* {
|
||||
* p = tlsf_malloc(tlsf, size);
|
||||
* }
|
||||
*
|
||||
* Therefore it is safe to use tlsf_realloc here.
|
||||
*/
|
||||
static void *lua_tlsf_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
|
||||
{
|
||||
tlsf_t tlsf = ud;
|
||||
|
||||
(void)osize;
|
||||
|
||||
return tlsf_realloc(tlsf, ptr, nsize);
|
||||
}
|
||||
|
||||
LUALIB_API lua_State *lua_riot_newstate(void *memory, size_t mem_size,
|
||||
lua_CFunction panicf)
|
||||
{
|
||||
lua_State *L;
|
||||
|
||||
#ifdef LUA_DEBUG
|
||||
Memcontrol *mc = memory;
|
||||
#endif
|
||||
|
||||
/* If we are using the lua debug module, let's reserve a space for the
|
||||
* memcontrol block directly. We don't use the allocator because we lose
|
||||
* the pointer, so we won't be able to free it and we will get a false
|
||||
* positive if we try to check for memory leaks.
|
||||
*/
|
||||
#ifdef LUA_DEBUG
|
||||
memory = (Memcontrol *)memory + 1;
|
||||
mem_size -= (uint8_t *)memory - (uint8_t *)mc;
|
||||
#endif
|
||||
|
||||
tlsf_t tlsf = tlsf_create_with_pool(memory, mem_size);
|
||||
|
||||
#ifdef LUA_DEBUG
|
||||
luaB_init_memcontrol(mc, lua_tlsf_alloc, tlsf);
|
||||
L = luaB_newstate(mc);
|
||||
#else
|
||||
L = lua_newstate(lua_tlsf_alloc, tlsf);
|
||||
#endif
|
||||
|
||||
if (L != NULL) {
|
||||
lua_atpanic(L, panicf);
|
||||
}
|
||||
|
||||
return L;
|
||||
}
|
||||
|
||||
static const luaL_Reg loadedlibs[LUAR_LOAD_O_ALL] = {
|
||||
{ "_G", luaopen_base },
|
||||
{ LUA_LOADLIBNAME, luaopen_package },
|
||||
{ LUA_COLIBNAME, luaopen_coroutine },
|
||||
{ LUA_TABLIBNAME, luaopen_table },
|
||||
{ LUA_IOLIBNAME, luaopen_io },
|
||||
{ LUA_OSLIBNAME, luaopen_os },
|
||||
{ LUA_STRLIBNAME, luaopen_string },
|
||||
{ LUA_MATHLIBNAME, luaopen_math },
|
||||
{ LUA_UTF8LIBNAME, luaopen_utf8 },
|
||||
{ LUA_DBLIBNAME, luaopen_debug },
|
||||
};
|
||||
|
||||
LUALIB_API int lua_riot_openlibs(lua_State *L, uint16_t modmask)
|
||||
{
|
||||
int lib_index;
|
||||
|
||||
#ifdef LUA_DEBUG
|
||||
luaL_requiref(L, LUA_TESTLIBNAME, luaB_opentests, 1);
|
||||
lua_pop(L, 1);
|
||||
#endif
|
||||
|
||||
for (lib_index = 0; lib_index < LUAR_LOAD_O_ALL;
|
||||
lib_index++, modmask >>= 1) {
|
||||
const luaL_Reg *lib = loadedlibs + lib_index;
|
||||
|
||||
if (!(modmask & 1)) {
|
||||
continue;
|
||||
}
|
||||
/* TODO: how can the loading fail? */
|
||||
luaL_requiref(L, lib->name, lib->func, 1);
|
||||
lua_pop(L, 1); /* remove lib from stack (it is already global) */
|
||||
}
|
||||
|
||||
return lib_index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Jump back to a save point (defined with setjmp).
|
||||
*
|
||||
* @note This function never returns!
|
||||
*/
|
||||
NORETURN static int _jump_back(lua_State *L)
|
||||
{
|
||||
jmp_buf *jump_buffer = *(jmp_buf **)lua_getextraspace(L);
|
||||
|
||||
/* FIXME: I dont think it's OK to print a message */
|
||||
lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
|
||||
lua_tostring(L, -1));
|
||||
|
||||
/* TODO: try to return some info about the error object. */
|
||||
|
||||
longjmp(*jump_buffer, 1);
|
||||
}
|
||||
|
||||
static int lua_riot_do_module_or_buf(const uint8_t *buf, size_t buflen,
|
||||
const char *modname, void *memory, size_t mem_size,
|
||||
uint16_t modmask, int *retval)
|
||||
{
|
||||
jmp_buf jump_buffer;
|
||||
lua_State *volatile L = NULL;
|
||||
volatile int tmp_retval = 0; /* we need to make it volatile because of the
|
||||
setjmp/longjmp */
|
||||
volatile int status = LUAR_EXIT;
|
||||
int compilation_result;
|
||||
|
||||
if (setjmp(jump_buffer)) { /* We'll teleport back here if something goes wrong*/
|
||||
status = LUAR_INTERNAL_ERR;
|
||||
goto lua_riot_do_error;
|
||||
}
|
||||
|
||||
L = lua_riot_newstate(memory, mem_size, _jump_back);
|
||||
if (L == NULL) {
|
||||
status = LUAR_STARTUP_ERR;
|
||||
goto lua_riot_do_error;
|
||||
}
|
||||
|
||||
/* lua_getextraspace() gives us a pointer to an are large enough to hold a
|
||||
* pointer.
|
||||
*
|
||||
* We store a pointer to the jump buffer in that area.
|
||||
*
|
||||
* lua_getextraspace() is therefore a pointer to a pointer to jump_buffer.
|
||||
*/
|
||||
*(jmp_buf **)lua_getextraspace(L) = &jump_buffer;
|
||||
|
||||
tmp_retval = lua_riot_openlibs(L, modmask);
|
||||
if (tmp_retval != LUAR_LOAD_O_ALL) {
|
||||
status = LUAR_LOAD_ERR;
|
||||
goto lua_riot_do_error;
|
||||
}
|
||||
|
||||
if (buf == NULL) {
|
||||
compilation_result = lua_riot_getloader(L, modname);
|
||||
}
|
||||
else {
|
||||
compilation_result = luaL_loadbufferx(L, (const char *)buf,
|
||||
buflen, modname, "t");
|
||||
}
|
||||
|
||||
switch (compilation_result) {
|
||||
case LUAR_MODULE_NOTFOUND:
|
||||
status = LUAR_NOMODULE;
|
||||
goto lua_riot_do_error;
|
||||
case LUA_ERRSYNTAX:
|
||||
status = LUAR_COMPILE_ERR;
|
||||
goto lua_riot_do_error;
|
||||
case LUA_ERRMEM: /* fallthrough */
|
||||
case LUA_ERRGCMM: /* fallthrough */
|
||||
default:
|
||||
status = LUAR_MEMORY_ERR;
|
||||
goto lua_riot_do_error;
|
||||
case LUA_OK:
|
||||
break;
|
||||
}
|
||||
|
||||
if (buf != NULL) {
|
||||
lua_pushstring(L, modname);
|
||||
}
|
||||
|
||||
switch (lua_pcall(L, 1, 1, 0)) {
|
||||
case LUA_ERRRUN: /* fallthrough */
|
||||
case LUA_ERRGCMM: /* fallthrough */
|
||||
default:
|
||||
status = LUAR_RUNTIME_ERR;
|
||||
puts(lua_tostring(L, -1));
|
||||
goto lua_riot_do_error;
|
||||
case LUA_ERRMEM:
|
||||
status = LUAR_MEMORY_ERR;
|
||||
goto lua_riot_do_error;
|
||||
case LUA_OK:
|
||||
break;
|
||||
}
|
||||
|
||||
tmp_retval = lua_tonumber(L, 1);
|
||||
|
||||
lua_riot_do_error:
|
||||
|
||||
if (L != NULL) {
|
||||
lua_riot_close(L);
|
||||
}
|
||||
|
||||
if (retval != NULL) {
|
||||
*retval = tmp_retval;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API int lua_riot_do_module(const char *modname, void *memory, size_t mem_size,
|
||||
uint16_t modmask, int *retval)
|
||||
{
|
||||
return lua_riot_do_module_or_buf(NULL, 0, modname, memory, mem_size, modmask,
|
||||
retval);
|
||||
}
|
||||
|
||||
LUALIB_API int lua_riot_do_buffer(const uint8_t *buf, size_t buflen, void *memory,
|
||||
size_t mem_size, uint16_t modmask, int *retval)
|
||||
{
|
||||
return lua_riot_do_module_or_buf(buf, buflen, "=BUFFER", memory, mem_size,
|
||||
modmask, retval);
|
||||
}
|
||||
|
||||
#define MAX_ERR_STRING ((sizeof(lua_riot_str_errors) / sizeof(*lua_riot_str_errors)) - 1)
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
|
||||
LUALIB_API const char *lua_riot_strerror(int errn)
|
||||
{
|
||||
return lua_riot_str_errors[MIN((unsigned int)errn, MAX_ERR_STRING)];
|
||||
}
|
||||
|
||||
/** @} */
|
||||
148
pkg/lua/doc.txt
148
pkg/lua/doc.txt
@ -1,6 +1,152 @@
|
||||
/**
|
||||
* @defgroup pkg_lua Lua ported to RIOT
|
||||
* @ingroup pkg
|
||||
* @brief Provides Lua support for RIOT
|
||||
* @brief Provides a Lua interpreter for RIOT
|
||||
* @see https://github.com/lua/lua
|
||||
* @see sys_lua
|
||||
*
|
||||
* # Lua programming language support
|
||||
*
|
||||
* ## Introduction
|
||||
*
|
||||
* This package embeds a [Lua 5.3](https://www.lua.org/) interpreter into RIOT.
|
||||
* With a few exceptions, all the APIs mentioned in the
|
||||
* [official documentation](https://www.lua.org/manual/5.3/) are available in
|
||||
* this package too.
|
||||
*
|
||||
* ## Running Lua code.
|
||||
*
|
||||
* lua_run.h contains functions that make it easy to setup the interpreter and
|
||||
* catch errors in a safe way. The functions from Lua's auxlib can still be used
|
||||
* but then you must supply your own allocator and panic routines, load the
|
||||
* builtin modules, etc.
|
||||
*
|
||||
* To run a chunk of code stored in an array use:
|
||||
* ```
|
||||
* lua_riot_do_buffer(const char *buf, size_t buflen, void *memory,
|
||||
* size_t mem_size, uint16_t modmask, int *retval);
|
||||
* ```
|
||||
* The interpreter will not use the global heap for allocations, instead the
|
||||
* user must supply a memory buffer.
|
||||
*
|
||||
* To save some memory, some builtin modules can be left out. `modmask` specifies
|
||||
* which builtins to load. Note that if a builtin is not loaded by C code, then
|
||||
* it cannot be loaded by Lua code later.
|
||||
*
|
||||
* `lua_riot_do_buffer` takes care of setting up the Lua state, registering a panic
|
||||
* handler that does not crash the application, configuring an allocator, loading
|
||||
* libraries, etc.
|
||||
*
|
||||
* To run a module as a script use `lua_riot_do_module`. This is roughly equivalent
|
||||
* to executing:
|
||||
* ```
|
||||
* require('modulename')
|
||||
* ```
|
||||
*
|
||||
* ## Memory requirements
|
||||
*
|
||||
* While generally efficient, the Lua interpreter was not really designed for
|
||||
* constrained devices.
|
||||
*
|
||||
* A basic interpreter session typically requires about 12kB RAM. The stack
|
||||
* but it depends on the functions used (string handling tends to use more stack).
|
||||
* It also depends on the platform.
|
||||
*
|
||||
* There is currently no easy way to determine the stack needs other than trial
|
||||
* and error. Future versions of the package will include instrumentation to
|
||||
* this end.
|
||||
*
|
||||
* ## Adding your own modules.
|
||||
*
|
||||
* `lua_loadlib.c` contains two loaders, one for modules written in Lua and
|
||||
* another one for C extensions.
|
||||
*
|
||||
* An index to the modules is stored in a table (there are two, one for each
|
||||
* kind of module). The tables are indexed by the module name and must be sorted
|
||||
* in ascending order by this key.
|
||||
*
|
||||
* The definitions for the table types are in `lua_builtin.h`. The loader module
|
||||
* containes empty tables, defined as weak symbols so they can be ovewritten
|
||||
* by the application. The variables that must be defined are:
|
||||
*
|
||||
* ```
|
||||
* /** Table containing all built in pure lua modules */
|
||||
* const struct lua_riot_builtin_lua *const lua_riot_builtin_lua_table;
|
||||
* /** Number of elements of lua_riot_builtin_lua_table */
|
||||
* const size_t lua_riot_builtin_lua_table_len;
|
||||
*
|
||||
* /** Table containing all built in c lua modules */
|
||||
* const struct lua_riot_builtin_c *const lua_riot_builtin_c_table;
|
||||
* /** Number of elements of lua_riot_builtin_c_table */
|
||||
* const size_t lua_riot_builtin_c_table_len;
|
||||
* ```
|
||||
*
|
||||
* Currently, these must be defined manually in the application code. In the
|
||||
* future a script will generate this tables, populating them with both RIOT
|
||||
* modules and the user modules.
|
||||
*
|
||||
*
|
||||
* ## Customizations
|
||||
*
|
||||
* The upstream Lua code is used without with the following modifications.
|
||||
*
|
||||
* Modifications that affect the API:
|
||||
*
|
||||
* - lua.c (the main interface to the interpreter) is replaced by our own
|
||||
* stripped-down version. The REPL is no longer included.
|
||||
* - loadlib.c (the "package" module) is replaced by our own (simplified)
|
||||
* loader. All the code dealing with files and dynamic loading has been
|
||||
* removed.
|
||||
* - os.tmpname() is removed as it caused compiler warnings and it is not
|
||||
* really possible to use it right. Use io.tmpfile() instead.
|
||||
* - The test module has been modified to allow it run in the RIOT environment.
|
||||
* This is not a public API, though.
|
||||
*
|
||||
* Other modifications:
|
||||
*
|
||||
* - There is a patch changing the Makefile. This updated makefile is not used
|
||||
* in the package, but is provided to aid development in a PC.
|
||||
* - Some patches to reduce stack and memory usage.
|
||||
*
|
||||
* ### Patches
|
||||
*
|
||||
* A version of Lua with the patches applied is available at
|
||||
* https://github.com/riot-appstore/lua. It can be downloaded and compiled in
|
||||
* desktop computer, and the official test suite (https://www.lua.org/tests/)
|
||||
* can then be run.
|
||||
*
|
||||
* Alternatively, the patches in this package can be directly applied to the
|
||||
* official distribution.
|
||||
*
|
||||
* The updated makefile creates two standalone executables. Tests should be run
|
||||
* with the debug executable.
|
||||
*
|
||||
* ## TODO
|
||||
*
|
||||
* The following features are missing and will be eventually added:
|
||||
*
|
||||
* - Load source code incrementally. It can be done now, but then the rest of the
|
||||
* interpreter setup must be loaded manually.
|
||||
* - Bindings to access RIOT functionality.
|
||||
* - Support in the build system for easily including application-specific
|
||||
* modules.
|
||||
* - Instrumentation to measure stack consumption (and maybe prevent overflow).
|
||||
* - Support for "frozen tables" (i.e. tables that live in ROM).
|
||||
* - Provide a better way of supplying data to a script and getting back results.
|
||||
* - Specify a function to call inside a module (????)
|
||||
* - Expand this readme into a proper manual.
|
||||
*
|
||||
*/
|
||||
|
||||
/* These are docs for the future (when we have the script to compile module tables) */
|
||||
/*
|
||||
* # Running Lua and C code
|
||||
*
|
||||
* see \ref sys_lua for information on how to access RIOT modules from within
|
||||
* Lua.
|
||||
*
|
||||
* While it is possible to include your application specific modules and run
|
||||
* arbitrary Lua code only just using this interpreter, the \ref sys_lua module
|
||||
* provides an automated way of handling Lua modules.
|
||||
*
|
||||
*/
|
||||
|
||||
84
pkg/lua/include/lua_builtin.h
Normal file
84
pkg/lua/include/lua_builtin.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
/**
|
||||
* @ingroup pkg_lua
|
||||
* @{
|
||||
* @file
|
||||
*
|
||||
* @brief Definitions for including built-in modules.
|
||||
* @author Juan Carrano <j.carrano@fu-berlin.de>
|
||||
*
|
||||
* The modules must be placed in the tables lua_riot_builtin_lua_table (for lua
|
||||
* source code) and lua_riot_builtin_c_table (for C extensions) and the lengths
|
||||
* of these tables must be in lua_riot_builtin_lua_table_len and
|
||||
* lua_riot_builtin_c_table_len.
|
||||
*
|
||||
* These symbols are defined as weak, so there if they are not defined elsewhere
|
||||
* they will default to zero (or NULL), that is, empty tables.
|
||||
*/
|
||||
|
||||
#ifndef LUA_BUILTIN_H
|
||||
#define LUA_BUILTIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Avoid compilation errors where there are no external modules defined */
|
||||
/**
|
||||
* Attribute to make symbols weak.
|
||||
*
|
||||
* @todo This should be made part of RIOT.
|
||||
*/
|
||||
#define WEAK __attribute__((weak))
|
||||
|
||||
/**
|
||||
* Only the first `LUAR_MAX_MODULE_NAME` characters of a module name
|
||||
* will be considered when performing a lookup.
|
||||
*/
|
||||
#define LUAR_MAX_MODULE_NAME 64
|
||||
|
||||
/**
|
||||
* Entry describing a pure lua module whose source is built into the
|
||||
* application binary.
|
||||
*/
|
||||
struct lua_riot_builtin_lua {
|
||||
const char *name; /*!< Name of the module */
|
||||
const uint8_t *code; /*!< Lua source code buffer*/
|
||||
size_t code_size; /*!< Size of the source code buffer. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Entry describing a c lua module built into the
|
||||
* application binary.
|
||||
*/
|
||||
struct lua_riot_builtin_c {
|
||||
const char *name; /*!< Name of the module */
|
||||
int (*luaopen)(lua_State *); /*!< Loader function. It must place the module
|
||||
* table at the top of the lua stack.
|
||||
* @todo Add better docs.
|
||||
*/
|
||||
};
|
||||
|
||||
/** Table containing all built in pure lua modules */
|
||||
extern WEAK const struct lua_riot_builtin_lua *const lua_riot_builtin_lua_table;
|
||||
/** Number of elements of lua_riot_builtin_lua_table */
|
||||
extern WEAK const size_t lua_riot_builtin_lua_table_len;
|
||||
|
||||
/** Table containing all built in c lua modules */
|
||||
extern WEAK const struct lua_riot_builtin_c *const lua_riot_builtin_c_table;
|
||||
/** Number of elements of lua_riot_builtin_c_table */
|
||||
extern WEAK const size_t lua_riot_builtin_c_table_len;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" }
|
||||
#endif
|
||||
|
||||
#endif /* LUA_BUILTIN_H */
|
||||
|
||||
/** @} */
|
||||
58
pkg/lua/include/lua_loadlib.h
Normal file
58
pkg/lua/include/lua_loadlib.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
/**
|
||||
* @ingroup pkg_lua
|
||||
* @{
|
||||
* @file
|
||||
*
|
||||
* @brief Lightweight C interface to the package loader.
|
||||
* @author Juan Carrano <j.carrano@fu-berlin.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LUA_LOADLIB_H
|
||||
#define LUA_LOADLIB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Error code for when a modules is not found.
|
||||
*
|
||||
* The numeric value is chosen so that there is no collision with Lua's
|
||||
* own error codes.
|
||||
*/
|
||||
#define LUAR_MODULE_NOTFOUND 50
|
||||
|
||||
/**
|
||||
* Load a module as a chunk.
|
||||
*
|
||||
* This function is a lightweight "require". It does not require the "package"
|
||||
* module to be loaded and does not register the module.
|
||||
* Only the builtin tables are searched.
|
||||
*
|
||||
* Upon sucessful execution, the compiled chunk will be at the top of the lua
|
||||
* stack.
|
||||
*
|
||||
* @param L Initialized Lua interpreter state.
|
||||
* @param name Name of the module.
|
||||
*
|
||||
* @return Same as lua_load. If the module is a C-module, then this will
|
||||
* always succeed and return LUA_OK.
|
||||
*/
|
||||
int lua_riot_getloader(lua_State *L, const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LUA_LOADLIB_H */
|
||||
|
||||
/** @} */
|
||||
223
pkg/lua/include/lua_run.h
Normal file
223
pkg/lua/include/lua_run.h
Normal file
@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Freie Universität Berlin
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
/**
|
||||
* @ingroup pkg_lua
|
||||
* @file
|
||||
* @{
|
||||
*
|
||||
* @brief Convenience functions for running Lua code.
|
||||
* @author Juan Carrano <j.carrano@fu-berlin.de>
|
||||
*
|
||||
* This functions make it easy to create and use new Lua context:
|
||||
* It provides:
|
||||
*
|
||||
* - Easy to use routines for executing modules as scrips.
|
||||
* - Control over which modules get loaded.
|
||||
* - Support for using a local heap allocator.
|
||||
* - Out of memory handling via setjmp/longjmp.
|
||||
*
|
||||
* This library is not strictly required, as all of the functionality could be
|
||||
* implemented in terms of the public lua api, but it covers most of the use
|
||||
* cases, and thus avoids code repetition in applications.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LUA_RUN_H
|
||||
#define LUA_RUN_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Convert a library index into a bit mask.
|
||||
*/
|
||||
#define LUAR_LOAD_FLAG(n) (((uint16_t)1) << (n))
|
||||
|
||||
/**
|
||||
* Order in which the builtin libraries are loaded.
|
||||
*/
|
||||
enum LUAR_LOAD_ORDER {
|
||||
LUAR_LOAD_O_BASE,
|
||||
LUAR_LOAD_O_PACKAGE,
|
||||
LUAR_LOAD_O_CORO,
|
||||
LUAR_LOAD_O_TABLE,
|
||||
LUAR_LOAD_O_IO,
|
||||
LUAR_LOAD_O_OS,
|
||||
LUAR_LOAD_O_STRING,
|
||||
LUAR_LOAD_O_MATH,
|
||||
LUAR_LOAD_O_UTF8,
|
||||
LUAR_LOAD_O_DEBUG,
|
||||
LUAR_LOAD_O_ALL,
|
||||
};
|
||||
|
||||
/** Load the base globals (_G) */
|
||||
#define LUAR_LOAD_BASE LUAR_LOAD_FLAG(LUAR_LOAD_O_BASE)
|
||||
/** Load ´package´ */
|
||||
#define LUAR_LOAD_PACKAGE LUAR_LOAD_FLAG(LUAR_LOAD_O_PACKAGE)
|
||||
/** Load ´coroutine´ */
|
||||
#define LUAR_LOAD_CORO LUAR_LOAD_FLAG(LUAR_LOAD_O_CORO)
|
||||
/** Load ´table´ */
|
||||
#define LUAR_LOAD_TABLE LUAR_LOAD_FLAG(LUAR_LOAD_O_TABLE)
|
||||
/** Load ´io´ */
|
||||
#define LUAR_LOAD_IO LUAR_LOAD_FLAG(LUAR_LOAD_O_IO)
|
||||
/** Load ´os´ */
|
||||
#define LUAR_LOAD_OS LUAR_LOAD_FLAG(LUAR_LOAD_O_OS)
|
||||
/** Load ´string´ */
|
||||
#define LUAR_LOAD_STRING LUAR_LOAD_FLAG(LUAR_LOAD_O_STRING)
|
||||
/** Load ´math´ */
|
||||
#define LUAR_LOAD_MATH LUAR_LOAD_FLAG(LUAR_LOAD_O_MATH)
|
||||
/** Load ´utf8´ */
|
||||
#define LUAR_LOAD_UTF8 LUAR_LOAD_FLAG(LUAR_LOAD_O_UTF8)
|
||||
/** Load ´debug´ */
|
||||
#define LUAR_LOAD_DEBUG LUAR_LOAD_FLAG(LUAR_LOAD_O_DEBUG)
|
||||
|
||||
/* TODO: maybe we can implement a "restricted base" package containing a subset
|
||||
* of base that is safe. */
|
||||
|
||||
#define LUAR_LOAD_ALL (0xFFFF) /** Load all standard modules */
|
||||
#define LUAR_LOAD_NONE (0x0000) /** Do not load any modules */
|
||||
|
||||
/** Errors that can be raised when running lua code. */
|
||||
enum LUAR_ERRORS {
|
||||
LUAR_EXIT, /** The program exited without error. */
|
||||
LUAR_STARTUP_ERR, /** Error setting up the interpreter. */
|
||||
LUAR_LOAD_ERR, /** Error while loading libraries. */
|
||||
LUAR_NOMODULE, /** The specified module could not be found. */
|
||||
LUAR_COMPILE_ERR, /** The Lua code failed to compile. */
|
||||
LUAR_RUNTIME_ERR, /** Error in code execution. */
|
||||
LUAR_MEMORY_ERR, /** Lua could not allocate enough memory */
|
||||
LUAR_INTERNAL_ERR /** Error inside the Lua VM.
|
||||
* Right now, if this happens, you may leak memory from
|
||||
* the heap. If your program is the only one using the
|
||||
* dynamic allocation, just clean the heap.
|
||||
*/
|
||||
};
|
||||
|
||||
/**
|
||||
* Human-readable description of the errors
|
||||
*/
|
||||
extern const char *lua_riot_str_errors[];
|
||||
|
||||
/**
|
||||
* Return a string describing an error from LUAR_ERRORS.
|
||||
*
|
||||
* @param errn Error number as returned by lua_riot_do_buffer() or
|
||||
* lua_riot_do_buffer()
|
||||
*
|
||||
* @return A string describing the error, or "Unknown error".
|
||||
*/
|
||||
LUALIB_API const char *lua_riot_strerror(int errn);
|
||||
|
||||
/**
|
||||
* Initialize a lua state and set the panic handler.
|
||||
*
|
||||
* @todo Use a per-state allocator
|
||||
*
|
||||
* @param memory Pointer to memory region that will be used as heap for
|
||||
* the allocator. Currently this functionality is not
|
||||
* supported and this must be set to NULL.
|
||||
* @param mem_size Size of the memory region that will be used as heap.
|
||||
* Currently this functionality is not supported and this
|
||||
* must be set to 0.
|
||||
* @param panicf Function to be passed to lua_atpanic. If set to NULL,
|
||||
* a generic function that does nothing will be used.
|
||||
*
|
||||
* @return the new state, or NULL if there is a memory allocation error.
|
||||
*/
|
||||
LUALIB_API lua_State *lua_riot_newstate(void *memory, size_t mem_size,
|
||||
lua_CFunction panicf);
|
||||
|
||||
/**
|
||||
* Terminate the lua state.
|
||||
*
|
||||
* You must call this function if you want the finalizers (the __gc metamethods)
|
||||
* to be called.
|
||||
*/
|
||||
#ifndef LUA_DEBUG
|
||||
#define lua_riot_close lua_close
|
||||
#else
|
||||
#define lua_riot_close luaB_close
|
||||
#endif /* LUA_DEBUG */
|
||||
|
||||
/**
|
||||
* Open builtin libraries.
|
||||
*
|
||||
* This is like luaL_openlibs but it allows selecting which libraries will
|
||||
* be loaded.
|
||||
*
|
||||
* Libraries are loaded in the order specified by the LUAR_LOAD_ORDER enum. If
|
||||
* there is an error the load sequence is aborted and the index of the library
|
||||
* that failed is reported.
|
||||
*
|
||||
* If debuging is enabled (compile with the LUA_DEBUG macro), then the test
|
||||
* library will be unconditionally loaded.
|
||||
*
|
||||
* @param L Lua state
|
||||
* @param modmask Binary mask that indicates which modules should be
|
||||
* loaded. The mask is made from a combination of the
|
||||
* LUAR_LOAD_* macros.
|
||||
*
|
||||
* @return The index of the library that failed to load, or LUAR_LOAD_O_ALL
|
||||
* if all libraries were loaded.
|
||||
*/
|
||||
LUALIB_API int lua_riot_openlibs(lua_State *L, uint16_t modmask);
|
||||
|
||||
/**
|
||||
* Initialize the interpreter and run a built-in module in protected mode.
|
||||
*
|
||||
* In addition to running code in protected mode, this also sets a panic
|
||||
* function that long-jumps back to this function, in case there is an internal
|
||||
* interpreter error (LUAR_INTERNAL_ERR).
|
||||
* Right now the only things that the application can are either to abort(),
|
||||
* or to manually reset the heap (only if there's no other thread using it).
|
||||
*
|
||||
* @param modname name of the module.
|
||||
* @param memory @see lua_riot_newstate()
|
||||
* @param mem_size @see lua_riot_newstate()
|
||||
* @param modmask @see lua_riot_newstate()
|
||||
* @param[out] retval Value returned by the lua code, if it is a number,
|
||||
* or zero if no value is returned or the value is not
|
||||
* a number. If retval is null, the value is not stored.
|
||||
*
|
||||
* @return An error code ( @see LUAR_ERRORS). LUAR_EXIT indicates no error.
|
||||
*/
|
||||
LUALIB_API int lua_riot_do_module(const char *modname, void *memory, size_t mem_size,
|
||||
uint16_t modmask, int *retval);
|
||||
|
||||
/**
|
||||
* Initialize the interpreter and run a user supplied buffer in protected mode.
|
||||
*
|
||||
* Only text data (i.e. lua source code) can be loaded by this function. The
|
||||
* lua interpreter is not robust against corrupt binary code.
|
||||
*
|
||||
* @see lua_riot_do_module() for more information on internal errors.
|
||||
*
|
||||
* @param buf Text data (lua source code).
|
||||
* @param buflen Size of the text data in bytes. If buf is
|
||||
* a zero-terminated string, the zero must not be counted.
|
||||
* @param memory @see lua_riot_newstate()
|
||||
* @param mem_size @see lua_riot_newstate()
|
||||
* @param modmask @see lua_riot_newstate()
|
||||
* @param[out] retval @see lua_riot_do_module()
|
||||
* @return @see lua_riot_do_module().
|
||||
*/
|
||||
LUALIB_API int lua_riot_do_buffer(const uint8_t *buf, size_t buflen, void *memory,
|
||||
size_t mem_size, uint16_t modmask, int *retval);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" }
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* LUA_RUN_H */
|
||||
@ -1,62 +0,0 @@
|
||||
From b681cb20ee6bfc31b8ba23ec321140aae6e53e9d Mon Sep 17 00:00:00 2001
|
||||
From: danpetry <daniel.petry@fu-berlin.de>
|
||||
Date: Wed, 23 May 2018 14:09:17 +0200
|
||||
Subject: [PATCH 1/1] Remove dependency on nonexistent RIOT syscalls
|
||||
|
||||
Os.rename and os.clock, in Lua, now always return an error message.
|
||||
Also, l_randomizePivot, which is used by table.sort, will always
|
||||
supply 0 rather than a pseudorandom number.
|
||||
---
|
||||
loslib.c | 7 ++-----
|
||||
ltablib.c | 4 +++-
|
||||
2 files changed, 5 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/loslib.c b/loslib.c
|
||||
index dd2bb378..f9e5cbd2 100644
|
||||
--- a/loslib.c
|
||||
+++ b/loslib.c
|
||||
@@ -157,9 +157,7 @@ static int os_remove (lua_State *L) {
|
||||
|
||||
|
||||
static int os_rename (lua_State *L) {
|
||||
- const char *fromname = luaL_checkstring(L, 1);
|
||||
- const char *toname = luaL_checkstring(L, 2);
|
||||
- return luaL_fileresult(L, rename(fromname, toname) == 0, NULL);
|
||||
+ return luaL_error(L, "This function is not implemented in RIOT yet");
|
||||
}
|
||||
|
||||
|
||||
@@ -181,8 +179,7 @@ static int os_getenv (lua_State *L) {
|
||||
|
||||
|
||||
static int os_clock (lua_State *L) {
|
||||
- lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
|
||||
- return 1;
|
||||
+ return luaL_error(L, "This function is not implemented in RIOT yet");
|
||||
}
|
||||
|
||||
|
||||
diff --git a/ltablib.c b/ltablib.c
|
||||
index 588bf40d..8895b653 100644
|
||||
--- a/ltablib.c
|
||||
+++ b/ltablib.c
|
||||
@@ -235,13 +235,15 @@ static int unpack (lua_State *L) {
|
||||
/* type for array indices */
|
||||
typedef unsigned int IdxT;
|
||||
|
||||
-
|
||||
/*
|
||||
** Produce a "random" 'unsigned int' to randomize pivot choice. This
|
||||
** macro is used only when 'sort' detects a big imbalance in the result
|
||||
** of a partition. (If you don't want/need this "randomness", ~0 is a
|
||||
** good choice.)
|
||||
*/
|
||||
+
|
||||
+#define l_randomizePivot() 0
|
||||
+
|
||||
#if !defined(l_randomizePivot) /* { */
|
||||
|
||||
#include <time.h>
|
||||
--
|
||||
2.17.0
|
||||
|
||||
62
pkg/lua/patches/0001-Remove-luaL_newstate.patch
Normal file
62
pkg/lua/patches/0001-Remove-luaL_newstate.patch
Normal file
@ -0,0 +1,62 @@
|
||||
From ef0650e050057db5af2e0b4f934f294656c261a7 Mon Sep 17 00:00:00 2001
|
||||
From: Juan Carrano <j.carrano@fu-berlin.de>
|
||||
Date: Tue, 24 Apr 2018 16:38:37 +0200
|
||||
Subject: [PATCH 1/8] Remove luaL_newstate.
|
||||
|
||||
---
|
||||
lauxlib.c | 25 -------------------------
|
||||
lauxlib.h | 2 --
|
||||
2 files changed, 27 deletions(-)
|
||||
|
||||
diff --git a/lauxlib.c b/lauxlib.c
|
||||
index 7b14ca4d..018a4347 100644
|
||||
--- a/lauxlib.c
|
||||
+++ b/lauxlib.c
|
||||
@@ -1005,31 +1005,6 @@ LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
|
||||
}
|
||||
|
||||
|
||||
-static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
|
||||
- (void)ud; (void)osize; /* not used */
|
||||
- if (nsize == 0) {
|
||||
- free(ptr);
|
||||
- return NULL;
|
||||
- }
|
||||
- else
|
||||
- return realloc(ptr, nsize);
|
||||
-}
|
||||
-
|
||||
-
|
||||
-static int panic (lua_State *L) {
|
||||
- lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
|
||||
- lua_tostring(L, -1));
|
||||
- return 0; /* return to Lua to abort */
|
||||
-}
|
||||
-
|
||||
-
|
||||
-LUALIB_API lua_State *luaL_newstate (void) {
|
||||
- lua_State *L = lua_newstate(l_alloc, NULL);
|
||||
- if (L) lua_atpanic(L, &panic);
|
||||
- return L;
|
||||
-}
|
||||
-
|
||||
-
|
||||
LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver, size_t sz) {
|
||||
const lua_Number *v = lua_version(L);
|
||||
if (sz != LUAL_NUMSIZES) /* check numeric types */
|
||||
diff --git a/lauxlib.h b/lauxlib.h
|
||||
index 1d65c975..77d1494d 100644
|
||||
--- a/lauxlib.h
|
||||
+++ b/lauxlib.h
|
||||
@@ -89,8 +89,6 @@ LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
|
||||
const char *name, const char *mode);
|
||||
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
|
||||
|
||||
-LUALIB_API lua_State *(luaL_newstate) (void);
|
||||
-
|
||||
LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx);
|
||||
|
||||
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
From 2e86c4b6b7061b69929d601096e3f0a086ffcc81 Mon Sep 17 00:00:00 2001
|
||||
From: Juan Carrano <j.carrano@fu-berlin.de>
|
||||
Date: Thu, 3 May 2018 16:55:05 +0200
|
||||
Subject: [PATCH 2/8] Allow LUAL_BUFFERSIZE to be defined in the command line.
|
||||
|
||||
---
|
||||
luaconf.h | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/luaconf.h b/luaconf.h
|
||||
index 118f997a..e816db00 100644
|
||||
--- a/luaconf.h
|
||||
+++ b/luaconf.h
|
||||
@@ -748,12 +748,16 @@
|
||||
** smaller buffer would force a memory allocation for each call to
|
||||
** 'string.format'.)
|
||||
*/
|
||||
+#ifndef LUAL_BUFFERSIZE
|
||||
+
|
||||
#if LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE
|
||||
#define LUAL_BUFFERSIZE 8192
|
||||
#else
|
||||
#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
|
||||
#endif
|
||||
|
||||
+#endif
|
||||
+
|
||||
/* }================================================================== */
|
||||
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
From bd9e76ed9c9044521537d66fd017a21e98aa53c3 Mon Sep 17 00:00:00 2001
|
||||
From: Juan Carrano <j.carrano@fu-berlin.de>
|
||||
Date: Mon, 7 May 2018 13:29:15 +0200
|
||||
Subject: [PATCH 3/8] Make size of LoadF buffer configurable.
|
||||
|
||||
---
|
||||
lauxlib.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/lauxlib.c b/lauxlib.c
|
||||
index 018a4347..8bd2b5af 100644
|
||||
--- a/lauxlib.c
|
||||
+++ b/lauxlib.c
|
||||
@@ -635,7 +635,7 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
|
||||
typedef struct LoadF {
|
||||
int n; /* number of pre-read characters */
|
||||
FILE *f; /* file being read */
|
||||
- char buff[BUFSIZ]; /* area for reading file */
|
||||
+ char buff[LUAL_BUFFERSIZE]; /* area for reading file */
|
||||
} LoadF;
|
||||
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
||||
95
pkg/lua/patches/0004-Remove-os.tmpname.patch
Normal file
95
pkg/lua/patches/0004-Remove-os.tmpname.patch
Normal file
@ -0,0 +1,95 @@
|
||||
From c414df012e8382df3ae078c6dda5554e6c505e31 Mon Sep 17 00:00:00 2001
|
||||
From: Juan Carrano <j.carrano@fu-berlin.de>
|
||||
Date: Mon, 7 May 2018 13:59:06 +0200
|
||||
Subject: [PATCH 4/8] Remove os.tmpname.
|
||||
|
||||
It is a potential source of bugs, causes compiler warnings when building
|
||||
without POSIX, behaves differently under POSIX, and cannot be fixed.
|
||||
|
||||
Also, it used a stack variable whose size could be really big under certain
|
||||
C standard libraries.
|
||||
|
||||
Any program using os.tmpname is should be fixed.
|
||||
---
|
||||
loslib.c | 51 ---------------------------------------------------
|
||||
1 file changed, 51 deletions(-)
|
||||
|
||||
diff --git a/loslib.c b/loslib.c
|
||||
index dd2bb378..69a5f531 100644
|
||||
--- a/loslib.c
|
||||
+++ b/loslib.c
|
||||
@@ -99,45 +99,6 @@ static time_t l_checktime (lua_State *L, int arg) {
|
||||
/* }================================================================== */
|
||||
|
||||
|
||||
-/*
|
||||
-** {==================================================================
|
||||
-** Configuration for 'tmpnam':
|
||||
-** By default, Lua uses tmpnam except when POSIX is available, where
|
||||
-** it uses mkstemp.
|
||||
-** ===================================================================
|
||||
-*/
|
||||
-#if !defined(lua_tmpnam) /* { */
|
||||
-
|
||||
-#if defined(LUA_USE_POSIX) /* { */
|
||||
-
|
||||
-#include <unistd.h>
|
||||
-
|
||||
-#define LUA_TMPNAMBUFSIZE 32
|
||||
-
|
||||
-#if !defined(LUA_TMPNAMTEMPLATE)
|
||||
-#define LUA_TMPNAMTEMPLATE "/tmp/lua_XXXXXX"
|
||||
-#endif
|
||||
-
|
||||
-#define lua_tmpnam(b,e) { \
|
||||
- strcpy(b, LUA_TMPNAMTEMPLATE); \
|
||||
- e = mkstemp(b); \
|
||||
- if (e != -1) close(e); \
|
||||
- e = (e == -1); }
|
||||
-
|
||||
-#else /* }{ */
|
||||
-
|
||||
-/* ISO C definitions */
|
||||
-#define LUA_TMPNAMBUFSIZE L_tmpnam
|
||||
-#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
|
||||
-
|
||||
-#endif /* } */
|
||||
-
|
||||
-#endif /* } */
|
||||
-/* }================================================================== */
|
||||
-
|
||||
-
|
||||
-
|
||||
-
|
||||
static int os_execute (lua_State *L) {
|
||||
const char *cmd = luaL_optstring(L, 1, NULL);
|
||||
int stat = system(cmd);
|
||||
@@ -163,17 +124,6 @@ static int os_rename (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
-static int os_tmpname (lua_State *L) {
|
||||
- char buff[LUA_TMPNAMBUFSIZE];
|
||||
- int err;
|
||||
- lua_tmpnam(buff, err);
|
||||
- if (err)
|
||||
- return luaL_error(L, "unable to generate a unique filename");
|
||||
- lua_pushstring(L, buff);
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
-
|
||||
static int os_getenv (lua_State *L) {
|
||||
lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
|
||||
return 1;
|
||||
@@ -392,7 +342,6 @@ static const luaL_Reg syslib[] = {
|
||||
{"rename", os_rename},
|
||||
{"setlocale", os_setlocale},
|
||||
{"time", os_time},
|
||||
- {"tmpname", os_tmpname},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
||||
164
pkg/lua/patches/0005-Do-not-allocate-buffers-on-the-stack.patch
Normal file
164
pkg/lua/patches/0005-Do-not-allocate-buffers-on-the-stack.patch
Normal file
@ -0,0 +1,164 @@
|
||||
From 0900faaa14e95b24ad126bb64eebfed60121608b Mon Sep 17 00:00:00 2001
|
||||
From: Juan Carrano <j.carrano@fu-berlin.de>
|
||||
Date: Wed, 9 May 2018 14:05:53 +0200
|
||||
Subject: [PATCH 5/8] Do not allocate buffers on the stack.
|
||||
|
||||
Change luaL_Buffer so that the memory for the object is always allocated in the heap.
|
||||
---
|
||||
lauxlib.c | 29 +++++++++++++++++++----------
|
||||
lauxlib.h | 1 -
|
||||
lstrlib.c | 6 +++---
|
||||
ltablib.c | 2 +-
|
||||
4 files changed, 23 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/lauxlib.c b/lauxlib.c
|
||||
index 8bd2b5af..3767439f 100644
|
||||
--- a/lauxlib.c
|
||||
+++ b/lauxlib.c
|
||||
@@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "lua.h"
|
||||
+#include "llimits.h" /* to get lua_assert */
|
||||
|
||||
#include "lauxlib.h"
|
||||
|
||||
@@ -493,10 +494,9 @@ static void *newbox (lua_State *L, size_t newsize) {
|
||||
|
||||
|
||||
/*
|
||||
-** check whether buffer is using a userdata on the stack as a temporary
|
||||
-** buffer
|
||||
+** check whether buffer has been assigned a memory region.
|
||||
*/
|
||||
-#define buffonstack(B) ((B)->b != (B)->initb)
|
||||
+#define buffallocated(B) ((B)->b != NULL)
|
||||
|
||||
|
||||
/*
|
||||
@@ -504,6 +504,15 @@ static void *newbox (lua_State *L, size_t newsize) {
|
||||
*/
|
||||
LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
|
||||
lua_State *L = B->L;
|
||||
+
|
||||
+ lua_assert((B->size == 0) == (B->b == NULL));
|
||||
+ lua_assert((B->n <= B->size));
|
||||
+
|
||||
+ /* Force an allocation if the requested size is zero and the buffer is not
|
||||
+ * initialized. This avoids weird bugs */
|
||||
+ if (sz == 0 && B->size == 0)
|
||||
+ sz = 1;
|
||||
+
|
||||
if (B->size - B->n < sz) { /* not enough space? */
|
||||
char *newbuff;
|
||||
size_t newsize = B->size * 2; /* double buffer size */
|
||||
@@ -512,11 +521,10 @@ LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
|
||||
if (newsize < B->n || newsize - B->n < sz)
|
||||
luaL_error(L, "buffer too large");
|
||||
/* create larger buffer */
|
||||
- if (buffonstack(B))
|
||||
+ if (buffallocated(B))
|
||||
newbuff = (char *)resizebox(L, -1, newsize);
|
||||
else { /* no buffer yet */
|
||||
newbuff = (char *)newbox(L, newsize);
|
||||
- memcpy(newbuff, B->b, B->n * sizeof(char)); /* copy original content */
|
||||
}
|
||||
B->b = newbuff;
|
||||
B->size = newsize;
|
||||
@@ -542,7 +550,7 @@ LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
|
||||
LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
|
||||
lua_State *L = B->L;
|
||||
lua_pushlstring(L, B->b, B->n);
|
||||
- if (buffonstack(B)) {
|
||||
+ if (buffallocated(B)) {
|
||||
resizebox(L, -2, 0); /* delete old buffer */
|
||||
lua_remove(L, -2); /* remove its header from the stack */
|
||||
}
|
||||
@@ -559,23 +567,24 @@ LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
|
||||
lua_State *L = B->L;
|
||||
size_t l;
|
||||
const char *s = lua_tolstring(L, -1, &l);
|
||||
- if (buffonstack(B))
|
||||
+ if (buffallocated(B))
|
||||
lua_insert(L, -2); /* put value below buffer */
|
||||
luaL_addlstring(B, s, l);
|
||||
- lua_remove(L, (buffonstack(B)) ? -2 : -1); /* remove value */
|
||||
+ lua_remove(L, -2); /* remove value */
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
|
||||
B->L = L;
|
||||
- B->b = B->initb;
|
||||
+ B->b = NULL;
|
||||
B->n = 0;
|
||||
- B->size = LUAL_BUFFERSIZE;
|
||||
+ B->size = 0;
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
|
||||
luaL_buffinit(L, B);
|
||||
+
|
||||
return luaL_prepbuffsize(B, sz);
|
||||
}
|
||||
|
||||
diff --git a/lauxlib.h b/lauxlib.h
|
||||
index 77d1494d..b11afc9a 100644
|
||||
--- a/lauxlib.h
|
||||
+++ b/lauxlib.h
|
||||
@@ -148,7 +148,6 @@ typedef struct luaL_Buffer {
|
||||
size_t size; /* buffer size */
|
||||
size_t n; /* number of characters in buffer */
|
||||
lua_State *L;
|
||||
- char initb[LUAL_BUFFERSIZE]; /* initial buffer */
|
||||
} luaL_Buffer;
|
||||
|
||||
|
||||
diff --git a/lstrlib.c b/lstrlib.c
|
||||
index 934b7db8..a978d07a 100644
|
||||
--- a/lstrlib.c
|
||||
+++ b/lstrlib.c
|
||||
@@ -773,7 +773,7 @@ static int str_gsub (lua_State *L) {
|
||||
luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
|
||||
tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
|
||||
"string/function/table expected");
|
||||
- luaL_buffinit(L, &b);
|
||||
+ luaL_buffinitsize(L, &b, luaL_len(L, 1));
|
||||
if (anchor) {
|
||||
p++; lp--; /* skip anchor character */
|
||||
}
|
||||
@@ -1020,7 +1020,7 @@ static int str_format (lua_State *L) {
|
||||
const char *strfrmt = luaL_checklstring(L, arg, &sfl);
|
||||
const char *strfrmt_end = strfrmt+sfl;
|
||||
luaL_Buffer b;
|
||||
- luaL_buffinit(L, &b);
|
||||
+ luaL_buffinitsize(L, &b, LUAL_BUFFERSIZE);
|
||||
while (strfrmt < strfrmt_end) {
|
||||
if (*strfrmt != L_ESC)
|
||||
luaL_addchar(&b, *strfrmt++);
|
||||
@@ -1335,7 +1335,7 @@ static int str_pack (lua_State *L) {
|
||||
size_t totalsize = 0; /* accumulate total size of result */
|
||||
initheader(L, &h);
|
||||
lua_pushnil(L); /* mark to separate arguments from string buffer */
|
||||
- luaL_buffinit(L, &b);
|
||||
+ luaL_buffinitsize(L, &b, LUAL_BUFFERSIZE);
|
||||
while (*fmt != '\0') {
|
||||
int size, ntoalign;
|
||||
KOption opt = getdetails(&h, totalsize, &fmt, &size, &ntoalign);
|
||||
diff --git a/ltablib.c b/ltablib.c
|
||||
index 588bf40d..0e50898b 100644
|
||||
--- a/ltablib.c
|
||||
+++ b/ltablib.c
|
||||
@@ -173,7 +173,7 @@ static int tconcat (lua_State *L) {
|
||||
const char *sep = luaL_optlstring(L, 2, "", &lsep);
|
||||
lua_Integer i = luaL_optinteger(L, 3, 1);
|
||||
last = luaL_optinteger(L, 4, last);
|
||||
- luaL_buffinit(L, &b);
|
||||
+ luaL_buffinitsize(L, &b, LUAL_BUFFERSIZE);
|
||||
for (; i < last; i++) {
|
||||
addfield(L, &b, i);
|
||||
luaL_addlstring(&b, sep, lsep);
|
||||
--
|
||||
2.17.1
|
||||
|
||||
497
pkg/lua/patches/0006-Cleanup-test-module.patch
Normal file
497
pkg/lua/patches/0006-Cleanup-test-module.patch
Normal file
@ -0,0 +1,497 @@
|
||||
From 542105cafbba381ef40c414a4025ea25d20371a2 Mon Sep 17 00:00:00 2001
|
||||
From: Juan Carrano <j.carrano@fu-berlin.de>
|
||||
Date: Mon, 14 May 2018 15:19:14 +0200
|
||||
Subject: [PATCH 6/8] Cleanup test module.
|
||||
|
||||
This patch makes several improvements to the test module intended
|
||||
to allow testing inside embedded environments:
|
||||
|
||||
- It does not rely in the standalone intepreter (lua.c).
|
||||
- Removes all global variables from the test code.
|
||||
- It allows the user to use the state's extra space (the vanilla
|
||||
ltest does not reserve any space for the user).
|
||||
- Makes the instrumented test allocator use the user supply
|
||||
allocator instead of malloc/free.
|
||||
- The user must provide a panic function. ltests.c no longer sets
|
||||
it's own panic function.
|
||||
- Loading of the test modules is controlled by the LUA_DEBUG
|
||||
macro.
|
||||
|
||||
This changes should enable heavily customized lua deployments
|
||||
(such as would be found in an embedded microprocessor) to be
|
||||
tested with minimal modifications.
|
||||
---
|
||||
linit.c | 4 ++-
|
||||
ltests.c | 89 ++++++++++++++++++++++++++--------------------
|
||||
ltests.h | 105 ++++++++++++++++++++++++++++++++++++-------------------
|
||||
lua.c | 36 +++++++++++++++++--
|
||||
lua.h | 7 +++-
|
||||
5 files changed, 163 insertions(+), 78 deletions(-)
|
||||
|
||||
diff --git a/linit.c b/linit.c
|
||||
index 897ae352..c7ecd387 100644
|
||||
--- a/linit.c
|
||||
+++ b/linit.c
|
||||
@@ -50,7 +50,9 @@ static const luaL_Reg loadedlibs[] = {
|
||||
{LUA_MATHLIBNAME, luaopen_math},
|
||||
{LUA_UTF8LIBNAME, luaopen_utf8},
|
||||
{LUA_DBLIBNAME, luaopen_debug},
|
||||
-#if defined(LUA_COMPAT_BITLIB)
|
||||
+#if defined(LUA_DEBUG)
|
||||
+ {LUA_TESTLIBNAME, luaB_opentests},
|
||||
+#elif defined(LUA_COMPAT_BITLIB) /* No COMPAT and DEBUG at the same time */
|
||||
{LUA_BITLIBNAME, luaopen_bit32},
|
||||
#endif
|
||||
{NULL, NULL}
|
||||
diff --git a/ltests.c b/ltests.c
|
||||
index 6dba514a..3ca77d2c 100644
|
||||
--- a/ltests.c
|
||||
+++ b/ltests.c
|
||||
@@ -4,7 +4,6 @@
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
-#define ltests_c
|
||||
#define LUA_CORE
|
||||
|
||||
#include "lprefix.h"
|
||||
@@ -40,12 +39,6 @@
|
||||
#if defined(LUA_DEBUG)
|
||||
|
||||
|
||||
-void *l_Trick = 0;
|
||||
-
|
||||
-
|
||||
-int islocked = 0;
|
||||
-
|
||||
-
|
||||
#define obj_at(L,k) (L->ci->func + (k))
|
||||
|
||||
|
||||
@@ -64,14 +57,6 @@ static void pushobject (lua_State *L, const TValue *o) {
|
||||
api_incr_top(L);
|
||||
}
|
||||
|
||||
-
|
||||
-static int tpanic (lua_State *L) {
|
||||
- fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
|
||||
- lua_tostring(L, -1));
|
||||
- return (exit(EXIT_FAILURE), 0); /* do not return to Lua */
|
||||
-}
|
||||
-
|
||||
-
|
||||
/*
|
||||
** {======================================================================
|
||||
** Controlled version for realloc.
|
||||
@@ -103,11 +88,6 @@ typedef union Header {
|
||||
|
||||
#endif
|
||||
|
||||
-
|
||||
-Memcontrol l_memcontrol =
|
||||
- {0L, 0L, 0L, 0L, {0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L}};
|
||||
-
|
||||
-
|
||||
static void freeblock (Memcontrol *mc, Header *block) {
|
||||
if (block) {
|
||||
size_t size = block->d.size;
|
||||
@@ -116,16 +96,17 @@ static void freeblock (Memcontrol *mc, Header *block) {
|
||||
lua_assert(*(cast(char *, block + 1) + size + i) == MARK);
|
||||
mc->objcount[block->d.type]--;
|
||||
fillmem(block, sizeof(Header) + size + MARKSIZE); /* erase block */
|
||||
- free(block); /* actually free block */
|
||||
+ mc->alloc_f(mc->alloc_ud, block, size, 0); /* actually free block */
|
||||
mc->numblocks--; /* update counts */
|
||||
mc->total -= size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-void *debug_realloc (void *ud, void *b, size_t oldsize, size_t size) {
|
||||
+static void *debug_realloc (void *ud, void *b, size_t oldsize, size_t size) {
|
||||
Memcontrol *mc = cast(Memcontrol *, ud);
|
||||
Header *block = cast(Header *, b);
|
||||
+
|
||||
int type;
|
||||
if (mc->memlimit == 0) { /* first time? */
|
||||
char *limit = getenv("MEMLIMIT"); /* initialize memory limit */
|
||||
@@ -152,7 +133,9 @@ void *debug_realloc (void *ud, void *b, size_t oldsize, size_t size) {
|
||||
size_t commonsize = (oldsize < size) ? oldsize : size;
|
||||
size_t realsize = sizeof(Header) + size + MARKSIZE;
|
||||
if (realsize < size) return NULL; /* arithmetic overflow! */
|
||||
- newblock = cast(Header *, malloc(realsize)); /* alloc a new block */
|
||||
+ /* alloc a new block */
|
||||
+ newblock = cast(Header *, mc->alloc_f(mc->alloc_ud, NULL, oldsize, realsize));
|
||||
+
|
||||
if (newblock == NULL) return NULL; /* really out of memory? */
|
||||
if (block) {
|
||||
memcpy(newblock + 1, block + 1, commonsize); /* copy old contents */
|
||||
@@ -578,18 +561,26 @@ static int get_limits (lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static Memcontrol *get_memcontrol(lua_State *L)
|
||||
+{
|
||||
+ void *ud;
|
||||
+
|
||||
+ lua_getallocf(L, &ud);
|
||||
+
|
||||
+ return (Memcontrol *)ud;
|
||||
+}
|
||||
|
||||
static int mem_query (lua_State *L) {
|
||||
if (lua_isnone(L, 1)) {
|
||||
- lua_pushinteger(L, l_memcontrol.total);
|
||||
- lua_pushinteger(L, l_memcontrol.numblocks);
|
||||
- lua_pushinteger(L, l_memcontrol.maxmem);
|
||||
+ lua_pushinteger(L, get_memcontrol(L)->total);
|
||||
+ lua_pushinteger(L, get_memcontrol(L)->numblocks);
|
||||
+ lua_pushinteger(L, get_memcontrol(L)->maxmem);
|
||||
return 3;
|
||||
}
|
||||
else if (lua_isnumber(L, 1)) {
|
||||
unsigned long limit = cast(unsigned long, luaL_checkinteger(L, 1));
|
||||
if (limit == 0) limit = ULONG_MAX;
|
||||
- l_memcontrol.memlimit = limit;
|
||||
+ get_memcontrol(L)->memlimit = limit;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
@@ -597,7 +588,7 @@ static int mem_query (lua_State *L) {
|
||||
int i;
|
||||
for (i = LUA_NUMTAGS - 1; i >= 0; i--) {
|
||||
if (strcmp(t, ttypename(i)) == 0) {
|
||||
- lua_pushinteger(L, l_memcontrol.objcount[i]);
|
||||
+ lua_pushinteger(L, get_memcontrol(L)->objcount[i]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -608,9 +599,9 @@ static int mem_query (lua_State *L) {
|
||||
|
||||
static int settrick (lua_State *L) {
|
||||
if (ttisnil(obj_at(L, 1)))
|
||||
- l_Trick = NULL;
|
||||
+ gettrick(L) = NULL;
|
||||
else
|
||||
- l_Trick = gcvalue(obj_at(L, 1));
|
||||
+ gettrick(L) = gcvalue(obj_at(L, 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -827,13 +818,22 @@ static int num2int (lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
+/* ugly way of getting the panic function without changing it.
|
||||
+ */
|
||||
+static lua_CFunction lua_getpanic (lua_State *L)
|
||||
+{
|
||||
+ lua_CFunction panicf = lua_atpanic(L, NULL);
|
||||
+ lua_atpanic(L, panicf);
|
||||
+
|
||||
+ return panicf;
|
||||
+}
|
||||
|
||||
static int newstate (lua_State *L) {
|
||||
void *ud;
|
||||
lua_Alloc f = lua_getallocf(L, &ud);
|
||||
lua_State *L1 = lua_newstate(f, ud);
|
||||
if (L1) {
|
||||
- lua_atpanic(L1, tpanic);
|
||||
+ lua_atpanic(L1, lua_getpanic(L));
|
||||
lua_pushlightuserdata(L, L1);
|
||||
}
|
||||
else
|
||||
@@ -1549,19 +1549,32 @@ static const struct luaL_Reg tests_funcs[] = {
|
||||
};
|
||||
|
||||
|
||||
-static void checkfinalmem (void) {
|
||||
- lua_assert(l_memcontrol.numblocks == 0);
|
||||
- lua_assert(l_memcontrol.total == 0);
|
||||
+void luaB_init_memcontrol(Memcontrol *mc, lua_Alloc f, void *ud)
|
||||
+{
|
||||
+ memset(mc, 0, sizeof(*mc));
|
||||
+
|
||||
+ mc->alloc_f = f;
|
||||
+ mc->alloc_ud = ud;
|
||||
+}
|
||||
+
|
||||
+lua_State * luaB_newstate(Memcontrol *mc)
|
||||
+{
|
||||
+ return lua_newstate(debug_realloc, mc);
|
||||
}
|
||||
|
||||
+void luaB_close(lua_State *L)
|
||||
+{
|
||||
+ Memcontrol * l_memcontrol = get_memcontrol(L);
|
||||
+
|
||||
+ lua_close(L);
|
||||
+
|
||||
+ lua_assert(l_memcontrol->numblocks == 0);
|
||||
+ lua_assert(l_memcontrol->total == 0);
|
||||
+}
|
||||
|
||||
int luaB_opentests (lua_State *L) {
|
||||
void *ud;
|
||||
- lua_atpanic(L, &tpanic);
|
||||
- atexit(checkfinalmem);
|
||||
lua_assert(lua_getallocf(L, &ud) == debug_realloc);
|
||||
- lua_assert(ud == cast(void *, &l_memcontrol));
|
||||
- lua_setallocf(L, lua_getallocf(L, NULL), ud);
|
||||
luaL_newlib(L, tests_funcs);
|
||||
return 1;
|
||||
}
|
||||
diff --git a/ltests.h b/ltests.h
|
||||
index 9d26fcb0..8e10670b 100644
|
||||
--- a/ltests.h
|
||||
+++ b/ltests.h
|
||||
@@ -4,12 +4,18 @@
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
+
|
||||
#ifndef ltests_h
|
||||
#define ltests_h
|
||||
|
||||
+/*
|
||||
+** The whole module only makes sense with LUA_DEBUG on
|
||||
+*/
|
||||
+#if defined(LUA_DEBUG)
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
+
|
||||
/* test Lua with no compatibility code */
|
||||
#undef LUA_COMPAT_MATHLIB
|
||||
#undef LUA_COMPAT_IPAIRS
|
||||
@@ -24,9 +30,6 @@
|
||||
#undef LUA_COMPAT_MODULE
|
||||
|
||||
|
||||
-#define LUA_DEBUG
|
||||
-
|
||||
-
|
||||
/* turn on assertions */
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
@@ -48,6 +51,9 @@
|
||||
|
||||
/* memory-allocator control variables */
|
||||
typedef struct Memcontrol {
|
||||
+ lua_Alloc alloc_f;
|
||||
+ void * alloc_ud;
|
||||
+
|
||||
unsigned long numblocks;
|
||||
unsigned long total;
|
||||
unsigned long maxmem;
|
||||
@@ -55,16 +61,6 @@ typedef struct Memcontrol {
|
||||
unsigned long objcount[LUA_NUMTAGS];
|
||||
} Memcontrol;
|
||||
|
||||
-LUA_API Memcontrol l_memcontrol;
|
||||
-
|
||||
-
|
||||
-/*
|
||||
-** generic variable for debug tricks
|
||||
-*/
|
||||
-extern void *l_Trick;
|
||||
-
|
||||
-
|
||||
-
|
||||
/*
|
||||
** Function to traverse and check all memory used by Lua
|
||||
*/
|
||||
@@ -74,38 +70,72 @@ int lua_checkmemory (lua_State *L);
|
||||
/* test for lock/unlock */
|
||||
|
||||
struct L_EXTRA { int lock; int *plock; };
|
||||
+
|
||||
+enum {LUA_OLDEXTRASPACE = LUA_EXTRASPACE };
|
||||
#undef LUA_EXTRASPACE
|
||||
-#define LUA_EXTRASPACE sizeof(struct L_EXTRA)
|
||||
-#define getlock(l) cast(struct L_EXTRA*, lua_getextraspace(l))
|
||||
+
|
||||
+struct COMP_L_EXTRA {
|
||||
+ char user_extraspace[LUA_OLDEXTRASPACE];
|
||||
+ struct L_EXTRA debug_extraspace;
|
||||
+ void *l_Trick; /* generic variable for debug tricks */
|
||||
+};
|
||||
+
|
||||
+#define LUA_EXTRASPACE sizeof(struct COMP_L_EXTRA)
|
||||
+
|
||||
+#define getlock(l) \
|
||||
+ (cast(struct COMP_L_EXTRA*, lua_getextraspace(l))->debug_extraspace)
|
||||
+
|
||||
+#define gettrick(l) \
|
||||
+ (cast(struct COMP_L_EXTRA*, lua_getextraspace(l))->l_Trick)
|
||||
+
|
||||
#define luai_userstateopen(l) \
|
||||
- (getlock(l)->lock = 0, getlock(l)->plock = &(getlock(l)->lock))
|
||||
+ (gettrick(l) = 0, getlock(l).lock = 0, getlock(l).plock = &(getlock(l).lock))
|
||||
#define luai_userstateclose(l) \
|
||||
- lua_assert(getlock(l)->lock == 1 && getlock(l)->plock == &(getlock(l)->lock))
|
||||
+ lua_assert(getlock(l).lock == 1 && getlock(l).plock == &(getlock(l).lock))
|
||||
#define luai_userstatethread(l,l1) \
|
||||
- lua_assert(getlock(l1)->plock == getlock(l)->plock)
|
||||
+ lua_assert(getlock(l1).plock == getlock(l).plock)
|
||||
#define luai_userstatefree(l,l1) \
|
||||
- lua_assert(getlock(l)->plock == getlock(l1)->plock)
|
||||
-#define lua_lock(l) lua_assert((*getlock(l)->plock)++ == 0)
|
||||
-#define lua_unlock(l) lua_assert(--(*getlock(l)->plock) == 0)
|
||||
+ lua_assert(getlock(l).plock == getlock(l1).plock)
|
||||
+#define lua_lock(l) lua_assert((*getlock(l).plock)++ == 0)
|
||||
+#define lua_unlock(l) lua_assert(--(*getlock(l).plock) == 0)
|
||||
|
||||
|
||||
|
||||
+/* Load the test library and assert that the intepreter is correctly set up
|
||||
+ * for testing.
|
||||
+ */
|
||||
LUA_API int luaB_opentests (lua_State *L);
|
||||
|
||||
-LUA_API void *debug_realloc (void *ud, void *block,
|
||||
- size_t osize, size_t nsize);
|
||||
-
|
||||
-#if defined(lua_c)
|
||||
-#define luaL_newstate() lua_newstate(debug_realloc, &l_memcontrol)
|
||||
-#define luaL_openlibs(L) \
|
||||
- { (luaL_openlibs)(L); \
|
||||
- luaL_requiref(L, "T", luaB_opentests, 1); \
|
||||
- lua_pop(L, 1); }
|
||||
-#endif
|
||||
-
|
||||
-
|
||||
-
|
||||
-/* change some sizes to give some bugs a chance */
|
||||
+/* Initialize the control block for the test allocator.
|
||||
+ * The test allocator is a wrapper around the user supplied allocator that
|
||||
+ * records diagnostic and debug information.
|
||||
+ *
|
||||
+ * It uses a Memcontrol structure as the "ud" userdata pointer. Inside this
|
||||
+ * structure the "real" allocator is stored and will be called to perform the
|
||||
+ * actual memory operations.
|
||||
+ *
|
||||
+ * Set f and ud to your application's allocator.
|
||||
+ */
|
||||
+LUA_API void luaB_init_memcontrol(Memcontrol *mc, lua_Alloc f, void *ud);
|
||||
+
|
||||
+/* Create a new state with a specially instrumented allocator.
|
||||
+ *
|
||||
+ * You must supply a properly initialized Memcontrol structure.
|
||||
+ * */
|
||||
+LUA_API lua_State * luaB_newstate(Memcontrol *mc);
|
||||
+
|
||||
+/* Close the lua state and check that all memory has been freed.
|
||||
+ */
|
||||
+LUA_API void luaB_close(lua_State *L);
|
||||
+
|
||||
+#define LUA_TESTLIBNAME "T"
|
||||
+
|
||||
+/* Change some sizes to give some bugs a chance
|
||||
+ * Activate this macro to make tests harder.
|
||||
+ * This is not enabled my default because the user may want only the
|
||||
+ * functionality of the test module.
|
||||
+ */
|
||||
+#ifdef DEBUG_OVERRIDE_SIZES
|
||||
|
||||
#undef LUAL_BUFFERSIZE
|
||||
#define LUAL_BUFFERSIZE 23
|
||||
@@ -125,5 +155,8 @@ LUA_API void *debug_realloc (void *ud, void *block,
|
||||
#define STRCACHE_N 23
|
||||
#define STRCACHE_M 5
|
||||
|
||||
-#endif
|
||||
+#endif /* DEBUG_OVERRIDE_SIZES */
|
||||
+
|
||||
+#endif /* LUA_DEBUG */
|
||||
|
||||
+#endif /* ltests_h */
|
||||
diff --git a/lua.c b/lua.c
|
||||
index 62de0f58..a41cd305 100644
|
||||
--- a/lua.c
|
||||
+++ b/lua.c
|
||||
@@ -592,21 +592,53 @@ static int pmain (lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
|
||||
+ (void)ud; (void)osize; /* not used */
|
||||
+ if (nsize == 0) {
|
||||
+ free(ptr);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ else
|
||||
+ return realloc(ptr, nsize);
|
||||
+}
|
||||
+
|
||||
+static int panic (lua_State *L) {
|
||||
+ lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
|
||||
+ lua_tostring(L, -1));
|
||||
+ return 0; /* return to Lua to abort */
|
||||
+}
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
int status, result;
|
||||
- lua_State *L = luaL_newstate(); /* create state */
|
||||
+ lua_State *L;
|
||||
+
|
||||
+ #ifdef LUA_DEBUG
|
||||
+ Memcontrol mc;
|
||||
+ luaB_init_memcontrol(&mc, l_alloc, NULL);
|
||||
+ L = luaB_newstate(&mc);
|
||||
+ #else
|
||||
+ L = lua_newstate(l_alloc, NULL);
|
||||
+ #endif /* LUA_DEBUG */
|
||||
+
|
||||
if (L == NULL) {
|
||||
l_message(argv[0], "cannot create state: not enough memory");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
+
|
||||
+ lua_atpanic(L, &panic);
|
||||
lua_pushcfunction(L, &pmain); /* to call 'pmain' in protected mode */
|
||||
lua_pushinteger(L, argc); /* 1st argument */
|
||||
lua_pushlightuserdata(L, argv); /* 2nd argument */
|
||||
status = lua_pcall(L, 2, 1, 0); /* do the call */
|
||||
result = lua_toboolean(L, -1); /* get result */
|
||||
report(L, status);
|
||||
- lua_close(L);
|
||||
+
|
||||
+ #ifdef LUA_DEBUG
|
||||
+ luaB_close(L);
|
||||
+ #else
|
||||
+ lua_close(L);
|
||||
+ #endif /* LUA_DEBUG */
|
||||
+
|
||||
return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
diff --git a/lua.h b/lua.h
|
||||
index fc4e2388..b40f0d5c 100644
|
||||
--- a/lua.h
|
||||
+++ b/lua.h
|
||||
@@ -124,7 +124,6 @@ typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud);
|
||||
typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
|
||||
|
||||
|
||||
-
|
||||
/*
|
||||
** generic extra include file
|
||||
*/
|
||||
@@ -132,6 +131,12 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
|
||||
#include LUA_USER_H
|
||||
#endif
|
||||
|
||||
+/* (optional) test module
|
||||
+ *
|
||||
+ * Note that the ltests.h file will do nothing if LUA_DEBUG is not defined.
|
||||
+ * This is done this way to avoid having a conditional dependency.
|
||||
+ */
|
||||
+#include "ltests.h"
|
||||
|
||||
/*
|
||||
** RCS ident string
|
||||
--
|
||||
2.17.1
|
||||
|
||||
358
pkg/lua/patches/0007-Add-a-proper-makefile.patch
Normal file
358
pkg/lua/patches/0007-Add-a-proper-makefile.patch
Normal file
@ -0,0 +1,358 @@
|
||||
From 1cfceae0d4d4ead217af7b66ed24b3909eb22dd2 Mon Sep 17 00:00:00 2001
|
||||
From: Juan Carrano <j.carrano@fu-berlin.de>
|
||||
Date: Mon, 14 May 2018 15:31:09 +0200
|
||||
Subject: [PATCH 7/8] Add a proper makefile.
|
||||
|
||||
The new makefile has automatic dependencies, can buid a debug an
|
||||
a non debug version simultaneously and is way cleaner.
|
||||
---
|
||||
.gitignore | 7 ++
|
||||
Makefile | 116 +++++++++++++++++++++++++++++++
|
||||
makefile | 198 -----------------------------------------------------
|
||||
3 files changed, 123 insertions(+), 198 deletions(-)
|
||||
create mode 100644 .gitignore
|
||||
create mode 100644 Makefile
|
||||
delete mode 100644 makefile
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
new file mode 100644
|
||||
index 00000000..08e46c95
|
||||
--- /dev/null
|
||||
+++ b/.gitignore
|
||||
@@ -0,0 +1,7 @@
|
||||
+*.o
|
||||
+*.gch
|
||||
+*.d
|
||||
+*.a
|
||||
+lua
|
||||
+lua-dbg
|
||||
+*.patch
|
||||
diff --git a/Makefile b/Makefile
|
||||
new file mode 100644
|
||||
index 00000000..2735db8d
|
||||
--- /dev/null
|
||||
+++ b/Makefile
|
||||
@@ -0,0 +1,116 @@
|
||||
+
|
||||
+RM= rm -f
|
||||
+LD=CC
|
||||
+ARFLAGS = rcs
|
||||
+
|
||||
+CWARNS= \
|
||||
+ -Wall \
|
||||
+ -pedantic \
|
||||
+ -Wextra \
|
||||
+ -Wshadow \
|
||||
+ -Wsign-compare \
|
||||
+ -Wundef \
|
||||
+ -Wwrite-strings \
|
||||
+ -Wredundant-decls \
|
||||
+ -Wdisabled-optimization \
|
||||
+ -Waggregate-return \
|
||||
+ -Wdouble-promotion \
|
||||
+ -Wdeclaration-after-statement \
|
||||
+ -Wmissing-prototypes \
|
||||
+ -Wnested-externs \
|
||||
+ -Wstrict-prototypes \
|
||||
+ -Wc++-compat \
|
||||
+ -Wold-style-definition
|
||||
+ #-Wno-aggressive-loop-optimizations # not accepted by clang \
|
||||
+ #-Wlogical-op # not accepted by clang \
|
||||
+ # the next warnings generate too much noise, so they are disabled
|
||||
+ # -Wconversion -Wno-sign-conversion \
|
||||
+ # -Wsign-conversion \
|
||||
+ # -Wconversion \
|
||||
+ # -Wstrict-overflow=2 \
|
||||
+ # -Wformat=2 \
|
||||
+ # -Wcast-qual \
|
||||
+
|
||||
+# -DEXTERNMEMCHECK -DHARDSTACKTESTS -DHARDMEMTESTS -DTRACEMEM='"tempmem"'
|
||||
+# -g -DLUA_USER_H='"ltests.h"'
|
||||
+# -pg -malign-double
|
||||
+# -DLUA_USE_CTYPE -DLUA_USE_APICHECK
|
||||
+# (in clang, '-ftrapv' for runtime checks of integer overflows)
|
||||
+# -fsanitize=undefined -ftrapv
|
||||
+TESTFLAGS= -DDEBUG_OVERRIDE_SIZES
|
||||
+
|
||||
+OFLAGS?=-O2
|
||||
+CFLAGS?= -std=c99 $(OFLAGS) $(CWARNS)
|
||||
+DEPFLAGS= -MM -MP -MQ $@ -MQ $*.o -MQ $*-dbg.o
|
||||
+LIBS?= -lm -ldl -lreadline
|
||||
+LDFLAGS?=$(LIBS)
|
||||
+
|
||||
+ifeq ($(LUA_32BITS),true)
|
||||
+CFLAGS+= -DLUA_32BITS
|
||||
+endif
|
||||
+
|
||||
+# rwildcard
|
||||
+# Use this function to recursively search for all files with a certain
|
||||
+# extension
|
||||
+rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
|
||||
+
|
||||
+ALL_C_FILES=$(call rwildcard,,*.c)
|
||||
+C_FILES=$(filter-out lua.c,$(ALL_C_FILES))
|
||||
+D_FILES=$(call rwildcard,,*.d)
|
||||
+O_FILES=$(call rwildcard,,*.o)
|
||||
+GCH_FILES=$(call rwildcard,,*.gch)
|
||||
+
|
||||
+NEEDED_OBJECTS=$(C_FILES:.c=.o)
|
||||
+DBG_OBJECTS=$(C_FILES:.c=-dbg.o)
|
||||
+
|
||||
+all: lua liblua.a lua-dbg liblua-dbg.a
|
||||
+
|
||||
+# --------------------------- cleaning -------------------------------------- #
|
||||
+
|
||||
+.PHONY: clean
|
||||
+clean: $(foreach f,$(O_FILES),$(f)-clean) \
|
||||
+ $(foreach f,$(GCH_FILES),$(f)-clean) \
|
||||
+ liblua.a-clean lua-clean liblua-dbg.a-clean lua-dbg-clean
|
||||
+
|
||||
+PHONY: depclean
|
||||
+depclean: $(foreach dfile,$(D_FILES),$(dfile)-clean)
|
||||
+
|
||||
+.PHONY: allclean
|
||||
+allclean: clean depclean
|
||||
+
|
||||
+%-clean:
|
||||
+ $(RM) $*
|
||||
+
|
||||
+# ----------------------------- DEPENDENCIES --------------------------------- #
|
||||
+
|
||||
+# If we are only cleaning then ignore the dependencies
|
||||
+ifneq ($(MAKECMDGOALS),depclean)
|
||||
+ifneq ($(MAKECMDGOALS),clean)
|
||||
+ifneq ($(MAKECMDGOALS),allclean)
|
||||
+-include $(C_FILES:.c=.d)
|
||||
+endif
|
||||
+endif
|
||||
+endif
|
||||
+
|
||||
+%.d: %.c
|
||||
+ $(CC) $(CFLAGS) $(DEPFLAGS) $< >$@
|
||||
+
|
||||
+# --------------------------- Output targets --------------------------------- #
|
||||
+
|
||||
+liblua.a: $(NEEDED_OBJECTS)
|
||||
+
|
||||
+liblua-dbg.a: $(DBG_OBJECTS)
|
||||
+
|
||||
+lua: lua.o liblua.a
|
||||
+
|
||||
+lua-dbg: lua-dbg.o liblua-dbg.a
|
||||
+
|
||||
+# --------------------------- Implicit rules --------------------------------- #
|
||||
+
|
||||
+%.a:
|
||||
+ @echo $(MSG_ARCHIVING)
|
||||
+ $(AR) $(ARFLAGS) $@ $^
|
||||
+
|
||||
+%-dbg.o: %.c
|
||||
+ # Override optimization options
|
||||
+ $(CC) $(CFLAGS) -O0 -g -dA -DLUA_DEBUG -DDEBUG_OVERRIDE_SIZES -c $< -o $@
|
||||
diff --git a/makefile b/makefile
|
||||
deleted file mode 100644
|
||||
index 8160d4fb..00000000
|
||||
--- a/makefile
|
||||
+++ /dev/null
|
||||
@@ -1,198 +0,0 @@
|
||||
-# makefile for building Lua
|
||||
-# see INSTALL for installation instructions
|
||||
-# see ../Makefile and luaconf.h for further customization
|
||||
-
|
||||
-# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
|
||||
-
|
||||
-# Warnings valid for both C and C++
|
||||
-CWARNSCPP= \
|
||||
- -pedantic \
|
||||
- -Wextra \
|
||||
- -Wshadow \
|
||||
- -Wsign-compare \
|
||||
- -Wundef \
|
||||
- -Wwrite-strings \
|
||||
- -Wredundant-decls \
|
||||
- -Wdisabled-optimization \
|
||||
- -Waggregate-return \
|
||||
- -Wdouble-promotion \
|
||||
- #-Wno-aggressive-loop-optimizations # not accepted by clang \
|
||||
- #-Wlogical-op # not accepted by clang \
|
||||
- # the next warnings generate too much noise, so they are disabled
|
||||
- # -Wconversion -Wno-sign-conversion \
|
||||
- # -Wsign-conversion \
|
||||
- # -Wconversion \
|
||||
- # -Wstrict-overflow=2 \
|
||||
- # -Wformat=2 \
|
||||
- # -Wcast-qual \
|
||||
-
|
||||
-# The next warnings are neither valid nor needed for C++
|
||||
-CWARNSC= -Wdeclaration-after-statement \
|
||||
- -Wmissing-prototypes \
|
||||
- -Wnested-externs \
|
||||
- -Wstrict-prototypes \
|
||||
- -Wc++-compat \
|
||||
- -Wold-style-definition \
|
||||
-
|
||||
-
|
||||
-CWARNS= $(CWARNSCPP) $(CWARNSC)
|
||||
-
|
||||
-
|
||||
-# -DEXTERNMEMCHECK -DHARDSTACKTESTS -DHARDMEMTESTS -DTRACEMEM='"tempmem"'
|
||||
-# -g -DLUA_USER_H='"ltests.h"'
|
||||
-# -pg -malign-double
|
||||
-# -DLUA_USE_CTYPE -DLUA_USE_APICHECK
|
||||
-# (in clang, '-ftrapv' for runtime checks of integer overflows)
|
||||
-# -fsanitize=undefined -ftrapv
|
||||
-TESTS= -DLUA_USER_H='"ltests.h"'
|
||||
-
|
||||
-# -mtune=native -fomit-frame-pointer
|
||||
-# -fno-stack-protector
|
||||
-LOCAL = $(TESTS) $(CWARNS) -g
|
||||
-
|
||||
-
|
||||
-
|
||||
-# enable Linux goodies
|
||||
-MYCFLAGS= $(LOCAL) -std=c99 -DLUA_USE_LINUX -DLUA_COMPAT_5_2
|
||||
-MYLDFLAGS= $(LOCAL) -Wl,-E
|
||||
-MYLIBS= -ldl -lreadline
|
||||
-
|
||||
-
|
||||
-CC= clang-3.8
|
||||
-CFLAGS= -Wall -O2 $(MYCFLAGS)
|
||||
-AR= ar rcu
|
||||
-RANLIB= ranlib
|
||||
-RM= rm -f
|
||||
-
|
||||
-
|
||||
-
|
||||
-# == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========
|
||||
-
|
||||
-
|
||||
-LIBS = -lm
|
||||
-
|
||||
-CORE_T= liblua.a
|
||||
-CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
|
||||
- lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \
|
||||
- ltm.o lundump.o lvm.o lzio.o ltests.o
|
||||
-AUX_O= lauxlib.o
|
||||
-LIB_O= lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o lstrlib.o \
|
||||
- lutf8lib.o lbitlib.o loadlib.o lcorolib.o linit.o
|
||||
-
|
||||
-LUA_T= lua
|
||||
-LUA_O= lua.o
|
||||
-
|
||||
-# LUAC_T= luac
|
||||
-# LUAC_O= luac.o print.o
|
||||
-
|
||||
-ALL_T= $(CORE_T) $(LUA_T) $(LUAC_T)
|
||||
-ALL_O= $(CORE_O) $(LUA_O) $(LUAC_O) $(AUX_O) $(LIB_O)
|
||||
-ALL_A= $(CORE_T)
|
||||
-
|
||||
-all: $(ALL_T)
|
||||
-
|
||||
-o: $(ALL_O)
|
||||
-
|
||||
-a: $(ALL_A)
|
||||
-
|
||||
-$(CORE_T): $(CORE_O) $(AUX_O) $(LIB_O)
|
||||
- $(AR) $@ $?
|
||||
- $(RANLIB) $@
|
||||
-
|
||||
-$(LUA_T): $(LUA_O) $(CORE_T)
|
||||
- $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(CORE_T) $(LIBS) $(MYLIBS) $(DL)
|
||||
-
|
||||
-$(LUAC_T): $(LUAC_O) $(CORE_T)
|
||||
- $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(CORE_T) $(LIBS) $(MYLIBS)
|
||||
-
|
||||
-clean:
|
||||
- rcsclean -u
|
||||
- $(RM) $(ALL_T) $(ALL_O)
|
||||
-
|
||||
-depend:
|
||||
- @$(CC) $(CFLAGS) -MM *.c
|
||||
-
|
||||
-echo:
|
||||
- @echo "CC = $(CC)"
|
||||
- @echo "CFLAGS = $(CFLAGS)"
|
||||
- @echo "AR = $(AR)"
|
||||
- @echo "RANLIB = $(RANLIB)"
|
||||
- @echo "RM = $(RM)"
|
||||
- @echo "MYCFLAGS = $(MYCFLAGS)"
|
||||
- @echo "MYLDFLAGS = $(MYLDFLAGS)"
|
||||
- @echo "MYLIBS = $(MYLIBS)"
|
||||
- @echo "DL = $(DL)"
|
||||
-
|
||||
-$(ALL_O): makefile
|
||||
-
|
||||
-# DO NOT EDIT
|
||||
-# automatically made with 'gcc -MM l*.c'
|
||||
-
|
||||
-lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
||||
- lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \
|
||||
- ltable.h lundump.h lvm.h
|
||||
-lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h
|
||||
-lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
-lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
-lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
|
||||
- llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
|
||||
- ldo.h lgc.h lstring.h ltable.h lvm.h
|
||||
-lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
-lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h
|
||||
-ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
-ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
||||
- lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \
|
||||
- ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h
|
||||
-ldo.o: ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
||||
- lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \
|
||||
- lparser.h lstring.h ltable.h lundump.h lvm.h
|
||||
-ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \
|
||||
- ltm.h lzio.h lmem.h lundump.h
|
||||
-lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \
|
||||
- lgc.h lstate.h ltm.h lzio.h lmem.h
|
||||
-lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
||||
- llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
|
||||
-linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h
|
||||
-liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
-llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h \
|
||||
- lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h llex.h lparser.h \
|
||||
- lstring.h ltable.h
|
||||
-lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
-lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
||||
- llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h
|
||||
-loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
-lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \
|
||||
- ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \
|
||||
- lvm.h
|
||||
-lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h
|
||||
-loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
-lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
|
||||
- llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
|
||||
- ldo.h lfunc.h lstring.h lgc.h ltable.h
|
||||
-lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
||||
- lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \
|
||||
- lstring.h ltable.h
|
||||
-lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
|
||||
- lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h
|
||||
-lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
-ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
||||
- llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
|
||||
-ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
-ltests.o: ltests.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
||||
- lobject.h ltm.h lzio.h lmem.h lauxlib.h lcode.h llex.h lopcodes.h \
|
||||
- lparser.h lctype.h ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h \
|
||||
- lualib.h
|
||||
-ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
||||
- llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h
|
||||
-lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
-lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
|
||||
- lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \
|
||||
- lundump.h
|
||||
-lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
-lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
||||
- llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \
|
||||
- ltable.h lvm.h
|
||||
-lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \
|
||||
- lobject.h ltm.h lzio.h
|
||||
-
|
||||
-# (end of Makefile)
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
From a3bb3e20c12dd7436fe4c3ec4c4f09b98ed0c443 Mon Sep 17 00:00:00 2001
|
||||
From: Juan Carrano <j.carrano@fu-berlin.de>
|
||||
Date: Tue, 29 May 2018 11:55:49 +0200
|
||||
Subject: [PATCH 8/8] Default to 32 bit build and small buffer size.
|
||||
|
||||
Set the word length and buffer size in luaconf.h so that it doesn't have to
|
||||
be specified in the compiler's command line each time.
|
||||
|
||||
LUAL_BUFFERSIZE can still be overrriden by -DLUAL_BUFFERSIZE=xxxx.
|
||||
To force a 64 bit build, define LUA_64BIT.
|
||||
---
|
||||
luaconf.h | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/luaconf.h b/luaconf.h
|
||||
index e816db00..8093833d 100644
|
||||
--- a/luaconf.h
|
||||
+++ b/luaconf.h
|
||||
@@ -33,7 +33,9 @@
|
||||
** ensure that all software connected to Lua will be compiled with the
|
||||
** same configuration.
|
||||
*/
|
||||
-/* #define LUA_32BITS */
|
||||
+#ifndef LUA_64BITS
|
||||
+#define LUA_32BITS
|
||||
+#endif
|
||||
|
||||
|
||||
/*
|
||||
@@ -753,7 +755,7 @@
|
||||
#if LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE
|
||||
#define LUAL_BUFFERSIZE 8192
|
||||
#else
|
||||
-#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
|
||||
+#define LUAL_BUFFERSIZE 64
|
||||
#endif
|
||||
|
||||
#endif
|
||||
--
|
||||
2.17.1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user