Merge branch 'dev-esp32-idf4-lua53' into dev-esp32-idf4

This commit is contained in:
Johny Mattsson 2021-08-24 10:42:43 +10:00
commit dba57fa0ea
225 changed files with 30454 additions and 3431 deletions

View File

@ -6,10 +6,11 @@ jobs:
build:
strategy:
fail-fast: false
matrix:
lua_ver: ['5.1']
numbers: ['float','integral']
target: ['esp32','esp32c3']
lua_ver: ['5.1', '5.3']
numbers: ['default', 'alternate']
target: ['esp32', 'esp32s2', 'esp32s3', 'esp32c3']
runs-on: ubuntu-latest
@ -28,19 +29,27 @@ jobs:
- name: Install dependencies
run: ./install.sh
shell: bash
- name: Build firmware (Lua 5.1)
if: ${{ matrix.lua_ver == '5.1' && matrix.numbers == 'float' }}
- name: Build firmware (default configuration)
if: ${{ matrix.numbers == 'default' }}
run: |
cp sdkconfig.defaults sdkconfig
make IDF_TARGET=${{ matrix.target }}
shell: bash
- name: Build firmware (Lua 5.1, integer-only)
if: ${{ matrix.lua_ver == '5.1' && matrix.numbers == 'integral' }}
if: ${{ matrix.lua_ver == '5.1' && matrix.numbers == 'alternate' }}
run: |
cp sdkconfig.defaults sdkconfig
echo CONFIG_LUA_NUMBER_INTEGRAL=y >> sdkconfig
make IDF_TARGET=${{ matrix.target }}
shell: bash
- name: Build firmware (Lua 5.3, 64bit int/double)
if: ${{ matrix.lua_ver == '5.3' && matrix.numbers == 'alternate' }}
run: |
cp sdkconfig.defaults sdkconfig
echo CONFIG_LUA_NUMBER_INT64=y >> sdkconfig
echo CONFIG_LUA_NUMBER_DOUBLE=y >> sdkconfig
make IDF_TARGET=${{ matrix.target }}
shell: bash
- name: Upload luac.cross
uses: actions/upload-artifact@v2
if: ${{ success() }}

View File

@ -1,15 +1,7 @@
idf_component_register(
SRCS "ip_fmt.c" "lextra.c" "linit.c" "lnodeaux.c" "uart.c" "user_main.c"
SRCS "ip_fmt.c" "user_main.c"
INCLUDE_DIRS "include"
REQUIRES "lua"
PRIV_REQUIRES "nvs_flash"
LDFRAGMENTS "nodemcu.lf"
)
target_compile_options(${COMPONENT_LIB} PRIVATE -DCONFIG_NODEMCU_CMODULE_UART)
target_link_libraries(${COMPONENT_LIB}
"-u UART_module_selected1"
"-u lua_rotables_part_map"
"-Wl,-defsym=lua_rotables_map=_lua_rotables_map_start"
"-Wl,-defsym=lua_libs_map=_lua_libs_map_start"
)

View File

@ -1,8 +1,7 @@
#ifndef __MODULE_H__
#define __MODULE_H__
#include "sdkconfig.h"
#include "lrotable.h"
#include "lnodemcu.h"
/* Registering a module within NodeMCU is really easy these days!
*
@ -18,11 +17,11 @@
*
* Then simply put a line like this at the bottom of your module file:
*
* NODEMCU_MODULE(MYNAME, "myname", myname_map, luaopen_myname);
* NODEMCU_MODULE(MYNAME, "myname", myname, luaopen_myname);
*
* or perhaps
*
* NODEMCU_MODULE(MYNAME, "myname", myname_map, NULL);
* NODEMCU_MODULE(MYNAME, "myname", myname, NULL);
*
* if you don't need an init function.
*
@ -36,23 +35,6 @@
#define MODULE_PASTE_(x,y) x##y
#define MODULE_EXPAND_PASTE_(x,y) MODULE_PASTE_(x,y)
#ifdef LUA_CROSS_COMPILER
#ifdef _MSC_VER
//on msvc it is necessary to go through more pre-processor hoops to get the
//section name built; string merging does not happen in the _declspecs.
//NOTE: linker magic is invoked via the magical '$' character. Caveat editor.
#define __TOKIFY(s) .rodata1$##s
#define __TOTOK(s) __TOKIFY(s)
#define __STRINGIFY(x) #x
#define __TOSTRING(x) __STRINGIFY(x)
#define __ROSECNAME(s) __TOSTRING(__TOTOK(s))
#define LOCK_IN_SECTION(s) __declspec ( allocate( __ROSECNAME(s) ) )
#else
#define LOCK_IN_SECTION(s) __attribute__((used,unused,section(".rodata1." #s)))
#endif
#else
#define LOCK_IN_SECTION(s) __attribute__((used,unused,section(".lua_" #s)))
#endif
/* For the ROM table, we name the variable according to ( | denotes concat):
* cfgname | _module_selected | CONFIG_NODEMCU_CMODULE_##cfgname
* where the CONFIG_NODEMCU_CMODULE_XYZ macro is first expanded to yield either
@ -65,10 +47,10 @@
*/
#define NODEMCU_MODULE(cfgname, luaname, map, initfunc) \
const LOCK_IN_SECTION(libs) \
luaR_entry MODULE_PASTE_(lua_lib_,cfgname) = { luaname, LRO_FUNCVAL(initfunc) }; \
ROTable_entry MODULE_PASTE_(lua_lib_,cfgname) = { luaname, LRO_FUNCVAL(initfunc) }; \
const LOCK_IN_SECTION(rotable) \
luaR_entry MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(CONFIG_NODEMCU_CMODULE_,cfgname))) \
= {luaname, LRO_ROVAL(map ## _map)}
ROTable_entry MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(CONFIG_NODEMCU_CMODULE_,cfgname))) \
= {luaname, LRO_ROVAL(map)}
#endif
@ -89,6 +71,6 @@
// NODEMCU_MODULE_STD() defines the entry points for an external module:
#define NODEMCU_MODULE_STD() \
static const LOCK_IN_SECTION(libs) \
luaR_entry lua_lib_module = {MODNAME, LRO_FUNCVAL(module_init)}; \
const LOCK_IN_SECTION(rotable) \
luaR_entry MODULE_EXPAND_PASTE_(EXTMODNAME, _entry) = {MODNAME, LRO_ROVAL(module_map)};
ROTable_entry lua_lib_module = {MODNAME, LRO_FUNCVAL(module_init)}; \
const const LOCK_IN_SECTION(rotable) \
ROTable_entry MODULE_EXPAND_PASTE_(EXTMODNAME, _entry) = {MODNAME, LRO_ROVAL(module_map)};

View File

@ -1,167 +0,0 @@
/*
** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $
** Initialization of libraries for lua.c
** See Copyright Notice in lua.h
*/
#define linit_c
#define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include "luaconf.h"
#include "module.h"
#include "lstate.h"
#include "lrotable.h"
#include <assert.h>
#include <stdalign.h>
LROT_EXTERN(strlib);
LROT_EXTERN(tab_funcs);
LROT_EXTERN(dblib);
LROT_EXTERN(co_funcs);
LROT_EXTERN(math);
#if defined(LUA_CROSS_COMPILER)
LROT_EXTERN(oslib);
//LROT_EXTERN(iolib);
#endif
/*
* The NodeMCU Lua initalisation has been adapted to use linker-based module
* registration. This uses a PSECT naming convention to allow the ROTable and
* initialisation function entries to be collected by the linker into two
* consoliated ROTables. This significantly simplifies adding new modules and
* configuring builds with a small subset of the total modules.
*
* This linker-based approach is not practical for cross compiler builds which
* must link on a range of platforms, and where we don't have control of PSECT
* placement. However unlike the target builds, the luac.cross builds only
* used a small and fixed list of libraries and so in this case the table can
* be defined in this source file, so in this case all library ROTables are
* defined here, avoiding the need for linker magic is avoided on host builds.
*
* Note that a separate ROTable is defined in lbaselib.c for the base functions
* and there is a metatable index cascade from _G to this base function table to
* the master rotables table. In the target build, the linker marshals the
* table, hence the LROT_BREAK() macros which don't 0 terminate the lists.
*/
#ifdef _MSC_VER
//MSVC requires us to declare these sections before we refer to them
#pragma section(__ROSECNAME(A), read)
#pragma section(__ROSECNAME(zzzzzzzz), read)
#pragma section(__ROSECNAME(libs), read)
#pragma section(__ROSECNAME(rotable), read)
//These help us to find the beginning and ending of the RO data. NOTE: linker
//magic is used; the section names are lexically sorted, so 'a' and 'z' are
//important to keep the other sections lexically between these two dummy
//variables. Check your mapfile output if you need to fiddle with this stuff.
const LOCK_IN_SECTION(A) char _ro_start[1] = {0};
const LOCK_IN_SECTION(zzzzzzzz) char _ro_end[1] = {0};
#endif
#if defined(LUA_CROSS_COMPILER)
LROT_PUBLIC_BEGIN(LOCK_IN_SECTION(rotable) lua_rotables)
LROT_TABENTRY( string, strlib )
LROT_TABENTRY( table, tab_funcs )
LROT_TABENTRY( coroutine, co_funcs )
LROT_TABENTRY( debug, dblib)
LROT_TABENTRY( math, math )
LROT_TABENTRY( ROM, lua_rotables )
LROT_TABENTRY( os, oslib )
//LROT_TABENTRY( io, iolib )
LROT_END(lua_rotables, NULL, 0)
#else
// Due to limitations in the IDF linker fragment generation, we have to
// play with link-time symbol generation/aliasing to set up the rotables
// properly. As part of that, we need to use a different name for the
// table here.
LROT_PUBLIC_BEGIN(LOCK_IN_SECTION(rotable) lua_rotables_part)
#ifdef CONFIG_LUA_BUILTIN_STRING
LROT_TABENTRY( string, strlib )
#endif
#ifdef CONFIG_LUA_BUILTIN_TABLE
LROT_TABENTRY( table, tab_funcs )
#endif
#ifdef CONFIG_LUA_BUILTIN_COROUTINE
LROT_TABENTRY( coroutine, co_funcs )
#endif
#ifdef CONFIG_LUA_BUILTIN_DEBUG
LROT_TABENTRY( debug, dblib)
#endif
#ifdef CONFIG_LUA_BUILTIN_MATH
LROT_TABENTRY( math, math )
#endif
LROT_TABENTRY( ROM, lua_rotables_part )
LROT_BREAK(lua_rotables_part)
#endif
LROT_PUBLIC_BEGIN(LOCK_IN_SECTION(libs) lua_libs)
LROT_FUNCENTRY( _, luaopen_base )
LROT_FUNCENTRY( package, luaopen_package )
#ifdef CONFIG_LUA_BUILTIN_STRING
LROT_FUNCENTRY( string, luaopen_string )
#endif
#ifdef CONFIG_LUA_BUILTIN_TABLE
LROT_FUNCENTRY( table, luaopen_table )
#endif
#ifdef CONFIG_LUA_BUILTIN_DEBUG
LROT_FUNCENTRY( debug, luaopen_debug )
#endif
#ifndef LUA_CROSS_COMPILER
LROT_BREAK(lua_libs)
#else
LROT_FUNCENTRY( io, luaopen_io )
LROT_END( lua_libs, NULL, 0)
#endif
#ifndef LUA_CROSS_COMPILER
extern void luaL_dbgbreak(void);
#endif
/* Historically the linker script took care of zero terminating both the
* lua_libs and lua_rotable arrays, but the IDF currently does not
* support injecting LONG(0) entries. To compensate, we have explicit
* end markers here which the linker fragment then place appropriately
* to terminate aforementioned arrays.
*/
const luaR_entry LOCK_IN_SECTION(libs_end_marker) libs_end_marker= { 0, };
const luaR_entry LOCK_IN_SECTION(rotable_end_marker) rotable_end_marker = { 0, };
void luaL_openlibs (lua_State *L) {
lua_pushrotable(L, LROT_TABLEREF(lua_libs));
lua_pushnil(L); /* first key */
/* loop round and open libraries */
#ifndef LUA_CROSS_COMPILER
// luaL_dbgbreak(); // This is a test point for debugging library start ups
#endif
while (lua_next(L, -2) != 0) {
if (lua_islightfunction(L,-1) &&
fvalue(L->top-1)) { // only process function entries
lua_pushvalue(L, -2);
lua_call(L, 1, 0); // call luaopen_XXX(libname)
} else {
lua_pop(L, 1);
}
}
lua_pop(L, 1); //cleanup stack
}
#ifndef LUA_CROSS_COMPILER
# ifdef LUA_NUMBER_INTEGRAL
# define COMPARE <=
# else
# define COMPARE ==
# endif
_Static_assert(_Alignof(luaR_entry) COMPARE 8, "Unexpected alignment of module registration - update the linker script snippets to match!");
_Static_assert(sizeof(luaR_entry) COMPARE 24, "Unexpect size of array member - update the linker script snippets to match!");
#endif

View File

@ -1,41 +1,17 @@
[sections:lua_libs]
entries:
.lua_libs
[sections:lua_libs_end_marker]
entries:
.lua_libs_end_marker
[sections:lua_rotable]
entries:
.lua_rotable
[sections:lua_rotable_end_marker]
entries:
.lua_rotable_end_marker
[sections:lua_esp_event_cb_table]
entries:
.lua_esp_event_cb_table
[scheme:nodemcu_arrays]
entries:
lua_libs -> flash_rodata
lua_libs_end_marker -> flash_rodata
lua_rotable -> flash_rodata
lua_rotable_end_marker -> flash_rodata
lua_esp_event_cb_table -> flash_rodata
# Important: don't change the alignments below without also updating the
# _Static_assert over in linit.c and/or nodemcu_esp_event.h!
# _Static_assert over in nodemcu_esp_event.h!
[mapping:nodemcu]
archive: *
entries:
* (nodemcu_arrays);
lua_libs -> flash_rodata KEEP() ALIGN(8) SURROUND(lua_libs_map),
lua_libs_end_marker -> flash_rodata KEEP(),
lua_rotable -> flash_rodata ALIGN(8) SURROUND(lua_rotables_map),
lua_rotable_end_marker -> flash_rodata KEEP(),
lua_esp_event_cb_table -> flash_rodata KEEP() ALIGN(4) SURROUND(esp_event_cb_table)

View File

@ -9,6 +9,7 @@
* 2014/1/1, v1.0 create this file.
*******************************************************************************/
#include "lua.h"
#include "linput.h"
#include "platform.h"
#include <string.h>
#include <stdlib.h>
@ -19,7 +20,6 @@
#include "nvs_flash.h"
#include "flash_api.h"
#include "driver/console.h"
#include "task/task.h"
#include "sections.h"
#include "nodemcu_esp_event.h"
@ -93,24 +93,9 @@ static void handle_default_loop_event(task_param_t param, task_prio_t prio)
// +================== New task interface ==================+
static void start_lua ()
{
char* lua_argv[] = { (char *)"lua", (char *)"-i", NULL };
NODE_DBG("Task task_lua started.\n");
lua_main( 2, lua_argv );
}
static void handle_input(task_param_t flag, task_prio_t priority) {
(void)priority;
lua_handle_input (flag);
}
static task_handle_t input_task;
task_handle_t user_get_input_sig(void) {
return input_task;
}
bool user_process_input(bool force) {
return task_post_low(input_task, force);
if (lua_main()) // If it returns true then LFS restart is needed
lua_main();
}
void nodemcu_init(void)
@ -144,8 +129,6 @@ void __attribute__((noreturn)) app_main(void)
{
task_init();
input_task = task_get_id (handle_input);
relayed_event_handled = xSemaphoreCreateBinary();
relayed_event_task = task_get_id(handle_default_loop_event);
@ -156,19 +139,7 @@ void __attribute__((noreturn)) app_main(void)
relay_default_loop_events,
NULL);
ConsoleSetup_t cfg;
cfg.bit_rate = CONFIG_NODEMCU_CONSOLE_BIT_RATE;
cfg.data_bits = CONSOLE_NUM_BITS_8;
cfg.parity = CONSOLE_PARITY_NONE;
cfg.stop_bits = CONSOLE_STOP_BITS_1;
cfg.auto_baud =
#ifdef CONFIG_NODEMCU_CONSOLE_BIT_RATE_AUTO
true;
#else
false;
#endif
console_init (&cfg, input_task);
platform_uart_start(CONFIG_ESP_CONSOLE_UART_NUM);
setvbuf(stdout, NULL, _IONBF, 0);
nodemcu_init ();

View File

@ -1,4 +1,4 @@
if(NOT "${IDF_TARGET}" STREQUAL "esp32c3")
if(IDF_TARGET STREQUAL "esp32")
idf_component_register(
SRCS "CAN.c"

View File

@ -1,5 +0,0 @@
idf_component_register(
SRCS "console.c"
INCLUDE_DIRS "include"
REQUIRES "task" "esp32"
)

View File

@ -1,197 +0,0 @@
/*
* Copyright 2016 Dius Computing Pty Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the copyright holders nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @author Johny Mattsson <jmattsson@dius.com.au>
*/
#include "driver/console.h"
#include "driver/uart.h"
#include "esp_intr_alloc.h"
#include "soc/soc.h"
#include "soc/uart_reg.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "sys/reent.h"
#include <unistd.h>
#include "rom/libc_stubs.h"
#include "rom/uart.h"
#define UART_INPUT_QUEUE_SZ 0x100
// These used to be available in soc/uart_register.h:
#define UART_GET_RXFIFO_RD_BYTE(i) GET_PERI_REG_BITS2(UART_FIFO_REG(i) , UART_RXFIFO_RD_BYTE_V, UART_RXFIFO_RD_BYTE_S)
#define UART_GET_RXFIFO_CNT(i) GET_PERI_REG_BITS2(UART_STATUS_REG(i) , UART_RXFIFO_CNT_V, UART_RXFIFO_CNT_S)
#define UART_SET_AUTOBAUD_EN(i,val) SET_PERI_REG_BITS(UART_AUTOBAUD_REG(i) ,UART_AUTOBAUD_EN_V,(val),UART_AUTOBAUD_EN_S)
typedef int (*_read_r_fn) (struct _reent *r, int fd, void *buf, int size);
static _read_r_fn _read_r_app;
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
static _read_r_fn _read_r_pro;
#endif
static xQueueHandle uart0Q;
static task_handle_t input_task = 0;
// --- Syscall support for reading from STDIN_FILENO ---------------
static int console_read_r (struct _reent *r, int fd, void *buf, int size, _read_r_fn next)
{
if (fd == STDIN_FILENO)
{
static _lock_t stdin_lock;
_lock_acquire_recursive (&stdin_lock);
char *c = (char *)buf;
int i = 0;
for (; i < size; ++i)
{
if (!console_getc (c++))
break;
}
_lock_release_recursive (&stdin_lock);
return i;
}
else if (next)
return next (r, fd, buf, size);
else
return -1;
}
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
static int console_read_r_pro (struct _reent *r, int fd, void *buf, int size)
{
return console_read_r (r, fd, buf, size, _read_r_pro);
}
#endif
static int console_read_r_app (struct _reent *r, int fd, void *buf, int size)
{
return console_read_r (r, fd, buf, size, _read_r_app);
}
// --- End syscall support -------------------------------------------
static void uart0_rx_intr_handler (void *arg)
{
(void)arg;
bool received = false;
uint32_t status = READ_PERI_REG(UART_INT_ST_REG(CONSOLE_UART));
while (status)
{
if (status & UART_FRM_ERR_INT_ENA)
{
// TODO: report somehow?
WRITE_PERI_REG(UART_INT_CLR_REG(CONSOLE_UART), UART_FRM_ERR_INT_ENA);
}
if ((status & UART_RXFIFO_TOUT_INT_ENA) ||
(status & UART_RXFIFO_FULL_INT_ENA))
{
uint32_t fifo_len = UART_GET_RXFIFO_CNT(CONSOLE_UART);
for (uint32_t i = 0; i < fifo_len; ++i)
{
received = true;
char c = UART_GET_RXFIFO_RD_BYTE(CONSOLE_UART);
if (uart0Q)
xQueueSendToBackFromISR (uart0Q, &c, NULL);
}
WRITE_PERI_REG(UART_INT_CLR_REG(CONSOLE_UART),
UART_RXFIFO_TOUT_INT_ENA | UART_RXFIFO_FULL_INT_ENA);
}
status = READ_PERI_REG(UART_INT_ST_REG(CONSOLE_UART));
}
if (received && input_task)
task_post_isr_low (input_task, false);
}
void console_setup (const ConsoleSetup_t *cfg)
{
esp_rom_uart_tx_wait_idle (CONSOLE_UART);
uart_config_t uart_conf = {
.baud_rate = cfg->bit_rate,
.data_bits =
cfg->data_bits == CONSOLE_NUM_BITS_5 ? UART_DATA_5_BITS :
cfg->data_bits == CONSOLE_NUM_BITS_6 ? UART_DATA_6_BITS :
cfg->data_bits == CONSOLE_NUM_BITS_7 ? UART_DATA_7_BITS :
UART_DATA_8_BITS,
.stop_bits =
cfg->stop_bits == CONSOLE_STOP_BITS_1 ? UART_STOP_BITS_1 :
cfg->stop_bits == CONSOLE_STOP_BITS_2 ? UART_STOP_BITS_2 :
UART_STOP_BITS_1_5,
.parity =
cfg->parity == CONSOLE_PARITY_NONE ? UART_PARITY_DISABLE :
cfg->parity == CONSOLE_PARITY_EVEN ? UART_PARITY_EVEN :
UART_PARITY_ODD,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
};
uart_param_config(CONSOLE_UART, &uart_conf);
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
// TODO: Make this actually work
UART_SET_AUTOBAUD_EN(CONSOLE_UART, cfg->auto_baud);
#endif
}
void console_init (const ConsoleSetup_t *cfg, task_handle_t tsk)
{
input_task = tsk;
uart0Q = xQueueCreate (UART_INPUT_QUEUE_SZ, sizeof (char));
console_setup (cfg);
uart_isr_register(CONSOLE_UART, uart0_rx_intr_handler, NULL, 0, NULL);
uart_set_rx_timeout(CONSOLE_UART, 2);
uart_set_rx_full_threshold(CONSOLE_UART, 10);
uart_enable_intr_mask(CONSOLE_UART,
UART_RXFIFO_TOUT_INT_ENA_M |
UART_RXFIFO_FULL_INT_ENA_M |
UART_FRM_ERR_INT_ENA_M);
// Register our console_read_r_xxx functions to support stdin input
#if defined(CONFIG_IDF_TARGET_ESP32C3)
_read_r_app = syscall_table_ptr->_read_r;
syscall_table_ptr->_read_r = console_read_r_app;
#else
_read_r_app = syscall_table_ptr_app->_read_r;
_read_r_pro = syscall_table_ptr_pro->_read_r;
syscall_table_ptr_app->_read_r = console_read_r_app;
syscall_table_ptr_pro->_read_r = console_read_r_pro;
#endif
}
bool console_getc (char *c)
{
return (uart0Q && (xQueueReceive (uart0Q, c, 0) == pdTRUE));
}

View File

@ -1,74 +0,0 @@
/*
* Copyright 2016 Dius Computing Pty Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the copyright holders nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @author Johny Mattsson <jmattsson@dius.com.au>
*/
#include "esp_rom_uart.h"
#include "task/task.h"
#include <stdint.h>
#include <stdbool.h>
#define CONSOLE_UART CONFIG_ESP_CONSOLE_UART_NUM
typedef enum
{
CONSOLE_NUM_BITS_5 = 0x0,
CONSOLE_NUM_BITS_6 = 0x1,
CONSOLE_NUM_BITS_7 = 0x2,
CONSOLE_NUM_BITS_8 = 0x3
} ConsoleNumBits_t;
typedef enum
{
CONSOLE_PARITY_NONE = 0x2,
CONSOLE_PARITY_ODD = 0x1,
CONSOLE_PARITY_EVEN = 0x0
} ConsoleParity_t;
typedef enum
{
CONSOLE_STOP_BITS_1 = 0x1,
CONSOLE_STOP_BITS_1_5 = 0x2,
CONSOLE_STOP_BITS_2 = 0x3
} ConsoleStopBits_t;
typedef struct
{
uint32_t bit_rate;
ConsoleNumBits_t data_bits;
ConsoleParity_t parity;
ConsoleStopBits_t stop_bits;
bool auto_baud;
} ConsoleSetup_t;
void console_init (const ConsoleSetup_t *cfg, task_handle_t tsk);
void console_setup (const ConsoleSetup_t *cfg);
bool console_getc (char *c);

View File

@ -1,10 +1,117 @@
idf_component_register(
SRCS "lapi.c" "lauxlib.c" "lbaselib.c" "lcode.c" "ldblib.c" "ldebug.c"
"ldo.c" "ldump.c" "legc.c" "lflash.c" "lfunc.c" "lgc.c" "llex.c" "lmathlib.c"
"lmem.c" "loadlib.c" "lobject.c" "lopcodes.c" "lparser.c" "lrotable.c"
"lstate.c" "lstring.c" "lstrlib.c" "ltable.c" "ltablib.c" "ltm.c"
"lua.c" "lundump.c" "lvm.c" "lzio.c"
INCLUDE_DIRS "."
REQUIRES "platform" "uzlib" "driver_console"
PRIV_REQUIRES "base_nodemcu" "embedded_lfs"
if(CONFIG_LUA_VERSION_51)
set(srcs
"lua-5.1/lapi.c"
"lua-5.1/lauxlib.c"
"lua-5.1/lbaselib.c"
"lua-5.1/lcode.c"
"lua-5.1/ldblib.c"
"lua-5.1/ldebug.c"
"lua-5.1/ldo.c"
"lua-5.1/ldump.c"
"lua-5.1/lflash.c"
"lua-5.1/lfunc.c"
"lua-5.1/lgc.c"
"lua-5.1/llex.c"
"lua-5.1/lmathlib.c"
"lua-5.1/lmem.c"
"lua-5.1/lnodemcu.c"
"lua-5.1/loadlib.c"
"lua-5.1/lobject.c"
"lua-5.1/lopcodes.c"
"lua-5.1/lparser.c"
"lua-5.1/lstate.c"
"lua-5.1/lstring.c"
"lua-5.1/lstrlib.c"
"lua-5.1/ltable.c"
"lua-5.1/ltablib.c"
"lua-5.1/ltm.c"
"lua-5.1/lua.c"
"lua-5.1/lundump.c"
"lua-5.1/lvm.c"
"lua-5.1/lzio.c"
)
set(luadir "lua-5.1")
elseif(CONFIG_LUA_VERSION_53)
set(srcs
"lua-5.3/lapi.c"
"lua-5.3/lauxlib.c"
"lua-5.3/lbaselib.c"
"lua-5.3/lbitlib.c"
"lua-5.3/lcode.c"
"lua-5.3/lcorolib.c"
"lua-5.3/lctype.c"
"lua-5.3/ldblib.c"
"lua-5.3/ldebug.c"
"lua-5.3/ldo.c"
"lua-5.3/ldump.c"
"lua-5.3/lfunc.c"
"lua-5.3/lgc.c"
"lua-5.3/llex.c"
"lua-5.3/lmathlib.c"
"lua-5.3/lmem.c"
"lua-5.3/lnodemcu.c"
"lua-5.3/loadlib.c"
"lua-5.3/lobject.c"
"lua-5.3/lopcodes.c"
"lua-5.3/lparser.c"
"lua-5.3/lstate.c"
"lua-5.3/lstring.c"
"lua-5.3/lstrlib.c"
"lua-5.3/ltable.c"
"lua-5.3/ltablib.c"
"lua-5.3/ltm.c"
"lua-5.3/lua.c"
"lua-5.3/lundump.c"
"lua-5.3/lutf8lib.c"
"lua-5.3/lvm.c"
"lua-5.3/lzio.c"
)
set(luadir "lua-5.3")
endif()
set(common_srcs
"common/lextra.c"
"common/lfs.c"
"common/linput.c"
"common/linit.c"
"common/lnodeaux.c"
"common/lpanic.c"
)
idf_component_register(
SRCS ${srcs} ${common_srcs}
INCLUDE_DIRS ${luadir} "common"
REQUIRES "platform" "nvs_flash" "uzlib"
PRIV_REQUIRES "base_nodemcu" "embedded_lfs"
LDFRAGMENTS "link_lua.lf"
)
#
# Cross compiler targets
#
# Not sure why we can't directly depend on ${SDKCONFIG_HEADER} in our
# externalproject_add(), but them's the brakes...
set(luac_build_dir "${BUILD_DIR}/luac_cross")
add_custom_command(
OUTPUT sdkconfig.h
COMMAND mkdir -p "${luac_build_dir}" && cp ${SDKCONFIG_HEADER} ${luac_build_dir}/sdkconfig.h
DEPENDS ${SDKCONFIG_HEADER}
VERBATIM
)
add_custom_target(sdkconfig_h DEPENDS sdkconfig.h)
externalproject_add(luac_cross_build
PREFIX ${luac_build_dir}
SOURCE_DIR ${COMPONENT_DIR}/${luadir}/host
CONFIGURE_COMMAND ""
BUILD_COMMAND make -f ${COMPONENT_DIR}/${luadir}/host/idf.mk LUAC_BUILD_DIR=${luac_build_dir} LUA_PATH=${COMPONENT_DIR}/${luadir} PYTHON=${PYTHON}
INSTALL_COMMAND ""
BUILD_ALWAYS 1
DEPENDS sdkconfig_h
)
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
"${BUILD_DIR}/luac_cross/luac.cross;${BUILD_DIR}/luac_cross/${luadir}" )

View File

@ -1,12 +1,46 @@
menu "Lua configuration"
choice LUA_VERSION
prompt "Lua version"
default LUA_VERSION_51
help
The version of Lua interpreter to use.
config LUA_VERSION_51
bool "Lua 5.1"
config LUA_VERSION_53
bool "Lua 5.3"
endchoice
config LUA_NUMBER_INTEGRAL
depends on LUA_VERSION_51
bool "Integer-only build"
default "n"
help
Build Lua without support for floating point numbers.
Not generally recommended, but can save on code size.
config LUA_NUMBER_INT64
depends on LUA_VERSION_53
bool "Use 64bit integers"
default "n"
help
Build Lua with 64bit integers. This provides a greater value
range, but at the expense of extra memory usage and somewhat
reduced performance over the default 32bit integers.
config LUA_NUMBER_DOUBLE
depends on LUA_VERSION_53
bool "Use double precision floating point"
default "n"
help
Build Lua with double floating point precision. This provides
a greater value range, but at the expense of extra memory
usage and somewhat reduced performance over the default
single precision floating point.
menu "Core Lua modules"
config LUA_BUILTIN_STRING
@ -33,6 +67,13 @@ menu "Lua configuration"
help
Includes the math module (recommended).
config LUA_BUILTIN_UTF8
depends on !LUA_VERSION_51
bool "UTF8 module"
default "y"
help
Includes the debug module (required by our Lua VM).
config LUA_BUILTIN_DEBUG
bool "Debug module"
default "n"
@ -78,4 +119,11 @@ menu "Lua configuration"
endmenu
config LUA_REQUIRED_MODULES
bool
default y
select NODEMCU_CMODULE_PIPE
select NODEMCU_CMODULE_UART
select LUA_BUILTIN_DEBUG
endmenu

103
components/lua/common/lfs.c Normal file
View File

@ -0,0 +1,103 @@
#include "lfs.h"
#include "esp_partition.h"
#include "nvs_flash.h"
#include "platform.h"
#if defined(CONFIG_NODEMCU_EMBEDDED_LFS_SIZE)
// Symbol provided by embedded_lfs component
extern const char lua_flash_store_reserved[0];
#endif
bool lfs_get_location(lfs_location_info_t *out)
{
#if defined(CONFIG_NODEMCU_EMBEDDED_LFS_SIZE)
out->size = CONFIG_NODEMCU_EMBEDDED_LFS_SIZE;
out->addr_mem = lua_flash_store_reserved;
out->addr_phys = spi_flash_cache2phys(lua_flash_store_reserved);
if (out->addr_phys == SPI_FLASH_CACHE2PHYS_FAIL) {
NODE_ERR("spi_flash_cache2phys failed\n");
return false;
}
else
return true;
#else
const esp_partition_t *part = esp_partition_find_first(
PLATFORM_PARTITION_TYPE_NODEMCU,
PLATFORM_PARTITION_SUBTYPE_NODEMCU_LFS,
NULL);
if (!part)
return false; // Nothing to do if no LFS partition available
out->size = part->size; // in bytes
out->addr_mem = spi_flash_phys2cache(out->addr_phys, SPI_FLASH_MMAP_DATA);
out->addr_phys = part->address;
if (!out->addr_mem) { // not already mmap'd, have to do it ourselves
spi_flash_mmap_handle_t ignored;
esp_err_t err = spi_flash_mmap(
out->addr_phys, out->size, SPI_FLASH_MMAP_DATA, &out->addr_mem, &ignored);
if (err != ESP_OK) {
NODE_ERR("Unable to access LFS partition - is it 64kB aligned as it needs to be?\n");
return false;
}
}
return true;
#endif
}
#define LFS_LOAD_NS "lfsload"
#define LFS_LOAD_FILE_KEY "filename"
bool lfs_get_load_filename(char *buf, size_t bufsiz)
{
bool res = false;
nvs_handle_t handle;
esp_err_t err = nvs_open(LFS_LOAD_NS, NVS_READONLY, &handle);
if (err != ESP_OK)
goto out;
err = nvs_get_str(handle, LFS_LOAD_FILE_KEY, buf, &bufsiz);
if (err != ESP_OK)
goto close_out;
res = true;
close_out:
nvs_close(handle);
out:
return res;
}
bool lfs_set_load_filename(const char *fname)
{
bool res = false;
nvs_handle_t handle;
esp_err_t err = nvs_open(LFS_LOAD_NS, NVS_READWRITE, &handle);
if (err != ESP_OK)
goto out;
err = nvs_set_str(handle, LFS_LOAD_FILE_KEY, fname);
if (err != ESP_OK)
goto close_out;
res = true;
close_out:
nvs_close(handle);
out:
return res;
}
bool lfs_clear_load_filename(void)
{
bool res = false;
nvs_handle_t handle;
esp_err_t err = nvs_open(LFS_LOAD_NS, NVS_READWRITE, &handle);
if (err != ESP_OK)
goto out;
err = nvs_erase_key(handle, LFS_LOAD_FILE_KEY);
if (err != ESP_OK)
goto close_out;
res = true;
close_out:
nvs_close(handle);
out:
return res;
}

View File

@ -0,0 +1,21 @@
#ifndef _LFS_H_
#define _LFS_H_
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
typedef struct {
uint32_t size;
uint32_t addr_phys; // physical address in flash
const void *addr_mem; // memory mapped address
} lfs_location_info_t;
bool lfs_get_location(lfs_location_info_t *out);
// Setting & getting of filename during reboot/load cycle
bool lfs_get_load_filename(char *buf, size_t bufsiz);
bool lfs_set_load_filename(const char *fname);
bool lfs_clear_load_filename(void);
#endif

View File

@ -0,0 +1,170 @@
/*
** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $
** Initialization of libraries for lua.c
** See Copyright Notice in lua.h
*/
#define linit_c
#define LUA_LIB
#define LUA_CORE
/*
** NodeMCU uses RO segment based static ROTable declarations for all library
** tables, including the index of library tables itself (the ROM table). These
** tables can be moved from RAM to flash ROM on the ESPs.
**
** On the ESPs targets, we can marshal the table entries through linker-based
** PSECTs to enable the library initiation tables to be bound during the link
** process rather than being statically declared here. This simplifies the
** addition of new modules and configuring builds with a subset of the total
** modules available.
**
** Such a linker-based approach is not practical for cross compiler builds that
** must link on a range of platforms, and where we don't have control of PSECT
** placement. However unlike the target builds, the luac.cross builds only
** use a small and fixed list of libraries and so in this case all of libraries
** are defined here, avoiding the need for linker magic on host builds.
**
** Note that a separate ROTable is defined in lbaselib.c on luac.cross builds
** for the base functions. (These use linker based entries on target builds)
** and there is a metatable index cascade from _G to this base function table
** to the master rotables table. In the target build, the linker marshals the
** table, hence the LROT_BREAK() macros which don't 0 terminate the lists and
** skip generating the ROtable header.
*/
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include "lstate.h"
#include "lnodemcu.h"
#if LUA_VERSION_NUM == 501
#include "lflash.h"
#endif
extern LROT_TABLE(strlib);
extern LROT_TABLE(tab_funcs);
extern LROT_TABLE(dblib);
extern LROT_TABLE(co_funcs);
extern LROT_TABLE(mathlib);
extern LROT_TABLE(utf8);
#if defined(LUA_CROSS_COMPILER)
/* _G __index -> rotables __index -> base_func */
extern LROT_TABLE(rotables_meta);
extern LROT_TABLE(base_func);
#if LUA_VERSION_NUM == 501
extern LROT_TABLE(oslib);
extern LROT_TABLE(iolib);
#endif
LROT_BEGIN(rotables_meta, NULL, LROT_MASK_INDEX)
LROT_TABENTRY( __index, base_func)
LROT_END(rotables_meta, NULL, LROT_MASK_INDEX)
LROT_BEGIN(rotables, LROT_TABLEREF(rotables_meta), 0)
LROT_TABENTRY( string, strlib )
LROT_TABENTRY( table, tab_funcs )
LROT_TABENTRY( coroutine, co_funcs )
LROT_TABENTRY( debug, dblib)
LROT_TABENTRY( math, mathlib )
#if LUA_VERSION_NUM >= 503
LROT_TABENTRY( utf8, utf8 )
#endif
LROT_TABENTRY( ROM, rotables )
#if LUA_VERSION_NUM == 501
LROT_TABENTRY( os, oslib )
LROT_TABENTRY( io, iolib )
#endif
LROT_END(rotables, LROT_TABLEREF(rotables_meta), 0)
LROT_BEGIN(lua_libs, NULL, 0)
LROT_FUNCENTRY( _G, luaopen_base )
LROT_FUNCENTRY( package, luaopen_package )
LROT_FUNCENTRY( string, luaopen_string )
#if LUA_VERSION_NUM >= 503
LROT_FUNCENTRY( nodemcu, luaN_init )
#endif
LROT_FUNCENTRY( io, luaopen_io )
LROT_FUNCENTRY( is, luaopen_os )
LROT_END(lua_libs, NULL, 0)
#else
/* These symbols get created by the linker fragment mapping:nodemcu
* at the head of the lua libs init table and the rotables, respectively.
*/
extern const ROTable_entry _lua_libs_map_start[];
extern const ROTable_entry _lua_rotables_map_start[];
ROTable rotables_ROTable; /* NOT const in this case */
LROT_ENTRIES_IN_SECTION(rotables, rotable)
#ifdef CONFIG_LUA_BUILTIN_STRING
LROT_TABENTRY( string, strlib )
#endif
#ifdef CONFIG_LUA_BUILTIN_TABLE
LROT_TABENTRY( table, tab_funcs )
#endif
#ifdef CONFIG_LUA_BUILTIN_COROUTINE
LROT_TABENTRY( coroutine, co_funcs )
#endif
#ifdef CONFIG_LUA_BUILTIN_DEBUG
LROT_TABENTRY( debug, dblib)
#endif
#ifdef CONFIG_LUA_BUILTIN_MATH
LROT_TABENTRY( math, mathlib )
#endif
#ifdef CONFIG_LUA_BUILTIN_UTF8
LROT_TABENTRY( utf8, utf8 )
#endif
LROT_TABENTRY( ROM, rotables )
LROT_BREAK(lua_rotables_part)
LROT_ENTRIES_IN_SECTION(lua_libs, libs)
LROT_FUNCENTRY( _G, luaopen_base )
LROT_FUNCENTRY( package, luaopen_package )
#ifdef CONFIG_LUA_BUILTIN_STRING
LROT_FUNCENTRY( string, luaopen_string )
#endif
LROT_FUNCENTRY( nodemcu, luaN_init )
LROT_BREAK(lua_libs)
#endif
/* Historically the linker script took care of zero terminating both the
* lua_libs and lua_rotable arrays, but the IDF currently does not
* support injecting LONG(0) entries. To compensate, we have explicit
* end markers here which the linker fragment then place appropriately
* to terminate aforementioned arrays.
*/
const ROTable_entry LOCK_IN_SECTION(libs_end_marker) libs_end_marker= { 0, };
const ROTable_entry LOCK_IN_SECTION(rotable_end_marker) rotable_end_marker = { 0, };
void luaL_openlibs (lua_State *L) {
#ifdef LUA_CROSS_COMPILER
const ROTable_entry *p = LROT_TABLEREF(lua_libs)->entry;
#else
const ROTable_entry *p = _lua_libs_map_start;
lua_createrotable(L, LROT_TABLEREF(rotables), _lua_rotables_map_start, NULL);
#endif
for ( ; p->key; p++) {
#if LUA_VERSION_NUM == 501
if (ttislightfunction(&p->value) && fvalue(&p->value)) {
lua_pushcfunction(L, fvalue(&p->value));
lua_pushstring(L, p->key);
lua_call(L, 1, 0); // call luaopen_XXX(libname)
}
#else
if (ttislcf(&p->value) && fvalue(&p->value))
luaL_requiref(L, p->key, fvalue(&p->value), 1);
#endif
}
}
#ifndef LUA_CROSS_COMPILER
_Static_assert(_Alignof(ROTable_entry) <= 8, "Unexpected alignment of module registration - update the linker script snippets to match!");
#endif

View File

@ -0,0 +1,119 @@
#include "platform.h"
#include "linput.h"
#include "lua.h"
#include "lauxlib.h"
#include <stdio.h>
static struct input_state {
char *data;
int line_pos;
size_t len;
const char *prompt;
char last_nl_char;
} ins = {0};
#define NUL '\0'
#define BS '\010'
#define CR '\r'
#define LF '\n'
#define DEL 0x7f
#define BS_OVER "\010 \010"
bool input_echo = true;
bool run_input = true;
/*
** The input state (ins) is private, so input_setup() exposes the necessary
** access to public properties and is called in user_init() before the Lua
** enviroment is initialised.
*/
void input_setup(int bufsize, const char *prompt) {
// Initialise non-zero elements
ins.data = malloc(bufsize);
ins.len = bufsize;
ins.prompt = prompt;
}
void input_setprompt (const char *prompt) {
ins.prompt = prompt;
}
size_t feed_lua_input(const char *buf, size_t n)
{
for (size_t i = 0; i < n; ++i) {
char ch = buf[i];
if (!run_input) // We're no longer interested in the remaining bytes
return i;
/* handle CR & LF characters and aggregate \n\r and \r\n pairs */
char tmp_last_nl_char = ins.last_nl_char;
/* handle CR & LF characters
filters second char of LF&CR (\n\r) or CR&LF (\r\n) sequences */
if ((ch == CR && tmp_last_nl_char == LF) || // \n\r sequence -> skip \r
(ch == LF && tmp_last_nl_char == CR)) // \r\n sequence -> skip \n
{
continue;
}
/* backspace key */
if (ch == DEL || ch == BS) {
if (ins.line_pos > 0) {
if(input_echo) printf(BS_OVER);
ins.line_pos--;
}
ins.data[ins.line_pos] = 0;
continue;
}
/* end of data */
if (ch == CR || ch == LF) {
ins.last_nl_char = ch;
if (input_echo) putchar(LF);
if (ins.line_pos == 0) {
/* Get a empty line, then go to get a new line */
printf(ins.prompt);
fflush(stdout);
} else {
ins.data[ins.line_pos++] = LF;
lua_input_string(ins.data, ins.line_pos);
ins.line_pos = 0;
}
continue;
}
else
ins.last_nl_char = NUL;
if(input_echo) putchar(ch);
/* it's a large line, discard it */
if ( ins.line_pos + 1 >= ins.len ){
ins.line_pos = 0;
}
ins.data[ins.line_pos++] = ch;
}
return n; // we consumed/buffered all the provided data
}
void output_redirect(const char *str, size_t l) {
lua_State *L = lua_getstate();
int n = lua_gettop(L);
lua_pushliteral(L, "stdout");
lua_rawget(L, LUA_REGISTRYINDEX); /* fetch reg.stdout */
if (lua_istable(L, -1)) { /* reg.stdout is pipe */
lua_rawgeti(L, -1, 1); /* get the pipe_write func from stdout[1] */
lua_insert(L, -2); /* and move above the pipe ref */
lua_pushlstring(L, str, l);
if (lua_pcall(L, 2, 0, 0) != LUA_OK) { /* Reg.stdout:write(str) */
lua_writestringerror("error calling stdout:write(%s)\n", lua_tostring(L, -1));
esp_restart();
}
} else { /* reg.stdout == nil */
printf(str, l);
}
lua_settop(L, n); /* Make sure all code paths leave stack unchanged */
}

View File

@ -0,0 +1,15 @@
#ifndef _LINPUT_H_
#define _LINPUT_H_
#include <stdbool.h>
#include <stddef.h>
void input_setup(int bufsize, const char *prompt);
void input_setprompt (const char *prompt);
unsigned feed_lua_input(const char *buf, size_t n);
extern bool input_echo;
extern bool run_input;
#endif /* READLINE_APP_H */

View File

@ -99,7 +99,7 @@ char* luaX_alloc_string(lua_State* L, int idx, int max_length) {
// luaX_free_string deallocates memory of a string allocated with luaX_alloc_string
void luaX_free_string(lua_State* L, char* st) {
if (st)
luaM_freearray(L, st, strlen(st) + 1, char);
luaN_freearray(L, st, strlen(st) + 1);
}
// luaX_unset_ref unpins a reference to a lua object in the registry

View File

@ -36,6 +36,7 @@
#define _NODEMCU_LNODEAUX_H_
#include "lua.h"
#include <stdbool.h>
// lua_ref_t represents a reference to a lua object in the registry
typedef int lua_ref_t;

View File

@ -0,0 +1,54 @@
#include "lpanic.h"
#include "lauxlib.h"
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#ifndef LUA_CROSS_COMPILER
#include "esp_system.h"
/* defined in esp_system_internal.h */
void esp_reset_reason_set_hint(esp_reset_reason_t hint);
#endif
#ifndef LUA_CROSS_COMPILER
/*
* upper 28 bit have magic value 0xD1EC0DE0
* if paniclevel is valid (i.e. matches magic value)
* lower 4 bits have paniclevel:
* 0 = no panic occurred
* 1..15 = one..fifteen subsequent panic(s) occurred
*/
static __NOINIT_ATTR uint32_t l_rtc_panic_val;
void panic_clear_nvval() {
l_rtc_panic_val = 0xD1EC0DE0;
}
int panic_get_nvval() {
if ((l_rtc_panic_val & 0xfffffff0) == 0xD1EC0DE0) {
return (l_rtc_panic_val & 0xf);
}
panic_clear_nvval();
return 0;
}
#endif
int lpanic (lua_State *L) {
(void)L; /* to avoid warnings */
#ifndef LUA_CROSS_COMPILER
uint8_t paniclevel = panic_get_nvval();
if (paniclevel < 15) paniclevel++;
l_rtc_panic_val = 0xD1EC0DE0 | paniclevel;
#endif
lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
lua_tostring(L, -1));
#ifndef LUA_CROSS_COMPILER
fflush(stdout);
/* call abort() directly - we don't want another reset cause to intervene */
esp_reset_reason_set_hint(ESP_RST_PANIC);
#endif
abort();
while (1) {}
return 0;
}

View File

@ -0,0 +1,10 @@
#ifndef _LUA_PANIC_H_
#define _LUA_PANIC_H_
#include "lua.h"
void panic_clear_nvval (void);
int panic_get_nvval (void);
int lpanic (lua_State *L);
#endif

View File

@ -1,12 +0,0 @@
// Lua EGC (Emergeny Garbage Collector) interface
#include "legc.h"
#include "lstate.h"
void legc_set_mode(lua_State *L, int mode, int limit) {
global_State *g = G(L);
g->egcmode = mode;
g->memlimit = limit;
}

View File

@ -1,17 +0,0 @@
// Lua EGC (Emergeny Garbage Collector) interface
#ifndef __LEGC_H__
#define __LEGC_H__
#include "lstate.h"
// EGC operations modes
#define EGC_NOT_ACTIVE 0 // EGC disabled
#define EGC_ON_ALLOC_FAILURE 1 // run EGC on allocation failure
#define EGC_ON_MEM_LIMIT 2 // run EGC when an upper memory limit is hit
#define EGC_ALWAYS 4 // always run EGC before an allocation
void legc_set_mode(lua_State *L, int mode, int limit);
#endif

View File

@ -0,0 +1,35 @@
[sections:lua_libs]
entries:
.lua_libs
[sections:lua_libs_end_marker]
entries:
.lua_libs_end_marker
[sections:lua_rotable]
entries:
.lua_rotable
[sections:lua_rotable_end_marker]
entries:
.lua_rotable_end_marker
[scheme:lua_arrays]
entries:
lua_libs -> flash_rodata
lua_libs_end_marker -> flash_rodata
lua_rotable -> flash_rodata
lua_rotable_end_marker -> flash_rodata
# Important: don't change the alignments below without also updating the
# _Static_assert over in linit.c!
[mapping:lua]
archive: *
entries:
* (lua_arrays);
lua_libs -> flash_rodata KEEP() ALIGN(8) SURROUND(lua_libs_map),
lua_libs_end_marker -> flash_rodata KEEP(),
lua_rotable -> flash_rodata KEEP() ALIGN(8) SURROUND(lua_rotables_map),
lua_rotable_end_marker -> flash_rodata KEEP()

View File

@ -1,157 +0,0 @@
/* Read-only tables for Lua */
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
#include "lrotable.h"
#include "lauxlib.h"
#include "lstring.h"
#include "lobject.h"
#include "lapi.h"
#ifdef _MSC_VER
#define ALIGNED_STRING __declspec( align( 4 ) ) char
#else
#define ALIGNED_STRING __attribute__((aligned(4))) char
#endif
#define LA_LINES 32
#define LA_SLOTS 4
//#define COLLECT_STATS
/*
* All keyed ROtable access passes through luaR_findentry(). ROTables
* are simply a list of <key><TValue value> pairs. The existing algo
* did a linear scan of this vector of pairs looking for a match.
*
* A N×M lookaside cache has been added, with a simple hash on the key's
* TString addr and the ROTable addr to identify one of N lines. Each
* line has M slots which are scanned. This is all done in RAM and is
* perhaps 20x faster than the corresponding random Flash accesses which
* will cause flash faults.
*
* If a match is found and the table addresses match, then this entry is
* probed first. In practice the hit-rate here is over 99% so the code
* rarely fails back to doing the linear scan in ROM.
*
* Note that this hash does a couple of prime multiples and a modulus 2^X
* with is all evaluated in H/W, and adequately randomizes the lookup.
*/
#define HASH(a,b) ((((519*(size_t)(a)))>>4) + ((b) ? (b)->tsv.hash: 0))
static struct {
unsigned hash;
unsigned addr:24;
unsigned ndx:8;
} cache[LA_LINES][LA_SLOTS];
#ifdef COLLECT_STATS
unsigned cache_stats[3];
#define COUNT(i) cache_stats[i]++
#else
#define COUNT(i)
#endif
static int lookup_cache(unsigned hash, ROTable *rotable) {
int i = (hash>>2) & (LA_LINES-1), j;
for (j = 0; j<LA_SLOTS; j++) {
if (cache[i][j].hash == hash &&
((size_t)rotable & 0xffffffu) == cache[i][j].addr) {
COUNT(0);
return cache[i][j].ndx;
}
}
COUNT(1);
return -1;
}
static void update_cache(unsigned hash, ROTable *rotable, unsigned ndx) {
int i = (hash)>>2 & (LA_LINES-1), j;
COUNT(2);
if (ndx>0xffu)
return;
for (j = LA_SLOTS-1; j>0; j--)
cache[i][j] = cache[i][j-1];
cache[i][0].hash = hash;
cache[i][0].addr = (size_t) rotable;
cache[i][0].ndx = ndx;
}
/*
* Find a string key entry in a rotable and return it. Note that this internally
* uses a null key to denote a metatable search.
*/
const TValue* luaR_findentry(ROTable *rotable, TString *key, unsigned *ppos) {
const luaR_entry *pentry = rotable;
static const ALIGNED_STRING metatablestr[] = "__metatable";
const char *strkey = key ? getstr(key) : metatablestr;
unsigned hash = HASH(rotable, key);
unsigned i = 0;
int j = lookup_cache(hash, rotable);
unsigned l = key ? key->tsv.len : sizeof("__metatable")-1;
if (pentry) {
if (j >= 0 && !strcmp(pentry[j].key, strkey)) {
if (ppos)
*ppos = j;
//printf("%3d hit %p %s\n", (hash>>2) & (LA_LINES-1), rotable, strkey);
return &pentry[j].value;
}
/*
* The invariants for 1st word comparison are deferred to here since they
* aren't needed if there is a cache hit. Note that the termination null
* is included so a "on\0" has a mask of 0xFFFFFF and "a\0" has 0xFFFF.
*/
unsigned name4, mask4 = l > 2 ? (~0u) : (~0u)>>((3-l)*8);
memcpy(&name4, strkey, sizeof(name4));
for(;pentry->key != NULL; i++, pentry++) {
if (((*(unsigned *)pentry->key ^ name4) & mask4) == 0 &&
!strcmp(pentry->key, strkey)) {
//printf("%p %s hit after %d probes \n", rotable, strkey, (int)(pentry-rotable));
if (ppos)
*ppos = i;
update_cache(hash, rotable, pentry - rotable);
//printf("%3d %3d %p %s\n", (hash>>2) & (LA_LINES-1), (int)(pentry-rotable), rotable, strkey);
return &pentry->value;
}
}
}
//printf("%p %s miss after %d probes \n", rotable, strkey, (int)(pentry-rotable));
return luaO_nilobject;
}
/* Find the metatable of a given table */
void* luaR_getmeta(ROTable *rotable) {
const TValue *res = luaR_findentry(rotable, NULL, NULL);
return res && ttisrotable(res) ? rvalue(res) : NULL;
}
static void luaR_next_helper(lua_State *L, ROTable *pentries, int pos,
TValue *key, TValue *val) {
if (pentries[pos].key) {
/* Found an entry */
setsvalue(L, key, luaS_new(L, pentries[pos].key));
setobj2s(L, val, &pentries[pos].value);
} else {
setnilvalue(key);
setnilvalue(val);
}
}
/* next (used for iteration) */
void luaR_next(lua_State *L, ROTable *rotable, TValue *key, TValue *val) {
unsigned keypos;
/* Special case: if key is nil, return the first element of the rotable */
if (ttisnil(key))
luaR_next_helper(L, rotable, 0, key, val);
else if (ttisstring(key)) {
/* Find the previous key again */
luaR_findentry(rotable, rawtsvalue(key), &keypos);
/* Advance to next key */
keypos ++;
luaR_next_helper(L, rotable, keypos, key, val);
}
}

View File

@ -1,99 +0,0 @@
/* Read-only tables for Lua */
#ifndef lrotable_h
#define lrotable_h
#include "lua.h"
#include "luaconf.h"
#include "lobject.h"
#include "llimits.h"
/* Macros one can use to define rotable entries */
#define LRO_FUNCVAL(v) {{.p = v}, LUA_TLIGHTFUNCTION}
#define LRO_LUDATA(v) {{.p = v}, LUA_TLIGHTUSERDATA}
#define LRO_NUMVAL(v) {{.n = v}, LUA_TNUMBER}
#define LRO_ROVAL(v) {{.p = (void*)v}, LUA_TROTABLE}
#define LRO_NILVAL {{.p = NULL}, LUA_TNIL}
#ifdef LUA_CROSS_COMPILER
#define LRO_STRKEY(k) k
#else
#define LRO_STRKEY(k) ((__attribute__((aligned(4))) char *) k)
#endif
#define LROT_TABLE(t) static const LUA_REG_TYPE t ## _map[];
#define LROT_PUBLIC_TABLE(t) const LUA_REG_TYPE t ## _map[];
#define LROT_TABLEREF(t) ((void *) t ## _map)
#define LROT_BEGIN(t) static const LUA_REG_TYPE t ## _map [] = {
#define LROT_PUBLIC_BEGIN(t) const LUA_REG_TYPE t ## _map[] = {
#define LROT_EXTERN(t) extern const LUA_REG_TYPE t ## _map[]
#define LROT_TABENTRY(n,t) {LRO_STRKEY(#n), LRO_ROVAL(t ## _map)},
#define LROT_FUNCENTRY(n,f) {LRO_STRKEY(#n), LRO_FUNCVAL(f)},
#define LROT_NUMENTRY(n,x) {LRO_STRKEY(#n), LRO_NUMVAL(x)},
#define LROT_LUDENTRY(n,x) {LRO_STRKEY(#n), LRO_LUDATA((void *) x)},
#define LROT_END(t,mt, f) {NULL, LRO_NILVAL} };
#define LROT_BREAK(t) };
#define LUA_REG_TYPE luaR_entry
#define LREGISTER(L, name, table) return 0
/* Maximum length of a rotable name and of a string key*/
#define LUA_MAX_ROTABLE_NAME 32
/* Type of a numeric key in a rotable */
typedef int luaR_numkey;
/* An entry in the read only table */
typedef struct luaR_entry {
const char *key;
const TValue value;
} luaR_entry;
/*
* The current ROTable implmentation is a vector of luaR_entry terminated by a
* nil record. The convention is to use ROtable * to refer to the entire vector
* as a logical ROTable.
*/
typedef const struct luaR_entry ROTable;
const TValue* luaR_findentry(ROTable *tab, TString *key, unsigned *ppos);
const TValue* luaR_findentryN(ROTable *tab, luaR_numkey numkey, unsigned *ppos);
void luaR_next(lua_State *L, ROTable *tab, TValue *key, TValue *val);
void* luaR_getmeta(ROTable *tab);
int luaR_isrotable(void *p);
/*
* Set inRO check depending on platform. Note that this implementation needs
* to work on both the host (luac.cross) and ESP targets. The luac.cross
* VM is used for the -e option, and is primarily used to be able to debug
* VM changes on the more developer-friendly hot gdb environment.
*/
#if defined(LUA_CROSS_COMPILER)
#if defined(_MSC_VER)
//msvc build uses these dummy vars to locate the beginning and ending addresses of the RO data
extern const char _ro_start[], _ro_end[];
#define IN_RODATA_AREA(p) (((const char*)(p)) >= _ro_start && ((const char *)(p)) <= _ro_end)
#else /* one of the POSIX variants */
#if defined(__CYGWIN__)
#define _RODATA_END __end__
#elif defined(__MINGW32__)
#define _RODATA_END end
#else
#define _RODATA_END _edata
#endif
extern const char _RODATA_END[];
#define IN_RODATA_AREA(p) (((const char *)(p)) < _RODATA_END)
#endif /* defined(_MSC_VER) */
#else /* xtensa tool chain for ESP32 target */
#include "compiler.h"
#define IN_RODATA_AREA(p) (((const char *)p) >= RODATA_START_ADDRESS && ((const char *)p) <= RODATA_END_ADDRESS)
#endif /* defined(LUA_CROSS_COMPILER) */
/* Return 1 if the given pointer is a rotable */
#define luaR_isrotable(p) IN_RODATA_AREA(p)
#endif

View File

@ -0,0 +1,68 @@
all: build
HOSTCC?=$(PYTHON) -m ziglang cc
ifeq ($V,)
Q:=@
endif
LUAC_OBJ_DIR:=$(LUAC_BUILD_DIR)/$(notdir $(LUA_PATH))
LUAC_CFLAGS:= \
-I$(LUAC_BUILD_DIR) \
-I$(LUA_PATH) \
-I$(LUA_PATH)/host \
-I$(LUA_PATH)/../common \
-I$(LUA_PATH)/../../uzlib \
-O2 -g -Wall -Wextra -Wno-sign-compare
LUAC_LDFLAGS:= -ldl -lm
LUAC_DEFINES += \
-DLUA_CROSS_COMPILER \
-DLUA_USE_HOST \
-DLUA_USE_STDIO \
vpath %.c $(LUA_PATH)/host $(LUA_PATH) $(LUA_PATH)/../common $(LUA_PATH)/../../uzlib
LUA_SRCS:=\
luac.c lflashimg.c loslib.c print.c liolib.c \
lapi.c lauxlib.c lbaselib.c lcode.c ldblib.c ldebug.c \
ldo.c ldump.c lfunc.c lgc.c llex.c \
lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c lparser.c \
lnodemcu.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c \
ltm.c lundump.c lvm.c lzio.c \
linit.c lpanic.c \
uzlib_deflate.c crc32.c \
LUAC_OBJS:=$(LUA_SRCS:%.c=$(LUAC_OBJ_DIR)/%.o)
LUAC_CROSS:=$(LUAC_BUILD_DIR)/luac.cross
$(LUAC_OBJ_DIR):
@mkdir -p "$@"
$(LUAC_OBJ_DIR)/%.o: %.c | $(LUAC_OBJ_DIR)
@echo '[hostcc] $(notdir $@)'
$Q$(HOSTCC) $(LUAC_DEFINES) $(LUAC_CFLAGS) "$<" -c -o "$@"
$(LUAC_OBJ_DIR)/%.d: SHELL=/bin/bash
$(LUAC_OBJ_DIR)/%.d: %.c | $(LUAC_OBJ_DIR)
@echo '[ dep] $<'
@rm -f "$@"
$Qset -eo pipefail; $(HOSTCC) $(LUAC_DEFINES) $(LUAC_CFLAGS) -M "$<" | sed 's,\($*\.o\)[ :]*,$(LUAC_OBJ_DIR)/\1 $@ : ,g' > "$@.tmp"; mv "$@.tmp" "$@"
build: $(LUAC_DEPS) $(LUAC_CROSS)
$(LUAC_CROSS): $(LUAC_OBJS)
@echo '[ link] $(notdir $@)'
$Q$(HOSTCC) $(LUAC_CFLAGS) $^ $(LUAC_LDFLAGS) -o "$@"
# zig cc (0.8.0 at least) seems to get itself all confused with its cache
# when we're running a separate path for dependencies, so we skip them for
# now as for most people they're not needed anyway.
ifneq ($(findstring zig,$(HOSTCC)),zig)
LUAC_DEPS:=$(LUAC_OBJS:%.o=%.d)
ifneq ($(MAKECMDGOALS),clean)
-include $(LUAC_DEPS)
endif
endif

View File

@ -6,7 +6,6 @@
#define LUAC_CROSS_FILE
#include "luac_cross.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
@ -109,10 +108,11 @@ static uint *flashAddrTag = flashImage + LUA_MAX_FLASH_SIZE;
#define setFlashAddrTag(v) flashAddrTag[_TW(v)] |= _TB(v)
#define getFlashAddrTag(v) ((flashAddrTag[_TW(v)]&_TB(v)) != 0)
#define fatal luac_fatal
#ifdef _MSC_VER
extern void __declspec( noreturn ) fatal( const char* message );
extern void __declspec( noreturn ) luac_fatal( const char* message );
#else
extern void __attribute__((noreturn)) fatal(const char* message);
extern void __attribute__((noreturn)) luac_fatal(const char* message);
#endif
#ifdef LOCAL_DEBUG
@ -188,10 +188,8 @@ static void scanProtoStrings(lua_State *L, const Proto* f) {
if (f->source)
addTS(L, f->source);
#ifdef LUA_OPTIMIZE_DEBUG
if (f->packedlineinfo)
addTS(L, luaS_new(L, cast(const char *, f->packedlineinfo)));
#endif
for (i = 0; i < f->sizek; i++) {
if (ttisstring(f->k + i))
@ -357,11 +355,7 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
}
/* The debug optimised version has a different Proto layout */
#ifdef LUA_OPTIMIZE_DEBUG
#define PROTO_COPY_MASK "AHAAAAAASIIIIIIIAI"
#else
#define PROTO_COPY_MASK "AHAAAAAASIIIIIIIIAI"
#endif
/*
* Do the actual prototype copy.
@ -385,14 +379,10 @@ static void *functionToFlash(lua_State* L, const Proto* orig) {
f.k = cast(TValue *, flashCopy(L, f.sizek, "V", f.k));
f.code = cast(Instruction *, flashCopy(L, f.sizecode, "I", f.code));
#ifdef LUA_OPTIMIZE_DEBUG
if (f.packedlineinfo) {
TString *ts=luaS_new(L, cast(const char *,f.packedlineinfo));
f.packedlineinfo = cast(unsigned char *, resolveTString(L, ts)) + sizeof (FlashTS);
}
#else
f.lineinfo = cast(int *, flashCopy(L, f.sizelineinfo, "I", f.lineinfo));
#endif
f.locvars = cast(struct LocVar *, flashCopy(L, f.sizelocvars, "SII", f.locvars));
f.upvalues = cast(TString **, flashCopy(L, f.sizeupvalues, "S", f.upvalues));
return cast(void *, flashCopy(L, 1, PROTO_COPY_MASK, &f));
@ -401,10 +391,10 @@ static void *functionToFlash(lua_State* L, const Proto* orig) {
uint dumpToFlashImage (lua_State* L, const Proto *main, lua_Writer w,
void* data, int strip,
lu_int32 address, lu_int32 maxSize) {
(void)strip;
// parameter strip is ignored for now
(void)strip;
FlashHeader *fh = cast(FlashHeader *, flashAlloc(L, sizeof(FlashHeader)));
int status;
int i, status;
lua_newtable(L);
scanProtoStrings(L, main);
createROstrt(L, fh);
@ -416,7 +406,7 @@ uint dumpToFlashImage (lua_State* L, const Proto *main, lua_Writer w,
fatal ("The image is too large for specfied LFS size");
}
if (address) { /* in absolute mode convert addresses to mapped address */
for (uint i = 0 ; i < curOffset; i++)
for (i = 0 ; i < curOffset; i++)
if (getFlashAddrTag(i))
flashImage[i] = 4*flashImage[i] + address;
lua_unlock(L);
@ -434,7 +424,7 @@ uint dumpToFlashImage (lua_State* L, const Proto *main, lua_Writer w,
status = uzlib_compress (&oBuf, &oLen,
(const uint8_t *)flashImage, bmLen+fh->flash_size);
if (status != UZLIB_OK) {
fatal("Out of memory during image compression");
luac_fatal("Out of memory during image compression");
}
lua_unlock(L);
#if 0

View File

@ -17,7 +17,7 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#include "lnodemcu.h"
#define IO_INPUT 1
#define IO_OUTPUT 2
@ -439,7 +439,10 @@ static int f_flush (lua_State *L) {
return pushresult(L, fflush(tofile(L)) == 0, NULL);
}
LROT_PUBLIC_BEGIN(iolib)
LROT_TABLE(iolib);
LROT_BEGIN(iolib, NULL, LROT_MASK_GC_INDEX)
LROT_TABENTRY( __index, iolib )
LROT_FUNCENTRY( close, io_close )
LROT_FUNCENTRY( flush, io_flush )
LROT_FUNCENTRY( input, io_input )
@ -449,10 +452,14 @@ LROT_PUBLIC_BEGIN(iolib)
LROT_FUNCENTRY( read, io_read )
LROT_FUNCENTRY( type, io_type )
LROT_FUNCENTRY( write, io_write )
LROT_TABENTRY( __index, iolib )
LROT_END(iolib, NULL, 0)
LROT_END(iolib, NULL, LROT_MASK_GC_INDEX)
LROT_BEGIN(flib)
LROT_TABLE(flib);
LROT_BEGIN(flib, NULL, LROT_MASK_GC_INDEX)
LROT_FUNCENTRY( __gc, io_gc )
LROT_TABENTRY( __index, flib )
LROT_FUNCENTRY( __tostring, io_tostring )
LROT_FUNCENTRY( close, io_close )
LROT_FUNCENTRY( flush, f_flush )
LROT_FUNCENTRY( lines, f_lines )
@ -460,9 +467,6 @@ LROT_BEGIN(flib)
LROT_FUNCENTRY( seek, f_seek )
LROT_FUNCENTRY( setvbuf, f_setvbuf )
LROT_FUNCENTRY( write, f_write )
LROT_FUNCENTRY( __gc, io_gc )
LROT_FUNCENTRY( __tostring, io_tostring )
LROT_TABENTRY( __index, flib )
LROT_END(flib, NULL, LROT_MASK_GC_INDEX)
static const luaL_Reg io_base[] = {{NULL, NULL}};

View File

@ -6,7 +6,6 @@
#define LUAC_CROSS_FILE
#include "luac_cross.h"
#include <errno.h>
#include <locale.h>
#include <stdlib.h>
@ -20,8 +19,7 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#include "lnodemcu.h"
static int os_pushresult (lua_State *L, int i, const char *filename) {
int en = errno; /* calls to Lua API may change this value */
@ -221,32 +219,26 @@ static int os_exit (lua_State *L) {
exit(luaL_optint(L, 1, EXIT_SUCCESS));
}
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 1
#include "lrotable.h"
LROT_PUBLIC_BEGIN(oslib)
LROT_FUNCENTRY(clock, os_clock)
LROT_FUNCENTRY(date, os_date)
LROT_BEGIN(oslib, NULL, 0)
LROT_FUNCENTRY( clock, os_clock )
LROT_FUNCENTRY( date, os_date )
#if !defined LUA_NUMBER_INTEGRAL
LROT_FUNCENTRY(difftime, os_difftime)
LROT_FUNCENTRY( difftime, os_difftime )
#endif
LROT_FUNCENTRY(execute, os_execute)
LROT_FUNCENTRY(exit, os_exit)
LROT_FUNCENTRY(getenv, os_getenv)
LROT_FUNCENTRY(remove, os_remove)
LROT_FUNCENTRY(rename, os_rename)
LROT_FUNCENTRY(setlocale, os_setlocale)
LROT_FUNCENTRY(time, os_time)
LROT_FUNCENTRY(tmpname, os_tmpname)
LROT_FUNCENTRY( execute, os_execute )
LROT_FUNCENTRY( exit, os_exit )
LROT_FUNCENTRY( getenv, os_getenv )
LROT_FUNCENTRY( remove, os_remove )
LROT_FUNCENTRY( rename, os_rename )
LROT_FUNCENTRY( setlocale, os_setlocale )
LROT_FUNCENTRY( time, os_time )
LROT_FUNCENTRY( tmpname, os_tmpname )
LROT_END(oslib, NULL, 0)
/* }====================================================== */
LUALIB_API int luaopen_os (lua_State *L) {
(void)L;
//LREGISTER(L, LUA_OSLIBNAME, oslib); // <------------- ???
return 0;
return 1;
}

View File

@ -5,15 +5,15 @@
*/
#define LUAC_CROSS_FILE
#define luac_c
#define LUA_CORE
#include "luac_cross.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define luac_c
#define LUA_CORE
#include "lua.h"
#include "lauxlib.h"
@ -42,11 +42,12 @@ static const char* execute; /* executed a Lua file */
static const char* progname=PROGNAME; /* actual program name */
static DumpTargetInfo target;
void fatal(const char* message)
void luac_fatal(const char* message)
{
fprintf(stderr,"%s: %s\n",progname,message);
exit(EXIT_FAILURE);
}
#define fatal(s) luac_fatal(s)
static void cannot(const char* what)
{
@ -280,8 +281,8 @@ static int pmain(lua_State* L)
if (!lua_checkstack(L,argc)) fatal("too many input files");
if (execute)
{
if (luaL_loadfile(L,execute)!=0) fatal(lua_tostring(L,-1));
luaL_openlibs(L);
if (luaL_loadfile(L,execute)!=0) fatal(lua_tostring(L,-1));
lua_pushstring(L, execute);
if (lua_pcall(L, 1, 1, 0)) fatal(lua_tostring(L,-1));
if (!lua_isfunction(L, -1))

View File

@ -6,7 +6,6 @@
#define LUAC_CROSS_FILE
#include "luac_cross.h"
#include <ctype.h>
#include <stdio.h>

View File

@ -6,11 +6,9 @@
#define lapi_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
//#include <assert.h>
#include <math.h>
#include <string.h>
#include "lapi.h"
@ -26,7 +24,6 @@
#include "ltm.h"
#include "lundump.h"
#include "lvm.h"
#include "lrotable.h"
#if 0
const char lua_ident[] =
@ -155,6 +152,16 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
*/
/*
** convert an acceptable stack index into an absolute index
*/
LUA_API int lua_absindex (lua_State *L, int idx) {
return (idx > 0 || idx <= LUA_REGISTRYINDEX)
? idx
: cast_int(L->top - L->base) - 1 + idx;
}
LUA_API int lua_gettop (lua_State *L) {
return cast_int(L->top - L->base);
}
@ -243,6 +250,12 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) {
LUA_API int lua_type (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
return (o == luaO_nilobject) ? LUA_TNONE : ttnov(o);
}
LUA_API int lua_fulltype (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
}
@ -250,7 +263,7 @@ LUA_API int lua_type (lua_State *L, int idx) {
LUA_API const char *lua_typename (lua_State *L, int t) {
UNUSED(L);
return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
return (t == LUA_TNONE || t >= LUA_NUMTAGS) ? "no value" : luaT_typenames[t];
}
@ -287,32 +300,25 @@ LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
}
LUA_API int lua_equal (lua_State *L, int index1, int index2) {
LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
StkId o1, o2;
int i;
int i = 0;
lua_lock(L); /* may call tag method */
o1 = index2adr(L, index1);
o2 = index2adr(L, index2);
i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
if (o1 != luaO_nilobject && o2 != luaO_nilobject) {
switch (op) {
case LUA_OPEQ: i = luaV_equalval(L, o1, o2); break;
case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
default: api_check(L, 0);
}
}
lua_unlock(L);
return i;
}
LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
StkId o1, o2;
int i;
lua_lock(L); /* may call tag method */
o1 = index2adr(L, index1);
o2 = index2adr(L, index2);
i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
: luaV_lessthan(L, o1, o2);
lua_unlock(L);
return i;
}
LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
TValue n;
const TValue *o = index2adr(L, idx);
@ -363,11 +369,10 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
LUA_API size_t lua_objlen (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
switch (ttype(o)) {
switch (ttnov(o)) {
case LUA_TSTRING: return tsvalue(o)->len;
case LUA_TUSERDATA: return uvalue(o)->len;
case LUA_TTABLE: return luaH_getn(hvalue(o));
case LUA_TROTABLE: return luaH_getn_ro(rvalue(o));
case LUA_TNUMBER: {
size_t l;
lua_lock(L); /* `luaV_tostring' may create a new string */
@ -405,16 +410,14 @@ LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
LUA_API const void *lua_topointer (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
switch (ttype(o)) {
case LUA_TTABLE: return hvalue(o);
case LUA_TTABLE:
case LUA_TROTABLE:
return hvalue(o);
case LUA_TFUNCTION: return clvalue(o);
case LUA_TTHREAD: return thvalue(o);
case LUA_TUSERDATA:
case LUA_TLIGHTUSERDATA:
return lua_touserdata(L, idx);
case LUA_TROTABLE:
return rvalue(o);
case LUA_TLIGHTFUNCTION:
return fvalue(o);
case LUA_TUSERDATA: return lua_touserdata(L, idx);
case LUA_TLIGHTUSERDATA: return pvalue(o);
case LUA_TLIGHTFUNCTION: return fvalue(o);
default: return NULL;
}
}
@ -492,18 +495,23 @@ LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
Closure *cl;
lua_lock(L);
luaC_checkGC(L);
api_checknelems(L, n);
cl = luaF_newCclosure(L, n, getcurrenv(L));
cl->c.f = fn;
L->top -= n;
while (n--)
setobj2n(L, &cl->c.upvalue[n], L->top+n);
setclvalue(L, L->top, cl);
lua_assert(iswhite(obj2gco(cl)));
api_incr_top(L);
if (n == 0) {
setfvalue(L->top, fn);
api_incr_top(L);
} else {
Closure *cl;
luaC_checkGC(L);
api_checknelems(L, n);
cl = luaF_newCclosure(L, n, getcurrenv(L));
cl->c.f = fn;
L->top -= n;
while (n--)
setobj2n(L, &cl->c.upvalue[n], L->top+n);
setclvalue(L, L->top, cl);
lua_assert(iswhite(obj2gco(cl)));
api_incr_top(L);
}
lua_unlock(L);
}
@ -523,16 +531,10 @@ LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
lua_unlock(L);
}
LUA_API void lua_pushrotable (lua_State *L, void *p) {
lua_lock(L);
setrvalue(L->top, p);
api_incr_top(L);
lua_unlock(L);
}
LUA_API void lua_pushlightfunction(lua_State *L, void *p) {
LUA_API void lua_pushrotable (lua_State *L, const ROTable *t) {
lua_lock(L);
setfvalue(L->top, p);
sethvalue(L, L->top, cast(ROTable *,t));
api_incr_top(L);
lua_unlock(L);
}
@ -553,17 +555,17 @@ LUA_API int lua_pushthread (lua_State *L) {
*/
LUA_API void lua_gettable (lua_State *L, int idx) {
LUA_API int lua_gettable (lua_State *L, int idx) {
StkId t;
lua_lock(L);
t = index2adr(L, idx);
api_checkvalidindex(L, t);
luaV_gettable(L, t, L->top - 1, L->top - 1);
lua_unlock(L);
return ttnov(L->top - 1);
}
LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
StkId t;
TValue key;
lua_lock(L);
@ -575,29 +577,58 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
luaV_gettable(L, t, &key, L->top);
api_incr_top(L);
lua_unlock(L);
return ttnov(L->top - 1);
}
LUA_API void lua_rawget (lua_State *L, int idx) {
LUA_API int lua_geti (lua_State *L, int idx, int n) {
StkId t;
const TValue *res;
TValue key;
lua_lock(L);
t = index2adr(L, idx);
api_check(L, ttistable(t) || ttisrotable(t));
res = ttistable(t) ? luaH_get(hvalue(t), L->top - 1) : luaH_get_ro(rvalue(t), L->top - 1);
setobj2s(L, L->top - 1, res);
api_checkvalidindex(L, t);
fixedstack(L);
setnvalue(&key, n);
unfixedstack(L);
luaV_gettable(L, t, &key, L->top);
api_incr_top(L);
lua_unlock(L);
return ttnov(L->top - 1);
}
LUA_API int lua_rawget (lua_State *L, int idx) {
StkId t;
lua_lock(L);
t = index2adr(L, idx);
api_check(L, ttistable(t));
setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
lua_unlock(L);
return ttnov(L->top - 1);
}
LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
LUA_API int lua_rawgeti (lua_State *L, int idx, int n) {
StkId o;
lua_lock(L);
o = index2adr(L, idx);
api_check(L, ttistable(o) || ttisrotable(o));
setobj2s(L, L->top, ttistable(o) ? luaH_getnum(hvalue(o), n) : luaH_getnum_ro(rvalue(o), n))
api_check(L, ttistable(o));
setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
api_incr_top(L);
lua_unlock(L);
return ttnov(L->top - 1);
}
LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
StkId t;
TValue k;
lua_lock(L);
t = index2adr(L, idx);
api_check(L, ttistable(t));
setpvalue(&k, cast(void *, p));
setobj2s(L, L->top, luaH_get(hvalue(t), &k));
api_incr_top(L);
lua_unlock(L);
return ttnov(L->top - 1);
}
@ -616,27 +647,21 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
int res;
lua_lock(L);
obj = index2adr(L, objindex);
switch (ttype(obj)) {
switch (ttnov(obj)) {
case LUA_TTABLE:
mt = hvalue(obj)->metatable;
break;
case LUA_TUSERDATA:
mt = uvalue(obj)->metatable;
break;
case LUA_TROTABLE:
mt = (Table*)luaR_getmeta(rvalue(obj));
break;
default:
mt = G(L)->mt[ttype(obj)];
mt = G(L)->mt[ttnov(obj)];
break;
}
if (mt == NULL)
res = 0;
else {
if(luaR_isrotable(mt))
setrvalue(L->top, mt)
else
sethvalue(L, L->top, mt)
sethvalue(L, L->top, mt)
api_incr_top(L);
res = 1;
}
@ -730,40 +755,54 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
}
LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) {
StkId o;
TValue k;
lua_lock(L);
api_checknelems(L, 1);
o = index2adr(L, idx);
api_check(L, ttistable(o));
fixedstack(L);
setpvalue(&k, cast(void *, p))
setobj2t(L, luaH_set(L, hvalue(o), &k), L->top-1);
unfixedstack(L);
luaC_barriert(L, hvalue(o), L->top-1);
L->top--;
lua_unlock(L);
}
LUA_API int lua_setmetatable (lua_State *L, int objindex) {
TValue *obj;
Table *mt;
int isrometa = 0;
lua_lock(L);
api_checknelems(L, 1);
obj = index2adr(L, objindex);
api_checkvalidindex(L, obj);
if (ttisnil(L->top - 1))
if (ttisnil(L->top - 1)) {
mt = NULL;
else {
api_check(L, ttistable(L->top - 1) || ttisrotable(L->top - 1));
if (ttistable(L->top - 1))
mt = hvalue(L->top - 1);
else {
mt = (Table*)rvalue(L->top - 1);
isrometa = 1;
}
} else {
api_check(L, ttistable(L->top - 1));
mt = hvalue(L->top - 1);
}
switch (ttype(obj)) {
switch (ttype(obj)) { /* use basetype to retain subtypes*/
case LUA_TTABLE: {
hvalue(obj)->metatable = mt;
if (mt && !isrometa)
if (mt && !isrotable(mt))
luaC_objbarriert(L, hvalue(obj), mt);
break;
}
case LUA_TUSERDATA: {
uvalue(obj)->metatable = mt;
if (mt && !isrometa)
if (mt && !isrotable(mt))
luaC_objbarrier(L, rawuvalue(obj), mt);
break;
}
case LUA_TISROTABLE: { /* Ignore any changes to a ROTable MT */
break;
}
default: {
G(L)->mt[ttype(obj)] = mt;
G(L)->mt[ttnov(obj)] = mt;
break;
}
}
@ -813,7 +852,7 @@ LUA_API int lua_setfenv (lua_State *L, int idx) {
#define checkresults(L,na,nr) \
api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)))
LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
StkId func;
@ -914,14 +953,14 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
}
LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int stripping) {
int status;
TValue *o;
lua_lock(L);
api_checknelems(L, 1);
o = L->top - 1;
if (isLfunction(o))
status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
status = luaU_dump(L, clvalue(o)->l.p, writer, data, stripping);
else
status = 1;
lua_unlock(L);
@ -929,6 +968,30 @@ LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
}
LUA_API int lua_stripdebug (lua_State *L, int stripping){
TValue *o = L->top - 1;
Proto *p = NULL;
int res = -1;
lua_lock(L);
api_checknelems(L, 1);
if (isLfunction(o)) {
p = clvalue(o)->l.p;
if (p && !isLFSobject(p) && (unsigned) stripping < 3 ) {
// found a valid proto to strip
res = luaG_stripdebug(L, p, stripping, 1);
}
} else if (ttisnil(L->top - 1)) {
// get or set the default strip level
if ((unsigned) stripping < 3)
G(L)->stripdefault = stripping;
res = G(L)->stripdefault;
}
L->top--;
lua_unlock(L);
return res;
}
LUA_API int lua_status (lua_State *L) {
return L->status;
}
@ -1039,8 +1102,8 @@ LUA_API int lua_next (lua_State *L, int idx) {
int more;
lua_lock(L);
t = index2adr(L, idx);
api_check(L, ttistable(t) || ttisrotable(t));
more = ttistable(t) ? luaH_next(L, hvalue(t), L->top - 1) : luaH_next_ro(L, rvalue(t), L->top - 1);
api_check(L, ttistable(t));
more = luaH_next(L, hvalue(t), L->top - 1);
if (more) {
api_incr_top(L);
}
@ -1149,3 +1212,15 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
return name;
}
LUA_API void lua_setegcmode ( lua_State *L, int mode, int limit) {
G(L)->egcmode = mode;
G(L)->memlimit = limit;
}
LUA_API void lua_getegcinfo (lua_State *L, int *totals) {
if (totals) {
totals[0] = G(L)->totalbytes;
totals[1] = G(L)->estimate;
}
}

View File

@ -4,20 +4,16 @@
** See Copyright Notice in lua.h
*/
#define LUAC_CROSS_FILE
#include "lua.h"
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#ifndef LUA_CROSS_COMPILER
#include "esp_system.h"
#include "vfs.h"
/* defined in esp_system_internal.h */
void esp_reset_reason_set_hint(esp_reset_reason_t hint);
#else
#endif
/* This file uses only the official API of Lua.
@ -27,14 +23,14 @@ void esp_reset_reason_set_hint(esp_reset_reason_t hint);
#define lauxlib_c
#define LUA_LIB
#include "lrotable.h"
#include "lnodemcu.h"
#include "lauxlib.h"
#include "lgc.h"
#include "ldo.h"
#include "lobject.h"
#include "lstate.h"
#include "legc.h"
#include "lpanic.h"
#define FREELIST_REF 0 /* free list of references */
@ -277,7 +273,7 @@ LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
return 1;
}
LUALIB_API int luaL_rometatable (lua_State *L, const char* tname, void *p) {
LUALIB_API int luaL_rometatable (lua_State *L, const char* tname, const ROTable *p) {
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */
if (!lua_isnil(L, -1)) /* name already in use? */
return 0; /* leave previous value on top, but return 0 */
@ -288,21 +284,25 @@ LUALIB_API int luaL_rometatable (lua_State *L, const char* tname, void *p) {
return 1;
}
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
void *p = lua_touserdata(L, ud);
if (p != NULL) { /* value is a userdata? */
if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
lua_pop(L, 2); /* remove both metatables */
return p;
}
if (!lua_rawequal(L, -1, -2)) /* not the same? */
p = NULL; /* value is a userdata with wrong metatable */
lua_pop(L, 2); /* remove both metatables */
return p;
}
}
luaL_typerror(L, ud, tname); /* else error */
return NULL; /* to avoid warnings */
return NULL; /* value is not a userdata with a metatable */
}
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
void *p = luaL_testudata(L, ud, tname);
if (p == NULL) luaL_typerror(L, ud, tname);
return p;
}
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
if (!lua_checkstack(L, space))
@ -315,22 +315,6 @@ LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
tag_error(L, narg, t);
}
LUALIB_API void luaL_checkanyfunction (lua_State *L, int narg) {
if (lua_type(L, narg) != LUA_TFUNCTION && lua_type(L, narg) != LUA_TLIGHTFUNCTION) {
const char *msg = lua_pushfstring(L, "function or lightfunction expected, got %s",
luaL_typename(L, narg));
luaL_argerror(L, narg, msg);
}
}
LUALIB_API void luaL_checkanytable (lua_State *L, int narg) {
if (lua_type(L, narg) != LUA_TTABLE && lua_type(L, narg) != LUA_TROTABLE) {
const char *msg = lua_pushfstring(L, "table or rotable expected, got %s",
luaL_typename(L, narg));
luaL_argerror(L, narg, msg);
}
}
LUALIB_API void luaL_checkany (lua_State *L, int narg) {
if (lua_type(L, narg) == LUA_TNONE)
@ -449,7 +433,7 @@ LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
for (i=0; i<nup; i++) /* copy upvalues to the top */
lua_pushvalue(L, -nup);
if (ftype == LUA_USELIGHTFUNCTIONS)
lua_pushlightfunction(L, l->func);
lua_pushcfunction(L, l->func);
else
lua_pushcclosure(L, l->func, nup);
lua_setfield(L, -(nup+2), l->name);
@ -561,7 +545,7 @@ LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
lua_pushvalue(L, -2);
lua_settable(L, -4); /* set new table into field */
}
else if (!lua_istable(L, -1) && !lua_isrotable(L, -1)) { /* field has a non-table value? */
else if (!lua_istable(L, -1)) { /* field has a non-table value? */
lua_pop(L, 2); /* remove table and value */
return fname; /* return problematic part of the name */
}
@ -703,6 +687,26 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
}
LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref) {
int reft;
/*
* If the ref is positive and the entry in table t exists then
* overwrite the value otherwise fall through to luaL_ref()
*/
if (ref) {
if (*ref >= 0) {
t = abs_index(L, t);
lua_rawgeti(L, t, *ref);
reft = lua_type(L, -1);
lua_pop(L, 1);
if (reft != LUA_TNIL) {
lua_rawseti(L, t, *ref);
return;
}
}
*ref = luaL_ref(L, t);
}
}
/*
** {======================================================
@ -710,14 +714,33 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
** =======================================================
*/
#ifdef LUA_CROSS_COMPILER
typedef struct LoadF {
int extraline;
#ifdef LUA_CROSS_COMPILER
FILE *f;
#else
int f;
#endif
char buff[LUAL_BUFFERSIZE];
} LoadF;
#ifdef LUA_CROSS_COMPILER
# define freopen_bin(f,fn) freopen(f,"rb",fn)
# define read_buff(b,f) fread(b, 1, sizeof (b), f)
#else
# define strerror(n) ""
#undef feof
# define feof(f) vfs_eof(f)
#undef fopen
# define fopen(f, m) vfs_open(f, m)
# define freopen_bin(fn,f) ((void) vfs_close(f), vfs_open(fn, "r"))
#undef getc
# define getc(f) vfs_getc(f)
#undef ungetc
# define ungetc(c,f) vfs_ungetc(c, f)
# define read_buff(b,f) vfs_read(f, b, sizeof (b))
#endif
static const char *getF (lua_State *L, void *ud, size_t *size) {
LoadF *lf = (LoadF *)ud;
@ -728,7 +751,7 @@ static const char *getF (lua_State *L, void *ud, size_t *size) {
return "\n";
}
if (feof(lf->f)) return NULL;
*size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
*size = read_buff(lf->buff, lf->f);
return (*size > 0) ? lf->buff : NULL;
}
@ -748,14 +771,19 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
int c;
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
lf.extraline = 0;
if (filename == NULL) {
#ifdef LUA_CROSS_COMPILER
lua_pushliteral(L, "=stdin");
lf.f = stdin;
#else
return luaL_error(L, "filename is NULL");
#endif
}
else {
lua_pushfstring(L, "@%s", filename);
lf.f = fopen(filename, "r");
if (lf.f == NULL) return errfile(L, "open", fnameindex);
if (!lf.f) return errfile(L, "open", fnameindex);
}
c = getc(lf.f);
if (c == '#') { /* Unix exec. file? */
@ -764,8 +792,8 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
if (c == '\n') c = getc(lf.f);
}
if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
lf.f = freopen_bin(filename, lf.f); /* reopen in binary mode */
if (!lf.f) return errfile(L, "reopen", fnameindex);
/* skip eventual `#!...' */
while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) {}
@ -773,95 +801,21 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
}
ungetc(c, lf.f);
status = lua_load(L, getF, &lf, lua_tostring(L, -1));
#ifdef LUA_CROSS_COMPILER
readstatus = ferror(lf.f);
if (filename) fclose(lf.f); /* close file (even in case of errors) */
if (readstatus) {
lua_settop(L, fnameindex); /* ignore results from `lua_load' */
return errfile(L, "read", fnameindex);
}
lua_remove(L, fnameindex);
return status;
}
#else
#include <fcntl.h>
typedef struct LoadFSF {
int extraline;
int f;
char buff[LUAL_BUFFERSIZE];
} LoadFSF;
static const char *getFSF (lua_State *L, void *ud, size_t *size) {
LoadFSF *lf = (LoadFSF *)ud;
(void)L;
if (L == NULL && size == NULL) // Direct mode check
return NULL;
if (lf->extraline) {
lf->extraline = 0;
*size = 1;
return "\n";
}
if (vfs_eof(lf->f)) return NULL;
*size = vfs_read(lf->f, lf->buff, sizeof(lf->buff));
return (*size > 0) ? lf->buff : NULL;
}
static int errfsfile (lua_State *L, const char *what, int fnameindex) {
const char *filename = lua_tostring(L, fnameindex) + 1;
lua_pushfstring(L, "cannot %s %s", what, filename);
lua_remove(L, fnameindex);
return LUA_ERRFILE;
}
LUALIB_API int luaL_loadfsfile (lua_State *L, const char *filename) {
LoadFSF lf;
int status;
int c;
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
lf.extraline = 0;
if (filename == NULL) {
return luaL_error(L, "filename is NULL");
}
else {
lua_pushfstring(L, "@%s", filename);
lf.f = vfs_open(filename, "r");
if (!lf.f) return errfsfile(L, "open", fnameindex);
}
// if(fs_size(lf.f)>LUAL_BUFFERSIZE)
// return luaL_error(L, "file is too big");
c = vfs_getc(lf.f);
if (c == '#') { /* Unix exec. file? */
lf.extraline = 1;
while ((c = vfs_getc(lf.f)) != VFS_EOF && c != '\n') ; /* skip first line */
if (c == '\n') c = vfs_getc(lf.f);
}
if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
vfs_close(lf.f);
lf.f = vfs_open(filename, "r"); /* reopen in binary mode */
if (!lf.f) return errfsfile(L, "reopen", fnameindex);
/* skip eventual `#!...' */
while ((c = vfs_getc(lf.f)) != VFS_EOF && c != LUA_SIGNATURE[0])
;
lf.extraline = 0;
}
vfs_ungetc(c, lf.f);
status = lua_load(L, getFSF, &lf, lua_tostring(L, -1));
if (filename) vfs_close(lf.f); /* close file (even in case of errors) */
(void) readstatus;
if (filename) vfs_close(lf.f); /* close file (even in case of errors) */
#endif
lua_remove(L, fnameindex);
return status;
}
#endif
typedef struct LoadS {
const char *s;
@ -959,56 +913,11 @@ LUALIB_API void luaL_assertfail(const char *file, int line, const char *message)
#endif
}
#ifndef LUA_CROSS_COMPILER
/*
* upper 28 bit have magic value 0xD1EC0DE0
* if paniclevel is valid (i.e. matches magic value)
* lower 4 bits have paniclevel:
* 0 = no panic occurred
* 1..15 = one..fifteen subsequent panic(s) occurred
*/
static __NOINIT_ATTR uint32_t l_rtc_panic_val;
int panic_get_nvval() {
if ((l_rtc_panic_val & 0xfffffff0) == 0xD1EC0DE0) {
return (l_rtc_panic_val & 0xf);
}
panic_clear_nvval();
return 0;
}
void panic_clear_nvval() {
l_rtc_panic_val = 0xD1EC0DE0;
}
#endif
static int panic (lua_State *L) {
(void)L; /* to avoid warnings */
#ifndef LUA_CROSS_COMPILER
uint8_t paniclevel = panic_get_nvval();
if (paniclevel < 15) paniclevel++;
l_rtc_panic_val = 0xD1EC0DE0 | paniclevel;
#endif
#if defined(LUA_USE_STDIO)
fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
lua_tostring(L, -1));
#else
luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
lua_tostring(L, -1));
#endif
#ifndef LUA_CROSS_COMPILER
/* call abort() directly - we don't want another reset cause to intervene */
esp_reset_reason_set_hint(ESP_RST_PANIC);
abort();
#endif
while (1) {}
return 0;
}
LUALIB_API lua_State *luaL_newstate (void) {
lua_State *L = lua_newstate(l_alloc, NULL);
lua_setallocf(L, l_alloc, L); /* allocator need lua_State. */
if (L) lua_atpanic(L, &panic);
if (L) lua_atpanic(L, lpanic);
return L;
}

View File

@ -8,12 +8,13 @@
#ifndef lauxlib_h
#define lauxlib_h
#include "lua.h"
#ifdef LUA_LIB
#include "lnodemcu.h"
#endif
#include <stdio.h>
#if defined(LUA_COMPAT_GETN)
LUALIB_API int (luaL_getn) (lua_State *L, int t);
LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
@ -43,7 +44,7 @@ LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname,
LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
const luaL_Reg *l);
LUALIB_API void (luaL_register_light) (lua_State *L, const char *libname,
const luaL_Reg *l);
const luaL_Reg *l);
LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
@ -62,11 +63,10 @@ LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
LUALIB_API void (luaL_checkanyfunction) (lua_State *L, int narg);
LUALIB_API void (luaL_checkanytable) (lua_State *L, int narg);
LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
LUALIB_API int (luaL_rometatable) (lua_State *L, const char* tname, void *p);
LUALIB_API int (luaL_rometatable) (lua_State *L, const char* tname, const ROTable *p);
LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
LUALIB_API void (luaL_where) (lua_State *L, int lvl);
@ -77,12 +77,11 @@ LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
LUALIB_API int (luaL_ref) (lua_State *L, int t);
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
#define luaL_unref2(l,t,r) do {luaL_unref(L, (t), (r)); r = LUA_NOREF;} while (0)
LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref);
#ifdef LUA_CROSS_COMPILER
LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
#else
LUALIB_API int (luaL_loadfsfile) (lua_State *L, const char *filename);
#endif
LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
const char *name);
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
@ -112,7 +111,12 @@ LUALIB_API void luaL_assertfail(const char *file, int line, const char *message)
#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a))
#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
#define luaL_optunsigned(L,a,d) ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d)))
#define luaL_checktable(L,n) luaL_checktype(L, (n), LUA_TTABLE);
#define luaL_checkfunction(L,n) luaL_checktype(L, (n), LUA_TFUNCTION);
#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
@ -121,7 +125,7 @@ LUALIB_API void luaL_assertfail(const char *file, int line, const char *message)
(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
#else
#define luaL_dofile(L, fn) \
(luaL_loadfsfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
#endif
#define luaL_dostring(L, s) \
@ -165,6 +169,18 @@ LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
/* }====================================================== */
LUALIB_API int (luaL_pushlfsmodules) (lua_State *L);
LUALIB_API int (luaL_pushlfsmodule) (lua_State *L);
LUALIB_API int (luaL_pushlfsdts) (lua_State *L);
LUALIB_API void (luaL_lfsreload) (lua_State *L);
LUALIB_API int (luaL_pcallx) (lua_State *L, int narg, int nres);
LUALIB_API int (luaL_posttask) ( lua_State* L, int prio );
#define LUA_TASK_LOW 0
#define LUA_TASK_MEDIUM 1
#define LUA_TASK_HIGH 2
/* }====================================================== */
/* compatibility with ref system */
@ -184,7 +200,3 @@ LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
#endif
#ifndef LUA_CROSS_COMPILER
int panic_get_nvval();
void panic_clear_nvval();
#endif

View File

@ -8,17 +8,14 @@
#define lbaselib_c
#define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
/*
@ -27,6 +24,10 @@
** model but changing `fputs' to put the strings at a proper place
** (a console window or a log file, for instance).
*/
#ifdef LUA_CROSS_COMPILER
#undef puts
#define puts(s) printf("%s",s)
#endif
static int luaB_print (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
int i;
@ -40,20 +41,11 @@ static int luaB_print (lua_State *L) {
if (s == NULL)
return luaL_error(L, LUA_QL("tostring") " must return a string to "
LUA_QL("print"));
#if defined(LUA_USE_STDIO)
if (i>1) fputs("\t", stdout);
fputs(s, stdout);
#else
if (i>1) luai_writestring("\t", 1);
luai_writestring(s, strlen(s));
#endif
if (i>1) puts("\t");
puts(s);
lua_pop(L, 1); /* pop result */
}
#if defined(LUA_USE_STDIO)
fputs("\n", stdout);
#else
luai_writeline();
#endif
puts("\n");
return 0;
}
@ -112,7 +104,7 @@ static int luaB_getmetatable (lua_State *L) {
static int luaB_setmetatable (lua_State *L) {
int t = lua_type(L, 2);
luaL_checktype(L, 1, LUA_TTABLE);
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE || t == LUA_TROTABLE, 2,
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
"nil or table expected");
if (luaL_getmetafield(L, 1, "__metatable"))
luaL_error(L, "cannot change a protected metatable");
@ -175,7 +167,7 @@ static int luaB_rawequal (lua_State *L) {
static int luaB_rawget (lua_State *L) {
luaL_checkanytable(L, 1);
luaL_checktable(L, 1);
luaL_checkany(L, 2);
lua_settop(L, 2);
lua_rawget(L, 1);
@ -183,7 +175,7 @@ static int luaB_rawget (lua_State *L) {
}
static int luaB_rawset (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checktable(L, 1);
luaL_checkany(L, 2);
luaL_checkany(L, 3);
lua_settop(L, 3);
@ -233,7 +225,7 @@ static int luaB_type (lua_State *L) {
static int luaB_next (lua_State *L) {
luaL_checkanytable(L, 1);
luaL_checktable(L, 1);
lua_settop(L, 2); /* create a 2nd argument if there isn't one */
if (lua_next(L, 1))
return 2;
@ -245,7 +237,7 @@ static int luaB_next (lua_State *L) {
static int luaB_pairs (lua_State *L) {
luaL_checkanytable(L, 1);
luaL_checktable(L, 1);
lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
lua_pushvalue(L, 1); /* state, */
lua_pushnil(L); /* and initial value */
@ -255,7 +247,7 @@ static int luaB_pairs (lua_State *L) {
static int ipairsaux (lua_State *L) {
int i = luaL_checkint(L, 2);
luaL_checkanytable(L, 1);
luaL_checktable(L, 1);
i++; /* next value */
lua_pushinteger(L, i);
lua_rawgeti(L, 1, i);
@ -264,7 +256,7 @@ static int ipairsaux (lua_State *L) {
static int luaB_ipairs (lua_State *L) {
luaL_checkanytable(L, 1);
luaL_checktable(L, 1);
lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
lua_pushvalue(L, 1); /* state, */
lua_pushinteger(L, 0); /* and initial value */
@ -296,7 +288,7 @@ static int luaB_loadfile (lua_State *L) {
#ifdef LUA_CROSS_COMPILER
return load_aux(L, luaL_loadfile(L, fname));
#else
return load_aux(L, luaL_loadfsfile(L, fname));
return load_aux(L, luaL_loadfile(L, fname));
#endif
}
@ -343,7 +335,7 @@ static int luaB_dofile (lua_State *L) {
#ifdef LUA_CROSS_COMPILER
if (luaL_loadfile(L, fname) != 0) lua_error(L);
#else
if (luaL_loadfsfile(L, fname) != 0) lua_error(L);
if (luaL_loadfile(L, fname) != 0) lua_error(L);
#endif
lua_call(L, 0, LUA_MULTRET);
return lua_gettop(L) - n;
@ -462,29 +454,24 @@ static int luaB_newproxy (lua_State *L) {
return 1;
}
#include "lrotable.h"
LROT_EXTERN(lua_rotable_base);
/*
* Separate ROTables are used for the base functions and library ROTables, with
* the base functions ROTable declared below. The library ROTable is chained
* from this using its __index meta-method.
*
* ESP builds use specific linker directives to marshal all the ROTable entries
* for the library modules into a single ROTable in the PSECT ".lua_rotable".
* This is not practical on Posix builds using a standard GNU link, so the
* equivalent ROTable for the core libraries defined in linit.c for the cross-
* compiler build.
*/
LROT_EXTERN(lua_rotables);
LROT_PUBLIC_BEGIN(base_func_meta)
LROT_TABENTRY( __index, lua_rotables )
LROT_END(base_func, base_func_meta, LROT_MASK_INDEX)
LROT_PUBLIC_BEGIN(base_func)
** ESP builds use specific linker directives to marshal all the ROTable entries
** for the library modules including the base library into an entry vector in
** the PSECT ".lua_rotable" including the base library entries; this is bound
** into a ROTable in linit.c which then hooked into the __index metaentry for
** _G so that base library and ROM tables are directly resolved through _G.
**
** The host-based luac.cross builds which must use a standard GNU link or
** MSVC so this linker-specfic assembly approach can't be used. In this case
** luaopen_base returns a base_func ROTable so a two cascade resolution. See
** description in init.c for further details.
*/
#ifdef LUA_CROSS_COMPILER
LROT_BEGIN(base_func, NULL, 0)
#else
LROT_ENTRIES_IN_SECTION(base_func, rotable)
#endif
LROT_FUNCENTRY(assert, luaB_assert)
LROT_FUNCENTRY(collectgarbage, luaB_collectgarbage)
LROT_FUNCENTRY(dofile, luaB_dofile)
@ -509,13 +496,11 @@ LROT_PUBLIC_BEGIN(base_func)
LROT_FUNCENTRY(type, luaB_type)
LROT_FUNCENTRY(unpack, luaB_unpack)
LROT_FUNCENTRY(xpcall, luaB_xpcall)
LROT_TABENTRY(__metatable, base_func_meta)
LROT_END(base_func, base_func_meta, LROT_MASK_INDEX)
LROT_BEGIN(G_meta)
LROT_TABENTRY( __index, base_func )
LROT_END(G_meta, NULL, 0)
#ifdef LUA_CROSS_COMPILER
LROT_END(base_func, NULL, 0)
#else
LROT_BREAK(base_func)
#endif
/*
** {======================================================
@ -645,14 +630,14 @@ static int luaB_corunning (lua_State *L) {
return 1;
}
LROT_PUBLIC_BEGIN(co_funcs)
LROT_BEGIN(co_funcs, NULL, 0)
LROT_FUNCENTRY( create, luaB_cocreate )
LROT_FUNCENTRY( resume, luaB_coresume )
LROT_FUNCENTRY( running, luaB_corunning )
LROT_FUNCENTRY( status, luaB_costatus )
LROT_FUNCENTRY( wrap, luaB_cowrap )
LROT_FUNCENTRY( yield, luaB_yield )
LROT_END (co_funcs, NULL, 0)
LROT_END(co_funcs, NULL, 0)
/* }====================================================== */
@ -661,19 +646,13 @@ static void auxopen (lua_State *L, const char *name,
lua_CFunction f, lua_CFunction u) {
lua_pushcfunction(L, u);
lua_pushcclosure(L, f, 1);
lua_setfield(L, -2, name);
lua_setglobal(L, name);
}
static void base_open (lua_State *L) {
/* set global _G */
extern LROT_TABLE(rotables);
LUALIB_API int luaopen_base (lua_State *L) {
lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_setglobal(L, "_G");
/* open lib into global table */
luaL_register_light(L, "_G", &((luaL_Reg) {0}));
lua_pushrotable(L, LROT_TABLEREF(G_meta));
lua_setmetatable(L, LUA_GLOBALSINDEX);
lua_settable(L, LUA_GLOBALSINDEX); /* set global _G */
lua_pushliteral(L, LUA_VERSION);
lua_setglobal(L, "_VERSION"); /* set global _VERSION */
/* `ipairs' and `pairs' need auxliliary functions as upvalues */
@ -681,16 +660,15 @@ static void base_open (lua_State *L) {
auxopen(L, "pairs", luaB_pairs, luaB_next);
/* `newproxy' needs a weaktable as upvalue */
lua_createtable(L, 0, 1); /* new table `w' */
lua_pushvalue(L, -1); /* `w' will be its own metatable */
lua_setmetatable(L, -2);
lua_pushliteral(L, "kv");
lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
lua_pushcclosure(L, luaB_newproxy, 1);
lua_pushvalue(L, -1); /* `w' will be its own metatable */
lua_setmetatable(L, -2);
lua_pushcclosure(L, luaB_newproxy, 1); /* Upval is table w */
lua_setglobal(L, "newproxy"); /* set global `newproxy' */
}
LUALIB_API int luaopen_base (lua_State *L) {
base_open(L);
return 1;
lua_pushrotable(L, LROT_TABLEREF(rotables));
lua_setglobal(L, "__index");
lua_pushvalue(L, LUA_GLOBALSINDEX); /* _G is its own metatable */
lua_setmetatable(L, LUA_GLOBALSINDEX);
return 0;
}

View File

@ -7,7 +7,6 @@
#define lcode_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <stdlib.h>
@ -781,8 +780,6 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
}
#ifdef LUA_OPTIMIZE_DEBUG
/*
* Attempted to write to last (null terminator) byte of lineinfo, so need
* to grow the lineinfo vector and extend the fill bytes
@ -829,10 +826,8 @@ static void generateInfoDeltaLine(FuncState *fs, int line) {
fs->lastlineOffset = p - fs->f->packedlineinfo - 1;
#undef addDLbyte
}
#endif
void luaK_fixline (FuncState *fs, int line) {
#ifdef LUA_OPTIMIZE_DEBUG
/* The fixup line can be the same as existing one and in this case there's nothing to do */
if (line != fs->lastline) {
/* first remove the current line reference */
@ -863,9 +858,6 @@ void luaK_fixline (FuncState *fs, int line) {
/* Then add the new line reference */
generateInfoDeltaLine(fs, line);
}
#else
fs->f->lineinfo[fs->pc - 1] = line;
#endif
}
@ -877,7 +869,6 @@ static int luaK_code (FuncState *fs, Instruction i, int line) {
MAX_INT, "code size overflow");
f->code[fs->pc] = i;
/* save corresponding line information */
#ifdef LUA_OPTIMIZE_DEBUG
/* note that frst time fs->lastline==0 through, so the else branch is taken */
if (fs->pc == fs->lineinfoLastPC+1) {
if (line == fs->lastline && f->packedlineinfo[fs->lastlineOffset] < INFO_MAX_LINECNT) {
@ -891,11 +882,6 @@ static int luaK_code (FuncState *fs, Instruction i, int line) {
luaK_fixline(fs,line);
}
fs->lineinfoLastPC = fs->pc;
#else
luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
MAX_INT, "code size overflow");
f->lineinfo[fs->pc] = line;
#endif
return fs->pc++;
}

View File

@ -7,7 +7,6 @@
#define ldblib_c
#define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h"
#include <stdio.h>
@ -18,8 +17,6 @@
#include "lualib.h"
#include "lstring.h"
#include "lflash.h"
#include "lrotable.h"
#include "sdkconfig.h"
static int db_getregistry (lua_State *L) {
@ -28,34 +25,16 @@ static int db_getregistry (lua_State *L) {
}
static int db_getstrings (lua_State *L) {
size_t i,n=0;
stringtable *tb;
GCObject *o;
#ifndef LUA_CROSS_COMPILER
const char *opt = lua_tolstring (L, 1, &n);
if (n==3 && memcmp(opt, "ROM", 4) == 0) {
if (G(L)->ROstrt.hash == NULL)
return 0;
tb = &G(L)->ROstrt;
}
else
#endif
tb = &G(L)->strt;
lua_settop(L, 0);
lua_createtable(L, tb->nuse, 0); /* create table the same size as the strt */
for (i=0, n=1; i<tb->size; i++) {
for(o = tb->hash[i]; o; o=o->gch.next) {
TString *ts =cast(TString *, o);
lua_pushnil(L);
setsvalue2s(L, L->top-1, ts);
lua_rawseti(L, -2, n++); /* enumerate the strt, adding elements */
static const char *const opts[] = {"RAM","ROM",NULL};
int opt = luaL_checkoption(L, 1, "RAM", opts);
if (lua_pushstringsarray(L, opt)) {
if(lua_getglobal(L, "table") == LUA_TTABLE) {
lua_getfield(L, -1, "sort"); /* look up table.sort function */
lua_replace(L, -2); /* dump the table table */
lua_pushvalue(L, -2); /* duplicate the strt_copy ref */
lua_call(L, 1, 0); /* table.sort(strt_copy) */
}
}
lua_getfield(L, LUA_GLOBALSINDEX, "table");
lua_getfield(L, -1, "sort"); /* look up table.sort function */
lua_replace(L, -2); /* dump the table table */
lua_pushvalue(L, -2); /* duplicate the strt_copy ref */
lua_call(L, 1, 0); /* table.sort(strt_copy) */
return 1;
}
@ -144,7 +123,7 @@ static int db_getinfo (lua_State *L) {
return 1;
}
}
else if (lua_isfunction(L, arg+1) || lua_islightfunction(L, arg+1)) {
else if (lua_isfunction(L, arg+1)) {
lua_pushfstring(L, ">%s", options);
options = lua_tostring(L, -1);
lua_pushvalue(L, arg+1);
@ -302,7 +281,7 @@ static int db_sethook (lua_State *L) {
}
else {
const char *smask = luaL_checkstring(L, arg+2);
luaL_checkanyfunction(L, arg+1);
luaL_checkfunction(L, arg+1);
count = luaL_optint(L, arg+3, 0);
func = hookf; mask = makemask(smask, count);
}
@ -367,7 +346,7 @@ static int db_debug (lua_State *L) {
#define LEVELS1 12 /* size of the first part of the stack */
#define LEVELS2 10 /* size of the second part of the stack */
static int db_errorfb (lua_State *L) {
static int debug_errorfb (lua_State *L) {
int level;
int firstpart = 1; /* still before eventual `...' */
int arg;
@ -419,7 +398,7 @@ static int db_errorfb (lua_State *L) {
return 1;
}
LROT_PUBLIC_BEGIN(dblib)
LROT_BEGIN(dblib, NULL, 0)
#ifndef CONFIG_LUA_BUILTIN_DEBUG_MINIMAL
#if defined(LUA_CROSS_COMPILER)
LROT_FUNCENTRY( debug, db_debug )
@ -440,7 +419,7 @@ LROT_PUBLIC_BEGIN(dblib)
LROT_FUNCENTRY( setmetatable, db_setmetatable )
LROT_FUNCENTRY( setupvalue, db_setupvalue )
#endif
LROT_FUNCENTRY( traceback, db_errorfb )
LROT_FUNCENTRY( traceback, debug_errorfb )
LROT_END(dblib, NULL, 0)
LUALIB_API int luaopen_debug (lua_State *L) {

View File

@ -7,7 +7,6 @@
#define ldebug_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
@ -183,8 +182,7 @@ static void info_tailcall (lua_Debug *ar) {
# define INFO_DELTA_7BITS 0x7F
# define INFO_MAX_LINECNT 126
Table *t = luaH_new(L, 0, 0);
#ifdef LUA_OPTIMIZE_DEBUG
Table *t = luaH_new(L, 0, 0);
int line = 0;
unsigned char *p = f->l.p->packedlineinfo;
if (p) {
@ -204,18 +202,11 @@ static void info_tailcall (lua_Debug *ar) {
setbvalue(luaH_setnum(L, t, line), 1);
}
}
#else
int *lineinfo = f->l.p->lineinfo;
int i;
for (i=0; i<f->l.p->sizelineinfo; i++)
setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
#endif
sethvalue(L, L->top, t);
sethvalue(L, L->top, t);
}
incr_top(L);
}
#ifdef LUA_OPTIMIZE_DEBUG
/*
* This may seem expensive but this is only accessed frequently in traceexec
* and the while loop will be executed roughly half the number of non-blank
@ -250,19 +241,18 @@ int luaG_getline (const Proto *f, int pc) {
static int stripdebug (lua_State *L, Proto *f, int level) {
int len = 0, sizepackedlineinfo;
TString* dummy;
switch (level) {
case 3:
sizepackedlineinfo = strlen(cast(char *, f->packedlineinfo))+1;
f->packedlineinfo = luaM_freearray(L, f->packedlineinfo, sizepackedlineinfo, unsigned char);
len += sizepackedlineinfo;
// fall-through
case 2:
len += f->sizelocvars * (sizeof(struct LocVar) + sizeof(dummy->tsv) + sizeof(struct LocVar *));
if (f->packedlineinfo) {
sizepackedlineinfo = strlen(cast(char *, f->packedlineinfo))+1;
f->packedlineinfo = luaM_freearray(L, f->packedlineinfo, sizepackedlineinfo, unsigned char);
len += sizepackedlineinfo;
}
// fall-through
case 1:
f->locvars = luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
f->upvalues = luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
len += f->sizelocvars * (sizeof(struct LocVar) + sizeof(dummy->tsv) + sizeof(struct LocVar *)) +
f->sizeupvalues * (sizeof(dummy->tsv) + sizeof(TString *));
len += f->sizelocvars*sizeof(struct LocVar) + f->sizeupvalues*sizeof(TString *);
f->sizelocvars = 0;
f->sizeupvalues = 0;
}
@ -278,7 +268,6 @@ LUA_API int luaG_stripdebug (lua_State *L, Proto *f, int level, int recv){
len += stripdebug (L, f, level);
return len;
}
#endif
static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
@ -328,21 +317,21 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
lua_lock(L);
if (*what == '>') {
StkId func = L->top - 1;
luai_apicheck(L, ttisfunction(func) || ttislightfunction(func));
luai_apicheck(L, ttisfunction(func));
what++; /* skip the '>' */
if (ttisfunction(func))
f = clvalue(func);
else
if (ttislightfunction(func))
plight = fvalue(func);
else
f = clvalue(func);
L->top--; /* pop function */
}
else if (ar->i_ci != 0) { /* no tail call? */
ci = L->base_ci + ar->i_ci;
lua_assert(ttisfunction(ci->func) || ttislightfunction(ci->func));
if (ttisfunction(ci->func))
f = clvalue(ci->func);
else
lua_assert(ttisfunction(ci->func));
if (ttislightfunction(ci->func))
plight = fvalue(ci->func);
else
f = clvalue(ci->func);
}
status = auxgetinfo(L, what, ar, f, plight, ci);
if (strchr(what, 'f')) {
@ -381,9 +370,6 @@ static int precheck (const Proto *pt) {
check(!(pt->is_vararg & VARARG_NEEDSARG) ||
(pt->is_vararg & VARARG_HASARG));
check(pt->sizeupvalues <= pt->nups);
#ifndef LUA_OPTIMIZE_DEBUG
check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
#endif
check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
return 1;
}
@ -670,7 +656,7 @@ static int isinstack (CallInfo *ci, const TValue *o) {
void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
const char *name = NULL;
const char *t = luaT_typenames[ttype(o)];
const char *t = luaT_typenames[ttnov(o)];
const char *kind = (isinstack(L->ci, o)) ?
getobjname(L, L->ci, cast_int(o - L->base), &name) :
NULL;
@ -698,8 +684,8 @@ void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
const char *t1 = luaT_typenames[ttype(p1)];
const char *t2 = luaT_typenames[ttype(p2)];
const char *t1 = luaT_typenames[ttnov(p1)];
const char *t2 = luaT_typenames[ttnov(p2)];
if (t1[2] == t2[2])
luaG_runerror(L, "attempt to compare two %s values", t1);
else
@ -722,7 +708,7 @@ static void addinfo (lua_State *L, const char *msg) {
void luaG_errormsg (lua_State *L) {
if (L->errfunc != 0) { /* is there an error handling function? */
StkId errfunc = restorestack(L, L->errfunc);
if (!ttisfunction(errfunc) && !ttislightfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
setobjs2s(L, L->top, L->top - 1); /* move argument */
setobjs2s(L, L->top - 1, errfunc); /* push function */
incr_top(L);

View File

@ -13,7 +13,6 @@
#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
#ifdef LUA_OPTIMIZE_DEBUG
# include "lvm.h"
# define getline(f,pc) (((f)->packedlineinfo) ? luaG_getline((f), pc) : 0)
# define INFO_FILL_BYTE 0x7F
@ -23,9 +22,6 @@
# define INFO_DELTA_7BITS 0x7F
# define INFO_MAX_LINECNT 126
# define lineInfoTop(fs) ((fs)->f->packedlineinfo + (fs)->lastlineOffset)
#else
# define getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
#endif
#define resethookcount(L) (L->hookcount = L->basehookcount)
@ -41,9 +37,7 @@ LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
LUAI_FUNC void luaG_errormsg (lua_State *L);
LUAI_FUNC int luaG_checkcode (const Proto *pt);
LUAI_FUNC int luaG_checkopenop (Instruction i);
#ifdef LUA_OPTIMIZE_DEBUG
LUAI_FUNC int luaG_getline (const Proto *f, int pc);
LUAI_FUNC int luaG_stripdebug (lua_State *L, Proto *f, int level, int recv);
#endif
#endif

View File

@ -8,7 +8,6 @@
#define ldo_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
@ -106,7 +105,7 @@ void luaD_throw (lua_State *L, int errcode) {
lua_unlock(L);
G(L)->panic(L);
}
// exit(EXIT_FAILURE);
// c_exit(EXIT_FAILURE);
}
}
@ -254,13 +253,13 @@ static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
return base;
}
static StkId tryfuncTM (lua_State *L, StkId func) {
const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
StkId p;
ptrdiff_t funcr = savestack(L, func);
if (!ttisfunction(tm))
if (!ttisfunction(tm)) {
luaG_typeerror(L, func, "call");
}
/* Open a hole inside the stack at `func' */
for (p = L->top; p > func; p--) setobjs2s(L, p, p-1);
incr_top(L);
@ -279,10 +278,10 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
int luaD_precall (lua_State *L, StkId func, int nresults) {
ptrdiff_t funcr;
LClosure *cl = NULL;
if (!ttisfunction(func) && !ttislightfunction(func)) /* `func' is not a function? */
if (!ttisfunction(func)) /* `func' is not a function? */
func = tryfuncTM(L, func); /* check the `function' tag method */
funcr = savestack(L, func);
if (ttisfunction(func))
if (!ttislightfunction(func))
cl = &clvalue(func)->l;
L->ci->savedpc = L->savedpc;
if (cl && !cl->isC) { /* Lua function? prepare its call */
@ -332,10 +331,10 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
if (L->hookmask & LUA_MASKCALL)
luaD_callhook(L, LUA_HOOKCALL, -1);
lua_unlock(L);
if (ttisfunction(ci->func))
n = (*curr_func(L)->c.f)(L); /* do the actual call */
else
if (ttislightfunction(ci->func))
n = ((lua_CFunction)fvalue(ci->func))(L); /* do the actual call */
else
n = (*curr_func(L)->c.f)(L); /* do the actual call */
lua_lock(L);
if (n < 0) /* yielding? */
return PCRYIELD;
@ -384,7 +383,7 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
** The arguments are on the stack, right after the function.
** When returns, all the results are on the stack, starting at the original
** function position.
*/
*/
void luaD_call (lua_State *L, StkId func, int nResults) {
if (++L->nCcalls >= LUAI_MAXCCALLS) {
if (L->nCcalls == LUAI_MAXCCALLS)

View File

@ -6,7 +6,6 @@
#define ldump_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
@ -229,7 +228,6 @@ static void DumpDebug(const Proto* f, DumpState* D)
{
int i,n;
#ifdef LUA_OPTIMIZE_DEBUG
n = (D->strip || f->packedlineinfo == NULL) ? 0: strlen(cast(char *,f->packedlineinfo))+1;
DumpInt(n,D);
Align4(D);
@ -237,15 +235,6 @@ static void DumpDebug(const Proto* f, DumpState* D)
{
DumpBlock(f->packedlineinfo, n, D);
}
#else
n= (D->strip) ? 0 : f->sizelineinfo;
DumpInt(n,D);
Align4(D);
for (i=0; i<n; i++)
{
DumpInt(f->lineinfo[i],D);
}
#endif
n= (D->strip) ? 0 : f->sizelocvars;
DumpInt(n,D);

View File

@ -5,7 +5,6 @@
#define lflash_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include "lobject.h"
@ -24,6 +23,8 @@
#include <stdlib.h>
#include <string.h>
#include "lfs.h"
/*
* Flash memory is a fixed memory addressable block that is serially allocated by the
* luac build process and the out image can be downloaded into SPIFSS and loaded into
@ -72,7 +73,7 @@ struct OUTPUT {
outBlock buffer;
int ndx;
uint32_t crc;
int (*fullBlkCB) (void);
void (*fullBlkCB) (void);
int flashLen;
int flagsLen;
int flagsNdx;
@ -80,12 +81,6 @@ struct OUTPUT {
const char *error;
} *out;
#ifdef CONFIG_NODEMCU_EMBEDDED_LFS_SIZE
extern const char lua_flash_store_reserved[0];
#endif
#ifdef NODE_DEBUG
extern void printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
void dumpStrt(stringtable *tb, const char *type) {
@ -97,9 +92,8 @@ void dumpStrt(stringtable *tb, const char *type) {
for (i=0; i<tb->size; i++)
for(o = tb->hash[i], j=0; o; (o=o->gch.next), j++ ) {
TString *ts =cast(TString *, o);
NODE_DBG("%5d %5d %08x %08x %5d %1s %s\n",
i, j, (size_t) ts, ts->tsv.hash, ts->tsv.len,
ts_isreadonly(ts) ? "R" : " ", getstr(ts));
NODE_DBG("%5d %5d %08x %08x %5d %s\n",
i, j, (size_t) ts, ts->tsv.hash, ts->tsv.len, getstr(ts));
}
}
@ -117,17 +111,25 @@ LUA_API void dumpStrings(lua_State *L) {
* writes are suppressed if the global writeToFlash is false. This is used in
* phase I where the pass is used to size the structures in flash.
*/
static void flashSetPosition(uint32_t offset){
NODE_DBG("flashSetPosition(%04x)\n", offset);
curOffset = offset;
static const char *flashPosition(void){
return flashAddr + curOffset;
}
static void flashBlock(const void* b, size_t size) {
NODE_DBG("flashBlock((%04x),%08x,%04x)\n", curOffset,(unsigned int)b,size);
static const char *flashSetPosition(uint32_t offset){
NODE_DBG("flashSetPosition(%04x)\n", offset);
curOffset = offset;
return flashPosition();
}
static const char *flashBlock(const void* b, size_t size) {
const void *cur = flashPosition();
NODE_DBG("flashBlock((%04x),%p,%04x)\n", curOffset,b,size);
lua_assert(ALIGN_BITS(b) == 0 && ALIGN_BITS(size) == 0);
platform_flash_write(b, flashAddrPhys+curOffset, size);
curOffset += size;
return cur;
}
@ -142,11 +144,11 @@ static void flashErase(uint32_t start, uint32_t end){
static int loadLFS (lua_State *L);
static int loadLFSgc (lua_State *L);
static int procFirstPass (void);
static void procFirstPass (void);
#endif
/* =====================================================================================
* luaN_init(), luaN_reload_reboot() and luaN_index() are exported via lflash.h.
* luaN_init() is exported via lflash.h.
* The first is the startup hook used in lstate.c and the last two are
* implementations of the node.flash API calls.
*/
@ -155,40 +157,15 @@ static int procFirstPass (void);
* Hook in lstate.c:f_luaopen() to set up ROstrt and ROpvmain if needed
*/
LUAI_FUNC void luaN_init (lua_State *L) {
#ifdef CONFIG_NODEMCU_EMBEDDED_LFS_SIZE
flashSize = CONFIG_NODEMCU_EMBEDDED_LFS_SIZE;
flashAddr = lua_flash_store_reserved;
flashAddrPhys = spi_flash_cache2phys(lua_flash_store_reserved);
if (flashAddrPhys == SPI_FLASH_CACHE2PHYS_FAIL) {
NODE_ERR("spi_flash_cache2phys failed\n");
lfs_location_info_t lfs_loc;
if (!lfs_get_location(&lfs_loc))
return;
}
#else
const esp_partition_t *part = esp_partition_find_first(
PLATFORM_PARTITION_TYPE_NODEMCU,
PLATFORM_PARTITION_SUBTYPE_NODEMCU_LFS,
NULL);
if (!part)
return; // Nothing to do if the size is zero
flashSize = part->size; // in bytes
flashAddrPhys = part->address;
flashAddr = spi_flash_phys2cache(flashAddrPhys, SPI_FLASH_MMAP_DATA);
if (!flashAddr) {
spi_flash_mmap_handle_t ignored;
esp_err_t err = spi_flash_mmap(
flashAddrPhys, flashSize, SPI_FLASH_MMAP_DATA,
cast(const void **, &flashAddr), &ignored);
if (err != ESP_OK) {
NODE_ERR("Unable to access LFS partition - is it 64kB aligned as it needs to be?\n");
return;
}
}
#endif
G(L)->LFSsize = flashSize;
flashSector = platform_flash_get_sector_of_address(flashAddrPhys);
FlashHeader *fh = cast(FlashHeader *, flashAddr);
G(L)->LFSsize = flashSize = lfs_loc.size;
flashAddr = lfs_loc.addr_mem;
flashAddrPhys = lfs_loc.addr_phys;
flashSector = platform_flash_get_sector_of_address(lfs_loc.addr_phys);
FlashHeader *fh = cast(FlashHeader *, lfs_loc.addr_mem);
curOffset = 0;
/*
@ -204,15 +181,15 @@ LUAI_FUNC void luaN_init (lua_State *L) {
}
if ((fh->flash_sig & (~FLASH_SIG_ABSOLUTE)) != FLASH_SIG ) {
NODE_ERR("Flash sig not correct: %u vs %u\n",
NODE_ERR("LFS sig not correct: 0x%x vs expected 0x%x\n",
fh->flash_sig & (~FLASH_SIG_ABSOLUTE), FLASH_SIG);
return;
}
if (fh->pROhash == ALL_SET ||
((fh->mainProto - cast(FlashAddr, fh)) >= fh->flash_size)) {
NODE_ERR("Flash size check failed: %x vs 0xFFFFFFFF; size: %u\n",
fh->mainProto - cast(FlashAddr, fh), fh->flash_size);
NODE_ERR("Flash size check failed: 0x%08x vs 0xFFFFFFFF; 0x%08x >= 0x%08x\n",
fh->pROhash, fh->mainProto - cast(FlashAddr, fh), fh->flash_size);
return;
}
@ -222,23 +199,24 @@ LUAI_FUNC void luaN_init (lua_State *L) {
G(L)->ROpvmain = cast(Proto *,fh->mainProto);
}
/* luaL_lfsreload() is exported via lauxlib.h */
/*
* Library function called by node.flashreload(filename).
*/
LUALIB_API int luaN_reload_reboot (lua_State *L) {
LUALIB_API void luaL_lfsreload (lua_State *L) {
#ifdef CONFIG_NODEMCU_EMBEDDED_LFS_SIZE
// Updating the LFS section is disabled for now because any changes to the
// image requires updating its checksum to prevent boot failure.
lua_pushstring(L, "Not allowed to write to LFS section");
return 1;
return;
#else
// luaL_dbgbreak();
const char *fn = lua_tostring(L, 1), *msg = "";
int status;
if (G(L)->LFSsize == 0) {
lua_pushstring(L, "No LFS partition allocated");
return 1;
return;
}
@ -270,7 +248,7 @@ LUALIB_API int luaN_reload_reboot (lua_State *L) {
lua_cpcall(L, &loadLFSgc, NULL);
lua_settop(L, 0);
lua_pushstring(L, msg);
return 1;
return;
}
if (status == 0) {
@ -290,62 +268,22 @@ LUALIB_API int luaN_reload_reboot (lua_State *L) {
NODE_ERR("%s\n", msg);
esp_restart();
return 0;
#endif // CONFIG_NODEMCU_EMBEDDED_LFS_SIZE
}
/*
* If the arg is a valid LFS module name then return the LClosure
* pointing to it. Otherwise return:
* - The Unix time that the LFS was built
* - The base address and length of the LFS
* - An array of the module names in the LFS
*/
LUAI_FUNC int luaN_index (lua_State *L) {
int n = lua_gettop(L);
/* Return nil + the LFS base address if the LFS size > 0 and it isn't loaded */
if (!(G(L)->ROpvmain)) {
lua_settop(L, 0);
lua_pushnil(L);
if (G(L)->LFSsize) {
lua_pushinteger(L, (lua_Integer) flashAddr);
lua_pushinteger(L, flashAddrPhys);
lua_pushinteger(L, G(L)->LFSsize);
return 4;
} else {
return 1;
}
}
/* Push the LClosure of the LFS index function */
Closure *cl = luaF_newLclosure(L, 0, hvalue(gt(L)));
cl->l.p = G(L)->ROpvmain;
lua_settop(L, n+1);
setclvalue(L, L->top-1, cl);
/* Move it infront of the arguments and call the index function */
lua_insert(L, 1);
lua_call(L, n, LUA_MULTRET);
/* Return it if the response if a single value (the function) */
if (lua_gettop(L) == 1)
return 1;
lua_assert(lua_gettop(L) == 2);
/* Otherwise add the base address of the LFS, and its size bewteen the */
/* Unix time and the module list, then return all 4 params. */
lua_pushinteger(L, (lua_Integer) flashAddr);
lua_insert(L, 2);
lua_pushinteger(L, flashAddrPhys);
lua_insert(L, 3);
lua_pushinteger(L, cast(FlashHeader *, flashAddr)->flash_size);
lua_insert(L, 4);
return 5;
LUA_API void lua_getlfsconfig (lua_State *L, intptr_t *config) {
if (!config)
return;
config[0] = (intptr_t) flashAddr; /* LFS region mapped address */
config[1] = flashAddrPhys; /* LFS region base flash address */
config[2] = G(L)->LFSsize; /* LFS region actual size */
config[3] = (G(L)->ROstrt.hash) ? cast(FlashHeader *, flashAddr)->flash_size : 0;
/* LFS region used */
config[4] = 0; /* Not used in Lua 5.1 */
}
#ifndef CONFIG_NODEMCU_EMBEDDED_LFS_SIZE
/* =====================================================================================
* The following routines use my uzlib which was based on pfalcon's inflate and
@ -440,7 +378,7 @@ static uint8_t recall_byte (uint32_t offset) {
* - Once the flags array is in-buffer this is also captured.
* This logic is slightly complicated by the last buffer is typically short.
*/
int procFirstPass (void) {
void procFirstPass (void) {
int len = (out->ndx % WRITE_BLOCKSIZE) ?
out->ndx % WRITE_BLOCKSIZE : WRITE_BLOCKSIZE;
if (out->ndx <= WRITE_BLOCKSIZE) {
@ -475,12 +413,10 @@ int procFirstPass (void) {
memcpy(out->flags + out->flagsNdx, out->block[0]->byte + start, len - start);
out->flagsNdx += (len -start) / WORDSIZE; /* flashLen and len are word aligned */
}
return 1;
}
int procSecondPass (void) {
void procSecondPass (void) {
/*
* The length rules are different for the second pass since this only processes
* upto the flashLen and not the full image. This also works in word units.
@ -518,12 +454,10 @@ int procSecondPass (void) {
flashBlock(&out->flash_sig, WORDSIZE);
out->fullBlkCB = NULL;
}
return 1;
}
/*
* loadLFS)() is protected called from luaN_reload_reboot so that it can recover
* loadLFS)() is protected called from luaL_lfsreload so that it can recover
* from out of memory and other thrown errors. loadLFSgc() GCs any resources.
*/
static int loadLFS (lua_State *L) {
@ -548,7 +482,7 @@ static int loadLFS (lua_State *L) {
in->len = vfs_size(in->fd);
if (in->len <= 200 || /* size of an empty luac output */
vfs_lseek(in->fd, in->len-4, VFS_SEEK_SET) != in->len-4 ||
vfs_read(in->fd, &out->len, sizeof(uint)) != sizeof(uint))
vfs_read(in->fd, &out->len, sizeof(uint32_t)) != sizeof(uint32_t))
flash_error("read error on LFS image file");
vfs_lseek(in->fd, 0, VFS_SEEK_SET);

View File

@ -43,8 +43,5 @@ typedef struct {
} FlashHeader;
LUAI_FUNC void luaN_init (lua_State *L);
LUAI_FUNC int luaN_flashSetup (lua_State *L);
LUAI_FUNC int luaN_reload_reboot (lua_State *L);
LUAI_FUNC int luaN_index (lua_State *L);
#endif

View File

@ -6,7 +6,6 @@
#define lfunc_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
@ -126,12 +125,7 @@ Proto *luaF_newproto (lua_State *L) {
f->numparams = 0;
f->is_vararg = 0;
f->maxstacksize = 0;
#ifdef LUA_OPTIMIZE_DEBUG
f->packedlineinfo = NULL;
#else
f->sizelineinfo = 0;
f->lineinfo = NULL;
#endif
f->sizelocvars = 0;
f->locvars = NULL;
f->linedefined = 0;
@ -146,15 +140,9 @@ void luaF_freeproto (lua_State *L, Proto *f) {
luaM_freearray(L, f->k, f->sizek, TValue);
luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
if (!proto_isreadonly(f)) {
luaM_freearray(L, f->code, f->sizecode, Instruction);
#ifdef LUA_OPTIMIZE_DEBUG
if (f->packedlineinfo) {
luaM_freearray(L, f->packedlineinfo, strlen(cast(char *, f->packedlineinfo))+1, unsigned char);
}
#else
luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
#endif
luaM_freearray(L, f->code, f->sizecode, Instruction);
if (f->packedlineinfo) {
luaM_freearray(L, f->packedlineinfo, strlen(cast(char *, f->packedlineinfo))+1, unsigned char);
}
luaM_free(L, f);
}

View File

@ -6,7 +6,6 @@
#define lgc_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
@ -21,14 +20,12 @@
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lrotable.h"
#define GCSTEPSIZE 1024u
#define GCSWEEPMAX 40
#define GCSWEEPCOST 10
#define GCFINALIZECOST 100
#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS))
#define makewhite(g,x) \
@ -55,7 +52,6 @@
#define markobject(g,t) { if (iswhite(obj2gco(t))) \
reallymarkobject(g, obj2gco(t)); }
#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause)
@ -82,7 +78,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
case LUA_TUSERDATA: {
Table *mt = gco2u(o)->metatable;
gray2black(o); /* udata are never gray */
if (mt && !luaR_isrotable(mt)) markobject(g, mt);
if (mt && isrwtable(mt)) markobject(g, mt);
markobject(g, gco2u(o)->env);
return;
}
@ -160,7 +156,6 @@ size_t luaC_separateudata (lua_State *L, int all) {
return deadmem;
}
static int traversetable (global_State *g, Table *h) {
int i;
int weakkey = 0;
@ -168,7 +163,7 @@ static int traversetable (global_State *g, Table *h) {
const TValue *mode = luaO_nilobject;
if (h->metatable) {
if (!luaR_isrotable(h->metatable))
if (isrwtable(h->metatable))
markobject(g, h->metatable);
mode = gfasttm(g, h->metatable, TM_MODE);
}
@ -331,14 +326,8 @@ static l_mem propagatemark (global_State *g) {
sizeof(TValue) * p->sizek +
sizeof(LocVar) * p->sizelocvars +
sizeof(TString *) * p->sizeupvalues +
(proto_isreadonly(p) ? 0 : sizeof(Instruction) * p->sizecode +
#ifdef LUA_OPTIMIZE_DEBUG
(p->packedlineinfo ?
strlen(cast(char *, p->packedlineinfo))+1 :
0));
#else
sizeof(int) * p->sizelineinfo);
#endif
sizeof(Instruction) * p->sizecode +
(p->packedlineinfo ? strlen(cast(char *, p->packedlineinfo))+1 : 0);
}
default: lua_assert(0); return 0;
}
@ -522,8 +511,8 @@ void luaC_freeall (lua_State *L) {
static void markmt (global_State *g) {
int i;
for (i=0; i<NUM_TAGS; i++)
if (g->mt[i] && !luaR_isrotable(g->mt[i])) markobject(g, g->mt[i]);
for (i=0; i<LUA_NUMTAGS; i++)
if (g->mt[i] && isrwtable(g->mt[i])) markobject(g, g->mt[i]);
}
@ -713,7 +702,7 @@ void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
global_State *g = G(L);
lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
lua_assert(g->gcstate != GCSfinalize && g->gcstate != GCSpause);
lua_assert(o->gch.tt != LUA_TTABLE);
lua_assert((gettt(o) & LUA_TMASK) != LUA_TTABLE);
/* must keep invariant? */
if (g->gcstate == GCSpropagate)
reallymarkobject(g, v); /* Restore invariant */

View File

@ -7,7 +7,6 @@
#define llex_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <ctype.h>
@ -62,6 +61,7 @@ static void save (LexState *ls, int c) {
void luaX_init (lua_State *L) {
(void)L;
}

View File

@ -8,8 +8,6 @@
#define llimits_h
//#include <limits.h>
#include "lua.h"
typedef LUAI_UINT32 lu_int32;
@ -104,7 +102,7 @@ typedef lu_int32 Instruction;
#ifndef lua_lock
#define lua_lock(L) ((void) 0)
#define lua_lock(L) ((void) 0)
#define lua_unlock(L) ((void) 0)
#endif
@ -115,7 +113,7 @@ typedef lu_int32 Instruction;
/*
** macro to control inclusion of some hard tests on stack reallocation
*/
*/
#ifndef HARDSTACKTESTS
#define condhardstacktests(x) ((void)0)
#else

View File

@ -7,7 +7,6 @@
#define lmathlib_c
#define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h"
#include <stdlib.h>
@ -15,7 +14,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#undef PI
#define PI (3.14159265358979323846)
@ -309,7 +307,7 @@ static int math_randomseed (lua_State *L) {
return 0;
}
LROT_PUBLIC_BEGIN(math)
LROT_BEGIN(mathlib, NULL, 0)
#ifdef LUA_NUMBER_INTEGRAL
LROT_FUNCENTRY( abs, math_abs )
LROT_FUNCENTRY( ceil, math_identity )
@ -354,7 +352,7 @@ LROT_PUBLIC_BEGIN(math)
LROT_NUMENTRY( pi, PI )
LROT_NUMENTRY( huge, HUGE_VAL )
#endif // #ifdef LUA_NUMBER_INTEGRAL
LROT_END(math, NULL, 0)
LROT_END(mathlib, NULL, 0)
/*

View File

@ -7,7 +7,6 @@
#define lmem_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"

View File

@ -8,12 +8,6 @@
#define lmem_h
//#ifdef LUA_CROSS_COMPILER
//#include <stddef.h>
//#else
//#include "c_stddef.h"
//#endif
#include "llimits.h"
#include "lua.h"

View File

@ -0,0 +1,259 @@
/*
** $Id: ltm.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
** Tag methods
** See Copyright Notice in lua.h
*/
#define lnodemcu_c
#define LUA_CORE
#include "lua.h"
#include <string.h>
#include "lobject.h"
#include "lstate.h"
#include "lauxlib.h"
#include "lgc.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lnodemcu.h"
//== NodeMCU lauxlib.h API extensions ========================================//
#ifdef LUA_USE_ESP
#include "task/task.h"
#include "platform.h"
/*
** Error Reporting Task. We can't pass a string parameter to the error reporter
** directly through the task interface the call is wrapped in a C closure with
** the error string as an Upval and this is posted to call the Lua reporter.
*/
static int errhandler_aux (lua_State *L) {
lua_getfield(L, LUA_REGISTRYINDEX, "onerror");
if (!lua_isfunction(L, -1)) {
lua_pop(L, 1);
lua_getglobal(L, "print");
}
lua_pushvalue(L, lua_upvalueindex(1));
lua_call(L, 1, 0); /* Using an error handler would cause an infinite loop! */
return 0;
}
/*
** Error handler for luaL_pcallx(), called from the lua_pcall() with a single
** argument -- the thrown error. This plus depth=2 is passed to debug.traceback()
** to convert into an error message which it handles in a separate posted task.
*/
static int errhandler (lua_State *L) {
lua_getglobal(L, "debug");
lua_getfield(L, -1, "traceback");
if (lua_isfunction(L, -1)) {
lua_insert(L, 1); /* insert tracback function above error */
lua_pop(L, 1); /* dump the debug table entry */
lua_pushinteger(L, 2); /* skip this function and traceback */
lua_call(L, 2, 1); /* call debug.traceback and return it as a string */
lua_pushcclosure(L, errhandler_aux, 1); /* report with str as upval */
luaL_posttask(L, LUA_TASK_HIGH);
}
return 0;
}
/*
** Use in CBs and other C functions to call a Lua function. This includes
** an error handler which will catch any error and then post this to the
** registered reporter function as a separate follow-on task.
*/
LUALIB_API int luaL_pcallx (lua_State *L, int narg, int nres) { // [-narg, +0, v]
int status;
int base = lua_gettop(L) - narg;
lua_pushcfunction(L, errhandler);
lua_insert(L, base); /* put under args */
status = lua_pcall(L, narg, nres, base);
lua_remove(L, base); /* remove traceback function */
if (status != LUA_OK && status != LUA_ERRRUN) {
lua_gc(L, LUA_GCCOLLECT, 0); /* call onerror directly if handler failed */
lua_pushliteral(L, "out of memory");
lua_pushcclosure(L, errhandler_aux, 1); /* report EOM as upval */
luaL_posttask(L, LUA_TASK_HIGH);
}
return status;
}
static task_handle_t task_handle = 0;
/*
** Task callback handler. Uses luaN_call to do a protected call with full traceback
*/
static void do_task (task_param_t task_fn_ref, task_prio_t prio) {
lua_State* L = lua_getstate();
if (prio < 0|| prio > 2)
luaL_error(L, "invalid posk task");
/* Pop the CB func from the Reg */
//dbg_printf("calling Reg[%u]\n", task_fn_ref);
lua_rawgeti(L, LUA_REGISTRYINDEX, (int) task_fn_ref);
luaL_checkfunction(L, -1);
luaL_unref(L, LUA_REGISTRYINDEX, (int) task_fn_ref);
lua_pushinteger(L, prio);
luaL_pcallx(L, 1, 0);
}
/*
** Schedule a Lua function for task execution
*/
LUALIB_API int luaL_posttask( lua_State* L, int prio ) { // [-1, +0, -]
if (!task_handle)
task_handle = task_get_id(do_task);
if (!lua_isfunction(L, -1) || prio < LUA_TASK_LOW|| prio > LUA_TASK_HIGH)
luaL_error(L, "invalid posk task");
//void *cl = clvalue(L->top-1);
int task_fn_ref = luaL_ref(L, LUA_REGISTRYINDEX);
//dbg_printf("posting Reg[%u]=%p\n",task_fn_ref,cl);
if(!task_post(prio, task_handle, (task_param_t)task_fn_ref)) {
luaL_unref(L, LUA_REGISTRYINDEX, task_fn_ref);
luaL_error(L, "Task queue overflow. Task not posted");
}
return task_fn_ref;
}
#else
LUALIB_API int luaL_posttask( lua_State* L, int prio ) {
(void)L; (void)prio;
return 0;
} /* Dummy stub on host */
#endif
#ifdef LUA_USE_ESP
/*
* Return an LFS function
*/
LUALIB_API int luaL_pushlfsmodule (lua_State *L) {
if (lua_pushlfsindex(L) == LUA_TNIL) {
lua_remove(L,-2); /* dump the name to balance the stack */
return 0; /* return nil if LFS not loaded */
}
lua_insert(L, -2);
lua_call(L, 1, 1);
if (!lua_isfunction(L, -1)) {
lua_pop(L, 1);
lua_pushnil(L); /* replace DTS by nil */
}
return 1;
}
/*
* Return an array of functions in LFS
*/
LUALIB_API int luaL_pushlfsmodules (lua_State *L) {
if (lua_pushlfsindex(L) == LUA_TNIL)
return 0; /* return nil if LFS not loaded */
lua_call(L, 0, 2);
lua_remove(L, -2); /* remove DTS leaving array */
return 1;
}
/*
* Return the Unix timestamp of the LFS image creation
*/
LUALIB_API int luaL_pushlfsdts (lua_State *L) {
if (lua_pushlfsindex(L) == LUA_TNIL)
return 0; /* return nil if LFS not loaded */
lua_call(L, 0, 1);
return 1;
}
#endif
//== NodeMCU lua.h API extensions ============================================//
LUA_API int lua_freeheap (void) {
#ifdef LUA_USE_HOST
return MAX_INT;
#else
return (int)esp_get_free_heap_size();
#endif
}
#define api_incr_top(L) {api_check(L, L->top < L->ci->top); L->top++;}
LUA_API int lua_pushstringsarray(lua_State *L, int opt) {
stringtable *tb = NULL;
int i, j;
lua_lock(L);
if (opt == 0)
tb = &G(L)->strt;
#ifdef LUA_USE_ESP
else if (opt == 1 && G(L)->ROstrt.hash)
tb = &G(L)->ROstrt;
#endif
if (tb == NULL) {
setnilvalue(L->top);
api_incr_top(L);
lua_unlock(L);
return 0;
}
Table *t = luaH_new(L, tb->nuse, 0);
sethvalue(L, L->top, t);
api_incr_top(L);
luaC_checkGC(L);
lua_unlock(L);
for (i = 0, j = 1; i < tb->size; i++) {
GCObject *o;
for(o = tb->hash[i]; o; o = o->gch.next) {
TValue v;
setsvalue(L, &v, o);
setobj2s(L, luaH_setnum(L, hvalue(L->top-1), j++), &v);
}
}
return 1;
}
LUA_API void lua_createrotable (lua_State *L, ROTable *t, const ROTable_entry *e, ROTable *mt) {
int i, j;
lu_byte flags = ~0;
const char *plast = (char *)"_";
for (i = 0; e[i].key; i++) {
if (e[i].key[0] == '_' && strcmp(e[i].key,plast)) {
plast = e[i].key;
lua_pushstring(L,e[i].key);
for (j=0; j<TM_EQ; j++){
if(rawtsvalue(L->top-1)==G(L)->tmname[i]) {
flags |= cast_byte(1u<<i);
break;
}
}
lua_pop(L,1);
}
}
t->next = (GCObject *)1;
t->tt = LUA_TROTABLE;
t->marked = LROT_MARKED;
t->flags = flags;
t->lsizenode = i;
t->metatable = cast(Table *, mt);
t->entry = cast(ROTable_entry *, e);
}
#ifdef LUA_USE_ESP
#include "lfunc.h"
/* Push the LClosure of the LFS index function */
LUA_API int lua_pushlfsindex (lua_State *L) {
lua_lock(L);
Proto *p = G(L)->ROpvmain;
if (p) {
Closure *cl = luaF_newLclosure(L, 0, hvalue(gt(L)));
cl->l.p = p;
setclvalue(L, L->top, cl);
} else {
setnilvalue(L->top);
}
api_incr_top(L);
lua_unlock(L);
return p ? LUA_TFUNCTION : LUA_TNIL;
}
#endif

View File

@ -0,0 +1,73 @@
/*
* NodeMCU extensions to Lua 5.1 for readonly Flash memory support
*/
#ifndef lnodemcu_h
#define lnodemcu_h
#include "lua.h"
#include "lobject.h"
#include "llimits.h"
#include "ltm.h"
#ifdef LUA_USE_HOST
#define LRO_STRKEY(k) k
#define LOCK_IN_SECTION(s)
#else
#define LRO_STRKEY(k) ((__attribute__((aligned(4))) const char *) k)
#define LOCK_IN_SECTION(s) __attribute__((used,unused,section(".lua_" #s)))
#endif
/* Macros used to declare rotable entries */
#define LRO_FUNCVAL(v) {{.p = v}, LUA_TLIGHTFUNCTION}
#define LRO_LUDATA(v) {{.p = cast(void*,v)}, LUA_TLIGHTUSERDATA}
#define LRO_NILVAL {{.p = NULL}, LUA_TNIL}
#define LRO_NUMVAL(v) {{.n = v}, LUA_TNUMBER}
#define LRO_INTVAL(v) LRO_NUMVAL(v)
#define LRO_FLOATVAL(v) LRO_NUMVAL(v)
#define LRO_ROVAL(v) {{.gc = cast(GCObject *, &(v ## _ROTable))}, LUA_TROTABLE}
#define LROT_MARKED 0 //<<<<<<<<<< *** TBD *** >>>>>>>>>>>
#define LROT_FUNCENTRY(n,f) {LRO_STRKEY(#n), LRO_FUNCVAL(f)},
#define LROT_LUDENTRY(n,x) {LRO_STRKEY(#n), LRO_LUDATA(x)},
#define LROT_NUMENTRY(n,x) {LRO_STRKEY(#n), LRO_NUMVAL(x)},
#define LROT_INTENTRY(n,x) LROT_NUMENTRY(n,x)
#define LROT_FLOATENTRY(n,x) LROT_NUMENTRY(n,x)
#define LROT_TABENTRY(n,t) {LRO_STRKEY(#n), LRO_ROVAL(t)},
#define LROT_TABLE(rt) const ROTable rt ## _ROTable
#define LROT_ENTRYREF(rt) (rt ##_entries)
#define LROT_TABLEREF(rt) (&rt ##_ROTable)
#define LROT_BEGIN(rt,mt,f) LROT_TABLE(rt); \
static ROTable_entry rt ## _entries[] = {
#define LROT_ENTRIES_IN_SECTION(rt,s) \
static ROTable_entry LOCK_IN_SECTION(s) rt ## _entries[] = {
#define LROT_END(rt,mt,f) {NULL, LRO_NILVAL} }; \
const ROTable rt ## _ROTable = { \
(GCObject *)1, LUA_TROTABLE, LROT_MARKED, \
cast(lu_byte, ~(f)), (sizeof(rt ## _entries)/sizeof(ROTable_entry)) - 1, \
cast(Table *, mt), cast(ROTable_entry *, rt ## _entries) };
#define LROT_BREAK(rt) };
#define LROT_MASK(m) cast(lu_byte, 1<<TM_ ## m)
/*
* These are statically coded can be any combination of the fast index tags
* listed in ltm.h: EQ, GC, INDEX, LEN, MODE, NEWINDEX or combined by anding
* GC+INDEX is the only common combination used, hence the combinaton macro
*/
#define LROT_MASK_EQ LROT_MASK(EQ)
#define LROT_MASK_GC LROT_MASK(GC)
#define LROT_MASK_INDEX LROT_MASK(INDEX)
#define LROT_MASK_LEN LROT_MASK(LEN)
#define LROT_MASK_MODE LROT_MASK(MODE)
#define LROT_MASK_NEWINDEX LROT_MASK(NEWINDEX)
#define LROT_MASK_GC_INDEX (LROT_MASK_GC | LROT_MASK_INDEX)
#define LUA_MAX_ROTABLE_NAME 32 /* Maximum length of a rotable name and of a string key*/
#ifdef LUA_CORE
#endif
#endif

View File

@ -11,7 +11,6 @@
#define loadlib_c
#define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h"
#include <stdlib.h>
@ -24,7 +23,6 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
/* prefix for open functions in C libraries */
#define LUA_POF "luaopen_"
@ -394,11 +392,7 @@ static int loader_Lua (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
filename = findfile(L, name, "path");
if (filename == NULL) return 1; /* library not found in this path */
#ifdef LUA_CROSS_COMPILER
if (luaL_loadfile(L, filename) != 0)
#else
if (luaL_loadfsfile(L, filename) != 0)
#endif
loaderror(L, filename);
return 1; /* library loaded successfully */
}
@ -479,7 +473,7 @@ static int ll_require (lua_State *L) {
}
/* Is this a readonly table? */
lua_getfield(L, LUA_GLOBALSINDEX, name);
if(lua_isrotable(L,-1)) {
if(lua_istable(L,-1)) {
return 1;
} else {
lua_pop(L, 1);
@ -572,7 +566,7 @@ static int ll_module (lua_State *L) {
const char *modname = luaL_checkstring(L, 1);
/* Is this a readonly table? */
lua_getfield(L, LUA_GLOBALSINDEX, modname);
if(lua_isrotable(L,-1)) {
if(lua_istable(L,-1)) {
return 0;
} else {
lua_pop(L, 1);
@ -658,9 +652,9 @@ static const luaL_Reg ll_funcs[] = {
static const lua_CFunction loaders[] =
{loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
LROT_PUBLIC_BEGIN(lmt)
LROT_FUNCENTRY(__gc,gctm)
LROT_END(lmt,lmt, LROT_MASK_GC)
LROT_BEGIN(lmt, NULL, LROT_MASK_GC)
LROT_FUNCENTRY( __gc, gctm )
LROT_END(lmt, NULL, LROT_MASK_GC)
LUALIB_API int luaopen_package (lua_State *L) {
int i;

View File

@ -1,3 +1,4 @@
/*
** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $
** Some generic functions over Lua objects
@ -7,7 +8,6 @@
#define lobject_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <stdio.h>
@ -25,7 +25,6 @@
#else
#include <limits.h>
#endif
const TValue luaO_nilobject_ = {LUA_TVALUE_NIL};
@ -54,7 +53,23 @@ int luaO_fb2int (int x) {
int luaO_log2 (unsigned int x) {
#ifdef LUA_CROSS_COMPILER
static const lu_byte log_2[256] = {
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
};
int l = -1;
while (x >= 256) { l += 8; x >>= 8; }
return l + log_2[x];
#else
return 31 - __builtin_clz(x);
#endif
}
@ -70,7 +85,7 @@ int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
case LUA_TLIGHTUSERDATA:
return pvalue(t1) == pvalue(t2);
case LUA_TROTABLE:
return rvalue(t1) == rvalue(t2);
return hvalue(t1) == hvalue(t2);
case LUA_TLIGHTFUNCTION:
return fvalue(t1) == fvalue(t2);
default:
@ -85,11 +100,11 @@ int luaO_str2d (const char *s, lua_Number *result) {
*result = lua_str2number(s, &endptr);
if (endptr == s) return 0; /* conversion failed */
if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
#if defined(LUA_CROSS_COMPILER)
#if defined(LUA_CROSS_COMPILER)
{
long lres = strtoul(s, &endptr, 16);
#if LONG_MAX != 2147483647L
if (lres & ~0xffffffffL)
#if INT_MAX != 2147483647L
if (lres & ~0xffffffffL)
*result = cast_num(-1);
else if (lres & 0x80000000L)
*result = cast_num(lres | ~0x7fffffffL);

View File

@ -17,7 +17,7 @@
/* tags for values visible from Lua */
#define LAST_TAG LUA_TTHREAD
#define NUM_TAGS (LAST_TAG+1)
#define LUA_NUMTAGS (LAST_TAG+1)
#define READONLYMASK (1<<7) /* denormalised bitmask for READONLYBIT and */
#define LFSMASK (1<<6) /* LFSBIT to avoid include proliferation */
@ -28,15 +28,18 @@
#define LUA_TUPVAL (LAST_TAG+2)
#define LUA_TDEADKEY (LAST_TAG+3)
#ifdef __XTENSA__
#ifdef LUA_USE_ESP8266
/*
** force aligned access to critical fields in Flash-based structures
** wo is the offset of aligned word in bytes 0,4,8,..
** bo is the field within the word in bits 0..31
**
** Note that this returns a lu_int32 as returning a byte can cause the
** gcc code generator to emit an extra extui instruction.
*/
#define GET_BYTE_FN(name,t,wo,bo) \
static inline lu_byte get ## name(void *o) { \
lu_byte res; /* extract named field */ \
static inline lu_int32 get ## name(void *o) { \
lu_int32 res; /* extract named field */ \
asm ("l32i %0, %1, " #wo "; extui %0, %0, " #bo ", 8;" : "=r"(res) : "r"(o) : );\
return res; }
#else
@ -49,14 +52,12 @@ static inline lu_byte get ## name(void *o) { return ((t *)o)->name; }
*/
typedef union GCObject GCObject;
/*
** Common Header for all collectable objects (in macro form, to be
** included in other objects)
*/
#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
/*
** Common header in struct form
*/
@ -93,43 +94,47 @@ typedef union {
#define TValuefields Value value; int tt
#define LUA_TVALUE_NIL {NULL}, LUA_TNIL
#if defined(LUA_PACK_TVALUES) && !defined(LUA_CROSS_COMPILER)
#pragma pack(4)
#ifdef LUA_USE_ESP
# pragma pack(4)
#endif
typedef struct lua_TValue {
TValuefields;
} TValue;
#if defined(LUA_PACK_TVALUES) && !defined(LUA_CROSS_COMPILER)
#pragma pack()
#ifdef LUA_USE_ESP
# pragma pack()
#endif
/* Macros to test type */
#define ttisnil(o) (ttype(o) == LUA_TNIL)
#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
#define ttisstring(o) (ttype(o) == LUA_TSTRING)
#define ttistable(o) (ttype(o) == LUA_TTABLE)
#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
#define ttisrotable(o) (ttype(o) == LUA_TROTABLE)
#define ttislightfunction(o) (ttype(o) == LUA_TLIGHTFUNCTION)
#define ttisnil(o) (ttype(o) == LUA_TNIL)
#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
#define ttisstring(o) (ttype(o) == LUA_TSTRING)
#define ttistable(o) (ttnov(o) == LUA_TTABLE)
#define ttisrwtable(o) (type(o) == LUA_TTABLE)
#define ttisrotable(o) (ttype(o) & LUA_TISROTABLE)
#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
#define ttislightfunction(o) (ttype(o) == LUA_TLIGHTFUNCTION)
#define ttisclfunction(o) (ttype(o) == LUA_TFUNCTION)
#define ttisfunction(o) (ttnov(o) == LUA_TFUNCTION)
/* Macros to access values */
#define ttype(o) ((void) (o)->value, (o)->tt)
#define ttnov(o) ((void) (o)->value, ((o)->tt & LUA_TMASK))
#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
#define rvalue(o) check_exp(ttisrotable(o), (o)->value.p)
#define fvalue(o) check_exp(ttislightfunction(o), (o)->value.p)
#define fvalue(o) check_exp(ttislightfunction(o), (o)->value.p)
#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
#define tsvalue(o) (&rawtsvalue(o)->tsv)
#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
#define uvalue(o) (&rawuvalue(o)->uv)
#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl)
#define clvalue(o) check_exp(ttisclfunction(o), &(o)->value.gc->cl)
#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h)
#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b)
#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th)
@ -156,9 +161,6 @@ typedef struct lua_TValue {
#define setpvalue(obj,x) \
{ void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TLIGHTUSERDATA; }
#define setrvalue(obj,x) \
{ void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TROTABLE; }
#define setfvalue(obj,x) \
{ void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TLIGHTFUNCTION; }
@ -192,7 +194,7 @@ typedef struct lua_TValue {
#define sethvalue(L,obj,x) \
{ GCObject *i_x = cast(GCObject *, (x)); \
TValue *i_o=(obj); \
i_o->value.gc=i_x; i_o->tt=LUA_TTABLE; \
i_o->value.gc=i_x; i_o->tt=gettt(x); \
checkliveness(G(L),i_o); }
#define setptvalue(L,obj,x) \
@ -227,7 +229,7 @@ typedef struct lua_TValue {
#define setttype(obj, stt) ((void) (obj)->value, (obj)->tt = (stt))
#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
#define iscollectable(o) (ttype(o) >= LUA_TSTRING && ttype(o) <= LUA_TMASK)
typedef TValue *StkId; /* index to stack elements */
@ -245,19 +247,10 @@ typedef union TString {
} tsv;
} TString;
#ifdef LUA_CROSS_COMPILER
#define isreadonly(o) (0)
#else
#define isreadonly(o) ((o).marked & READONLYMASK)
#endif
#define ts_isreadonly(ts) isreadonly((ts)->tsv)
#define getstr(ts) (ts_isreadonly(ts) ? \
cast(const char *, *(const char**)((ts) + 1)) : \
cast(const char *, (ts) + 1))
#define getstr(ts) cast(const char *, (ts) + 1)
#define svalue(o) getstr(rawtsvalue(o))
typedef union Udata {
L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
struct {
@ -268,7 +261,12 @@ typedef union Udata {
} uv;
} Udata;
#ifdef LUA_CROSS_COMPILER
#define isreadonly(o) (0)
#else
#define isreadonly(o) (getmarked(o) & READONLYMASK)
#endif
#define islfs(o) (getmarked(o) & LFSMASK)
/*
@ -279,20 +277,13 @@ typedef struct Proto {
TValue *k; /* constants used by the function */
Instruction *code;
struct Proto **p; /* functions defined inside the function */
#ifdef LUA_OPTIMIZE_DEBUG
unsigned char *packedlineinfo;
#else
int *lineinfo; /* map from opcodes to source lines */
#endif
struct LocVar *locvars; /* information about local variables */
TString **upvalues; /* upvalue names */
TString *source;
int sizeupvalues;
int sizek; /* size of `k' */
int sizecode;
#ifndef LUA_OPTIMIZE_DEBUG
int sizelineinfo;
#endif
int sizep; /* size of `p' */
int sizelocvars;
int linedefined;
@ -303,7 +294,6 @@ typedef struct Proto {
lu_byte is_vararg;
lu_byte maxstacksize;
} Proto;
#define proto_isreadonly(p) isreadonly(*(p))
/* masks for new-style vararg */
@ -373,6 +363,18 @@ typedef union Closure {
** Tables
*/
/*
** Common Table fields for both table versions (like CommonHeader in
** macro form, to be included in table structure definitions).
**
** Note that the sethvalue() macro works much like the setsvalue()
** macro and handles the abstracted type. the hvalue(o) macro can be
** used to access CommonTable fields and rw Table fields
*/
#define CommonTable CommonHeader; \
lu_byte flags; lu_byte lsizenode; struct Table *metatable
typedef union TKey {
struct {
TValuefields;
@ -390,10 +392,7 @@ typedef struct Node {
typedef struct Table {
CommonHeader;
lu_byte flags; /* 1<<p means tagmethod(p) is not present */
lu_byte lsizenode; /* log2 of size of `node' array */
struct Table *metatable;
CommonTable;
TValue *array; /* array part */
Node *node;
Node *lastfree; /* any free position is before this position */
@ -401,7 +400,23 @@ typedef struct Table {
int sizearray; /* size of `array' array */
} Table;
typedef const struct luaR_entry ROTable;
GET_BYTE_FN(flags,Table,4,16)
GET_BYTE_FN(lsizenode,Table,4,24)
typedef const struct ROTable_entry {
const char *key;
const TValue value;
} ROTable_entry;
typedef struct ROTable {
/* next always has the value (GCObject *)((size_t) 1); */
/* flags & 1<<p means tagmethod(p) is not present */
/* lsizenode is unused */
/* Like TStrings, the ROTable_entry vector follows the ROTable */
CommonTable;
ROTable_entry *entry;
} ROTable;
/*
** `module' operation for hashing (size is always a power of 2)

View File

@ -6,9 +6,7 @@
#define lopcodes_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "luac_cross.h"
#include "lopcodes.h"
/* ORDER OP */

View File

@ -186,8 +186,8 @@ OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
@ -197,8 +197,8 @@ OP_FORLOOP,/* A sBx R(A)+=R(A+2);
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
@ -240,7 +240,7 @@ OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
** bits 4-5: B arg mode
** bit 6: instruction set register A
** bit 7: operator is a test
*/
*/
enum OpArgMask {
OpArgN, /* argument is not used */

View File

@ -7,7 +7,6 @@
#define lparser_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
@ -344,12 +343,10 @@ static void open_func (LexState *ls, FuncState *fs) {
fs->bl = NULL;
f->source = ls->source;
f->maxstacksize = 2; /* registers 0/1 are always valid */
#ifdef LUA_OPTIMIZE_DEBUG
fs->packedlineinfoSize = 0;
fs->lastline = 0;
fs->lastlineOffset = 0;
fs->lineinfoLastPC = -1;
#endif
fs->h = luaH_new(L, 0, 0);
/* anchor table of constants and prototype (to avoid being collected) */
sethvalue2s(L, L->top, fs->h);
@ -367,15 +364,9 @@ static void close_func (LexState *ls) {
luaK_ret(fs, 0, 0); /* final return */
luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
f->sizecode = fs->pc;
#ifdef LUA_OPTIMIZE_DEBUG
f->packedlineinfo[fs->lastlineOffset+1]=0;
luaM_reallocvector(L, f->packedlineinfo, fs->packedlineinfoSize,
fs->lastlineOffset+2, unsigned char);
#else
luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
f->sizelineinfo = fs->pc;
#endif
luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
f->sizek = fs->nk;
luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
@ -392,20 +383,11 @@ static void close_func (LexState *ls) {
L->top -= 2; /* remove table and prototype from the stack */
}
#ifdef LUA_OPTIMIZE_DEBUG
static void compile_stripdebug(lua_State *L, Proto *f) {
int level;
lua_pushlightuserdata(L, &luaG_stripdebug );
lua_gettable(L, LUA_REGISTRYINDEX);
level = lua_isnil(L, -1) ? LUA_OPTIMIZE_DEBUG : lua_tointeger(L, -1);
lua_pop(L, 1);
if (level > 1) {
int len = luaG_stripdebug(L, f, level, 1);
UNUSED(len);
}
int level = G(L)->stripdefault;
if (level > 0)
luaG_stripdebug(L, f, level, 1);
}
#endif
Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
@ -422,9 +404,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
chunk(&lexstate);
check(&lexstate, TK_EOS);
close_func(&lexstate);
#ifdef LUA_OPTIMIZE_DEBUG
compile_stripdebug(L, funcstate.f);
#endif
L->top--; /* remove 'name' from stack */
lua_assert(funcstate.prev == NULL);
lua_assert(funcstate.f->nups == 0);

View File

@ -72,12 +72,10 @@ typedef struct FuncState {
lu_byte nactvar; /* number of active local variables */
upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
#ifdef LUA_OPTIMIZE_DEBUG
int packedlineinfoSize; /* only used during compilation for line info */
int lastline; /* ditto */
int lastlineOffset; /* ditto */
int lineinfoLastPC; /* ditto */
#endif
} FuncState;

View File

@ -7,7 +7,6 @@
#define lstate_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
@ -35,7 +34,7 @@ typedef struct LG {
lua_State l;
global_State g;
} LG;
static void stack_init (lua_State *L1, lua_State *L) {
@ -185,6 +184,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->memlimit = 0;
g->gcpause = LUAI_GCPAUSE;
g->gcstepmul = LUAI_GCMUL;
g->stripdefault = CONFIG_LUA_OPTIMIZE_DEBUG;
g->gcdept = 0;
#ifdef EGC_INITIAL_MODE
g->egcmode = EGC_INITIAL_MODE;
@ -197,13 +197,14 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->memlimit = 0;
#endif
#ifndef LUA_CROSS_COMPILER
g->ROstrt.size = 0;
g->ROstrt.nuse = 0;
g->ROstrt.hash = NULL;
g->ROpvmain = NULL;
g->LFSsize = 0;
g->ROstrt.size = 0;
g->ROstrt.nuse = 0;
g->ROstrt.hash = NULL;
g->ROpvmain = NULL;
g->LFSsize = 0;
g->error_reporter = 0;
#endif
for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL;
for (i=0; i<LUA_NUMTAGS; i++) g->mt[i] = NULL;
if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
/* memory allocation error: free partial state */
close_state(L);
@ -225,20 +226,17 @@ extern lua_State *luaL_newstate (void);
static lua_State *lua_crtstate;
lua_State *lua_open(void) {
lua_crtstate = luaL_newstate();
lua_crtstate = luaL_newstate();
return lua_crtstate;
}
lua_State *lua_getstate(void) {
return lua_crtstate;
}
LUA_API void lua_close (lua_State *L) {
#ifndef LUA_CROSS_COMPILER
#ifndef LUA_CROSS_COMPILER
lua_sethook( L, NULL, 0, 0 );
lua_crtstate = NULL;
lua_pushnil( L );
// lua_rawseti( L, LUA_REGISTRYINDEX, LUA_INT_HANDLER_KEY );
#endif
#endif
L = G(L)->mainthread; /* only the main thread can be closed */
lua_lock(L);
luaF_close(L, L->stack); /* close all upvalues for this thread */

View File

@ -56,7 +56,7 @@ typedef struct CallInfo {
#define curr_func(L) (ttisfunction(L->ci->func) ? clvalue(L->ci->func) : NULL)
#define curr_func(L) (ttisclfunction(L->ci->func) ? clvalue(L->ci->func) : NULL)
#define ci_func(ci) (ttisfunction((ci)->func) ? clvalue((ci)->func) : NULL)
#define f_isLua(ci) (!ttislightfunction((ci)->func) && !ci_func(ci)->c.isC)
#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
@ -87,17 +87,19 @@ typedef struct global_State {
lu_mem gcdept; /* how much GC is `behind schedule' */
int gcpause; /* size of pause between successive GCs */
int gcstepmul; /* GC `granularity' */
int stripdefault; /* default stripping level for compilation */
int egcmode; /* emergency garbage collection operation mode */
lua_CFunction panic; /* to be called in unprotected errors */
TValue l_registry;
struct lua_State *mainthread;
UpVal uvhead; /* head of double-linked list of all open upvalues */
struct Table *mt[NUM_TAGS]; /* metatables for basic types */
struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
TString *tmname[TM_N]; /* array with tag-method names */
#ifndef LUA_CROSS_COMPILER
stringtable ROstrt; /* Flash-based hash table for RO strings */
Proto *ROpvmain; /* Flash-based Proto main */
int LFSsize; /* Size of Lua Flash Store */
int error_reporter; /* Registry Index of error reporter task */
#endif
} global_State;
@ -159,7 +161,7 @@ union GCObject {
#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
#define gco2u(o) (&rawgco2u(o)->uv)
#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
#define gco2h(o) check_exp(((o)->gch.tt & LUA_TMASK) == LUA_TTABLE, &((o)->h))
#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
#define ngcotouv(o) \

View File

@ -8,7 +8,6 @@
#define lstring_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
@ -18,8 +17,6 @@
#include "lstate.h"
#include "lstring.h"
#define LUAS_READONLY_STRING 1
#define LUAS_REGULAR_STRING 0
void luaS_resize (lua_State *L, int newsize) {
stringtable *tb;
@ -53,26 +50,20 @@ void luaS_resize (lua_State *L, int newsize) {
}
static TString *newlstr (lua_State *L, const char *str, size_t l,
unsigned int h, int readonly) {
unsigned int h) {
TString *ts;
stringtable *tb;
stringtable *tb = &G(L)->strt;
if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
luaM_toobig(L);
tb = &G(L)->strt;
if ((tb->nuse + 1) > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
luaS_resize(L, tb->size*2); /* too crowded */
ts = cast(TString *, luaM_malloc(L, sizeof(TString) + (readonly ? sizeof(char**) : (l+1)*sizeof(char))));
ts = cast(TString *, luaM_malloc(L, sizeof(TString) + (l+1)*sizeof(char)));
ts->tsv.len = l;
ts->tsv.hash = h;
ts->tsv.marked = luaC_white(G(L));
ts->tsv.tt = LUA_TSTRING;
if (!readonly) {
memcpy(ts+1, str, l*sizeof(char));
((char *)(ts+1))[l] = '\0'; /* ending 0 */
} else {
*(char **)(ts+1) = (char *)str;
l_setbit((ts)->tsv.marked, READONLYBIT);
}
memcpy(ts+1, str, l*sizeof(char));
((char *)(ts+1))[l] = '\0'; /* ending 0 */
h = lmod(h, tb->size);
ts->tsv.next = tb->hash[h]; /* chain new entry */
tb->hash[h] = obj2gco(ts);
@ -80,15 +71,6 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
return ts;
}
static int lua_is_ptr_in_ro_area(const char *p) {
#ifdef LUA_CROSS_COMPILER
(void)p;
return 0; // TStrings are never in RO in luac.cross
#else
return IN_RODATA_AREA(p);
#endif
}
/*
* The string algorithm has been modified to be LFS-friendly. The previous eLua
* algo used the address of the string was in flash and the string was >4 bytes
@ -129,11 +111,7 @@ LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
}
}
#endif
/* New additions to the RAM strt are tagged as readonly if the string address
* is in the CTEXT segment (target only, not luac.cross) */
int readonly = (lua_is_ptr_in_ro_area(str) && l+1 > sizeof(char**) &&
l == strlen(str) ? LUAS_READONLY_STRING : LUAS_REGULAR_STRING);
return newlstr(L, str, l, h, readonly); /* not found */
return newlstr(L, str, l, h); /* not found */
}

View File

@ -13,8 +13,7 @@
#include "lstate.h"
#define sizestring(s) (sizeof(union TString)+(testbit(getmarked(s), READONLYBIT) ? sizeof(char **) : ((s)->len+1)*sizeof(char)))
#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char))
#define sizeudata(u) (sizeof(union Udata)+(u)->len)
#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))

View File

@ -7,7 +7,6 @@
#define lstrlib_c
#define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h"
#include <stdio.h>
@ -15,13 +14,11 @@
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
/* macro to `unsign' a character */
#define uchar(c) ((unsigned char)(c))
static int str_len (lua_State *L) {
size_t l;
luaL_checklstring(L, 1, &l);
@ -143,17 +140,25 @@ static int writer (lua_State *L, const void* b, size_t size, void* B) {
static int str_dump (lua_State *L) {
luaL_Buffer b;
int strip, tstrip = lua_type(L, 2);
if (tstrip == LUA_TBOOLEAN) {
strip = lua_toboolean(L, 2) ? 2 : 0;
} else if (tstrip == LUA_TNONE || tstrip == LUA_TNIL) {
strip = -1; /* This tells lua_dump to use the global strip default */
} else {
strip = lua_tointeger(L, 2);
luaL_argcheck(L, (unsigned)(strip) < 3, 2, "strip out of range");
}
luaL_checktype(L, 1, LUA_TFUNCTION);
lua_settop(L, 1);
luaL_buffinit(L,&b);
if (lua_dump(L, writer, &b) != 0)
luaL_error(L, "unable to dump given function");
if (lua_dump(L, writer, &b, strip) != 0)
return luaL_error(L, "unable to dump given function");
luaL_pushresult(&b);
return 1;
}
/*
** {======================================================
** PATTERN MATCHING
@ -634,7 +639,7 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
lua_pushlstring(L, s, e - s); /* keep original text */
}
else if (!lua_isstring(L, -1))
luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
luaL_addvalue(b); /* add result to accumulator */
}
@ -787,7 +792,7 @@ static int str_format (lua_State *L) {
sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
break;
}
#if !defined LUA_NUMBER_INTEGRAL
#if !defined LUA_NUMBER_INTEGRAL
case 'e': case 'E': case 'f':
case 'g': case 'G': {
sprintf(buff, form, (double)luaL_checknumber(L, arg));
@ -825,7 +830,21 @@ static int str_format (lua_State *L) {
return 1;
}
LROT_PUBLIC_BEGIN(strlib)
static int str_format2 (lua_State *L) {
if (lua_type(L, 2) == LUA_TTABLE) {
int i,n=lua_objlen(L,2);
lua_settop(L,2);
for (i = 1; i <= n; i++)
lua_rawgeti(L, 2, i);
lua_remove(L, 2);
}
return str_format(L);
}
LROT_BEGIN(strlib, NULL, LROT_MASK_INDEX)
LROT_TABENTRY( __index, strlib )
LROT_FUNCENTRY( __mod, str_format2 )
LROT_FUNCENTRY( byte, str_byte )
LROT_FUNCENTRY( char, str_char )
LROT_FUNCENTRY( dump, str_dump )
@ -845,8 +864,7 @@ LROT_PUBLIC_BEGIN(strlib)
LROT_FUNCENTRY( reverse, str_reverse )
LROT_FUNCENTRY( sub, str_sub )
LROT_FUNCENTRY( upper, str_upper )
LROT_TABENTRY( __index, strlib )
LROT_END(strlib, NULL, 0) // OR DO WE NEED LRTO_MASK_INDEX **TODO**
LROT_END(strlib, NULL, LROT_MASK_INDEX)
/*
** Open string library

View File

@ -20,7 +20,6 @@
#define ltable_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <math.h>
@ -33,7 +32,8 @@
#include "lobject.h"
#include "lstate.h"
#include "ltable.h"
#include "lrotable.h"
#include "lstring.h"
/*
** max size of array part is 2^MAXBITS
@ -48,7 +48,7 @@
#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
#define hashboolean(t,p) hashpow2(t, p)
@ -68,6 +68,10 @@
*/
#define numints cast_int(sizeof(lua_Number)/sizeof(int))
static const TValue* rotable_findentry(ROTable *rotable, TString *key, unsigned *ppos);
static void rotable_next_helper(lua_State *L, ROTable *pentries, int pos,
TValue *key, TValue *val);
static void rotable_next(lua_State *L, ROTable *rotable, TValue *key, TValue *val);
#define dummynode (&dummynode_)
@ -105,11 +109,11 @@ static Node *mainposition (const Table *t, const TValue *key) {
return hashstr(t, rawtsvalue(key));
case LUA_TBOOLEAN:
return hashboolean(t, bvalue(key));
case LUA_TROTABLE:
return hashpointer(t, rvalue(key));
case LUA_TLIGHTUSERDATA:
case LUA_TLIGHTFUNCTION:
return hashpointer(t, pvalue(key));
case LUA_TROTABLE:
return hashpointer(t, hvalue(key));
default:
return hashpointer(t, gcvalue(key));
}
@ -163,7 +167,12 @@ static int findindex (lua_State *L, Table *t, StkId key) {
int luaH_next (lua_State *L, Table *t, StkId key) {
int i = findindex(L, t, key); /* find original element */
int i;
if (isrotable(t)) {
rotable_next(L, (ROTable *) t, key, key+1);
return ttisnil(key) ? 0 : 1;
}
i = findindex(L, t, key); /* find original element */
for (i++; i < t->sizearray; i++) { /* try first array part */
if (!ttisnil(&t->array[i])) { /* a non-nil value? */
setnvalue(key, cast_num(i+1));
@ -182,12 +191,6 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
}
int luaH_next_ro (lua_State *L, void *t, StkId key) {
luaR_next(L, t, key, key+1);
return ttisnil(key) ? 0 : 1;
}
/*
** {=============================================================
** Rehash
@ -330,7 +333,7 @@ static Node *find_prev_node(Node *mp, Node *next) {
** first, check whether the moving node's main position is free. If not, check whether
** colliding node is in its main position or not: if it is not, move colliding
** node to an empty place and put moving node in its main position; otherwise
** (colliding node is in its main position), moving node goes to an empty position.
** (colliding node is in its main position), moving node goes to an empty position.
*/
static int move_node (lua_State *L, Table *t, Node *node) {
(void)L;
@ -372,7 +375,7 @@ static int move_node (lua_State *L, Table *t, Node *node) {
static int move_number (lua_State *L, Table *t, Node *node) {
(void)L; (void)t;
(void)L;
int key;
lua_Number n = nvalue(key2tval(node));
lua_number2int(key, n);
@ -565,6 +568,8 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
** search function for integers
*/
const TValue *luaH_getnum (Table *t, int key) {
if (isrotable(t))
return luaO_nilobject;
/* (1 <= key && key <= t->sizearray) */
if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
return &t->array[key-1];
@ -580,18 +585,16 @@ const TValue *luaH_getnum (Table *t, int key) {
}
}
/* same thing for rotables */
const TValue *luaH_getnum_ro (void *t, int key) {
(void)t; (void)key;
const TValue *res = NULL; // integer values not supported: luaR_findentryN(t, key, NULL);
return res ? res : luaO_nilobject;
}
/*
** search function for strings
*/
const TValue *luaH_getstr (Table *t, TString *key) {
if (isrotable(t)) {
if (key->tsv.len>LUA_MAX_ROTABLE_NAME)
return luaO_nilobject;
return rotable_findentry((ROTable*) t, key, NULL);
}
Node *n = hashstr(t, key);
do { /* check whether `key' is somewhere in the chain */
if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key)
@ -601,65 +604,41 @@ const TValue *luaH_getstr (Table *t, TString *key) {
return luaO_nilobject;
}
/* same thing for rotables */
const TValue *luaH_getstr_ro (void *t, TString *key) {
if (!t || key->tsv.len>LUA_MAX_ROTABLE_NAME)
return luaO_nilobject;
return luaR_findentry(t, key, NULL);
}
/*
** main search function
*/
const TValue *luaH_get (Table *t, const TValue *key) {
switch (ttype(key)) {
case LUA_TNIL: return luaO_nilobject;
case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
case LUA_TNUMBER: {
int k;
lua_Number n = nvalue(key);
lua_number2int(k, n);
if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
return luaH_getnum(t, k); /* use specialized version */
/* else go through */
}
/* fall-through */
default: {
Node *n = mainposition(t, key);
do { /* check whether `key' is somewhere in the chain */
if (luaO_rawequalObj(key2tval(n), key))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
return luaO_nilobject;
}
}
}
/* same thing for rotables */
const TValue *luaH_get_ro (void *t, const TValue *key) {
switch (ttype(key)) {
case LUA_TNIL: return luaO_nilobject;
case LUA_TSTRING: return luaH_getstr_ro(t, rawtsvalue(key));
case LUA_TNUMBER: {
int k;
lua_Number n = nvalue(key);
lua_number2int(k, n);
if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
return luaH_getnum_ro(t, k); /* use specialized version */
/* else go through */
}
/* fall-through */
default: {
return luaO_nilobject;
}
int type = ttype(key);
if (type == LUA_TNIL)
return luaO_nilobject;
if (type == LUA_TSTRING)
return luaH_getstr(t, rawtsvalue(key));
if (isrotable(t))
return luaO_nilobject;
if (type == LUA_TNUMBER) {
int k;
lua_Number n = nvalue(key);
lua_number2int(k, n);
if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
return luaH_getnum(t, k); /* use specialized version */
}
/* default */
Node *n = mainposition(t, key);
do { /* check whether `key' is somewhere in the chain */
if (luaO_rawequalObj(key2tval(n), key))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
return luaO_nilobject;
}
TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
const TValue *p = luaH_get(t, key);
const TValue *p;
if (isrotable(t))
luaG_runerror(L, "table is readonly");
p = luaH_get(t, key);
t->flags = 0;
if (p != luaO_nilobject)
return cast(TValue *, p);
@ -673,7 +652,10 @@ TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
TValue *luaH_setnum (lua_State *L, Table *t, int key) {
const TValue *p = luaH_getnum(t, key);
const TValue *p;
if (isrotable(t))
luaG_runerror(L, "table is readonly");
p = luaH_getnum(t, key);
if (p != luaO_nilobject)
return cast(TValue *, p);
else {
@ -685,7 +667,10 @@ TValue *luaH_setnum (lua_State *L, Table *t, int key) {
TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
const TValue *p = luaH_getstr(t, key);
const TValue *p;
if (isrotable(t))
luaG_runerror(L, "table is readonly");
p = luaH_getstr(t, key);
if (p != luaO_nilobject)
return cast(TValue *, p);
else {
@ -725,7 +710,10 @@ static int unbound_search (Table *t, unsigned int j) {
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
*/
int luaH_getn (Table *t) {
unsigned int j = t->sizearray;
unsigned int j;
if(isrotable(t))
return 0;
j = t->sizearray;
if (j > 0 && ttisnil(&t->array[j - 1])) {
/* there is a boundary in the array part: (binary) search for it */
unsigned int i = 0;
@ -742,14 +730,138 @@ int luaH_getn (Table *t) {
else return unbound_search(t, j);
}
/* same thing for rotables */
int luaH_getn_ro (void *t) {
(void)t;
return 0; // Integer Keys are not currently supported for ROTables
}
int luaH_isdummy (Node *n) { return n == dummynode; }
/*
** All keyed ROTable access passes through rotable_findentry(). ROTables
** are simply a list of <key><TValue value> pairs.
**
** The global KeyCache is used to avoid a relatively expensive Flash memory
** vector scan. A simple hash on the key's TString addr and the ROTable
** addr selects the cache line. The line's slots are then scanned for a
** hit.
**
** Unlike the standard hast which uses a prime line count therefore requires
** the use of modulus operation which is expensive on an IoT processor
** without H/W divide. This hash is power of 2 based which might not be
** quite so uniform but can be calcuated without using H/W-based instructions.
**
** If a match is found and the table addresses match, then this entry is
** probed first. In practice the hit-rate here is over 99% so the code
** rarely fails back to doing the linear scan in ROM.
** Note that this hash does a couple of prime multiples and a modulus 2^X
** with is all evaluated in H/W, and adequately randomizes the lookup.
*/
#define LA_LINES 32
#define LA_SLOTS 4
static size_t cache [LA_LINES][LA_SLOTS];
#define HASH(a,b) ((((29*(size_t)(a)) ^ (37*((b)->tsv.hash)))>>4) % LA_LINES)
#define NDX_SHFT 24
#define ADDR_MASK (((size_t) 1<<24)-1)
/*
* Find a string key entry in a rotable and return it. Note that this internally
* uses a null key to denote a metatable search.
*/
static const TValue* rotable_findentry(ROTable *t, TString *key, unsigned *ppos) {
const ROTable_entry *e = cast(const ROTable_entry *, t->entry);
const int tl = getlsizenode(t);
const char *strkey = getstr(key);
size_t *cl = cache[HASH(t, key)];
int i, j = 1, l;
if (!e || gettt(key) != LUA_TSTRING)
return luaO_nilobject;
l = key->tsv.len;
/* scan the ROTable lookaside cache and return if hit found */
for (i=0; i<LA_SLOTS; i++) {
int cl_ndx = cl[i] >> NDX_SHFT;
if ((((size_t)t - cl[i]) & ADDR_MASK) == 0 && cl_ndx < tl &&
strcmp(e[cl_ndx].key, strkey) == 0) {
if (ppos)
*ppos = cl_ndx;
return &e[cl_ndx].value;
}
}
/*
* A lot of search misses are metavalues, but tables typically only have at
* most a couple of them, so these are always put at the front of the table
* in ascending order and the metavalue scan short circuits using a straight
* strcmp()
*/
lu_int32 name4 = *(lu_int32 *) strkey;
if (*(char*)&name4 == '_') {
for(i = 0; i < tl; i++) {
j = strcmp(e[i].key, strkey);
if (j>=0)
break;
}
} else {
/*
* Ordinary (non-meta) keys can be unsorted. This is for legacy compatiblity,
* plus misses are pretty rare in this case. The masked name4 comparison is
* safe 4-byte comparison that nearly always avoids the more costly strcmp()
* for an actual hit validation.
*/
lu_int32 mask4 = l > 2 ? (~0u) : (~0u)>>((3-l)*8);
for(i = 0; i < tl; i++) {
if (((*(lu_int32 *)e[i].key ^ name4) & mask4) != 0)
continue;
j = strcmp(e[i].key, strkey);
if (j==0)
break;
}
}
if (j)
return luaO_nilobject;
if (ppos)
*ppos = i;
/* In the case of a hit, update the lookaside cache */
for (j = LA_SLOTS-1; j>0; j--)
cl[j] = cl[j-1];
cl[0] = ((size_t)t & ADDR_MASK) + (i << NDX_SHFT);
return &e[i].value;
}
static void rotable_next_helper(lua_State *L, ROTable *t, int pos,
TValue *key, TValue *val) {
const ROTable_entry *e = cast(const ROTable_entry *, t->entry);
if (pos < getlsizenode(t)) {
/* Found an entry */
setsvalue(L, key, luaS_new(L, e[pos].key));
setobj2s(L, val, &e[pos].value);
} else {
setnilvalue(key);
setnilvalue(val);
}
}
/* next (used for iteration) */
static void rotable_next(lua_State *L, ROTable *t, TValue *key, TValue *val) {
unsigned keypos = getlsizenode(t);
/* Special case: if key is nil, return the first element of the rotable */
if (ttisnil(key))
rotable_next_helper(L, t, 0, key, val);
else if (ttisstring(key)) {
/* Find the previous key again */
if (ttisstring(key)) {
rotable_findentry(t, rawtsvalue(key), &keypos);
}
/* Advance to next key */
rotable_next_helper(L, t, ++keypos, key, val);
}
}
#if defined(LUA_DEBUG)
Node *luaH_mainposition (const Table *t, const TValue *key) {
return mainposition(t, key);

View File

@ -16,26 +16,24 @@
#define gnext(n) ((n)->i_key.nk.next)
#define key2tval(n) (&(n)->i_key.tvk)
#define isrotable(t) (gettt(t)==LUA_TROTABLE)
#define isrwtable(t) (gettt(t)==LUA_TTABLE)
LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
LUAI_FUNC const TValue *luaH_getnum_ro (void *t, int key);
LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
LUAI_FUNC const TValue *luaH_getstr_ro (void *t, TString *key);
LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
LUAI_FUNC const TValue *luaH_get_ro (void *t, const TValue *key);
LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash);
LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
LUAI_FUNC void luaH_free (lua_State *L, Table *t);
LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
LUAI_FUNC int luaH_next_ro (lua_State *L, void *t, StkId key);
LUAI_FUNC int luaH_getn (Table *t);
LUAI_FUNC int luaH_getn_ro (void *t);
LUAI_FUNC int luaH_isdummy (Node *n);
#define LUA_MAX_ROTABLE_NAME 32
#if defined(LUA_DEBUG)
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
#endif

View File

@ -7,13 +7,11 @@
#define ltablib_c
#define LUA_LIB
#define LUAC_CROSS_FILE
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
@ -22,7 +20,7 @@
static int foreachi (lua_State *L) {
int i;
int n = aux_getn(L, 1);
luaL_checkanyfunction(L, 2);
luaL_checkfunction(L, 2);
for (i=1; i <= n; i++) {
lua_pushvalue(L, 2); /* function */
lua_pushinteger(L, i); /* 1st argument */
@ -38,7 +36,7 @@ static int foreachi (lua_State *L) {
static int foreach (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkanyfunction(L, 2);
luaL_checkfunction(L, 2);
lua_pushnil(L); /* first key */
while (lua_next(L, 1)) {
lua_pushvalue(L, 2); /* function */
@ -266,7 +264,7 @@ static int sort (lua_State *L) {
/* }====================================================== */
LROT_PUBLIC_BEGIN(tab_funcs)
LROT_BEGIN(tab_funcs, NULL, 0)
LROT_FUNCENTRY( concat, tconcat )
LROT_FUNCENTRY( foreach, foreach )
LROT_FUNCENTRY( foreachi, foreachi )

View File

@ -5,37 +5,35 @@
*/
#include <string.h>
#define ltm_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
#include "lobject.h"
#include "lstate.h"
#include "lgc.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lrotable.h"
/* These must be correspond to the LUA_T* defines in lua.h */
const char *const luaT_typenames[] = {
"nil", "boolean", "romtable", "lightfunction", "userdata", "number",
"string", "table", "function", "userdata", "thread",
"nil", "boolean", "lightfunction","number", // base type = 0, 1, 2, 3
"string", "table", "function", "userdata", "thread", // base type = 4, 5, 6, 7, 8
"proto", "upval"
};
void luaT_init (lua_State *L) {
static const char *const luaT_eventname[] = { /* ORDER TM */
"__index", "__newindex",
"__gc", "__mode", "__eq",
"__add", "__sub", "__mul", "__div", "__mod",
"__pow", "__unm", "__len", "__lt", "__le",
"__concat", "__call"
"__concat", "__call",
"__metatable"
};
int i;
for (i=0; i<TM_N; i++) {
@ -50,22 +48,14 @@ void luaT_init (lua_State *L) {
** tag methods
*/
const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
const TValue *tm;
const TValue *tm = luaH_getstr(events, ename);
lua_assert(event <= TM_EQ);
if (luaR_isrotable(events)) {
tm = luaH_getstr_ro(events, ename);
if (ttisnil(tm)) { /* no tag method? */
if (isrwtable(events)) /* if this a (RW) Table */
events->flags |= cast_byte(1u<<event); /* then cache this fact */
return NULL;
}
} else {
tm = luaH_getstr(events, ename);
if (ttisnil(tm)) { /* no tag method? */
events->flags |= cast_byte(1u<<event); /* cache this fact */
return NULL;
}
}
return tm;
else return tm;
}
@ -73,21 +63,14 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
Table *mt;
switch (ttype(o)) {
case LUA_TTABLE:
mt = hvalue(o)->metatable;
break;
case LUA_TROTABLE:
mt = (Table*)luaR_getmeta(rvalue(o));
mt = hvalue(o)->metatable;
break;
case LUA_TUSERDATA:
mt = uvalue(o)->metatable;
break;
default:
mt = G(L)->mt[ttype(o)];
mt = G(L)->mt[ttnov(o)];
}
if (!mt)
return luaO_nilobject;
else if (luaR_isrotable(mt))
return luaH_getstr_ro(mt, G(L)->tmname[event]);
else
return luaH_getstr(mt, G(L)->tmname[event]);
return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
}

View File

@ -7,10 +7,6 @@
#ifndef ltm_h
#define ltm_h
#include "lobject.h"
#include "lrotable.h"
/*
* WARNING: if you change the order of this enumeration,
* grep "ORDER TM"
@ -33,13 +29,16 @@ typedef enum {
TM_LE,
TM_CONCAT,
TM_CALL,
TM_METATABLE,
TM_N /* number of elements in the enum */
} TMS;
#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
(!luaR_isrotable(et) && ((et)->flags & (1u<<(e)))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
//#include "lobject.h"
#define fasttm(l,et,e) gfasttm(G(l), et, e)
#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
(getflags(et) & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
#define fasttm(l,et,e) gfasttm(G(l), et, e)
LUAI_DATA const char *const luaT_typenames[];

View File

@ -0,0 +1,5 @@
#include "llimits.h"
#include "lauxlib.h"
#include "lualib.h"
#define LUA_VERSION_51
#include "../lua-5.3/lua.c"

View File

@ -8,13 +8,11 @@
#ifndef lua_h
#define lua_h
#ifdef LUAC_CROSS_FILE
#include "luac_cross.h"
#endif
#include <stdint.h>
#include <stdarg.h>
#include <stddef.h>
#include <ctype.h>
#include <stdbool.h>
#include "luaconf.h"
@ -41,7 +39,8 @@
#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
/* thread status; 0 is OK */
/* thread status */
#define LUA_OK 0
#define LUA_YIELD 1
#define LUA_ERRRUN 2
#define LUA_ERRSYNTAX 3
@ -72,18 +71,22 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
** basic types
*/
#define LUA_TNONE (-1)
#define LUA_TNIL 0
#define LUA_TBOOLEAN 1
#define LUA_TROTABLE 2
#define LUA_TLIGHTFUNCTION 3
#define LUA_TLIGHTUSERDATA 4
#define LUA_TNUMBER 5
#define LUA_TSTRING 6
#define LUA_TTABLE 7
#define LUA_TFUNCTION 8
#define LUA_TUSERDATA 9
#define LUA_TTHREAD 10
#define LUA_TLIGHTUSERDATA 2
#define LUA_TNUMBER 3
#define LUA_TSTRING 4
#define LUA_TTABLE 5
#define LUA_TFUNCTION 6
#define LUA_TUSERDATA 7
#define LUA_TTHREAD 8
#define LUA_TISROTABLE (1<<4)
#define LUA_TISLIGHTFUNC (1<<5)
#define LUA_TMASK 15
#define LUA_TROTABLE (LUA_TTABLE + LUA_TISROTABLE)
#define LUA_TLIGHTFUNCTION (LUA_TFUNCTION + LUA_TISLIGHTFUNC)
/* minimum Lua stack available to a C function */
#define LUA_MINSTACK 20
@ -96,18 +99,14 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
#include LUA_USER_H
#endif
#if defined(LUA_OPTIMIZE_DEBUG) && LUA_OPTIMIZE_DEBUG == 0
#undef LUA_OPTIMIZE_DEBUG
#endif
/* type of numbers in Lua */
typedef LUA_NUMBER lua_Number;
typedef LUA_FLOAT lua_Float;
/* type for integer functions */
typedef LUA_INTEGER lua_Integer;
typedef LUAI_UINT32 lua_Unsigned;
/*
** state manipulation
@ -122,6 +121,7 @@ LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
/*
** basic stack manipulation
*/
LUA_API int (lua_absindex) (lua_State *L, int idx);
LUA_API int (lua_gettop) (lua_State *L);
LUA_API void (lua_settop) (lua_State *L, int idx);
LUA_API void (lua_pushvalue) (lua_State *L, int idx);
@ -142,11 +142,14 @@ LUA_API int (lua_isstring) (lua_State *L, int idx);
LUA_API int (lua_iscfunction) (lua_State *L, int idx);
LUA_API int (lua_isuserdata) (lua_State *L, int idx);
LUA_API int (lua_type) (lua_State *L, int idx);
LUA_API int (lua_fulltype) (lua_State *L, int idx);
LUA_API const char *(lua_typename) (lua_State *L, int tp);
LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
#define LUA_OPEQ 0
#define LUA_OPLT 1
#define LUA_OPLE 2
LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op);
LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
@ -173,18 +176,17 @@ LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
LUA_API void (lua_pushboolean) (lua_State *L, int b);
LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
LUA_API void (lua_pushlightfunction) (lua_State *L, void *p);
LUA_API void (lua_pushrotable) (lua_State *L, void *p);
LUA_API int (lua_pushthread) (lua_State *L);
/*
** get functions (Lua -> stack)
*/
LUA_API void (lua_gettable) (lua_State *L, int idx);
LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
LUA_API void (lua_rawget) (lua_State *L, int idx);
LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
LUA_API int (lua_gettable) (lua_State *L, int idx);
LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k);
LUA_API int (lua_rawget) (lua_State *L, int idx);
LUA_API int (lua_rawgeti) (lua_State *L, int idx, int n);
LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p);
LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
@ -198,6 +200,7 @@ LUA_API void (lua_settable) (lua_State *L, int idx);
LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
LUA_API void (lua_rawset) (lua_State *L, int idx);
LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p);
LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
LUA_API int (lua_setfenv) (lua_State *L, int idx);
@ -210,8 +213,8 @@ LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
const char *chunkname);
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int stripping);
LUA_API int (lua_stripdebug) (lua_State *L, int stripping);
/*
@ -271,10 +274,8 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
#define lua_strlen(L,i) lua_objlen(L, (i))
#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
#define lua_islightfunction(L,n) (lua_type(L, (n)) == LUA_TLIGHTFUNCTION)
#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
#define lua_isrotable(L,n) (lua_type(L, (n)) == LUA_TROTABLE)
#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
@ -289,14 +290,24 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ)
#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT)
#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n))
#define lua_tounsigned(L,i) ((lua_Unsigned)lua_tointeger(L,i))
/* error codes from cross-compiler returned by lua_dump */
/* target integer is too small to hold a value */
#define LUA_ERR_CC_INTOVERFLOW 101
/* target lua_Number is integral but a constant is non-integer */
#define LUA_ERR_CC_NOTINTEGER 102
/*
** compatibility macros and functions
*/
// BogdanM: modified for eLua interrupt support
//#define lua_open() luaL_newstate()
lua_State* lua_open(void);
lua_State* lua_getstate(void);
@ -372,24 +383,62 @@ struct lua_Debug {
int i_ci; /* active function */
};
int lua_main(void);
void lua_input_string (const char *line, int len);
/* }====================================================================== */
typedef struct __lua_load{
lua_State *L;
int firstline;
char *line;
int line_position;
size_t len;
int done;
const char *prmt;
}lua_Load;
/* NodeMCU extensions to the standard API */
int lua_main( int argc, char **argv );
typedef struct ROTable ROTable;
typedef const struct ROTable_entry ROTable_entry;
LUA_API void (lua_pushrotable) (lua_State *L, const ROTable *p);
LUA_API void (lua_createrotable) (lua_State *L, ROTable *t, ROTable_entry *e, ROTable *mt);
LUA_API int (lua_pushstringsarray) (lua_State *L, int opt);
LUA_API int (lua_freeheap) (void);
LUA_API void (lua_getlfsconfig) (lua_State *L, int *);
LUA_API int (lua_pushlfsindex) (lua_State *L);
#define EGC_NOT_ACTIVE 0 // EGC disabled
#define EGC_ON_ALLOC_FAILURE 1 // run EGC on allocation failure
#define EGC_ON_MEM_LIMIT 2 // run EGC when an upper memory limit is hit
#define EGC_ALWAYS 4 // always run EGC before an allocation
#ifdef LUA_USE_ESP
#define LUA_QUEUE_APP 0
#define LUA_QUEUE_UART 1
/**DEBUG**/extern void dbg_printf(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
#define luaN_freearray(L,b,l) luaM_freearray(L,b,l,sizeof(*b))
LUA_API void (lua_setegcmode) (lua_State *L, int mode, int limit);
LUA_API void (lua_getegcinfo) (lua_State *L, int *totals);
#else
#define ICACHE_RODATA_ATTR
#define dbg_printf printf
#ifndef LUA_CROSS_COMPILER
void lua_handle_input (bool force);
#endif
#ifdef DEVELOPMENT_USE_GDB
LUALIB_API void (lua_debugbreak)(void);
#else
#define lua_debugbreak() (void)(0)
#endif
// EGC operations modes
#define EGC_NOT_ACTIVE 0 // EGC disabled
#define EGC_ON_ALLOC_FAILURE 1 // run EGC on allocation failure
#define EGC_ON_MEM_LIMIT 2 // run EGC when an upper memory limit is hit
#define EGC_ALWAYS 4 // always run EGC before an allocation
void legc_set_mode(lua_State *L, int mode, int limit);
/******************************************************************************
* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
*

View File

@ -155,6 +155,11 @@
#define LUA_EXECDIR "!"
#define LUA_IGMARK "-"
#ifdef CONFIG_LUA_NUMBER_INTEGRAL
# define LUA_NUMBER_INTEGRAL
#else
# define LUA_PACK_TVALUES
#endif
/*
@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
@ -265,16 +270,6 @@
#endif
/*
@@ LUA_PROMPT is the default prompt used by stand-alone Lua.
@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua.
** CHANGE them if you want different prompts. (You can also change the
** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.)
*/
#define LUA_PROMPT "> "
#define LUA_PROMPT2 ">> "
/*
@@ LUA_PROGNAME is the default name for the stand-alone Lua program.
** CHANGE it if your stand-alone interpreter has a different name and
@ -299,54 +294,34 @@
** CHANGE them if you want to improve this functionality (e.g., by using
** GNU readline and history facilities).
*/
#if defined(LUA_USE_STDIO)
#if defined(LUA_CROSS_COMPILER) && defined(LUA_USE_READLINE)
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
#define lua_saveline(L,idx) \
if (lua_strlen(L,idx) > 0) /* non-empty line? */ \
add_history(lua_tostring(L, idx)); /* add it to history */
#define lua_freeline(L,b) ((void)L, free(b))
#else // #if defined(LUA_CROSS_COMPILER) && defined(LUA_USE_READLINE)
#define lua_readline(L,b,p) \
((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
#define lua_saveline(L,idx) { (void)L; (void)idx; }
#define lua_freeline(L,b) { (void)L; (void)b; }
#endif // #if defined(LUA_USE_READLINE)
#else // #if defined(LUA_USE_STDIO)
#define lua_readline(L,b,p) (readline4lua(p, b, LUA_MAXINPUT))
#define lua_saveline(L,idx) { (void)L; (void)idx; }
#define lua_freeline(L,b) { (void)L; (void)b; }
extern int readline4lua(const char *prompt, char *buffer, int length);
#endif // #if defined(LUA_USE_STDIO)
/*
@@ luai_writestring/luai_writeline define how 'print' prints its results.
@@ lua_writestring/lua_writeline define how 'print' prints its results.
** They are only used in libraries and the stand-alone program. (The #if
** avoids including 'stdio.h' everywhere.)
*/
#if !defined(LUA_USE_STDIO)
#define luai_writestring(s, l) fwrite(s, 1, l, stdout)
#define luai_writeline() puts("")
#endif // defined(LUA_USE_STDIO)
#ifdef LUA_USE_ESP
void output_redirect(const char *str, size_t l);
#define lua_writestring(s,l) output_redirect((s),(l))
#else
#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
#endif
#define luai_writeline() lua_writestring("\n",1)
/*
@@ luai_writestringerror defines how to print error messages.
@@ lua_writestringerror defines how to print error messages.
** (A format string with one argument is enough for Lua...)
*/
#if !defined(LUA_USE_STDIO)
#define luai_writestringerror(s,p) printf((s), (p))
#endif // defined(LUA_USE_STDIO)
/* }================================================================== */
#ifdef LUA_USE_ESP
#define lua_writestringerror(s,p) dbg_printf((s), (p))
#else
#define lua_writestringerror(s,p) fprintf(stderr, (s), (p))
#endif
/*
@ -586,6 +561,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
#define LUA_NUMBER_DOUBLE
#define LUA_NUMBER double
#endif
#define LUA_FLOAT double
/*
@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
@ -897,4 +873,6 @@ union luai_Cast { double l_d; long l_l; };
#error "Pipes not supported NodeMCU firmware"
#endif
#define LUA_DEBUG_HOOK lua_debugbreak
#endif

View File

@ -41,7 +41,7 @@ LUALIB_API int (luaopen_package) (lua_State *L);
/* open all previous libraries */
LUALIB_API void (luaL_openlibs) (lua_State *L);
LUALIB_API void (luaL_openlibs) (lua_State *L);

View File

@ -6,7 +6,6 @@
#define lundump_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
@ -164,16 +163,9 @@ static TString* LoadString(LoadState* S)
return NULL;
else
{
char* s;
if (!luaZ_direct_mode(S->Z)) {
s = luaZ_openspace(S->L,S->b,size);
LoadBlock(S,s,size);
return luaS_newlstr(S->L,s,size-1); /* remove trailing zero */
} else {
s = (char*)luaZ_get_crt_address(S->Z);
LoadBlock(S,NULL,size);
return luaS_newlstr(S->L,s,size-1);
}
char* s = luaZ_openspace(S->L,S->b,size);
LoadBlock(S,s,size);
return luaS_newlstr(S->L,s,size-1); /* remove trailing zero */
}
}
@ -181,13 +173,8 @@ static void LoadCode(LoadState* S, Proto* f)
{
int n=LoadInt(S);
Align4(S);
if (!luaZ_direct_mode(S->Z)) {
f->code=luaM_newvector(S->L,n,Instruction);
LoadVector(S,f->code,n,sizeof(Instruction));
} else {
f->code=(Instruction*)luaZ_get_crt_address(S->Z);
LoadVector(S,NULL,n,sizeof(Instruction));
}
f->code=luaM_newvector(S->L,n,Instruction);
LoadVector(S,f->code,n,sizeof(Instruction));
f->sizecode=n;
}
@ -236,28 +223,12 @@ static void LoadDebug(LoadState* S, Proto* f)
n=LoadInt(S);
Align4(S);
#ifdef LUA_OPTIMIZE_DEBUG
if(n) {
if (!luaZ_direct_mode(S->Z)) {
f->packedlineinfo=luaM_newvector(S->L,n,unsigned char);
LoadBlock(S,f->packedlineinfo,n);
} else {
f->packedlineinfo=(unsigned char*)luaZ_get_crt_address(S->Z);
LoadBlock(S,NULL,n);
}
f->packedlineinfo=luaM_newvector(S->L,n,unsigned char);
LoadBlock(S,f->packedlineinfo,n);
} else {
f->packedlineinfo=NULL;
}
#else
if (!luaZ_direct_mode(S->Z)) {
f->lineinfo=luaM_newvector(S->L,n,int);
LoadVector(S,f->lineinfo,n,sizeof(int));
} else {
f->lineinfo=(int*)luaZ_get_crt_address(S->Z);
LoadVector(S,NULL,n,sizeof(int));
}
f->sizelineinfo=n;
#endif
n=LoadInt(S);
f->locvars=luaM_newvector(S->L,n,LocVar);
f->sizelocvars=n;
@ -280,7 +251,6 @@ static Proto* LoadFunction(LoadState* S, TString* p)
Proto* f;
if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
f=luaF_newproto(S->L);
if (luaZ_direct_mode(S->Z)) l_setbit((f)->marked, READONLYBIT);
setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
f->source=LoadString(S); if (f->source==NULL) f->source=p;
f->linedefined=LoadInt(S);

View File

@ -50,11 +50,4 @@ LUAI_FUNC void luaU_print (const Proto* f, int full);
/* size of header of binary files */
#define LUAC_HEADERSIZE 12
/* error codes from cross-compiler */
/* target integer is too small to hold a value */
#define LUA_ERR_CC_INTOVERFLOW 101
/* target lua_Number is integral but a constant is non-integer */
#define LUA_ERR_CC_NOTINTEGER 102
#endif

View File

@ -7,7 +7,6 @@
#define lvm_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <stdio.h>
@ -25,7 +24,6 @@
#include "ltable.h"
#include "ltm.h"
#include "lvm.h"
#include "lrotable.h"
/* limit for table tag-method chains (to avoid loops) */
@ -41,7 +39,7 @@ LUA_NUMBER luai_ipow(LUA_NUMBER a, LUA_NUMBER b) {
LUA_NUMBER c = 1;
for (;;) {
if (b & 1)
c *= a;
c *= a;
b = b >> 1;
if (b == 0)
return c;
@ -134,26 +132,17 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
const TValue *res = luaH_get(h, key); /* do a primitive get */
if (!ttisnil(res) || /* result is no nil? */
if (!ttisnil(res) || /* result is no nil? */
(tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
setobj2s(L, val, res);
return;
}
/* else will try the tag method */
} else if (ttisrotable(t)) { /* `t' is a table? */
void *h = rvalue(t);
const TValue *res = luaH_get_ro(h, key); /* do a primitive get */
if (!ttisnil(res) || /* result is no nil? */
(tm = fasttm(L, (Table*)luaR_getmeta(h), TM_INDEX)) == NULL) { /* or no TM? */
setobj2s(L, val, res);
return;
}
/* else will try the tag method */
}
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
luaG_typeerror(L, t, "index");
if (ttisfunction(tm) || ttislightfunction(tm)) {
if (ttisfunction(tm)) {
callTMres(L, val, tm, t, key);
return;
}
@ -193,7 +182,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
luaG_typeerror(L, t, "index");
if (ttisfunction(tm) || ttislightfunction(tm)) {
if (ttisfunction(tm)) {
L->top--;
unfixedstack(L);
callTM(L, tm, t, key, val);
@ -282,7 +271,7 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
}
static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
int res;
if (ttype(l) != ttype(r))
return luaG_ordererror(L, l, r);
@ -305,8 +294,6 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
case LUA_TNIL: return 1;
case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
case LUA_TROTABLE:
return rvalue(t1) == rvalue(t2);
case LUA_TLIGHTUSERDATA:
case LUA_TLIGHTFUNCTION:
return pvalue(t1) == pvalue(t2);
@ -316,6 +303,8 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
TM_EQ);
break; /* will try TM */
}
case LUA_TROTABLE:
return hvalue(t1) == hvalue(t2);
case LUA_TTABLE: {
if (hvalue(t1) == hvalue(t2)) return 1;
tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
@ -440,7 +429,6 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb,
}
void luaV_execute (lua_State *L, int nexeccalls) {
LClosure *cl;
StkId base;
@ -582,10 +570,9 @@ void luaV_execute (lua_State *L, int nexeccalls) {
}
case OP_LEN: {
const TValue *rb = RB(i);
switch (ttype(rb)) {
case LUA_TTABLE:
case LUA_TROTABLE: {
setnvalue(ra, ttistable(rb) ? cast_num(luaH_getn(hvalue(rb))) : cast_num(luaH_getn_ro(rvalue(rb))));
switch (ttnov(rb)) {
case LUA_TTABLE: {
setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
break;
}
case LUA_TSTRING: {
@ -633,7 +620,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
}
case OP_LE: {
Protect(
if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
if (luaV_lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
dojump(L, pc, GETARG_sBx(*pc));
)
pc++;
@ -785,7 +772,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
setobj2t(L, luaH_setnum(L, h, last--), val);
luaC_barriert(L, h, val);
}
L->top = L->ci->top;
L->top = L->ci->top;
unfixedstack(L);
continue;
}

View File

@ -23,6 +23,7 @@
LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);

View File

@ -7,7 +7,6 @@
#define lzio_c
#define LUA_CORE
#define LUAC_CROSS_FILE
#include "lua.h"
#include <string.h>
@ -49,7 +48,7 @@ void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
z->L = L;
z->reader = reader;
z->data = data;
z->n = z->i = 0;
z->n = 0;
z->p = NULL;
}
@ -64,7 +63,6 @@ size_t luaZ_read (ZIO *z, void *b, size_t n) {
if (b)
memcpy(b, z->p, m);
z->n -= m;
z->i += m;
z->p += m;
if (b)
b = (char *)b + m;

View File

@ -43,9 +43,6 @@ typedef struct Mbuffer {
#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
#define luaZ_get_base_address(zio) ((const char *)((zio)->reader(NULL, (zio)->data, NULL)))
#define luaZ_direct_mode(zio) (luaZ_get_base_address(zio) != NULL)
#define luaZ_get_crt_address(zio) (luaZ_get_base_address(zio) + (zio)->i)
LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
@ -59,7 +56,6 @@ LUAI_FUNC int luaZ_lookahead (ZIO *z);
struct Zio {
size_t n; /* bytes still unread */
size_t i; /* buffer offset */
const char *p; /* current position in buffer */
lua_Reader reader;
void* data; /* additional data */

View File

@ -0,0 +1,52 @@
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
SUBDIRS = host
GEN_LIBS = liblua.a
endif
STD_CFLAGS=-std=gnu11 -Wimplicit -Wall
# Validate LUA setting
ifeq ("$(LUA)","53")
# ok
else ifeq ("$(LUA)","51")
$(error Your variable LUA="$(LUA)" looks like you probably want \
app/lua/Makefile instead)
else
$(error Expected environment variable "LUA" to be "53", not "$(LUA)")
endif
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
#
#DEFINES += -DDEVELOPMENT_TOOLS -DDEVELOPMENT_USE_GDB -DDEVELOPMENT_BREAK_ON_STARTUP_PIN=1
#EXTRA_CCFLAGS += -ggdb -O0
#############################################################
# Recursion Magic - Don't touch this!!
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ../spiffs
INCLUDES += -I ../libc
INCLUDES += -I ../modules
INCLUDES += -I ../platform
INCLUDES += -I ../uzlib
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile

View File

@ -0,0 +1,69 @@
all: build
HOSTCC?=$(PYTHON) -m ziglang cc
ifeq ($V,)
Q:=@
endif
LUAC_OBJ_DIR:=$(LUAC_BUILD_DIR)/$(notdir $(LUA_PATH))
LUAC_CFLAGS:= \
-I$(LUAC_BUILD_DIR) \
-I$(LUA_PATH) \
-I$(LUA_PATH)/host \
-I$(LUA_PATH)/../common \
-I$(LUA_PATH)/../../uzlib \
-O2 -g -Wall -Wextra -Wno-sign-compare -Wno-string-plus-int
LUAC_LDFLAGS:= -ldl -lm
LUAC_DEFINES += \
-DLUA_CROSS_COMPILER \
-DLUA_USE_HOST \
-DLUA_USE_STDIO \
vpath %.c $(LUA_PATH)/host $(LUA_PATH) $(LUA_PATH)/../common $(LUA_PATH)/../../uzlib
LUA_SRCS:=\
luac.c loslib.c liolib.c \
lapi.c lauxlib.c lbaselib.c lbitlib.c lcode.c lcorolib.c \
lctype.c ldblib.c ldebug.c ldo.c ldump.c lfunc.c \
lgc.c llex.c lmathlib.c lmem.c lnodemcu.c loadlib.c \
lobject.c lopcodes.c lparser.c lstate.c lstring.c lstrlib.c \
ltable.c ltablib.c ltm.c lundump.c lutf8lib.c lvm.c \
lzio.c \
linit.c lpanic.c \
uzlib_deflate.c crc32.c \
LUAC_OBJS:=$(LUA_SRCS:%.c=$(LUAC_OBJ_DIR)/%.o)
LUAC_CROSS:=$(LUAC_BUILD_DIR)/luac.cross
$(LUAC_OBJ_DIR):
@mkdir -p "$@"
$(LUAC_OBJ_DIR)/%.o: %.c | $(LUAC_OBJ_DIR)
@echo '[hostcc] $(notdir $@)'
$Q$(HOSTCC) $(LUAC_DEFINES) $(LUAC_CFLAGS) "$<" -c -o "$@"
$(LUAC_OBJ_DIR)/%.d: SHELL=/bin/bash
$(LUAC_OBJ_DIR)/%.d: %.c | $(LUAC_OBJ_DIR)
@echo '[ dep] $<'
@rm -f "$@"
$Qset -eo pipefail; $(HOSTCC) $(LUAC_DEFINES) $(LUAC_CFLAGS) -M "$<" | sed 's,\($*\.o\)[ :]*,$(LUAC_OBJ_DIR)/\1 $@ : ,g' > "$@.tmp"; mv "$@.tmp" "$@"
build: $(LUAC_DEPS) $(LUAC_CROSS)
$(LUAC_CROSS): $(LUAC_OBJS)
@echo '[ link] $(notdir $@)'
$Q$(HOSTCC) $(LUAC_CFLAGS) $^ $(LUAC_LDFLAGS) -o "$@"
# zig cc (0.8.0 at least) seems to get itself all confused with its cache
# when we're running a separate path for dependencies, so we skip them for
# now as for most people they're not needed anyway.
ifneq ($(findstring zig,$(HOSTCC)),zig)
LUAC_DEPS:=$(LUAC_OBJS:%.o=%.d)
ifneq ($(MAKECMDGOALS),clean)
-include $(LUAC_DEPS)
endif
endif

View File

@ -0,0 +1,776 @@
/*
** $Id: liolib.c,v 2.151.1.1 2017/04/19 17:29:57 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
#define liolib_c
#define LUA_LIB
#include "lprefix.h"
#include <ctype.h>
#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
/*
** Change this macro to accept other modes for 'fopen' besides
** the standard ones.
*/
#if !defined(l_checkmode)
/* accepted extensions to 'mode' in 'fopen' */
#if !defined(L_MODEEXT)
#define L_MODEEXT "b"
#endif
/* Check whether 'mode' matches '[rwa]%+?[L_MODEEXT]*' */
static int l_checkmode (const char *mode) {
return (*mode != '\0' && strchr("rwa", *(mode++)) != NULL &&
(*mode != '+' || (++mode, 1)) && /* skip if char is '+' */
(strspn(mode, L_MODEEXT) == strlen(mode))); /* check extensions */
}
#endif
/*
** {======================================================
** l_popen spawns a new process connected to the current
** one through the file streams.
** =======================================================
*/
#if !defined(l_popen) /* { */
#if defined(LUA_USE_POSIX) /* { */
#define l_popen(L,c,m) (fflush(NULL), popen(c,m))
#define l_pclose(L,file) (pclose(file))
#elif defined(LUA_USE_WINDOWS) /* }{ */
#define l_popen(L,c,m) (_popen(c,m))
#define l_pclose(L,file) (_pclose(file))
#else /* }{ */
/* ISO C definitions */
#define l_popen(L,c,m) \
((void)((void)c, m), \
luaL_error(L, "'popen' not supported"), \
(FILE*)0)
#define l_pclose(L,file) ((void)L, (void)file, -1)
#endif /* } */
#endif /* } */
/* }====================================================== */
#if !defined(l_getc) /* { */
#if defined(LUA_USE_POSIX)
#define l_getc(f) getc_unlocked(f)
#define l_lockfile(f) flockfile(f)
#define l_unlockfile(f) funlockfile(f)
#else
#define l_getc(f) getc(f)
#define l_lockfile(f) ((void)0)
#define l_unlockfile(f) ((void)0)
#endif
#endif /* } */
/*
** {======================================================
** l_fseek: configuration for longer offsets
** =======================================================
*/
#if !defined(l_fseek) /* { */
#if defined(LUA_USE_POSIX) /* { */
#include <sys/types.h>
#define l_fseek(f,o,w) fseeko(f,o,w)
#define l_ftell(f) ftello(f)
#define l_seeknum off_t
#elif defined(LUA_USE_WINDOWS) && !defined(_CRTIMP_TYPEINFO) \
&& defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */
/* Windows (but not DDK) and Visual C++ 2005 or higher */
#define l_fseek(f,o,w) _fseeki64(f,o,w)
#define l_ftell(f) _ftelli64(f)
#define l_seeknum __int64
#else /* }{ */
/* ISO C definitions */
#define l_fseek(f,o,w) fseek(f,o,w)
#define l_ftell(f) ftell(f)
#define l_seeknum long
#endif /* } */
#endif /* } */
/* }====================================================== */
#define IO_PREFIX "_IO_"
#define IOPREF_LEN (sizeof(IO_PREFIX)/sizeof(char) - 1)
#define IO_INPUT (IO_PREFIX "input")
#define IO_OUTPUT (IO_PREFIX "output")
typedef luaL_Stream LStream;
#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
#define isclosed(p) ((p)->closef == NULL)
static int io_type (lua_State *L) {
LStream *p;
luaL_checkany(L, 1);
p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE);
if (p == NULL)
lua_pushnil(L); /* not a file */
else if (isclosed(p))
lua_pushliteral(L, "closed file");
else
lua_pushliteral(L, "file");
return 1;
}
static int f_tostring (lua_State *L) {
LStream *p = tolstream(L);
if (isclosed(p))
lua_pushliteral(L, "file (closed)");
else
lua_pushfstring(L, "file (%p)", p->f);
return 1;
}
static FILE *tofile (lua_State *L) {
LStream *p = tolstream(L);
if (isclosed(p))
luaL_error(L, "attempt to use a closed file");
lua_assert(p->f);
return p->f;
}
/*
** When creating file handles, always creates a 'closed' file handle
** before opening the actual file; so, if there is a memory error, the
** handle is in a consistent state.
*/
static LStream *newprefile (lua_State *L) {
LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream));
p->closef = NULL; /* mark file handle as 'closed' */
luaL_setmetatable(L, LUA_FILEHANDLE);
return p;
}
/*
** Calls the 'close' function from a file handle. The 'volatile' avoids
** a bug in some versions of the Clang compiler (e.g., clang 3.0 for
** 32 bits).
*/
static int aux_close (lua_State *L) {
LStream *p = tolstream(L);
volatile lua_CFunction cf = p->closef;
p->closef = NULL; /* mark stream as closed */
return (*cf)(L); /* close it */
}
static int f_close (lua_State *L) {
tofile(L); /* make sure argument is an open stream */
return aux_close(L);
}
static int io_close (lua_State *L) {
if (lua_isnone(L, 1)) /* no argument? */
lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */
return f_close(L);
}
static int f_gc (lua_State *L) {
LStream *p = tolstream(L);
if (!isclosed(p) && p->f != NULL)
aux_close(L); /* ignore closed and incompletely open files */
return 0;
}
/*
** function to close regular files
*/
static int io_fclose (lua_State *L) {
LStream *p = tolstream(L);
int res = fclose(p->f);
return luaL_fileresult(L, (res == 0), NULL);
}
static LStream *newfile (lua_State *L) {
LStream *p = newprefile(L);
p->f = NULL;
p->closef = &io_fclose;
return p;
}
static void opencheck (lua_State *L, const char *fname, const char *mode) {
LStream *p = newfile(L);
p->f = fopen(fname, mode);
if (p->f == NULL)
luaL_error(L, "cannot open file '%s' (%s)", fname, strerror(errno));
}
static int io_open (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
LStream *p = newfile(L);
const char *md = mode; /* to traverse/check mode */
luaL_argcheck(L, l_checkmode(md), 2, "invalid mode");
p->f = fopen(filename, mode);
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
}
/*
** function to close 'popen' files
*/
static int io_pclose (lua_State *L) {
LStream *p = tolstream(L);
return luaL_execresult(L, l_pclose(L, p->f));
}
static int io_popen (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
LStream *p = newprefile(L);
p->f = l_popen(L, filename, mode);
p->closef = &io_pclose;
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
}
static int io_tmpfile (lua_State *L) {
LStream *p = newfile(L);
p->f = tmpfile();
return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
}
static FILE *getiofile (lua_State *L, const char *findex) {
LStream *p;
lua_getfield(L, LUA_REGISTRYINDEX, findex);
p = (LStream *)lua_touserdata(L, -1);
if (isclosed(p))
luaL_error(L, "standard %s file is closed", findex + IOPREF_LEN);
return p->f;
}
static int g_iofile (lua_State *L, const char *f, const char *mode) {
if (!lua_isnoneornil(L, 1)) {
const char *filename = lua_tostring(L, 1);
if (filename)
opencheck(L, filename, mode);
else {
tofile(L); /* check that it's a valid file handle */
lua_pushvalue(L, 1);
}
lua_setfield(L, LUA_REGISTRYINDEX, f);
}
/* return current value */
lua_getfield(L, LUA_REGISTRYINDEX, f);
return 1;
}
static int io_input (lua_State *L) {
return g_iofile(L, IO_INPUT, "r");
}
static int io_output (lua_State *L) {
return g_iofile(L, IO_OUTPUT, "w");
}
static int io_readline (lua_State *L);
/*
** maximum number of arguments to 'f:lines'/'io.lines' (it + 3 must fit
** in the limit for upvalues of a closure)
*/
#define MAXARGLINE 250
static void aux_lines (lua_State *L, int toclose) {
int n = lua_gettop(L) - 1; /* number of arguments to read */
luaL_argcheck(L, n <= MAXARGLINE, MAXARGLINE + 2, "too many arguments");
lua_pushinteger(L, n); /* number of arguments to read */
lua_pushboolean(L, toclose); /* close/not close file when finished */
lua_rotate(L, 2, 2); /* move 'n' and 'toclose' to their positions */
lua_pushcclosure(L, io_readline, 3 + n);
}
static int f_lines (lua_State *L) {
tofile(L); /* check that it's a valid file handle */
aux_lines(L, 0);
return 1;
}
static int io_lines (lua_State *L) {
int toclose;
if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */
if (lua_isnil(L, 1)) { /* no file name? */
lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT); /* get default input */
lua_replace(L, 1); /* put it at index 1 */
tofile(L); /* check that it's a valid file handle */
toclose = 0; /* do not close it after iteration */
}
else { /* open a new file */
const char *filename = luaL_checkstring(L, 1);
opencheck(L, filename, "r");
lua_replace(L, 1); /* put file at index 1 */
toclose = 1; /* close it after iteration */
}
aux_lines(L, toclose);
return 1;
}
/*
** {======================================================
** READ
** =======================================================
*/
/* maximum length of a numeral */
#if !defined (L_MAXLENNUM)
#define L_MAXLENNUM 200
#endif
/* auxiliary structure used by 'read_number' */
typedef struct {
FILE *f; /* file being read */
int c; /* current character (look ahead) */
int n; /* number of elements in buffer 'buff' */
char buff[L_MAXLENNUM + 1]; /* +1 for ending '\0' */
} RN;
/*
** Add current char to buffer (if not out of space) and read next one
*/
static int nextc (RN *rn) {
if (rn->n >= L_MAXLENNUM) { /* buffer overflow? */
rn->buff[0] = '\0'; /* invalidate result */
return 0; /* fail */
}
else {
rn->buff[rn->n++] = rn->c; /* save current char */
rn->c = l_getc(rn->f); /* read next one */
return 1;
}
}
/*
** Accept current char if it is in 'set' (of size 2)
*/
static int test2 (RN *rn, const char *set) {
if (rn->c == set[0] || rn->c == set[1])
return nextc(rn);
else return 0;
}
/*
** Read a sequence of (hex)digits
*/
static int readdigits (RN *rn, int hex) {
int count = 0;
while ((hex ? isxdigit(rn->c) : isdigit(rn->c)) && nextc(rn))
count++;
return count;
}
/*
** Read a number: first reads a valid prefix of a numeral into a buffer.
** Then it calls 'lua_stringtonumber' to check whether the format is
** correct and to convert it to a Lua number
*/
static int read_number (lua_State *L, FILE *f) {
RN rn;
int count = 0;
int hex = 0;
char decp[2];
rn.f = f; rn.n = 0;
decp[0] = lua_getlocaledecpoint(); /* get decimal point from locale */
decp[1] = '.'; /* always accept a dot */
l_lockfile(rn.f);
do { rn.c = l_getc(rn.f); } while (isspace(rn.c)); /* skip spaces */
test2(&rn, "-+"); /* optional signal */
if (test2(&rn, "00")) {
if (test2(&rn, "xX")) hex = 1; /* numeral is hexadecimal */
else count = 1; /* count initial '0' as a valid digit */
}
count += readdigits(&rn, hex); /* integral part */
if (test2(&rn, decp)) /* decimal point? */
count += readdigits(&rn, hex); /* fractional part */
if (count > 0 && test2(&rn, (hex ? "pP" : "eE"))) { /* exponent mark? */
test2(&rn, "-+"); /* exponent signal */
readdigits(&rn, 0); /* exponent digits */
}
ungetc(rn.c, rn.f); /* unread look-ahead char */
l_unlockfile(rn.f);
rn.buff[rn.n] = '\0'; /* finish string */
if (lua_stringtonumber(L, rn.buff)) /* is this a valid number? */
return 1; /* ok */
else { /* invalid format */
lua_pushnil(L); /* "result" to be removed */
return 0; /* read fails */
}
}
static int test_eof (lua_State *L, FILE *f) {
int c = getc(f);
ungetc(c, f); /* no-op when c == EOF */
lua_pushliteral(L, "");
return (c != EOF);
}
static int read_line (lua_State *L, FILE *f, int chop) {
luaL_Buffer b;
int c = '\0';
luaL_buffinit(L, &b);
while (c != EOF && c != '\n') { /* repeat until end of line */
char *buff = luaL_prepbuffer(&b); /* preallocate buffer */
int i = 0;
l_lockfile(f); /* no memory errors can happen inside the lock */
while (i < LUAL_BUFFERSIZE && (c = l_getc(f)) != EOF && c != '\n')
buff[i++] = c;
l_unlockfile(f);
luaL_addsize(&b, i);
}
if (!chop && c == '\n') /* want a newline and have one? */
luaL_addchar(&b, c); /* add ending newline to result */
luaL_pushresult(&b); /* close buffer */
/* return ok if read something (either a newline or something else) */
return (c == '\n' || lua_rawlen(L, -1) > 0);
}
static void read_all (lua_State *L, FILE *f) {
size_t nr;
luaL_Buffer b;
luaL_buffinit(L, &b);
do { /* read file in chunks of LUAL_BUFFERSIZE bytes */
char *p = luaL_prepbuffer(&b);
nr = fread(p, sizeof(char), LUAL_BUFFERSIZE, f);
luaL_addsize(&b, nr);
} while (nr == LUAL_BUFFERSIZE);
luaL_pushresult(&b); /* close buffer */
}
static int read_chars (lua_State *L, FILE *f, size_t n) {
size_t nr; /* number of chars actually read */
char *p;
luaL_Buffer b;
luaL_buffinit(L, &b);
p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */
nr = fread(p, sizeof(char), n, f); /* try to read 'n' chars */
luaL_addsize(&b, nr);
luaL_pushresult(&b); /* close buffer */
return (nr > 0); /* true iff read something */
}
static int g_read (lua_State *L, FILE *f, int first) {
int nargs = lua_gettop(L) - 1;
int success;
int n;
clearerr(f);
if (nargs == 0) { /* no arguments? */
success = read_line(L, f, 1);
n = first+1; /* to return 1 result */
}
else { /* ensure stack space for all results and for auxlib's buffer */
luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
success = 1;
for (n = first; nargs-- && success; n++) {
if (lua_type(L, n) == LUA_TNUMBER) {
size_t l = (size_t)luaL_checkinteger(L, n);
success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
}
else {
const char *p = luaL_checkstring(L, n);
if (*p == '*') p++; /* skip optional '*' (for compatibility) */
switch (*p) {
case 'n': /* number */
success = read_number(L, f);
break;
case 'l': /* line */
success = read_line(L, f, 1);
break;
case 'L': /* line with end-of-line */
success = read_line(L, f, 0);
break;
case 'a': /* file */
read_all(L, f); /* read entire file */
success = 1; /* always success */
break;
default:
return luaL_argerror(L, n, "invalid format");
}
}
}
}
if (ferror(f))
return luaL_fileresult(L, 0, NULL);
if (!success) {
lua_pop(L, 1); /* remove last result */
lua_pushnil(L); /* push nil instead */
}
return n - first;
}
static int io_read (lua_State *L) {
return g_read(L, getiofile(L, IO_INPUT), 1);
}
static int f_read (lua_State *L) {
return g_read(L, tofile(L), 2);
}
static int io_readline (lua_State *L) {
LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1));
int i;
int n = (int)lua_tointeger(L, lua_upvalueindex(2));
if (isclosed(p)) /* file is already closed? */
return luaL_error(L, "file is already closed");
lua_settop(L , 1);
luaL_checkstack(L, n, "too many arguments");
for (i = 1; i <= n; i++) /* push arguments to 'g_read' */
lua_pushvalue(L, lua_upvalueindex(3 + i));
n = g_read(L, p->f, 2); /* 'n' is number of results */
lua_assert(n > 0); /* should return at least a nil */
if (lua_toboolean(L, -n)) /* read at least one value? */
return n; /* return them */
else { /* first result is nil: EOF or error */
if (n > 1) { /* is there error information? */
/* 2nd result is error message */
return luaL_error(L, "%s", lua_tostring(L, -n + 1));
}
if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */
lua_settop(L, 0);
lua_pushvalue(L, lua_upvalueindex(1));
aux_close(L); /* close it */
}
return 0;
}
}
/* }====================================================== */
static int g_write (lua_State *L, FILE *f, int arg) {
int nargs = lua_gettop(L) - arg;
int status = 1;
for (; nargs--; arg++) {
if (lua_type(L, arg) == LUA_TNUMBER) {
/* optimization: could be done exactly as for strings */
int len = lua_isinteger(L, arg)
? fprintf(f, LUA_INTEGER_FMT,
(LUAI_UACINT)lua_tointeger(L, arg))
: fprintf(f, LUA_NUMBER_FMT,
(LUAI_UACNUMBER)lua_tonumber(L, arg));
status = status && (len > 0);
}
else {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
status = status && (fwrite(s, sizeof(char), l, f) == l);
}
}
if (status) return 1; /* file handle already on stack top */
else return luaL_fileresult(L, status, NULL);
}
static int io_write (lua_State *L) {
return g_write(L, getiofile(L, IO_OUTPUT), 1);
}
static int f_write (lua_State *L) {
FILE *f = tofile(L);
lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */
return g_write(L, f, 2);
}
static int f_seek (lua_State *L) {
static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
static const char *const modenames[] = {"set", "cur", "end", NULL};
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, "cur", modenames);
lua_Integer p3 = luaL_optinteger(L, 3, 0);
l_seeknum offset = (l_seeknum)p3;
luaL_argcheck(L, (lua_Integer)offset == p3, 3,
"not an integer in proper range");
op = l_fseek(f, offset, mode[op]);
if (op)
return luaL_fileresult(L, 0, NULL); /* error */
else {
lua_pushinteger(L, (lua_Integer)l_ftell(f));
return 1;
}
}
static int f_setvbuf (lua_State *L) {
static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
static const char *const modenames[] = {"no", "full", "line", NULL};
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, NULL, modenames);
lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
int res = setvbuf(f, NULL, mode[op], (size_t)sz);
return luaL_fileresult(L, res == 0, NULL);
}
static int io_flush (lua_State *L) {
return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
}
static int f_flush (lua_State *L) {
return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL);
}
/*
** functions for 'io' library
*/
static const luaL_Reg iolib[] = {
{"close", io_close},
{"flush", io_flush},
{"input", io_input},
{"lines", io_lines},
{"open", io_open},
{"output", io_output},
{"popen", io_popen},
{"read", io_read},
{"tmpfile", io_tmpfile},
{"type", io_type},
{"write", io_write},
{NULL, NULL}
};
/*
** methods for file handles
*/
static const luaL_Reg flib[] = {
{"close", f_close},
{"flush", f_flush},
{"lines", f_lines},
{"read", f_read},
{"seek", f_seek},
{"setvbuf", f_setvbuf},
{"write", f_write},
{"__gc", f_gc},
{"__tostring", f_tostring},
{NULL, NULL}
};
static void createmeta (lua_State *L) {
luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
lua_pushvalue(L, -1); /* push metatable */
lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */
lua_pop(L, 1); /* pop new metatable */
}
/*
** function to (not) close the standard files stdin, stdout, and stderr
*/
static int io_noclose (lua_State *L) {
LStream *p = tolstream(L);
p->closef = &io_noclose; /* keep file opened */
lua_pushnil(L);
lua_pushliteral(L, "cannot close standard file");
return 2;
}
static void createstdfile (lua_State *L, FILE *f, const char *k,
const char *fname) {
LStream *p = newprefile(L);
p->f = f;
p->closef = &io_noclose;
if (k != NULL) {
lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */
}
lua_setfield(L, -2, fname); /* add file to module */
}
LUAMOD_API int luaopen_io (lua_State *L) {
luaL_newlib(L, iolib); /* new module */
createmeta(L);
/* create (and set) default files */
createstdfile(L, stdin, IO_INPUT, "stdin");
createstdfile(L, stdout, IO_OUTPUT, "stdout");
createstdfile(L, stderr, NULL, "stderr");
return 1;
}

View File

@ -0,0 +1,409 @@
/*
** $Id: loslib.c,v 1.65.1.1 2017/04/19 17:29:57 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
#define loslib_c
#define LUA_LIB
#include "lprefix.h"
#include <errno.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
/*
** {==================================================================
** List of valid conversion specifiers for the 'strftime' function;
** options are grouped by length; group of length 2 start with '||'.
** ===================================================================
*/
#if !defined(LUA_STRFTIMEOPTIONS) /* { */
/* options for ANSI C 89 (only 1-char options) */
#define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%"
/* options for ISO C 99 and POSIX */
#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
"||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */
/* options for Windows */
#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \
"||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" /* two-char options */
#if defined(LUA_USE_WINDOWS)
#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN
#elif defined(LUA_USE_C89)
#define LUA_STRFTIMEOPTIONS L_STRFTIMEC89
#else /* C99 specification */
#define LUA_STRFTIMEOPTIONS L_STRFTIMEC99
#endif
#endif /* } */
/* }================================================================== */
/*
** {==================================================================
** Configuration for time-related stuff
** ===================================================================
*/
#if !defined(l_time_t) /* { */
/*
** type to represent time_t in Lua
*/
#define l_timet lua_Integer
#define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t))
static time_t l_checktime (lua_State *L, int arg) {
lua_Integer t = luaL_checkinteger(L, arg);
luaL_argcheck(L, (time_t)t == t, arg, "time out-of-bounds");
return (time_t)t;
}
#endif /* } */
#if !defined(l_gmtime) /* { */
/*
** By default, Lua uses gmtime/localtime, except when POSIX is available,
** where it uses gmtime_r/localtime_r
*/
#if defined(LUA_USE_POSIX) /* { */
#define l_gmtime(t,r) gmtime_r(t,r)
#define l_localtime(t,r) localtime_r(t,r)
#else /* }{ */
/* ISO C definitions */
#define l_gmtime(t,r) ((void)(r)->tm_sec, gmtime(t))
#define l_localtime(t,r) ((void)(r)->tm_sec, localtime(t))
#endif /* } */
#endif /* } */
/* }================================================================== */
/*
** {==================================================================
** Configuration for 'tmpnam':
** By default, Lua uses tmpnam except when POSIX is available, where
** it uses mkstemp.
** ===================================================================
*/
#if !defined(lua_tmpnam) /* { */
#if defined(__GNUC__) /* { */
#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);
if (cmd != NULL)
return luaL_execresult(L, stat);
else {
lua_pushboolean(L, stat); /* true if there is a shell */
return 1;
}
}
static int os_remove (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
return luaL_fileresult(L, remove(filename) == 0, filename);
}
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);
}
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;
}
static int os_clock (lua_State *L) {
lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
return 1;
}
/*
** {======================================================
** Time/Date operations
** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
** wday=%w+1, yday=%j, isdst=? }
** =======================================================
*/
static void setfield (lua_State *L, const char *key, int value) {
lua_pushinteger(L, value);
lua_setfield(L, -2, key);
}
static void setboolfield (lua_State *L, const char *key, int value) {
if (value < 0) /* undefined? */
return; /* does not set field */
lua_pushboolean(L, value);
lua_setfield(L, -2, key);
}
/*
** Set all fields from structure 'tm' in the table on top of the stack
*/
static void setallfields (lua_State *L, struct tm *stm) {
setfield(L, "sec", stm->tm_sec);
setfield(L, "min", stm->tm_min);
setfield(L, "hour", stm->tm_hour);
setfield(L, "day", stm->tm_mday);
setfield(L, "month", stm->tm_mon + 1);
setfield(L, "year", stm->tm_year + 1900);
setfield(L, "wday", stm->tm_wday + 1);
setfield(L, "yday", stm->tm_yday + 1);
setboolfield(L, "isdst", stm->tm_isdst);
}
static int getboolfield (lua_State *L, const char *key) {
int res;
res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1);
lua_pop(L, 1);
return res;
}
/* maximum value for date fields (to avoid arithmetic overflows with 'int') */
#if !defined(L_MAXDATEFIELD)
#define L_MAXDATEFIELD (INT_MAX / 2)
#endif
static int getfield (lua_State *L, const char *key, int d, int delta) {
int isnum;
int t = lua_getfield(L, -1, key); /* get field and its type */
lua_Integer res = lua_tointegerx(L, -1, &isnum);
if (!isnum) { /* field is not an integer? */
if (t != LUA_TNIL) /* some other value? */
return luaL_error(L, "field '%s' is not an integer", key);
else if (d < 0) /* absent field; no default? */
return luaL_error(L, "field '%s' missing in date table", key);
res = d;
}
else {
if (!(-L_MAXDATEFIELD <= res && res <= L_MAXDATEFIELD))
return luaL_error(L, "field '%s' is out-of-bound", key);
res -= delta;
}
lua_pop(L, 1);
return (int)res;
}
static const char *checkoption (lua_State *L, const char *conv,
ptrdiff_t convlen, char *buff) {
const char *option = LUA_STRFTIMEOPTIONS;
int oplen = 1; /* length of options being checked */
for (; *option != '\0' && oplen <= convlen; option += oplen) {
if (*option == '|') /* next block? */
oplen++; /* will check options with next length (+1) */
else if (memcmp(conv, option, oplen) == 0) { /* match? */
memcpy(buff, conv, oplen); /* copy valid option to buffer */
buff[oplen] = '\0';
return conv + oplen; /* return next item */
}
}
luaL_argerror(L, 1,
lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv));
return conv; /* to avoid warnings */
}
/* maximum size for an individual 'strftime' item */
#define SIZETIMEFMT 250
static int os_date (lua_State *L) {
size_t slen;
const char *s = luaL_optlstring(L, 1, "%c", &slen);
time_t t = luaL_opt(L, l_checktime, 2, time(NULL));
const char *se = s + slen; /* 's' end */
struct tm tmr, *stm;
if (*s == '!') { /* UTC? */
stm = l_gmtime(&t, &tmr);
s++; /* skip '!' */
}
else
stm = l_localtime(&t, &tmr);
if (stm == NULL) /* invalid date? */
return luaL_error(L,
"time result cannot be represented in this installation");
if (strcmp(s, "*t") == 0) {
lua_createtable(L, 0, 9); /* 9 = number of fields */
setallfields(L, stm);
}
else {
char cc[4]; /* buffer for individual conversion specifiers */
luaL_Buffer b;
cc[0] = '%';
luaL_buffinit(L, &b);
while (s < se) {
if (*s != '%') /* not a conversion specifier? */
luaL_addchar(&b, *s++);
else {
size_t reslen;
char *buff = luaL_prepbuffsize(&b, SIZETIMEFMT);
s++; /* skip '%' */
s = checkoption(L, s, se - s, cc + 1); /* copy specifier to 'cc' */
reslen = strftime(buff, SIZETIMEFMT, cc, stm);
luaL_addsize(&b, reslen);
}
}
luaL_pushresult(&b);
}
return 1;
}
static int os_time (lua_State *L) {
time_t t;
if (lua_isnoneornil(L, 1)) /* called without args? */
t = time(NULL); /* get current time */
else {
struct tm ts;
luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 1); /* make sure table is at the top */
ts.tm_sec = getfield(L, "sec", 0, 0);
ts.tm_min = getfield(L, "min", 0, 0);
ts.tm_hour = getfield(L, "hour", 12, 0);
ts.tm_mday = getfield(L, "day", -1, 0);
ts.tm_mon = getfield(L, "month", -1, 1);
ts.tm_year = getfield(L, "year", -1, 1900);
ts.tm_isdst = getboolfield(L, "isdst");
t = mktime(&ts);
setallfields(L, &ts); /* update fields with normalized values */
}
if (t != (time_t)(l_timet)t || t == (time_t)(-1))
return luaL_error(L,
"time result cannot be represented in this installation");
l_pushtime(L, t);
return 1;
}
static int os_difftime (lua_State *L) {
time_t t1 = l_checktime(L, 1);
time_t t2 = l_checktime(L, 2);
lua_pushnumber(L, (lua_Number)difftime(t1, t2));
return 1;
}
/* }====================================================== */
static int os_setlocale (lua_State *L) {
static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
LC_NUMERIC, LC_TIME};
static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
"numeric", "time", NULL};
const char *l = luaL_optstring(L, 1, NULL);
int op = luaL_checkoption(L, 2, "all", catnames);
lua_pushstring(L, setlocale(cat[op], l));
return 1;
}
static int os_exit (lua_State *L) {
int status;
if (lua_isboolean(L, 1))
status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE);
else
status = (int)luaL_optinteger(L, 1, EXIT_SUCCESS);
if (lua_toboolean(L, 2))
lua_close(L);
if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */
return 0;
}
static const luaL_Reg syslib[] = {
{"clock", os_clock},
{"date", os_date},
{"difftime", os_difftime},
{"execute", os_execute},
{"exit", os_exit},
{"getenv", os_getenv},
{"remove", os_remove},
{"rename", os_rename},
{"setlocale", os_setlocale},
{"time", os_time},
{"tmpname", os_tmpname},
{NULL, NULL}
};
/* }====================================================== */
LUAMOD_API int luaopen_os (lua_State *L) {
luaL_newlib(L, syslib);
return 1;
}

View File

@ -0,0 +1,623 @@
/*
** $Id: luac.c,v 1.76 2018/06/19 01:32:02 lhf Exp $
** Lua compiler (saves bytecodes to files; also lists bytecodes)
** See Copyright Notice in lua.h
*/
#define luac_c
#define LUA_CORE
#include "lprefix.h"
#include <alloca.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include "ldebug.h"
#include "lnodemcu.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "lundump.h"
static void PrintFunction(const Proto* f, int full);
#define luaU_print PrintFunction
#define PROGNAME "luac.cross" /* default program name */
#define OUTPUT PROGNAME ".out" /* default output file */
static int listing=0; /* list bytecodes? */
static int dumping=1; /* dump bytecodes? */
static int stripping=0; /* strip debug information? */
static char Output[]={ OUTPUT }; /* default output file name */
static const char* output=Output; /* actual output file name */
static const char* progname=PROGNAME; /* actual program name */
static int flash = 0; /* output flash image */
static lu_int32 address = 0; /* output flash image at absolute location */
static lu_int32 maxSize = 0x40000; /* maximuum uncompressed image size */
static int lookup = 0; /* output lookup-style master combination header */
static const char *execute; /* executed a Lua file */
char *LFSimageName;
#if 0
#define IROM0_SEG 0x40200000ul
#define IROM0_SEGMAX 0x00100000ul
#define IROM_OFFSET(a) (cast(lu_int32, (a)) - IROM0_SEG)
#else
// Safety checks disabled for now; would need to handle ESP32/ESP32S/ESP32C3
#define IROM_OFFSET(a)
#endif
static void fatal(const char *message) {
fprintf(stderr, "%s: %s\n", progname, message);
exit(EXIT_FAILURE);
}
static void cannot(const char *what) {
fprintf(stderr, "%s: cannot %s %s: %s\n", progname, what, output, strerror(errno));
exit(EXIT_FAILURE);
}
static void usage(const char *message) {
if ( *message == '-')
fprintf(stderr, "%s: unrecognized option '%s'\n", progname, message);
else
fprintf(stderr, "%s: %s\n", progname, message);
fprintf(stderr,
"usage: %s [options] [filenames]\n"
"Available options are:\n"
" -l list (use -l -l for full listing)\n"
" -o name output to file 'name' (default is \"%s\")\n"
" -e name execute a lua source file\n"
" -f output a flash image file\n"
" -F name load a flash image file\n"
" -a addr generate an absolute, rather than "
"position independent flash image file\n"
" (use with -F LFSimage -o absLFSimage to "
"convert an image to absolute format)\n"
" -i generate lookup combination master (default with option -f)\n"
" -m size maximum LFS image in bytes\n"
" -p parse only\n"
" -s strip debug information\n"
" -v show version information\n"
" -- stop handling options\n"
" - stop handling options and process stdin\n", progname, Output);
exit(EXIT_FAILURE);
}
#define IS(s) (strcmp(argv[i],s)==0)
static int doargs(int argc, char *argv[]) {
int i;
int version = 0;
lu_int32 offset = 0;
if (argv[0] != NULL && *argv[0] != 0) progname = argv[0];
for (i = 1; i < argc; i++) {
if ( *argv[i] != '-') { /* end of options; keep it */
break;
} else if (IS("--")) { /* end of options; skip it */
++i;
if (version) ++version;
break;
} else if (IS("-")) { /* end of options; use stdin */
break;
} else if (IS("-e")) { /* execute a lua source file file */
execute = argv[++i];
if (execute == NULL || *execute == 0 || *execute == '-')
usage("\"-e\" needs a file argument");
} else if (IS("-F")) { /* execute a lua source file file */
LFSimageName = argv[++i];
if (LFSimageName == NULL || *LFSimageName == 0 || *LFSimageName == '-')
usage("\"-F\" needs an LFS image file argument");
} else if (IS("-f")) { /* Flash image file */
flash = lookup = 1;
} else if (IS("-a")) { /* Absolue flash image file */
flash = lookup = 1;
address = strtol(argv[++i], NULL, 0);
#if 0
offset = IROM_OFFSET(address);
if (offset == 0 || offset > IROM0_SEGMAX)
usage("\"-a\" absolute address must be valid flash address");
#endif
} else if (IS("-i")) { /* lookup */
lookup = 1;
} else if (IS("-l")) { /* list */
++listing;
} else if (IS("-m")) { /* specify a maximum image size */
flash = lookup = 1;
maxSize = strtol(argv[++i], NULL, 0);
if (maxSize & 0xFFF)
usage("\"-m\" maximum size must be a multiple of 4,096");
} else if (IS("-o")) { /* output file */
output = argv[++i];
if (output == NULL || *output == 0 || ( *output == '-' && output[1] != 0))
usage("'-o' needs argument");
if (IS("-")) output = NULL;
} else if (IS("-p")) { /* parse only */
dumping = 0;
} else if (IS("-s")) { /* strip debug information */
stripping = 1;
} else if (IS("-v")) { /* show version */
++version;
} else { /* unknown option */
usage(argv[i]);
}
}
if (offset>0 && (output == NULL || LFSimageName == NULL ||
execute != NULL || i != argc))
usage("'-a' also requires '-o' and '-f' options without lua source files");
if (i == argc && (listing || !dumping)) {
dumping = 0;
argv[--i] = Output;
}
if (version) {
printf("%s\n", LUA_COPYRIGHT);
if (version == argc - 1) exit(EXIT_SUCCESS);
}
return i;
}
static const char *corename(lua_State *L, const TString *filename, int *len) {
(void)L;
const char *fn = getstr(filename) + 1;
const char *s = strrchr(fn, '/');
if (!s) s = strrchr(fn, '\\');
s = s ? s + 1 : fn;
while ( *s == '.') s++;
const char *e = strchr(s, '.');
if (len)
*len = e ? e - s : strlen(s);
return s;
}
/*
** If the luac command line includes multiple files or has the -f option
** then luac generates a main function to reference all sub-main prototypes.
** This is one of two types:
** Type 0 The standard luac combination main
** Type 1 A lookup wrapper that is used for LFS image dumps
*/
#define toproto(L, i) getproto(L->top + (i))
static const Proto *combine(lua_State *L, int n, int type) {
if (n == 1 && type == 0) {
return toproto(L, -1);
} else {
Proto *f;
int i, j;
/*
* Generate a minimal proto with 1 return, emtpy p, k & uv vectors
*/
if (luaL_loadbuffer(L, "\n", strlen("\n"), "=("PROGNAME ")") != LUA_OK)
fatal(lua_tostring(L, -1));
f = toproto(L, -1);
/*
* Allocate the vector for and bind the sub-protos
*/
luaM_reallocvector(L, f->p, f->sizep, n, Proto *);
f->sizep = n;
for (i = 0; i < n; i++) {
f->p[i] = toproto(L, i - n - 1);
if (f->p[i]->sizeupvalues > 0)
f->p[i]->upvalues[0].instack = 0;
}
f->numparams = 0;
f->maxstacksize = 1;
if (type == 1) {
/*
* For Type 1 main(), add a k vector of strings naming the corresponding
* protos with the Unixtime of the compile appended.
*/
luaM_reallocvector(L, f->k, f->sizek, n+1, TValue);
f->sizek = n + 1;
for (i = 0; i < n; i++) {
int len;
const char *name = corename(L, f->p[i]->source, &len);
TString* sname = luaS_newlstr(L, name, len);
for (j = 0; j < i; j++) {
if (tsvalue(f->k+j) == sname)
fatal(lua_pushfstring(L, "Cannot have duplicate files ('%s') in LFS", name));
}
setsvalue2n(L, f->k+i, sname);
}
setivalue(f->k+n, (lua_Integer) time(NULL));
}
return f;
}
}
static int writer(lua_State *L, const void *p, size_t size, void *u) {
UNUSED(L);
return (fwrite(p, size, 1, ((FILE **)u)[0]) != 1) && (size != 0);
}
static int msghandler (lua_State *L) {
const char *msg = lua_tostring(L, 1);
if (msg == NULL) /* is error object not a string? */
msg = lua_pushfstring(L, "(error object is a %s value)", luaL_typename(L, 1));
luaL_traceback(L, L, msg, 1); /* append a standard traceback */
return 1; /* return the traceback */
}
static int dofile (lua_State *L, const char *name) {
int status = luaL_loadfile(L, name);
if (status == LUA_OK) {
int base = lua_gettop(L);
lua_pushcfunction(L, msghandler); /* push message handler */
lua_insert(L, base); /* put it under function and args */
status = lua_pcall(L, 0, 0, base);
lua_remove(L, base); /* remove message handler from the stack */
}
if (status != LUA_OK) {
fprintf(stderr, "%s: %s\n", PROGNAME, lua_tostring(L, -1));
lua_pop(L, 1); /* remove message */
}
return status;
}
/*
** This function is an inintended consequence of constraints in ltable.c
** rotable_findentry(). The file list generates a ROTable in LFS and the
** rule for ROTables is that metavalue entries must be at the head of the
** ROTableentry list so argv file names with basenames starting with "__"
** must be head of the list. This is a botch. Sorry.
*/
static void reorderfiles(lua_State *L, int argc, char **list, char **argv) {
int i, j;
for (i = 0; i < argc; i++ ) {
TString *file = luaS_new(L,argv[i]);
if (strcmp("__", corename(L, file, NULL))) {
list[i] = argv[i]; /* add to the end of the new list */
} else {
for (j = 0; j < i; j++)
list[j+1] = list[j];
list[0] = argv[i]; /* add to the start of the new list */
}
}
}
static int pmain(lua_State *L) {
int argc = (int) lua_tointeger(L, 1);
char **argv = (char **) lua_touserdata(L, 2);
char **filelist = alloca(argc * sizeof(char *));
const Proto *f;
int i, status;
if (!lua_checkstack(L, argc + 1))
fatal("too many input files");
if (execute || address) {
luaL_openlibs(L); /* the nodemcu open will throw to signal an LFS reload */
status = dofile(L, execute);
if (status != LUA_OK)
return 0;
}
if (argc == 0)
return 0;
reorderfiles(L, argc, filelist, argv);
for (i = 0; i < argc; i++) {
const char *filename = IS("-") ? NULL : filelist[i];
if (luaL_loadfile(L, filename) != LUA_OK)
fatal(lua_tostring(L, -1));
//TODO: if strip = 2, replace proto->source by basename
}
f = combine(L, argc + (execute ? 1 : 0), lookup);
if (listing) luaU_print(f, listing > 1);
if (dumping) {
int result;
FILE *D = (output == NULL) ? stdout : fopen(output, "wb");
if (D == NULL) cannot("open");
lua_lock(L);
if (flash) {
UNUSED(address);
UNUSED(maxSize);
result = luaU_DumpAllProtos(L, f, writer, &D, stripping);
} else {
result = luaU_dump(L, f, writer, cast(void *, &D), stripping);
}
lua_unlock(L);
if (result == LUA_ERR_CC_INTOVERFLOW)
fatal("value too big or small for target integer type");
if (result == LUA_ERR_CC_NOTINTEGER)
fatal("target lua_Number is integral but fractional value found");
if (ferror(D)) cannot("write");
if (fclose(D)) cannot("close");
}
return 0;
}
int main(int argc, char *argv[]) {
lua_State *L;
int i = doargs(argc, argv);
int j, status;
argc -= i; argv += i;
if (argc <= 0 && execute == 0 && address == 0) usage("no input files given");
if (address)
luaN_setabsolute(address);
for (j = 0; j < 2 ; j++) {
L = luaL_newstate();
if (L == NULL) fatal("not enough memory for state");
lua_pushcfunction(L, &pmain);
lua_pushinteger(L, argc);
lua_pushlightuserdata(L, argv);
status = lua_pcall(L, 2, 0, 0);
if (status != LUA_OK) {
const char *res = luaL_optstring(L, -1, "");
if (strcmp(res, "!LFSrestart!") == 0) {
/*An LFS image has been loaded */
if (address) { /* write out as absolute image and exit */
lu_int32 size = cast(LFSHeader *, LFSregion)->flash_size;
FILE *af = fopen(output, "wb");
if (af == NULL) cannot("open");
if (fwrite(LFSregion, size, 1, af) != 1) cannot("write");
fclose(af);
exit(0);
}
/*otherwise simulate a restart */
lua_close(L);
continue; /* and loop around once more simulating restart */
}
char *err = strdup(lua_tostring(L, -1));
lua_close(L);
fatal(err);
}
lua_close(L);
break;
}
return EXIT_SUCCESS;
}
/*
** $Id: luac.c,v 1.76 2018/06/19 01:32:02 lhf Exp $
** print bytecodes
** See Copyright Notice in lua.h
*/
#include <ctype.h>
#include <stdio.h>
#define luac_c
#define LUA_CORE
#include "ldebug.h"
#include "lobject.h"
#include "lopcodes.h"
#define VOID(p) ((const void*)(p))
static void PrintString(const TString* ts)
{
const char* s=getstr(ts);
size_t i,n=tsslen(ts);
printf("%c",'"');
for (i=0; i<n; i++)
{
int c=(int)(unsigned char)s[i];
switch (c)
{
case '"': printf("\\\""); break;
case '\\': printf("\\\\"); break;
case '\a': printf("\\a"); break;
case '\b': printf("\\b"); break;
case '\f': printf("\\f"); break;
case '\n': printf("\\n"); break;
case '\r': printf("\\r"); break;
case '\t': printf("\\t"); break;
case '\v': printf("\\v"); break;
default: if (isprint(c))
printf("%c",c);
else
printf("\\%03d",c);
}
}
printf("%c",'"');
}
static void PrintConstant(const Proto* f, int i)
{
const TValue* o=&f->k[i];
switch (ttype(o))
{
case LUA_TNIL:
printf("nil");
break;
case LUA_TBOOLEAN:
printf(bvalue(o) ? "true" : "false");
break;
case LUA_TNUMFLT:
{
char buff[100];
sprintf(buff,LUA_NUMBER_FMT,fltvalue(o));
printf("%s",buff);
if (buff[strspn(buff,"-0123456789")]=='\0') printf(".0");
break;
}
case LUA_TNUMINT:
printf(LUA_INTEGER_FMT,ivalue(o));
break;
case LUA_TSHRSTR: case LUA_TLNGSTR:
PrintString(tsvalue(o));
break;
default: /* cannot happen */
printf("? type=%d",ttype(o));
break;
}
}
#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-")
#define MYK(x) (-1-(x))
static void PrintCode(const Proto* f)
{
const Instruction* code=f->code;
int pc,n=f->sizecode;
for (pc=0; pc<n; pc++)
{
Instruction i=code[pc];
OpCode o=GET_OPCODE(i);
int a=GETARG_A(i);
int b=GETARG_B(i);
int c=GETARG_C(i);
int ax=GETARG_Ax(i);
int bx=GETARG_Bx(i);
int sbx=GETARG_sBx(i);
int line=getfuncline(f,pc);
printf("\t%d\t",pc+1);
if (line>0) printf("[%d]\t",line); else printf("[-]\t");
printf("%-9s\t",luaP_opnames[o]);
switch (getOpMode(o))
{
case iABC:
printf("%d",a);
if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (MYK(INDEXK(b))) : b);
if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (MYK(INDEXK(c))) : c);
break;
case iABx:
printf("%d",a);
if (getBMode(o)==OpArgK) printf(" %d",MYK(bx));
if (getBMode(o)==OpArgU) printf(" %d",bx);
break;
case iAsBx:
printf("%d %d",a,sbx);
break;
case iAx:
printf("%d",MYK(ax));
break;
}
switch (o)
{
case OP_LOADK:
printf("\t; "); PrintConstant(f,bx);
break;
case OP_GETUPVAL:
case OP_SETUPVAL:
printf("\t; %s",UPVALNAME(b));
break;
case OP_GETTABUP:
printf("\t; %s",UPVALNAME(b));
if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
break;
case OP_SETTABUP:
printf("\t; %s",UPVALNAME(a));
if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); }
if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); }
break;
case OP_GETTABLE:
case OP_SELF:
if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
break;
case OP_SETTABLE:
case OP_ADD:
case OP_SUB:
case OP_MUL:
case OP_MOD:
case OP_POW:
case OP_DIV:
case OP_IDIV:
case OP_BAND:
case OP_BOR:
case OP_BXOR:
case OP_SHL:
case OP_SHR:
case OP_EQ:
case OP_LT:
case OP_LE:
if (ISK(b) || ISK(c))
{
printf("\t; ");
if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
printf(" ");
if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
}
break;
case OP_JMP:
case OP_FORLOOP:
case OP_FORPREP:
case OP_TFORLOOP:
printf("\t; to %d",sbx+pc+2);
break;
case OP_CLOSURE:
printf("\t; %p",VOID(f->p[bx]));
break;
case OP_SETLIST:
if (c==0) printf("\t; %d",(int)code[++pc]); else printf("\t; %d",c);
break;
case OP_EXTRAARG:
printf("\t; "); PrintConstant(f,ax);
break;
default:
break;
}
printf("\n");
}
}
#define SS(x) ((x==1)?"":"s")
#define S(x) (int)(x),SS(x)
static void PrintHeader(const Proto* f)
{
const char* s=f->source ? getstr(f->source) : "=?";
if (*s=='@' || *s=='=')
s++;
else if (*s==LUA_SIGNATURE[0])
s="(bstring)";
else
s="(string)";
printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n",
(f->linedefined==0)?"main":"function",s,
f->linedefined,f->lastlinedefined,
S(f->sizecode),VOID(f));
printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
(int)(f->numparams),f->is_vararg?"+":"",SS(f->numparams),
S(f->maxstacksize),S(f->sizeupvalues));
printf("%d local%s, %d constant%s, %d function%s\n",
S(f->sizelocvars),S(f->sizek),S(f->sizep));
}
static void PrintDebug(const Proto* f)
{
int i,n;
n=f->sizek;
printf("constants (%d) for %p:\n",n,VOID(f));
for (i=0; i<n; i++)
{
printf("\t%d\t",i+1);
PrintConstant(f,i);
printf("\n");
}
n=f->sizelocvars;
printf("locals (%d) for %p:\n",n,VOID(f));
for (i=0; i<n; i++)
{
printf("\t%d\t%s\t%d\t%d\n",
i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
}
n=f->sizeupvalues;
printf("upvalues (%d) for %p:\n",n,VOID(f));
for (i=0; i<n; i++)
{
printf("\t%d\t%s\t%d\t%d\n",
i,UPVALNAME(i),f->upvalues[i].instack,f->upvalues[i].idx);
}
}
static void PrintFunction(const Proto* f, int full)
{
int i,n=f->sizep;
PrintHeader(f);
PrintCode(f);
if (full) PrintDebug(f);
for (i=0; i<n; i++) PrintFunction(f->p[i],full);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,24 @@
/*
** $Id: lapi.h,v 2.9.1.1 2017/04/19 17:20:42 roberto Exp $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/
#ifndef lapi_h
#define lapi_h
#include "llimits.h"
#include "lstate.h"
#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \
"stack overflow");}
#define adjustresults(L,nres) \
{ if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \
"not enough elements in the stack")
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,306 @@
/*
** $Id: lauxlib.h,v 1.131.1.1 2017/04/19 17:20:42 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
#ifndef lauxlib_h
#define lauxlib_h
#include <stddef.h>
#include <stdio.h>
#include "lua.h"
#ifdef LUA_LIB
#include "lnodemcu.h"
#endif
/* extra error code for 'luaL_loadfilex' */
#define LUA_ERRFILE (LUA_ERRERR+1)
/* key, in the registry, for table of loaded modules */
#define LUA_LOADED_TABLE "_LOADED"
/* key, in the registry, for table of preloaded loaders */
#define LUA_PRELOAD_TABLE "_PRELOAD"
typedef struct luaL_Reg {
const char *name;
lua_CFunction func;
} luaL_Reg;
#define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number))
LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz);
#define luaL_checkversion(L) \
luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES)
LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg);
LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg,
size_t *l);
LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg,
const char *def, size_t *l);
LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg);
LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def);
LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg);
LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg,
lua_Integer def);
LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t);
LUALIB_API void (luaL_checkany) (lua_State *L, int arg);
LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname);
LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
LUALIB_API int (luaL_rometatable) (lua_State *L, const char* tname, const ROTable *p);
LUALIB_API void (luaL_where) (lua_State *L, int lvl);
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def,
const char *const lst[]);
LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
/* predefined references */
#define LUA_NOREF (-2)
#define LUA_REFNIL (-1)
LUALIB_API int (luaL_ref) (lua_State *L, int t);
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
#define luaL_unref2(l,t,r) do {luaL_unref(L, (t), (r)); r = LUA_NOREF;} while (0)
LUALIB_API void (luaL_reref) (lua_State *L, int t, int *ref);
LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
const char *mode);
#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL)
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,
const char *r);
LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname);
LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1,
const char *msg, int level);
LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
lua_CFunction openf, int glb);
/*
** ===============================================================
** some useful macros
** ===============================================================
*/
#define luaL_newlibtable(L,l) \
lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
#define luaL_newlib(L,l) \
(luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
#define luaL_argcheck(L, cond,arg,extramsg) \
((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
#define luaL_dofile(L, fn) \
(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
#define luaL_dostring(L, s) \
(luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL)
#define luaL_checkfunction(L,n) luaL_checktype(L, (n), LUA_TFUNCTION);
#define luaL_checktable(L,n) luaL_checktype(L, (n), LUA_TTABLE);
/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/
typedef struct luaL_Buffer {
char *b; /* buffer address */
size_t size; /* buffer size */
size_t n; /* number of characters in buffer */
lua_State *L;
char initb[LUAL_BUFFERSIZE]; /* initial buffer */
} luaL_Buffer;
#define luaL_addchar(B,c) \
((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \
((B)->b[(B)->n++] = (c)))
#define luaL_addsize(B,s) ((B)->n += (s))
LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz);
LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
/* }====================================================== */
/*
** {======================================================
** File handles for IO library
** =======================================================
*/
/*
** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and
** initial structure 'luaL_Stream' (it may contain other fields
** after that initial structure).
*/
#define LUA_FILEHANDLE "FILE*"
typedef struct luaL_Stream {
FILE *f; /* stream (NULL for incompletely created streams) */
lua_CFunction closef; /* to close stream (NULL for closed streams) */
} luaL_Stream;
/* }====================================================== */
LUALIB_API int (luaL_rometatable) (lua_State *L, const char* tname, const ROTable *t);
/* }====================================================== */
/* compatibility with old module system */
#if defined(LUA_COMPAT_MODULE)
LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
int sizehint);
LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
const luaL_Reg *l, int nup);
#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0))
#endif
/*
** {==================================================================
** "Abstraction Layer" for basic report of messages and errors
** ===================================================================
*/
/* print a string */
#if !defined(lua_writestring)
#ifdef LUA_USE_ESP
void output_redirect(const char *str, size_t l);
#define lua_writestring(s,l) output_redirect((s),(l))
#else
#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
#endif
#endif
/* print a newline and flush the output */
#if !defined(lua_writeline)
#ifdef LUA_USE_ESP8266
#define lua_writeline() lua_writestring("\n", 1)
#else
#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout))
#endif
#endif
/* print an error message. This is a primitive error output */
#if !defined(lua_writestringerror)
#ifdef LUA_USE_ESP8266
extern void dbg_printf(const char *fmt, ...);
#define lua_writestringerror(s,p) dbg_printf((s), (p))
#else
#define lua_writestringerror(s,p) (fprintf(stderr, (s), (p)), fflush(stderr))
#endif
#endif
/* }================================================================== */
/*
** {============================================================
** Compatibility with deprecated conversions
** =============================================================
*/
#if defined(LUA_COMPAT_APIINTCASTS)
#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a))
#define luaL_optunsigned(L,a,d) \
((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d)))
#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
#endif
/* }============================================================ */
/*
** {==================================================================
** NodeMCU extensions
** ===================================================================
*/
#define LUA_TASK_LOW 0
#define LUA_TASK_MEDIUM 1
#define LUA_TASK_HIGH 2
LUALIB_API int (luaL_pushlfsmodules) (lua_State *L);
LUALIB_API int (luaL_pushlfsdts) (lua_State *L);
LUALIB_API void (luaL_lfsreload) (lua_State *L);
LUALIB_API int (luaL_posttask) (lua_State* L, int prio);
LUALIB_API int (luaL_pcallx) (lua_State *L, int narg, int nres);
#define luaL_pushlfsmodule(l) lua_pushlfsfunc(L)
/* }============================================================ */
#ifndef LUA_CROSS_COMPILER
int panic_get_nvval(void);
void panic_clear_nvval(void);
#endif
#endif

View File

@ -0,0 +1,525 @@
/*
** $Id: lbaselib.c,v 1.314.1.1 2017/04/19 17:39:34 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
#define lbaselib_c
#define LUA_LIB
#include "lprefix.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
static int luaB_print (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
int i;
lua_getglobal(L, "tostring");
for (i=1; i<=n; i++) {
const char *s;
size_t l;
lua_pushvalue(L, -1); /* function to be called */
lua_pushvalue(L, i); /* value to print */
lua_call(L, 1, 1);
s = lua_tolstring(L, -1, &l); /* get result */
if (s == NULL)
return luaL_error(L, "'tostring' must return a string to 'print'");
if (i>1) lua_writestring("\t", 1);
lua_writestring(s, l);
lua_pop(L, 1); /* pop result */
}
lua_writeline();
return 0;
}
#define SPACECHARS " \f\n\r\t\v"
static const char *b_str2int (const char *s, int base, lua_Integer *pn) {
lua_Unsigned n = 0;
int neg = 0;
s += strspn(s, SPACECHARS); /* skip initial spaces */
if (*s == '-') { s++; neg = 1; } /* handle signal */
else if (*s == '+') s++;
if (!isalnum((unsigned char)*s)) /* no digit? */
return NULL;
do {
int digit = (isdigit((unsigned char)*s)) ? *s - '0'
: (toupper((unsigned char)*s) - 'A') + 10;
if (digit >= base) return NULL; /* invalid numeral */
n = n * base + digit;
s++;
} while (isalnum((unsigned char)*s));
s += strspn(s, SPACECHARS); /* skip trailing spaces */
*pn = (lua_Integer)((neg) ? (0u - n) : n);
return s;
}
static int luaB_tonumber (lua_State *L) {
if (lua_isnoneornil(L, 2)) { /* standard conversion? */
luaL_checkany(L, 1);
if (lua_type(L, 1) == LUA_TNUMBER) { /* already a number? */
lua_settop(L, 1); /* yes; return it */
return 1;
}
else {
size_t l;
const char *s = lua_tolstring(L, 1, &l);
if (s != NULL && lua_stringtonumber(L, s) == l + 1)
return 1; /* successful conversion to number */
/* else not a number */
}
}
else {
size_t l;
const char *s;
lua_Integer n = 0; /* to avoid warnings */
lua_Integer base = luaL_checkinteger(L, 2);
luaL_checktype(L, 1, LUA_TSTRING); /* no numbers as strings */
s = lua_tolstring(L, 1, &l);
luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
if (b_str2int(s, (int)base, &n) == s + l) {
lua_pushinteger(L, n);
return 1;
} /* else not a number */
} /* else not a number */
lua_pushnil(L); /* not a number */
return 1;
}
static int luaB_error (lua_State *L) {
int level = (int)luaL_optinteger(L, 2, 1);
lua_settop(L, 1);
if (lua_type(L, 1) == LUA_TSTRING && level > 0) {
luaL_where(L, level); /* add extra information */
lua_pushvalue(L, 1);
lua_concat(L, 2);
}
return lua_error(L);
}
static int luaB_getmetatable (lua_State *L) {
luaL_checkany(L, 1);
if (!lua_getmetatable(L, 1)) {
lua_pushnil(L);
return 1; /* no metatable */
}
luaL_getmetafield(L, 1, "__metatable");
return 1; /* returns either __metatable field (if present) or metatable */
}
static int luaB_setmetatable (lua_State *L) {
int t = lua_type(L, 2);
luaL_checktype(L, 1, LUA_TTABLE);
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
"nil or table expected");
if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL)
return luaL_error(L, "cannot change a protected metatable");
lua_settop(L, 2);
lua_setmetatable(L, 1);
return 1;
}
static int luaB_rawequal (lua_State *L) {
luaL_checkany(L, 1);
luaL_checkany(L, 2);
lua_pushboolean(L, lua_rawequal(L, 1, 2));
return 1;
}
static int luaB_rawlen (lua_State *L) {
int t = lua_type(L, 1);
luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1,
"table or string expected");
lua_pushinteger(L, lua_rawlen(L, 1));
return 1;
}
static int luaB_rawget (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkany(L, 2);
lua_settop(L, 2);
lua_rawget(L, 1);
return 1;
}
static int luaB_rawset (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkany(L, 2);
luaL_checkany(L, 3);
lua_settop(L, 3);
lua_rawset(L, 1);
return 1;
}
static int luaB_collectgarbage (lua_State *L) {
static const char *const opts[] = {"stop", "restart", "collect",
"count", "step", "setpause", "setstepmul", "setmemlimit",
"isrunning", NULL};
static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
LUA_GCISRUNNING};
int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
int ex = (int)luaL_optinteger(L, 2, 0);
int res = lua_gc(L, o, ex);
switch (o) {
case LUA_GCCOUNT: {
int b = lua_gc(L, LUA_GCCOUNTB, 0);
lua_pushnumber(L, (lua_Number)res + ((lua_Number)b/1024));
return 1;
}
case LUA_GCSTEP: case LUA_GCISRUNNING: {
lua_pushboolean(L, res);
return 1;
}
default: {
lua_pushinteger(L, res);
return 1;
}
}
}
static int luaB_type (lua_State *L) {
int t = lua_type(L, 1);
luaL_argcheck(L, t != LUA_TNONE, 1, "value expected");
lua_pushstring(L, lua_typename(L, t));
return 1;
}
static int pairsmeta (lua_State *L, const char *method, int iszero,
lua_CFunction iter) {
luaL_checkany(L, 1);
if (luaL_getmetafield(L, 1, method) == LUA_TNIL) { /* no metamethod? */
lua_pushcfunction(L, iter); /* will return generator, */
lua_pushvalue(L, 1); /* state, */
if (iszero) lua_pushinteger(L, 0); /* and initial value */
else lua_pushnil(L);
}
else {
lua_pushvalue(L, 1); /* argument 'self' to metamethod */
lua_call(L, 1, 3); /* get 3 values from metamethod */
}
return 3;
}
static int luaB_next (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 2); /* create a 2nd argument if there isn't one */
if (lua_next(L, 1))
return 2;
else {
lua_pushnil(L);
return 1;
}
}
static int luaB_pairs (lua_State *L) {
return pairsmeta(L, "__pairs", 0, luaB_next);
}
/*
** Traversal function for 'ipairs'
*/
static int ipairsaux (lua_State *L) {
lua_Integer i = luaL_checkinteger(L, 2) + 1;
lua_pushinteger(L, i);
return (lua_geti(L, 1, i) == LUA_TNIL) ? 1 : 2;
}
/*
** 'ipairs' function. Returns 'ipairsaux', given "table", 0.
** (The given "table" may not be a table.)
*/
static int luaB_ipairs (lua_State *L) {
#if defined(LUA_COMPAT_IPAIRS)
return pairsmeta(L, "__ipairs", 1, ipairsaux);
#else
luaL_checkany(L, 1);
lua_pushcfunction(L, ipairsaux); /* iteration function */
lua_pushvalue(L, 1); /* state */
lua_pushinteger(L, 0); /* initial value */
return 3;
#endif
}
static int load_aux (lua_State *L, int status, int envidx) {
if (status == LUA_OK) {
if (envidx != 0) { /* 'env' parameter? */
lua_pushvalue(L, envidx); /* environment for loaded function */
if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */
lua_pop(L, 1); /* remove 'env' if not used by previous call */
}
return 1;
}
else { /* error (message is on top of the stack) */
lua_pushnil(L);
lua_insert(L, -2); /* put before error message */
return 2; /* return nil plus error message */
}
}
static int luaB_loadfile (lua_State *L) {
const char *fname = luaL_optstring(L, 1, NULL);
const char *mode = luaL_optstring(L, 2, NULL);
int env = (!lua_isnone(L, 3) ? 3 : 0); /* 'env' index or 0 if no 'env' */
int status = luaL_loadfilex(L, fname, mode);
return load_aux(L, status, env);
}
/*
** {======================================================
** Generic Read function
** =======================================================
*/
/*
** reserved slot, above all arguments, to hold a copy of the returned
** string to avoid it being collected while parsed. 'load' has four
** optional arguments (chunk, source name, mode, and environment).
*/
#define RESERVEDSLOT 5
/*
** Reader for generic 'load' function: 'lua_load' uses the
** stack for internal stuff, so the reader cannot change the
** stack top. Instead, it keeps its resulting string in a
** reserved slot inside the stack.
*/
static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
(void)(ud); /* not used */
luaL_checkstack(L, 2, "too many nested functions");
lua_pushvalue(L, 1); /* get function */
lua_call(L, 0, 1); /* call it */
if (lua_isnil(L, -1)) {
lua_pop(L, 1); /* pop result */
*size = 0;
return NULL;
}
else if (!lua_isstring(L, -1))
luaL_error(L, "reader function must return a string");
lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */
return lua_tolstring(L, RESERVEDSLOT, size);
}
static int luaB_load (lua_State *L) {
int status;
size_t l;
const char *s = lua_tolstring(L, 1, &l);
const char *mode = luaL_optstring(L, 3, "bt");
int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */
if (s != NULL) { /* loading a string? */
const char *chunkname = luaL_optstring(L, 2, s);
status = luaL_loadbufferx(L, s, l, chunkname, mode);
}
else { /* loading from a reader function */
const char *chunkname = luaL_optstring(L, 2, "=(load)");
luaL_checktype(L, 1, LUA_TFUNCTION);
lua_settop(L, RESERVEDSLOT); /* create reserved slot */
status = lua_load(L, generic_reader, NULL, chunkname, mode);
}
return load_aux(L, status, env);
}
/* }====================================================== */
static int dofilecont (lua_State *L, int d1, lua_KContext d2) {
(void)d1; (void)d2; /* only to match 'lua_Kfunction' prototype */
return lua_gettop(L) - 1;
}
static int luaB_dofile (lua_State *L) {
const char *fname = luaL_optstring(L, 1, NULL);
lua_settop(L, 1);
if (luaL_loadfile(L, fname) != LUA_OK)
return lua_error(L);
lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
return dofilecont(L, 0, 0);
}
static int luaB_assert (lua_State *L) {
if (lua_toboolean(L, 1)) /* condition is true? */
return lua_gettop(L); /* return all arguments */
else { /* error */
luaL_checkany(L, 1); /* there must be a condition */
lua_remove(L, 1); /* remove it */
lua_pushliteral(L, "assertion failed!"); /* default message */
lua_settop(L, 1); /* leave only message (default if no other one) */
return luaB_error(L); /* call 'error' */
}
}
static int luaB_select (lua_State *L) {
int n = lua_gettop(L);
if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
lua_pushinteger(L, n-1);
return 1;
}
else {
lua_Integer i = luaL_checkinteger(L, 1);
if (i < 0) i = n + i;
else if (i > n) i = n;
luaL_argcheck(L, 1 <= i, 1, "index out of range");
return n - (int)i;
}
}
/*
** Continuation function for 'pcall' and 'xpcall'. Both functions
** already pushed a 'true' before doing the call, so in case of success
** 'finishpcall' only has to return everything in the stack minus
** 'extra' values (where 'extra' is exactly the number of items to be
** ignored).
*/
static int finishpcall (lua_State *L, int status, lua_KContext extra) {
if (status != LUA_OK && status != LUA_YIELD) { /* error? */
lua_pushboolean(L, 0); /* first result (false) */
lua_pushvalue(L, -2); /* error message */
return 2; /* return false, msg */
}
else
return lua_gettop(L) - (int)extra; /* return all results */
}
static int luaB_pcall (lua_State *L) {
int status;
luaL_checkany(L, 1);
lua_pushboolean(L, 1); /* first result if no errors */
lua_insert(L, 1); /* put it in place */
status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, finishpcall);
return finishpcall(L, status, 0);
}
/*
** Do a protected call with error handling. After 'lua_rotate', the
** stack will have <f, err, true, f, [args...]>; so, the function passes
** 2 to 'finishpcall' to skip the 2 first values when returning results.
*/
static int luaB_xpcall (lua_State *L) {
int status;
int n = lua_gettop(L);
luaL_checktype(L, 2, LUA_TFUNCTION); /* check error function */
lua_pushboolean(L, 1); /* first result */
lua_pushvalue(L, 1); /* function */
lua_rotate(L, 3, 2); /* move them below function's arguments */
status = lua_pcallk(L, n - 2, LUA_MULTRET, 2, 2, finishpcall);
return finishpcall(L, status, 2);
}
static int luaB_tostring (lua_State *L) {
luaL_checkany(L, 1);
luaL_tolstring(L, 1, NULL);
return 1;
}
#if defined(LUA_COMPAT_UNPACK)
static int luaB_unpack (lua_State *L) {
int n = lua_gettop(L); /* number of elements to pack */
lua_getglobal(L, "table");
lua_getfield(L, -1, "unpack");
lua_insert(L, 1);
lua_pop(L, 1);
lua_call(L, n, LUA_MULTRET);
return lua_gettop(L);
}
#endif
/*
** ESP builds use specific linker directives to marshal all the ROTable entries
** for the library modules including the base library into an entry vector in
** the PSECT ".lua_rotable" including the base library entries; this is bound
** into a ROTable in linit.c which then hooked into the __index metaentry for
** _G so that base library and ROM tables are directly resolved through _G.
**
** The host-based luac.cross builds which must use a standard GNU link or
** MSVC so this linker-specfic assembly approach can't be used. In this case
** luaopen_base returns a base_func ROTable so a two cascade resolution. See
** description in init.c for further details.
*/
#ifdef LUA_CROSS_COMPILER
LROT_BEGIN(base_func, NULL, 0)
#else
LROT_ENTRIES_IN_SECTION(base_func, rotable)
#endif
LROT_FUNCENTRY(assert, luaB_assert)
LROT_FUNCENTRY(collectgarbage, luaB_collectgarbage)
LROT_FUNCENTRY(dofile, luaB_dofile)
LROT_FUNCENTRY(error, luaB_error)
LROT_FUNCENTRY(getmetatable, luaB_getmetatable)
LROT_FUNCENTRY(ipairs, luaB_ipairs)
LROT_FUNCENTRY(loadfile, luaB_loadfile)
LROT_FUNCENTRY(load, luaB_load)
#if defined(LUA_COMPAT_LOADSTRING)
LROT_FUNCENTRY(loadstring, luaB_load)
#endif
LROT_FUNCENTRY(next, luaB_next)
LROT_FUNCENTRY(pairs, luaB_pairs)
LROT_FUNCENTRY(pcall, luaB_pcall)
LROT_FUNCENTRY(print, luaB_print)
LROT_FUNCENTRY(rawequal, luaB_rawequal)
LROT_FUNCENTRY(rawlen, luaB_rawlen)
LROT_FUNCENTRY(rawget, luaB_rawget)
LROT_FUNCENTRY(rawset, luaB_rawset)
LROT_FUNCENTRY(select, luaB_select)
LROT_FUNCENTRY(setmetatable, luaB_setmetatable)
LROT_FUNCENTRY(tonumber, luaB_tonumber)
LROT_FUNCENTRY(tostring, luaB_tostring)
LROT_FUNCENTRY(type, luaB_type)
#if defined(LUA_COMPAT_UNPACK)
LROT_FUNCENTRY(unpack, luaB_unpack)
#endif
LROT_FUNCENTRY(xpcall, luaB_xpcall)
#ifdef LUA_CROSS_COMPILER
LROT_END(base_func, NULL, 0)
#else
LROT_BREAK(base_func)
#endif
extern LROT_TABLE(rotables);
LUAMOD_API int luaopen_base (lua_State *L) {
lua_pushglobaltable(L); /* set global _G */
lua_pushliteral(L, LUA_VERSION); /* set global _VERSION */
lua_setfield(L, -2, "_VERSION");
lua_createtable (L, 0, 1); /* mt for _G */
lua_pushrotable(L, LROT_TABLEREF(rotables));
lua_setfield(L, -2, "__index"); /* mt.__index=ROM table */
lua_setmetatable(L, -2);
return 1; /* returns _G */
}

View File

@ -0,0 +1,233 @@
/*
** $Id: lbitlib.c,v 1.30.1.1 2017/04/19 17:20:42 roberto Exp $
** Standard library for bitwise operations
** See Copyright Notice in lua.h
*/
#define lbitlib_c
#define LUA_LIB
#include "lprefix.h"
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#if defined(LUA_COMPAT_BITLIB) /* { */
#define pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n))
#define checkunsigned(L,i) ((lua_Unsigned)luaL_checkinteger(L,i))
/* number of bits to consider in a number */
#if !defined(LUA_NBITS)
#define LUA_NBITS 32
#endif
/*
** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must
** be made in two parts to avoid problems when LUA_NBITS is equal to the
** number of bits in a lua_Unsigned.)
*/
#define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
/* macro to trim extra bits */
#define trim(x) ((x) & ALLONES)
/* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */
#define mask(n) (~((ALLONES << 1) << ((n) - 1)))
static lua_Unsigned andaux (lua_State *L) {
int i, n = lua_gettop(L);
lua_Unsigned r = ~(lua_Unsigned)0;
for (i = 1; i <= n; i++)
r &= checkunsigned(L, i);
return trim(r);
}
static int b_and (lua_State *L) {
lua_Unsigned r = andaux(L);
pushunsigned(L, r);
return 1;
}
static int b_test (lua_State *L) {
lua_Unsigned r = andaux(L);
lua_pushboolean(L, r != 0);
return 1;
}
static int b_or (lua_State *L) {
int i, n = lua_gettop(L);
lua_Unsigned r = 0;
for (i = 1; i <= n; i++)
r |= checkunsigned(L, i);
pushunsigned(L, trim(r));
return 1;
}
static int b_xor (lua_State *L) {
int i, n = lua_gettop(L);
lua_Unsigned r = 0;
for (i = 1; i <= n; i++)
r ^= checkunsigned(L, i);
pushunsigned(L, trim(r));
return 1;
}
static int b_not (lua_State *L) {
lua_Unsigned r = ~checkunsigned(L, 1);
pushunsigned(L, trim(r));
return 1;
}
static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) {
if (i < 0) { /* shift right? */
i = -i;
r = trim(r);
if (i >= LUA_NBITS) r = 0;
else r >>= i;
}
else { /* shift left */
if (i >= LUA_NBITS) r = 0;
else r <<= i;
r = trim(r);
}
pushunsigned(L, r);
return 1;
}
static int b_lshift (lua_State *L) {
return b_shift(L, checkunsigned(L, 1), luaL_checkinteger(L, 2));
}
static int b_rshift (lua_State *L) {
return b_shift(L, checkunsigned(L, 1), -luaL_checkinteger(L, 2));
}
static int b_arshift (lua_State *L) {
lua_Unsigned r = checkunsigned(L, 1);
lua_Integer i = luaL_checkinteger(L, 2);
if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1))))
return b_shift(L, r, -i);
else { /* arithmetic shift for 'negative' number */
if (i >= LUA_NBITS) r = ALLONES;
else
r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */
pushunsigned(L, r);
return 1;
}
}
static int b_rot (lua_State *L, lua_Integer d) {
lua_Unsigned r = checkunsigned(L, 1);
int i = d & (LUA_NBITS - 1); /* i = d % NBITS */
r = trim(r);
if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */
r = (r << i) | (r >> (LUA_NBITS - i));
pushunsigned(L, trim(r));
return 1;
}
static int b_lrot (lua_State *L) {
return b_rot(L, luaL_checkinteger(L, 2));
}
static int b_rrot (lua_State *L) {
return b_rot(L, -luaL_checkinteger(L, 2));
}
/*
** get field and width arguments for field-manipulation functions,
** checking whether they are valid.
** ('luaL_error' called without 'return' to avoid later warnings about
** 'width' being used uninitialized.)
*/
static int fieldargs (lua_State *L, int farg, int *width) {
lua_Integer f = luaL_checkinteger(L, farg);
lua_Integer w = luaL_optinteger(L, farg + 1, 1);
luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
if (f + w > LUA_NBITS)
luaL_error(L, "trying to access non-existent bits");
*width = (int)w;
return (int)f;
}
static int b_extract (lua_State *L) {
int w;
lua_Unsigned r = trim(checkunsigned(L, 1));
int f = fieldargs(L, 2, &w);
r = (r >> f) & mask(w);
pushunsigned(L, r);
return 1;
}
static int b_replace (lua_State *L) {
int w;
lua_Unsigned r = trim(checkunsigned(L, 1));
lua_Unsigned v = trim(checkunsigned(L, 2));
int f = fieldargs(L, 3, &w);
lua_Unsigned m = mask(w);
r = (r & ~(m << f)) | ((v & m) << f);
pushunsigned(L, r);
return 1;
}
static const luaL_Reg bitlib[] = {
{"arshift", b_arshift},
{"band", b_and},
{"bnot", b_not},
{"bor", b_or},
{"bxor", b_xor},
{"btest", b_test},
{"extract", b_extract},
{"lrotate", b_lrot},
{"lshift", b_lshift},
{"replace", b_replace},
{"rrotate", b_rrot},
{"rshift", b_rshift},
{NULL, NULL}
};
LUAMOD_API int luaopen_bit32 (lua_State *L) {
luaL_newlib(L, bitlib);
return 0;
}
#else /* }{ */
LUAMOD_API int luaopen_bit32 (lua_State *L) {
return luaL_error(L, "library 'bit32' has been deprecated");
}
#endif /* } */

Some files were not shown because too many files have changed in this diff Show More