完善脱机编程器(可选择复位模式)

D0、D1口线增加TTL UART7串口功能
This commit is contained in:
armfly 2020-04-08 02:04:47 +08:00
parent d42e58f3b7
commit 8577bbe287
116 changed files with 3659 additions and 26792 deletions

View File

@ -1,3 +1,42 @@
----------------------------------------------------------------------------
2020-04-08 V1.10
【修改&新增功能】
1. D0、D1口线增加TTL UART7串口功能lua可以读写该串口。
2. lua接口增加本机按键的访问函数(暂未调通,逻辑还存在问题)
3. lua接口函数modbus_write_u16, 如果只写1个寄存器用06H功能码多个寄存器才用10H功能码。
4. 脱机下载界面如果没接芯片长按S键执行了连续烧录界面会卡住没有提示。
修改为进入连续烧录模式后,按任意键退出连续烧录模式
5. 脱机编程器(缺省使用软件复位模式)
- lua脚本中增加RESET_TYPE变量: RESET_TYPE = 0 -- 0表示软件复位 1表示硬件复位
- 编程参数界面增加复位选项由lua选择、强制硬件复位、强制软件复位
【bug修复】
1. 修正V1.09新出的BUG, lua读取D8 GPIO异常.
2. 修改界面文字错误,"USB eMMM磁盘"更正为"USB eMMC磁盘"
3. lua小程序功能执行一次后再到脱机界面会显示lua小程序的输出窗口。
原因bsp_uart_fifo.c中fputc函数无条件执行LCD_MemoAddChar()函数
4. 屏幕息屏后只能唤醒一次,之后便不会再息屏,切换界面后正常息屏一次,之后又不行。已修复.
【其他】
1. 加入一拖四的源代码备份
- 该功能还未调通仅调试到能够同步读出4个芯片的ID
- 因为硬盘硬件损坏,编写调试了一个月的代码差一点丢失因此推送到git先备份起来
- 供电问题:
- 同时烧写4个芯片会涉及到TVCC供电不足的问题.
- TVCC引脚仅支持400mA
- 5V的引脚只支持1000mA电流5V输出有1个短路限流保护芯片碍事早知不要了
- H7-TOOL主板3.3V电流有270mA,因此无法4个主板同时烧写. 3.3V被拖垮到2.4V
- 上拉电阻问题主板最初只设计了一路SWD接口SWDIO引脚需要上拉电阻其他3路的SWDIO无上拉电阻
- 供电问题和上拉电阻问题可以通过设计一拖四转接板来解决
2. 用户反映运行lua程序界面和脱机界面的按键逻辑和其他的不一样比较不习惯
- 其他界面一般是长按确认执行。但是在这2个界面因为按钮功能需要频繁使用所以设计为短按执行.
- 原来准备修改的,但是没有想到更好的操作逻辑,暂时不改了。
3. 接受网友的建议生成的bin文件名中的全角括号修改为半角括号
4. doc下的修改记录.txt文件取消。内容记录到根目录 CHANGELOG文件.
----------------------------------------------------------------------------
2020-03-12 V1.09
【修改&新增功能】

View File

@ -1,50 +0,0 @@
程序名字: H7-TOOL_App
统一源代码。源代码功能.
1. 逻辑分析仪功能、示波器、虚拟串口、虚拟CAN、I2C控制器、SPI控制器、PWM控制器、GPIO控制
DAC控制、电流检测、编码器输入、频率计.
2. CMSIS DAP下载器功能、USB虚拟串口功能
3. 脱机下载器
- STM32
- EEPROM
- SPI FLASH
function disp(_addr, _len)
init(0xA0,1,8)
s=read(_addr,_len)
s1=""
for i=1,string.len(s),1 do
if (((i - 1) % 16) == 0) then
s1=s1.."\r\n"
end
s1=s1..string.format("%02X ",string.byte(s,i))
end
print(s1)
end
write(0,"12345678",5)
disp(0,32)
for i=0,512,16 do
write(i,"8234567890123456")
end
--- 内存查看 ---
--为了有干净的环境,先把可以收集的其他垃圾赶走先
collectgarbage("collect");
local c1 = collectgarbage("count")
print("最开始,Lua的内存为", c1)
local c2 = collectgarbage("count")
print("结束后,Lua的内存为", c2)

View File

@ -1,246 +0,0 @@
【待解决】
3. qspi_read(), lua连续读取存在问题. 2019-07-07
4. 文件管理界面写字库操作1分钟屏保进入后再唤醒程序实际在刷屏函数中出不来。
2019-12-09 V1.07
1. systick 中断优先级 = 0、 stm32h7xx_hal_conf.h
#define TICK_INT_PRIORITY 0 // ((uint32_t)0x0F) /*!< tick interrupt priority */
2. bsp_CheckRunTime, bsp_GetRunTime 函数内部去掉关闭中断的操作影响QSPI写操作。
----------------------------------------------------------------------------
2020-03-12 V1.09
【修改&新增功能】
1.脱机烧录功能
- 增加STM8芯片STM8S和STM8L系列
- 增加自动识别硬件烧录不同的程序识别算法由lua指定)
- 增加组合烧录比如一键烧写H7-TOOL的boot、app和QSPI Flash
- FLM算法文件和数据文件支持绝对路径和相对路径
- 优化LUA脚本支持读、写保护状态识别自动解除保护状态
- 取消程序文件的大小显示本次计数采用32点阵字体
- 支持PC机联机调试lua程序
- 打印内核ID、flash内容、RAM内容、UID、Option bytes
- 修改和显示目标CPU的RAM和任意寄存器
- 擦除CPU内部Flash、EEPROM
- 加读保护、解除保护
- 启动编程
- 解决无法烧录STM32L0xx芯片的BUGL0系列的Init函数需要传递形参1-2才行
- 烧录时LED快闪烧录成功候常亮烧录失败后熄灭
- 烧录界面增加清零本次计数、清零累计计数功能。修改产品序号功能未做,后面有空再做。
2.LUA
- print_hex 函数支持显示宽度和显示地址
【bug修复】
1.脱机编程算法占用的RAM可以通过lua文件指定V1.08是固定0x1000。 某些片子不够用
2.READ_FMC存在不能及时获取数据问题。解决方法FMC内存空间需要配置为禁止cashe
3.微型数控电源界面如果关闭了蜂鸣器,无法确认是否进入了电压设置状态。
4.00联机模式界面 切换屏幕显示方向时,日期和时间不会显示.
【其他】
1.修改switch case语句缩进格式
----------------------------------------------------------------------------
2020-02-06 V1.08 -- 主要增加脱机烧录功能
1.脱机编程器功能仅STM32芯片
- 通过文件浏览方式选择程序文件。不限制目录和文件个数。
- FLM算法文件从KEIL MDK中复制出来存放到emmc磁盘 \H7-TOOL\Programmer\FLM按厂商分类
- 目标程序文件、编程脚本存放到:\H7-TOOL\Programmer\User 文件夹。不限制目录级别和数量
- 动态解析FLM文件分离出内存镜像通过swd加载到目标cpu ram
- 支持多段bin写入
- 支持option bytes编程烧录完毕设置读保护
- 支持自动解除读保护
- 支持动态填充产品序号、UID加密字段、用户自定义字段
- 自动保存烧录次数,支持剩余次数限制功能
- 支持连续烧录模式检测到IC后自动烧录
- 可动态显示CPU电压和供电电流
- 通过lua脚本配置算法文件和数据文件bin以及控制编程过程
- lua非常灵活可以很方便扩充功能比如
- 日期窗口段内才允许烧录
- 目标板电流超限报警
- 限定UID(CPU唯一序号符合规则的才允许烧录
- UID加密算法由用户自己定义
- 填充任意短数据小于1K),比如可以写入生产日期时间或客户代码
- 关于程序文件保密问题。后期再考虑吧。
- 因为H7-TOOL软件开源,文件结构开源,为了避免程序文件被加工厂泄露,初步设想如下:
- 控制USB虚拟磁盘程序入口增加人工输入密码。
- 在虚拟磁盘扇区读写底层函数以512字节为单位增加客户自定义加密和解密算法。这样emmc数据内容
就是被加密的即使emmc芯片被复制出来放到其他H7-TOOL主板也无法识别。
2.菜单变更
- 联机模式长按S进入扩展功能菜单 : 脱机烧录器、LUA小程序、数据记录仪、系统设置
- 系统设置下级菜单硬件信息、参设设置、ESP32固件升级、USB eMMC磁盘、数据维护
【bug修复】
V1.07 lua新增bug 不在lua小程序界面执行PC机下下载lua程序会死机
- bsp_tft_lcd.c LCD_DrawMemo()函数,增加: 3284行
if (_pMemo->Text == 0)
{
return;
}
----------------------------------------------------------------------------
2019-12-26 V1.07
1.界面切换S键和C键功能交换符合正常逻辑。
2.系统设置界面增加USB磁盘访问eMMC
3.FatFS文件系统建立支持目录浏览
4.中文字库2MB存放到QSPI Flash末尾所有汉字都可以显示了无需CPU内嵌小字库。
5.系统设置界面可以写字库文件也可以刷新boot程序
6.实现Lua小程序脱机运行
7.数据记录仪只做了菜单(功能下个版本实现)
bug修复:
1. USB通信时熄屏后唤醒死机 while (wTransferState == 0){}
- 原因主程序SPI正在DMA传输显示数据按键中断服务程序中执行LCD休眠操作SPI被重置
导致DMA传输不能进入完成中断。
----------------------------------------------------------------------------
2019-12-09 V1.06
1.界面风格重新设计。24点阵、32点阵部分ASCII字符调整齐
2.实现长时间不按键自动熄屏功能
3.修改高侧电流界面120mA判据增加回差控制
4.bsp_key.c按键驱动增加长按弹起事件和短按弹起事件分开处理. 这样处理后
主状态函数中的 uint8_t ucIgnoreKey 忽略按键的代码就可以去掉了。
5.增加脱机烧录器界面(仅界面实现,未实现烧录功能)
6.联机界面增加时钟显示
----------------------------------------------------------------------------
2019-11-30 V1.05b
1.解决上电花屏2秒问题原因logo界面没刷屏
----------------------------------------------------------------------------
2019-11-29 V1.05 - 功能未增加,但是改动比较大,封一个版本。
1.HAL固件库、USB库升级到最新版来自于en.stm32cubeh7 V1.5.0
-所有的GPIO寄存器操作更改为如下宏因为新固件库取消了 BSRRH、BSRRL寄存器
#define BSP_SET_GPIO_1(gpio, pin) gpio->BSRR = pin
#define BSP_SET_GPIO_0(gpio, pin) gpio->BSRR = (uint32_t)pin << 16U
2.显示屏驱动采用SPI+DMA驱动。整屏刷新18ms。驱动由硬汉提供
- 修bsp_tft_st7789.c文件
- bsp_Idle()函数执行 ST7789_DrawScreen(); /* 硬件SPI+DMA+刷屏 */
- 使用0x30000000开始的240*240*2字节内存做显存
3.为了适应后台刷屏机制。所有的 while循环中bsp_Idle() 位置放到显示刷新后面
while (g_MainStatus == MS_CURRENT_METER)
{
if (fRefresh) /* 刷新整个界面 */
{
fRefresh = 0;
DispCurrentVolt();
AutoCurrentRange();
}
bsp_Idle(); /* 必须在fRefresh语句后边, 否则刚进入界面会有闪烁感 */
...
}
----------------------------------------------------------------------------
2019-11-25 V1.04
1.新增脉冲计数和频率计功能。status_pulse_meter.c
2.lua增加串口MODBUS接口函数
3.增加参数设置界面,目前可以关闭蜂鸣器,选择配色风格功能未做。
4.调整配色方案, ui_def.h文件定义颜色
5.部分界面的文字左对齐
6.系统设置-信息信息界面显示固件版本号
7.CDC串口驱动调整。COM切换时不开关USB设备。
8.解决虚拟串口波特率低于2400不正确的bug
9.源代码加入Teeny-usb协议栈未完全调通临时屏蔽了还是用ST的USB库
----------------------------------------------------------------------------
2019-11-04 V1.03b
1.增加微型数控电源。
2.整理bsp_timer.c, bso_tim_pwm.c文件
----------------------------------------------------------------------------
2019-11-03 V1.03a
1.GBK->UTF-8
2.TAB -> 4个空格
3.完善高侧电流表功能:电压、电流、功率、放电容量
4.增加二极管测量,和电阻测量同一个界面。
----------------------------------------------------------------------------
2019-10-20 V1.02
1.lua脚本增加bsp_GetRunTimer等时间函数方便统计时间
2.主程序状态函数重新整理了一下
3.adc均值计算增加滤波算法 bsp_cpu_adc.c
static float AdcSumAvg(uint8_t _AdcNo, uint8_t _Offset)
4.NTC电阻校准点增加到4点。0欧和20欧各一点解决低阻值误差7欧问题。还不完善。
----------------------------------------------------------------------------
2019-10-18 V1.01
1.bsp_CheckRunTime() 函数BUG
2.上电等主界面清蓝屏后再开背光,避免上电黑屏感觉颜色不均问题。
3.MAC地址根据CPU SN修改取值方式。1.00版取的字段不好出来MAC都一样
----------------------------------------------------------------------------
2019-10-17 V1.00
1.发布生产用程序版本
- Lua小程序相对比较完善。已应用到H7-TOOL批量检测
- 示波器功能还存在不少BUG后期再解决。
- 固件升级USB串口方式
- 其他功能均未做
----------------------------------------------------------------------------
2019-09-20 V0.5 - 模拟量校准
1.添加校准寄存器的读写功能
2019-09-13 V0.4 - 调试第6版主板
1. 修改LCD接口GPIO
2.
PA0/TIM2_CH1
----------------------------------------------------------------------------
2019-08-16 V0.4 - 调试emmc
- USB 虚拟磁盘需要在这个地方设置断点等USB枚举才能正常。
usdd_desc.c 文件,函数 uint8_t *USBD_MSC_SerialStrDescriptor
----------------------------------------------------------------------------
2019-08-13 V0.4 - 针对第5版硬件
1. 蜂鸣器 PH12 -- > PG1
2. EIO_D4_Config PH12调整
----------------------------------------------------------------------------
2019-06-29 V0.3 - 针对第4版硬件
1. 针对第4版主板LCD口线调整。用软件方式。
2. 按键
PF5/D7_DIR 改为 PF2/KEY2
PI1/KEY2 已到 PI1/D7_DIR
3. 【D10 TTLTX】- 方向 PE3 = 1 ==> PC6
【D0】 - 方向 PE0/D0_DIR ---> PH8/DO_DIR
----------------------------------------------------------------------------
2019-04-26
----------------------------------------------------------------------------
1. 示波器模块增加STMPE811控制增益和耦合
2.
2019-03-24
----------------------------------------------------------------------------
1. 移植lua
----------------------------------------------------------------------------
2019-02-06 V0.2
3.上电lwip ping 只能持续5秒
----------------------------------------------------------------------------
2019-02-05 V0.2
1.eeprom驱动。解决BUG。
2.添加modbus驱动
----------------------------------------------------------------------------
2018-12-02 V0.1
1. 首版

View File

@ -1,73 +0,0 @@
3. 脱机下载器
- STM32
- EEPROM
- SPI FLASH
-------------------------------------------------------------
64H - 下载LUA程序支持分包传输
主机发送:
01 ; 站号
64 ; 功能码
0100 0000 ; 总长度 4字节
0000 0000 : 偏移地址 4字节
0020 0000 : 本包数据长度 4字节
xx ... xx : 程序数据n个
CCCC : CRC16
从机应答:
01 ; 从机地址
64 ; 功能码
00 ; 执行结果0表示OK 1表示错误
CCCC : CRC16
-------------------------------------------------------------
65H - 执行临时的LUA程序命令帧带程序
主机发送:
01 ; 从机地址
65 ; 功能码
0100 : 本包数据长度 4字节
xxxx : 数据0结束
CCCC : CRC16
从机应答:
01 ; 从机地址
65 ; 功能码
00 ; 执行结果0表示OK 1表示错误
CCCC : CRC16
-------------------------------------------------------------
66H - write file
主机发送:
01 ; 站号
66 ; 功能码
0100 0000 ; 总长度 4字节
0000 0000 : 偏移地址 4字节
0020 0000 : 本包数据长度 4字节
xx ... xx : 数据n个
CCCC : CRC16
从机应答:
01 ; 从机地址
65 ; 功能码
00 ; 执行结果0表示OK 1表示错误
CCCC : CRC16
-------------------------------------------------------------
67H - read file
主机发送:
01 ; 站号
67 ; 功能码
0100 0000 ; 总长度 4字节 -- 先保留,好像用不到
0000 0000 : 偏移地址 4字节
0020 0000 : 数据长度 4字节
CCCC : CRC16
从机应答:
01 ; 从机地址
67 ; 功能码
00 ; 执行结果0表示OK 1表示错误
0000 0000 : 偏移地址 4字节
0000 0000 : 后续数据长度
xxx : 数据体
CCCC : CRC16

View File

@ -1,37 +0,0 @@
/*
lua 增加调试代码的方法:
lobject.c文件:
const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
#if 1
printf("%s", msg);
#endif
ldebug.c 文件 luaG_runerror 函数增加printf
lauxlib.c 文件 luaL_error函数增加printf
ldo.c 文件 luaD_throw 函数 printf("\r\nthrow errcode=%d\r\n", errcode);
lua.h 定义错误代码
#define LUA_ERRRUN 2
#define LUA_ERRSYNTAX 3
#define LUA_ERRMEM 4
#define LUA_ERRGCMM 5
#define LUA_ERRERR 6
一次分配内存不可以大于 MAX_SIZET
*/
/*
luaconf.h 文件对浮点和整数的处理。 缺省64位整数双精度浮点
default configuration for 64-bit Lua ('long long' and 'double')
*/
luaconf.h
#if LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE
#define LUAL_BUFFERSIZE 8192
#else
#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
#endif

View File

@ -1,3 +1,10 @@
--F01=<3D>Զ<EFBFBD>У׼,test_calib()
--F02=---У׼TVCC---,calib_tvcc_volt()
--F03=---У׼DAC<41><43>ѹ<EFBFBD>͵<EFBFBD><CDB5><EFBFBD>---,calib_dac()
--F04=---У׼ʾ<D7BC><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ---,calib_ch1ch2()
--F05=--У׼TVCC<43><43><EFBFBD><EFBFBD><EFBFBD>͸߲<CDB8><DFB2><EFBFBD><EFBFBD><EFBFBD>,calib_curr()
--F06=---У׼NTC---,calib_ntc()
beep()
print("<EFBFBD>ű<EFBFBD><EFBFBD>汾 V1.04 2019-11-28")

View File

@ -1,6 +1,16 @@
--H7-TOOL<4F><4C><EFBFBD><EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD>
--F01=<3D><><EFBFBD><EFBFBD><E5B9A6>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD>,test_gpio()
--F02=TVCC+NTC<54><43><EFBFBD><EFBFBD>,test_tvcc()
--F03=ʾ<><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD>,test_ch1ch2()
--F04=ִ<><D6B4>01-02-03,test_gpio() test_tvcc() test_ch1ch2()
--F05=<3D><><EFBFBD><EFBFBD>ת<EFBFBD>Ӱ<EFBFBD>LED,test_ledout()
--F06=ʱ<><CAB1>,print(os.date())
--F07=<3D><>չ<EFBFBD><D5B9><EFBFBD>̵<EFBFBD><CCB5><EFBFBD>ȫ<EFBFBD><C8AB>,test_extio_open_do()
--F08=<3D><>չ<EFBFBD><D5B9><EFBFBD>̵<EFBFBD><CCB5><EFBFBD>ȫ<EFBFBD><C8AB>,test_extio_close_do()
--F09=<3D><>չ<EFBFBD><D5B9>DI<44><49>ȡ,test_extio_di()
--F10=,close_all()
beep()
print("H7-TOOL<4F><4C><EFBFBD><EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѽ<EFBFBD><D1BC><EFBFBD>")
print("H7-TOOL<4F><4C><EFBFBD><EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѽ<EFBFBD><D1BC><EFBFBD> 2020-01-10")
--<2D><><EFBFBD><EFBFBD>GPIO<49><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function test_gpio(void)
@ -10,23 +20,23 @@ function test_gpio(void)
local time1
print("")
print("----<2D><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>----")
print("----<2D><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>----") delayms(5)
time1 = os.time()
print(os.date())
print(time1)
if (time1 < 1574937149) then
print("*****ʱ<>Ӵ<EFBFBD><D3B4><EFBFBD>*****")
print("*****ʱ<>Ӵ<EFBFBD><D3B4><EFBFBD>*****") delayms(5)
beep()
delayms(100)
beep()
delayms(100)
beep()
else
print("ʱ<EFBFBD><EFBFBD>OK > 1574937149")
print("ʱ<EFBFBD><EFBFBD>OK > 1574937149") delayms(5)
end
print("")
print("----<2D><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>----")
print("") delayms(5)
print("----<2D><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>----") delayms(5)
err=0
terr=0
--<2D><><EFBFBD><EFBFBD>TVCC<43><43><EFBFBD><EFBFBD>3.3V
@ -188,6 +198,7 @@ function test_ch1ch2(void)
local dac2 = {4095, 1024, 512, 256, 128, 64, 32, 16}
local mid2 = {43121, 41400, 37714, 37575, 37556, 37494, 37633, 42601}
local diff2 = {0.2, 0.1, 0.08, 0.08, 0.08, 0.08, 0.12, 0.17}
local str
print("") delayms(5)
print("----<2D><>ʼʾ<CABC><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·----") delayms(5)
@ -205,13 +216,17 @@ function test_ch1ch2(void)
errd = mid1[i] * diff1[i];
if (adc < mid1[i] - errd or adc > mid1[i] + errd) then
err = err + 1
print("dac=", dac) delayms(5)
print(" adc=", adc) delayms(5)
print(" error") delayms(5)
--print("dac=", dac) delayms(5)
--print(" adc=", adc) delayms(5)
--print(" error") delayms(5)
str = string.format("dac=%f adc=%f error", dac, adc)
print(str) delayms(5)
else
print("dac=", dac) delayms(5)
print(" adc=", adc) delayms(5)
print(" ok") delayms(5)
--print("dac=", dac) delayms(5)
--print(" adc=", adc) delayms(5)
--print(" ok") delayms(5)
str = string.format("dac=%f adc=%f ok", dac, adc)
print(str) delayms(5)
end
end
@ -224,13 +239,11 @@ function test_ch1ch2(void)
errd = mid2[i] * diff2[i];
if (adc < mid2[i] - errd or adc > mid2[i] + errd) then
err = err + 1
print("dac=", dac) delayms(5)
print(" adc=", adc) delayms(5)
print(" error") delayms(5)
str = string.format("dac=%f adc=%f error", dac, adc)
print(str) delayms(5)
else
print("dac=", dac) delayms(5)
print(" adc=", adc) delayms(5)
print(" ok") delayms(5)
str = string.format("dac=%f adc=%f ok", dac, adc)
print(str) delayms(5)
end
end
@ -296,7 +309,7 @@ function test_tvcc(void)
if (adc < mid1[i] - errd or adc > mid1[i] + errd) then
err = err + 1
print(name[i], adc, "error") delayms(5)
print(" OK=", mid1[i] - errd, mid1[i] + errd) delayms(5)
print(" <20><>ȷ<EFBFBD><C8B7>Χ = ", mid1[i] - errd, mid1[i] + errd) delayms(5)
else
print(name[i], adc, "ok") delayms(5)
end
@ -312,7 +325,7 @@ function test_tvcc(void)
if (adc < mid2[i] - errd or adc > mid2[i] + errd) then
err = err + 1
print(name[i], adc, "error") delayms(5)
print(" OK=", mid1[i] - errd, mid1[i] + errd) delayms(5)
print(" <20><>ȷ<EFBFBD><C8B7>Χ = ", mid2[i] - errd, mid2[i] + errd) delayms(5)
else
print(name[i], adc, "ok") delayms(5)
end

View File

@ -42,8 +42,12 @@ function cofig_chip1(void)
0x08000000, --Ŀ<><C4BF><EFBFBD><EFBFBD>ַ
AlgoFile_FLASH, --<2D><EFBFBD>ļ<EFBFBD>
"0:/H7-TOOL/Firmware/h7_tool_app.bin", --<2D><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
0x08020000, --Ŀ<><C4BF><EFBFBD><EFBFBD>ַ
"0:/H7-TOOL/Firmware/H7-BOOT.bin", --<2D><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
0x08000000, --Ŀ<><C4BF><EFBFBD><EFBFBD>ַ
-- AlgoFile_FLASH, --<2D><EFBFBD>ļ<EFBFBD>
-- "0:/H7-TOOL/Firmware/h7_tool_app.bin", --<2D><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
-- 0x08020000, --Ŀ<><C4BF><EFBFBD><EFBFBD>ַ
-- AlgoFile_QSPI, --<2D><EFBFBD>ļ<EFBFBD>
-- "0:/H7-TOOL/Fonts/GB2312ZK.bin", --<2D><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
@ -55,6 +59,8 @@ function cofig_chip1(void)
FLASH_ADDRESS = 0x08000000 --<2D><><EFBFBD><EFBFBD>FLASH<53><48>ʼ<EFBFBD><CABC>ַ
RESET_TYPE = 0 -- 0<><30>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ 1<><31>ʾӲ<CABE><D3B2><EFBFBD><EFBFBD>λ
--<2D>Ƿ<EFBFBD><C7B7>˶<EFBFBD>CPU<50>ں<EFBFBD>ID
CHECK_MCU_ID = 0
MCU_ID = 0x6BA02477

View File

@ -47,7 +47,7 @@ function cofig_chip1(void)
AlgoFile_QSPI, --<2D><EFBFBD>ļ<EFBFBD>
"0:/H7-TOOL/Fonts/GB2312ZK.bin", --<2D><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
0x90000000, --Ŀ<><C4BF><EFBFBD><EFBFBD>ַ
0x91E00000, --Ŀ<><C4BF><EFBFBD><EFBFBD>ַ
}
--1<><31>ʾ<EFBFBD><CABE>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><>ЩCPU<50><55>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD><EFBFBD>ٶȿ<D9B6><C8BF>ܶ࣬<DCB6><E0A3AC>Щ<EFBFBD><D0A9><EFBFBD>ܶ<EFBFBD>
@ -55,6 +55,8 @@ function cofig_chip1(void)
FLASH_ADDRESS = 0x08000000 --<2D><><EFBFBD><EFBFBD>FLASH<53><48>ʼ<EFBFBD><CABC>ַ
RESET_TYPE = 0 -- 0<><30>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ 1<><31>ʾӲ<CABE><D3B2><EFBFBD><EFBFBD>λ
--<2D>Ƿ<EFBFBD><C7B7>˶<EFBFBD>CPU<50>ں<EFBFBD>ID
CHECK_MCU_ID = 0
MCU_ID = 0x6BA02477

View File

@ -49,6 +49,10 @@ function cofig_chip1(void)
--1<><31>ʾ<EFBFBD><CABE>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><>ЩCPU<50><55>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD><EFBFBD>ٶȿ<D9B6><C8BF>ܶ࣬<DCB6><E0A3AC>Щ<EFBFBD><D0A9><EFBFBD>ܶ<EFBFBD>
ERASE_CHIP_ENABLE = 1
FLASH_ADDRESS = 0x08000000 --<2D><><EFBFBD><EFBFBD>FLASH<53><48>ʼ<EFBFBD><CABC>ַ
RESET_TYPE = 0 -- 0<><30>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ 1<><31>ʾӲ<CABE><D3B2><EFBFBD><EFBFBD>λ
--<2D>Ƿ<EFBFBD><C7B7>˶<EFBFBD>CPU<50>ں<EFBFBD>ID
CHECK_MCU_ID = 0
MCU_ID = 0x0BB11477

View File

@ -51,6 +51,8 @@ function cofig_chip1(void)
FLASH_ADDRESS = 0x08000000 --<2D><><EFBFBD><EFBFBD>FLASH<53><48>ʼ<EFBFBD><CABC>ַ
RESET_TYPE = 0 -- 0<><30>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ 1<><31>ʾӲ<CABE><D3B2><EFBFBD><EFBFBD>λ
--<2D>Ƿ<EFBFBD><C7B7>˶<EFBFBD>CPU<50>ں<EFBFBD>ID
CHECK_MCU_ID = 0
MCU_ID = 0x01BA01477

View File

@ -62,6 +62,8 @@ function cofig_chip1(void)
FLASH_ADDRESS = 0x08000000 --<2D><><EFBFBD><EFBFBD>FLASH<53><48>ʼ<EFBFBD><CABC>ַ
RESET_TYPE = 0 -- 0<><30>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ 1<><31>ʾӲ<CABE><D3B2><EFBFBD><EFBFBD>λ
--<2D>Ƿ<EFBFBD><C7B7>˶<EFBFBD>CPU<50>ں<EFBFBD>ID
CHECK_MCU_ID = 0
MCU_ID = 0x2BA01477

View File

@ -62,6 +62,8 @@ function cofig_chip1(void)
FLASH_ADDRESS = 0x08000000 --<2D><><EFBFBD><EFBFBD>FLASH<53><48>ʼ<EFBFBD><CABC>ַ
RESET_TYPE = 0 -- 0<><30>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ 1<><31>ʾӲ<CABE><D3B2><EFBFBD><EFBFBD>λ
--<2D>Ƿ<EFBFBD><C7B7>˶<EFBFBD>CPU<50>ں<EFBFBD>ID
CHECK_MCU_ID = 0
MCU_ID = 0x2BA01477

View File

@ -69,6 +69,8 @@ function cofig_chip1(void)
FLASH_ADDRESS = 0x08000000 --<2D><><EFBFBD><EFBFBD>FLASH<53><48>ʼ<EFBFBD><CABC>ַ
RESET_TYPE = 0 -- 0<><30>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ 1<><31>ʾӲ<CABE><D3B2><EFBFBD><EFBFBD>λ
--<2D>Ƿ<EFBFBD><C7B7>˶<EFBFBD>CPU<50>ں<EFBFBD>ID
CHECK_MCU_ID = 0
MCU_ID = 0x5BA02477

View File

@ -55,6 +55,8 @@ function cofig_chip1(void)
FLASH_ADDRESS = 0x08000000 --<2D><><EFBFBD><EFBFBD>FLASH<53><48>ʼ<EFBFBD><CABC>ַ
RESET_TYPE = 0 -- 0<><30>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ 1<><31>ʾӲ<CABE><D3B2><EFBFBD><EFBFBD>λ
--<2D>Ƿ<EFBFBD><C7B7>˶<EFBFBD>CPU<50>ں<EFBFBD>ID
CHECK_MCU_ID = 0
MCU_ID = 0x6BA02477

View File

@ -58,6 +58,8 @@ function cofig_chip1(void)
FLASH_ADDRESS = 0x08000000 --<2D><><EFBFBD><EFBFBD>FLASH<53><48>ʼ<EFBFBD><CABC>ַ
RESET_TYPE = 0 -- 0<><30>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ 1<><31>ʾӲ<CABE><D3B2><EFBFBD><EFBFBD>λ
--<2D>Ƿ<EFBFBD><C7B7>˶<EFBFBD>CPU<50>ں<EFBFBD>ID
CHECK_MCU_ID = 0
MCU_ID = 0x0BC11477

7
Doc/待解决问题.txt Normal file
View File

@ -0,0 +1,7 @@
--本文件记录一些待解决或待优化的问题--
1. qspi_read(), lua连续读取存在问题.
2. 文件管理界面写字库操作1分钟屏保进入后再唤醒程序实际在刷屏函数中出不来。
3. systick 中断优先级 = 0、 stm32h7xx_hal_conf.h
#define TICK_INT_PRIORITY 0 // ((uint32_t)0x0F) /*!< tick interrupt priority */
4. bsp_CheckRunTime, bsp_GetRunTime 函数内部去掉关闭中断的操作影响QSPI写操作。

File diff suppressed because it is too large Load Diff

View File

@ -1004,9 +1004,14 @@
<GroupName>Doc</GroupName>
<Files>
<File>
<FileName>02.例程修改记录.txt</FileName>
<FileName>CHANGELOG</FileName>
<FileType>5</FileType>
<FilePath>..\..\Doc\02.例程修改记录.txt</FilePath>
<FilePath>..\..\CHANGELOG</FilePath>
</File>
<File>
<FileName>待解决问题.txt</FileName>
<FileType>5</FileType>
<FilePath>..\..\Doc\待解决问题.txt</FilePath>
</File>
</Files>
</Group>
@ -1961,6 +1966,11 @@
<FileType>1</FileType>
<FilePath>..\..\User\daplink\source\daplink\cmsis-dap\SWO.c</FilePath>
</File>
<File>
<FileName>SW_DP_Multi.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\User\daplink\source\daplink\cmsis-dap\SW_DP_Multi.c</FilePath>
</File>
</Files>
</Group>
<Group>
@ -2042,6 +2052,11 @@
<FileType>1</FileType>
<FilePath>..\..\User\daplink\source\rtos_none\SysTick_Handler.c</FilePath>
</File>
<File>
<FileName>swd_host_multi.c</FileName>
<FileType>1</FileType>
<FilePath>..\..\User\daplink\source\daplink\interface\swd_host_multi.c</FilePath>
</File>
</Files>
</Group>
<Group>

View File

@ -68,7 +68,7 @@ __Vectors DCD __initial_sp ; Top of Stack
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0x00000109 ; Reserved H7-TOOL APP 固件版本
DCD 0x00000110 ; Reserved H7-TOOL APP 固件版本
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -29,6 +29,7 @@ enum
MS_PROG_SELECT_FILE, /* 脱机下载器浏览文件 */
MS_PROG_WORK, /* 脱机下载器工作界面 */
MS_PROG_SETTING, /* 脱机下载器参数设置 */
MS_PROG_MODIFY_PARAM, /* 修改参数比如复位类型 */
MS_VOLTAGE_METER, /* 电压表 */
MS_CURRENT_METER, /* 高侧电流表 */

View File

@ -100,6 +100,8 @@ typedef struct
uint16_t LcdSleepTime; /* 屏保时间 */
uint8_t FileListFont24; /* 1表示24点阵显示文件列表0表示16点阵 */
uint8_t ResetType; /* 0表示由lua脚本决定 1表示强制硬件复位 2表示强制软件复位 */
} PARAM_T;
/* 模拟量校准参数 */

View File

@ -13,6 +13,7 @@
void status_ProgSelectFile(void);
void status_ProgWork(void);
void status_ProgSetting(void);
void status_ProgModifyParam(void);
#endif

View File

@ -43,6 +43,7 @@
#include "target_reset.h"
#include "target_config.h"
#include "swd_host.h"
#include "SW_DP_Multi.h"
//#include "usbd_user.h"
#include "usb_if.h"
@ -86,13 +87,15 @@ int main(void)
bsp_InitESP32();
bsp_SetTVCC(3300);
DSO_InitHard();
DSO_SetDC(1, 1);
DSO_SetDC(2, 1);
DSO_SetGain(1, 3);
DSO_SetGain(2, 3);
bsp_SetTVCC(3300);
g_gMulSwd.MultiMode = 0; /* 测试一拖四模式 */
/* LwIP 初始化 */
{
@ -157,6 +160,10 @@ int main(void)
status_ProgSetting();
break;
case MS_PROG_MODIFY_PARAM: /* 脱机下载器 - 修改复位类型 */
status_ProgModifyParam();
break;
case MS_VOLTAGE_METER: /* 电压表 */
status_VoltageMeter();
break;

View File

@ -148,6 +148,8 @@ void InitBaseParam(void)
g_tParam.FileListFont24 = 0; /* 1表示24点阵显示文件列表0表示16点阵 */
g_tParam.ResetType = 0; /* ARM芯片复位模式 */
SaveParam();
}

View File

@ -83,6 +83,7 @@ const uint8_t *g_MenuProg1_Text[] =
" 2 清零本次计数",
" 3 清零累计计数",
" 4 输入产品序号",
" 5 修改编程参数",
/* 结束符号, 用于菜单函数自动识别菜单项个数 */
"&"
};
@ -134,7 +135,6 @@ void status_ProgWork(void)
BUTTON_T btn1, btn2, btn3;
FONT_T tFontNote;
FONT_T tFontText;
FONT_T tFont24;
FONT_T tFontBtn;
uint8_t cursor = 0;
uint8_t fRunOnce = 0;
@ -161,11 +161,6 @@ void status_ProgWork(void)
tFontBtn.FrontColor = INFO_NAME_COLOR; /* 字体颜色 */
tFontBtn.BackColor = CL_MASK; /* 文字背景颜色 */
tFontBtn.Space = 0; /* 文字间距,单位 = 像素 */
tFont24.FontCode = FC_ST_24; /* 字体代码 24点阵 */
tFont24.FrontColor = INFO_NAME_COLOR; /* 字体颜色 */
tFont24.BackColor = CL_MASK; /* 文字背景颜色 */
tFont24.Space = 0; /* 文字间距,单位 = 像素 */
}
LCD_ClrScr(FORM_BACK_COLOR);
@ -185,8 +180,6 @@ void status_ProgWork(void)
if (s_lua_read_len > 0)
{
const char *pNote1;
const char *pDataFileName;
uint32_t ulDataFileSize = 0;
char *p;
char buf[32];
@ -493,6 +486,11 @@ void status_ProgWork(void)
{
cursor = 0;
}
if (g_tProg.AutoStart == 1)
{
g_tProg.AutoStart = 0;
PG_PrintText("退出连续烧录");
}
fRefresh = 1;
break;
@ -709,6 +707,10 @@ void status_ProgSetting(void)
{
//g_MainStatus = MS_SYSTEM_SET;
}
else if (g_tMenuProg1.Cursor == 4) /* 修改编程参数 */
{
g_MainStatus = MS_PROG_MODIFY_PARAM;
}
break;
case KEY_UP_C: /* C键 下 */
@ -727,6 +729,187 @@ void status_ProgSetting(void)
}
}
/*
*********************************************************************************************************
* : status_ProgModifyParam
* :
* :
* :
*********************************************************************************************************
*/
#define PARAM_NUM 3
void status_ProgModifyParam(void)
{
uint8_t ucKeyCode; /* 按键代码 */
uint8_t fRefresh = 1;
uint8_t fSaveParam = 0;
uint8_t cursor = 0;
char buf[48];
uint8_t ucIgnoreKey = 1;
uint8_t active;
DispHeader2(93, "烧录参数");
DispHelpBar("长按S键选择参数",
"短按S、C键修改参数值");
while (g_MainStatus == MS_PROG_MODIFY_PARAM)
{
bsp_Idle();
if (fRefresh == 1)
{
fRefresh = 0;
/* 第1个参数 - 复位类型 */
{
if (cursor == 0)
{
active = 1;
}
else
{
active = 0;
}
if (g_tParam.ResetType == 0)
{
sprintf(buf, "由lua决定");
DispParamBar(0, "复位类型:", buf, active);
}
else if (g_tParam.ResetType == 1)
{
sprintf(buf, "强制硬件");
DispParamBar(0, "复位类型:", buf, active);
}
else
{
sprintf(buf, "强制软件");
DispParamBar(0, "复位类型:", buf, active);
}
}
/* 第2个参数 - 编程参数2 */
{
if (cursor == 1)
{
active = 1;
}
else
{
active = 0;
}
DispParamBar(1, "参数2:", "保留", active);
}
/* 第3个参数 - 编程参数3 */
{
if (cursor == 2)
{
active = 1;
}
else
{
active = 0;
}
DispParamBar(2, "参数3:", "保留", active);
}
}
ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
if (ucKeyCode != KEY_NONE)
{
/* 有键按下 */
switch (ucKeyCode)
{
case KEY_UP_S: /* S键 弹起 */
if (ucIgnoreKey == 1)
{
ucIgnoreKey = 0;
break;
}
if (cursor == 0)
{
if (g_tParam.ResetType == 0)
{
g_tParam.ResetType = 1;
}
else if (g_tParam.ResetType == 1)
{
g_tParam.ResetType = 2;
}
else
{
g_tParam.ResetType = 0;
}
}
else if (cursor == 1)
{
}
else if (cursor == 2)
{
}
fRefresh = 1;
fSaveParam = 1;
break;
case KEY_UP_C: /* C键 下 */
if (cursor == 0)
{
if (g_tParam.ResetType == 0)
{
g_tParam.ResetType = 2;
}
else if (g_tParam.ResetType == 2)
{
g_tParam.ResetType = 1;
}
else
{
g_tParam.ResetType = 0;
}
}
else if (cursor == 1)
{
}
else if (cursor == 2)
{
}
fRefresh = 1;
fSaveParam = 1;
break;
case KEY_LONG_DOWN_S: /* S键长按 - 选择参数 */
if (++cursor >= PARAM_NUM)
{
cursor = 0;
}
ucIgnoreKey = 1;
fRefresh = 1;
break;
case KEY_LONG_DOWN_C: /* C键长按 - 返回 */
PlayKeyTone();
g_MainStatus = MS_PROG_SETTING;
break;
default:
break;
}
}
}
if (fSaveParam == 1)
{
SaveParam(); /* 保存参数 */
}
}
/*
*********************************************************************************************************
* : DispProgCounter

View File

@ -706,7 +706,7 @@ void status_UsbEMMC(void)
{
uint8_t ucKeyCode; /* 按键代码 */
DispHeader2(93, "USB eMMM磁盘");
DispHeader2(93, "USB eMMC磁盘");
DispHelpBar("请在电脑操作eMMC文件",
"");

View File

@ -52,6 +52,8 @@ typedef enum
ES_GPIO_CAN = 6, /* CAN功能 */
ES_GPIO_I2C = 7, /* I2C功能 */
ES_GPIO_SWD_OUT = 8, /* 1拖4 SWD接口用 */
} EIO_SELECT_E;
void bsp_InitExtIO(void);

View File

@ -48,6 +48,14 @@
gpio_init.Pin = pin; \
HAL_GPIO_Init(gpio, &gpio_init);
#define GPIO_INIT_UART7(gpio, pin) \
gpio_init.Mode = GPIO_MODE_AF_PP; \
gpio_init.Pull = GPIO_NOPULL; \
gpio_init.Speed = GPIO_SPEED_FREQ_VERY_HIGH; \
gpio_init.Alternate = GPIO_AF11_UART7; \
gpio_init.Pin = pin; \
HAL_GPIO_Init(gpio, &gpio_init);
#define GPIO_DIR_SET_OUT(gpio, pin) BSP_SET_GPIO_1(gpio, pin) /* DIR = 1 输出 */
#define GPIO_DIR_SET_IN(gpio, pin) BSP_SET_GPIO_0(gpio, pin) /* DIR = 0 输入 */
@ -326,6 +334,13 @@ void EIO_D0_Config(EIO_SELECT_E _mode)
GPIO_INIT_INPUT(GPIOA, GPIO_PIN_15); /* 配置为GPIO 输入功能 */
GPIO_INIT_INPUT(GPIOI, GPIO_PIN_0); /* 配置为GPIO 输入功能 */
}
else if (_mode == ES_GPIO_UART)
{
GPIO_DIR_SET_OUT(GPIO_D0_DIR, PIN_D0_DIR); /* 设置为输出方向 - 先执行 */
GPIO_INIT_UART7(GPIOA, GPIO_PIN_15); /* 配置GPIO为UART7功能 */
GPIO_INIT_INPUT(GPIOI, GPIO_PIN_0); /* 配置为GPIO 输入功能 */
}
else
{
g_tVar.GpioMode[0] = 0;
@ -374,6 +389,12 @@ void EIO_D1_Config(EIO_SELECT_E _mode)
GPIO_INIT_INPUT(GPIOA, GPIO_PIN_8); /* 配置为GPIO输入功能 */
GPIO_INIT_INPUT(GPIOH, GPIO_PIN_10); /* 配置为GPIO输入功能 */
}
else if (_mode == ES_GPIO_UART)
{
GPIO_INIT_UART7(GPIOA, GPIO_PIN_8); /* 配置GPIO为UART7功能 */
GPIO_INIT_INPUT(GPIOI, GPIO_PIN_0); /* 配置为GPIO 输入功能 */
GPIO_DIR_SET_IN(GPIO_D1_DIR, PIN_D1_DIR); /* 设置为输入方向 - 后执行 */
}
else
{
g_tVar.GpioMode[1] = 0;
@ -444,7 +465,7 @@ void EIO_D3_Config(EIO_SELECT_E _mode)
/*
D3 - PG10/D3_DIR
PD1/FMC_D3
PE5/SPI4_MISO
PE5/SPI4_MISO GPIO)
PH11/TIM5_CH2/ENCODE1
*/
GPIO_InitTypeDef gpio_init;
@ -588,7 +609,7 @@ void EIO_D6_Config(EIO_SELECT_E _mode)
/*
D6 - PD10/D6_DIR
PE9/FMC_D6
PD3/SPI2_SCK --- io
PD3/SPI2_SCK --- gpio
PA0/TIM2_CH1
*/
GPIO_InitTypeDef gpio_init;
@ -608,6 +629,13 @@ void EIO_D6_Config(EIO_SELECT_E _mode)
GPIO_INIT_INPUT(GPIOA, GPIO_PIN_0); /* 配置为GPIO 输入功能 */
GPIO_INIT_OUT_PP(GPIOD, GPIO_PIN_3); /* 配置为GPIO 输出功能 */
}
else if (_mode == ES_GPIO_SWD_OUT)
{
GPIO_DIR_SET_OUT(GPIO_D6_DIR, PIN_D6_DIR); /* 设置为输出方向 - 先执行 */
GPIO_INIT_INPUT(GPIOA, GPIO_PIN_0); /* 配置为GPIO 输入功能 */
GPIO_INIT_INPUT(GPIOD, GPIO_PIN_3); /* 配置为GPIO 输出功能 */
GPIO_INIT_OUT_PP(GPIOE, GPIO_PIN_9);
}
else if (_mode == ES_FMC_OUT)
{
GPIO_DIR_SET_OUT(GPIO_D6_DIR, PIN_D6_DIR); /* 设置为输出方向 - 先执行 */
@ -657,6 +685,13 @@ void EIO_D7_Config(EIO_SELECT_E _mode)
GPIO_DIR_SET_OUT(GPIO_D7_DIR, PIN_D7_DIR); /* 设置为输出方向 - 先执行 */
GPIO_INIT_OUT_PP(GPIOI, GPIO_PIN_6); /* 配置为GPIO 输出功能 */
}
else if (_mode == ES_GPIO_SWD_OUT)
{
GPIO_INIT_INPUT(GPIOF, GPIO_PIN_0); /* 配置为GPIO 输入功能 */
GPIO_INIT_INPUT(GPIOI, GPIO_PIN_6); /* 配置为GPIO 输出功能 */
GPIO_DIR_SET_OUT(GPIO_D7_DIR, PIN_D7_DIR); /* 设置为输出方向 - 先执行 */
GPIO_INIT_OUT_PP(GPIOE, GPIO_PIN_10);
}
else if (_mode == ES_FMC_OUT)
{
GPIO_DIR_SET_OUT(GPIO_D7_DIR, PIN_D7_DIR); /* 设置为输出方向 - 先执行 */
@ -691,8 +726,8 @@ void EIO_D8_Config(EIO_SELECT_E _mode)
/*
D8 - PG9/NOE_DIR
PE11/FMC_D8
PD4/FMC_NOE
PI3/SPI2_MOSI - GPIO
PD4/FMC_NOE - GPIO
PI3/SPI2_MOSI
*/
GPIO_InitTypeDef gpio_init;
@ -720,6 +755,13 @@ void EIO_D8_Config(EIO_SELECT_E _mode)
GPIO_INIT_INPUT(GPIOI, GPIO_PIN_3); /* 配置为GPIO 输出功能 */
#endif
}
else if (_mode == ES_GPIO_SWD_OUT)
{
GPIO_DIR_SET_OUT(GPIO_D8_DIR, PIN_D8_DIR); /* 设置为输出方向 - 先执行 */
GPIO_INIT_OUT_PP(GPIOE, GPIO_PIN_11);
GPIO_INIT_INPUT(GPIOD, GPIO_PIN_4); /* 配置为GPIO 输入功能 */
GPIO_INIT_INPUT(GPIOI, GPIO_PIN_3); /* 配置为GPIO 输入功能 */
}
else if (_mode == ES_FMC_OUT)
{
GPIO_INIT_FMC(GPIOE, GPIO_PIN_11); /* 配置为FMC_D8功能 */
@ -781,6 +823,13 @@ void EIO_D9_Config(EIO_SELECT_E _mode)
GPIO_INIT_INPUT(GPIOF, GPIO_PIN_1); /* 配置为GPIO 输入功能 */
GPIO_INIT_OUT_PP(GPIOD, GPIO_PIN_5); /* 配置为GPIO 输出功能 */
}
else if (_mode == ES_GPIO_SWD_OUT)
{
GPIO_DIR_SET_OUT(GPIO_D9_DIR, PIN_D9_DIR); /* 设置为输出方向 - 先执行 */
GPIO_INIT_INPUT(GPIOF, GPIO_PIN_1); /* 配置为GPIO 输入功能 */
GPIO_INIT_INPUT(GPIOD, GPIO_PIN_5); /* 配置为GPIO 输出功能 */
GPIO_INIT_OUT_PP(GPIOE, GPIO_PIN_12); /* 配置为输出功能 */
}
else if (_mode == ES_FMC_OUT)
{
GPIO_INIT_FMC(GPIOE, GPIO_PIN_12); /* 配置为FMC功能 */
@ -1047,7 +1096,7 @@ void EIO_SetOutLevel(uint8_t _eio, uint8_t _level)
else if (_eio == EIO_D7)
GPIO_SET_LOW(GPIOI, GPIO_PIN_6);
else if (_eio == EIO_D8)
GPIO_SET_LOW(GPIOI, GPIO_PIN_3);
GPIO_SET_LOW(GPIOD, GPIO_PIN_4);
else if (_eio == EIO_D9)
GPIO_SET_LOW(GPIOD, GPIO_PIN_5);
else if (_eio == EIO_D10)
@ -1079,7 +1128,7 @@ void EIO_SetOutLevel(uint8_t _eio, uint8_t _level)
else if (_eio == EIO_D7)
GPIO_SET_HIGH(GPIOI, GPIO_PIN_6);
else if (_eio == EIO_D8)
GPIO_SET_HIGH(GPIOI, GPIO_PIN_3);
GPIO_SET_HIGH(GPIOD, GPIO_PIN_4);
else if (_eio == EIO_D9)
GPIO_SET_HIGH(GPIOD, GPIO_PIN_5);
else if (_eio == EIO_D10)
@ -1132,7 +1181,7 @@ uint8_t EIO_GetOutLevel(uint8_t _eio)
if (GPIO_OUT_IS_HIGH(GPIOI, GPIO_PIN_6))
re = 1;
if (_eio == EIO_D8)
if (GPIO_OUT_IS_HIGH(GPIOI, GPIO_PIN_3))
if (GPIO_OUT_IS_HIGH(GPIOD, GPIO_PIN_4))
re = 1;
if (_eio == EIO_D9)
if (GPIO_OUT_IS_HIGH(GPIOD, GPIO_PIN_5))
@ -1187,7 +1236,7 @@ uint8_t EIO_GetInputLevel(uint8_t _eio)
if (GPIO_IN_IS_HIGH(GPIOI, GPIO_PIN_6))
re = 1;
if (_eio == EIO_D8)
if (GPIO_IN_IS_HIGH(GPIOI, GPIO_PIN_3))
if (GPIO_IN_IS_HIGH(GPIOD, GPIO_PIN_4))
re = 1;
if (_eio == EIO_D9)
if (GPIO_IN_IS_HIGH(GPIOD, GPIO_PIN_5))

View File

@ -237,6 +237,8 @@ static void bsp_InitKeyVar(void)
*/
void bsp_PutKey(uint8_t _KeyCode)
{
s_KeyTimeOutCount = GetSleepTimeMinute() * 60 * 100u; /* 10ms单位 */
/* 屏幕熄灭阶段,丢弃唤醒键 */
if (s_LcdOn == 0)
{
@ -258,8 +260,6 @@ void bsp_PutKey(uint8_t _KeyCode)
{
s_tKey.Write = 0;
}
s_KeyTimeOutCount = GetSleepTimeMinute() * 60 * 100u; /* 10ms单位 */
}
/*

View File

@ -26,6 +26,7 @@
*/
#include "bsp.h"
#include "main.h"
#if UART1_FIFO_EN == 1
/* 串口1的GPIO PA9, PA10 RS323 DB9接口 */
@ -1075,6 +1076,8 @@ void bsp_SetUartParam(COM_PORT_E _ucPort, uint32_t BaudRate, uint32_t Parity, ui
/* Initialization Error */
Error_Handler(__FILE__, __LINE__);
}
comClearRxFifo(_ucPort); /* 清除接收缓冲区 */
}
/*
@ -1703,6 +1706,7 @@ void UART8_IRQHandler(void)
extern uint8_t USBCom_SendBuf(int _Port, uint8_t *_Buf, uint16_t _Len);
extern void lua_udp_SendBuf(uint8_t *_buf, uint16_t _len, uint16_t _port);
extern MEMO_T g_LuaMemo;
extern uint16_t g_MainStatus;
int fputc(int ch, FILE *f)
{
uint8_t buf[1];
@ -1712,7 +1716,10 @@ int fputc(int ch, FILE *f)
#if PRINT_TO_UDP == 1
lua_udp_SendBuf(buf, 1, LUA_UDP_PORT);
if (g_MainStatus == MS_LUA_EXEC_FILE)
{
LCD_MemoAddChar(&g_LuaMemo, ch);
}
#else
USBCom_SendBuf(1, buf, 1);
#endif

View File

@ -133,7 +133,6 @@ static const uint8_t ParityTable256[256] =
uint8_t GetParity(uint32_t data)
{
#if 1
uint8_t parity;
data ^= data >> 16;
@ -142,158 +141,12 @@ uint8_t GetParity(uint32_t data)
parity = ParityTable256[data & 0xff];
return parity;
#else
uint8_t parity = 0;
parity = (data >> 31) + (data >> 30) + (data >> 29) + (data >> 28)
+ (data >> 27) + (data >> 26) + (data >> 25) + (data >> 24)
+ (data >> 23) + (data >> 22) + (data >> 21) + (data >> 20)
+ (data >> 19) + (data >> 18) + (data >> 17) + (data >> 16)
+ (data >> 15) + (data >> 14) + (data >> 13) + (data >> 12)
+ (data >> 11) + (data >> 10) + (data >> 9) + (data >> 8)
+ (data >> 7) + (data >> 6) + (data >> 5) + (data >> 4)
+ (data >> 3) + (data >> 2) + (data >> 1) + (data >> 0);
if (parity & 1)
{
parity = 1;
}
else
{
parity = 0;
}
return parity;
#endif
}
//// SWD Transfer I/O
//// request: A[3:2] RnW APnDP
//// data: DATA[31:0]
//// return: ACK[2:0]
//#define SWD_TransferFunction(speed) /**/ \
//uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) { \
// uint32_t ack; \
// uint32_t bit; \
// uint32_t val; \
// uint32_t parity; \
// \
// uint32_t n; \
// \
// /* Packet Request */ \
// parity = 0U; \
// SW_WRITE_BIT(1U); /* Start Bit */ \
// bit = request >> 0; \
// SW_WRITE_BIT(bit); /* APnDP Bit */ \
// parity += bit; \
// bit = request >> 1; \
// SW_WRITE_BIT(bit); /* RnW Bit */ \
// parity += bit; \
// bit = request >> 2; \
// SW_WRITE_BIT(bit); /* A2 Bit */ \
// parity += bit; \
// bit = request >> 3; \
// SW_WRITE_BIT(bit); /* A3 Bit */ \
// parity += bit; \
// SW_WRITE_BIT(parity); /* Parity Bit */ \
// SW_WRITE_BIT(0U); /* Stop Bit */ \
// SW_WRITE_BIT(1U); /* Park Bit */ \
// \
// /* Turnaround */ \
// PIN_SWDIO_OUT_DISABLE(); \
// for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
// SW_CLOCK_CYCLE(); \
// } \
// \
// /* Acknowledge response */ \
// SW_READ_BIT(bit); \
// ack = bit << 0; \
// SW_READ_BIT(bit); \
// ack |= bit << 1; \
// SW_READ_BIT(bit); \
// ack |= bit << 2; \
// \
// if (ack == DAP_TRANSFER_OK) { /* OK response */ \
// /* Data transfer */ \
// if (request & DAP_TRANSFER_RnW) { \
// /* Read data */ \
// val = 0U; \
// parity = 0U; \
// for (n = 32U; n; n--) { \
// SW_READ_BIT(bit); /* Read RDATA[0:31] */ \
// parity += bit; \
// val >>= 1; \
// val |= bit << 31; \
// } \
// SW_READ_BIT(bit); /* Read Parity */ \
// if ((parity ^ bit) & 1U) { \
// ack = DAP_TRANSFER_ERROR; \
// } \
// if (data) { *data = val; } \
// /* Turnaround */ \
// for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
// SW_CLOCK_CYCLE(); \
// } \
// PIN_SWDIO_OUT_ENABLE(); \
// } else { \
// /* Turnaround */ \
// for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
// SW_CLOCK_CYCLE(); \
// } \
// PIN_SWDIO_OUT_ENABLE(); \
// /* Write data */ \
// val = *data; \
// parity = 0U; \
// for (n = 32U; n; n--) { \
// SW_WRITE_BIT(val); /* Write WDATA[0:31] */ \
// parity += val; \
// val >>= 1; \
// } \
// SW_WRITE_BIT(parity); /* Write Parity Bit */ \
// } \
// /* Idle cycles */ \
// n = DAP_Data.transfer.idle_cycles; \
// if (n) { \
// PIN_SWDIO_OUT(0U); \
// for (; n; n--) { \
// SW_CLOCK_CYCLE(); \
// } \
// } \
// PIN_SWDIO_OUT(1U); \
// return ((uint8_t)ack); \
// } \
// \
// if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { \
// /* WAIT or FAULT response */ \
// if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) { \
// for (n = 32U+1U; n; n--) { \
// SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */ \
// } \
// } \
// /* Turnaround */ \
// for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
// SW_CLOCK_CYCLE(); \
// } \
// PIN_SWDIO_OUT_ENABLE(); \
// if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { \
// PIN_SWDIO_OUT(0U); \
// for (n = 32U+1U; n; n--) { \
// SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ \
// } \
// } \
// PIN_SWDIO_OUT(1U); \
// return ((uint8_t)ack); \
// } \
// \
// /* Protocol error */ \
// for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) { \
// SW_CLOCK_CYCLE(); /* Back off data phase */ \
// } \
// PIN_SWDIO_OUT_ENABLE(); \
// PIN_SWDIO_OUT(1U); \
// return ((uint8_t)ack); \
//}
// SWD Transfer I/O
// request: A[3:2] RnW APnDP
// data: DATA[31:0]
// return: ACK[2:0]
uint8_t SWD_TransferFast(uint32_t request, uint32_t *data)
{
uint32_t ack;
@ -340,7 +193,7 @@ uint8_t SWD_TransferFast(uint32_t request, uint32_t *data)
/* Data transfer */
if (request & DAP_TRANSFER_RnW) {
/* Read data */
#if 1 /* armfly 优化奇偶校验算法 */
/* armfly 优化奇偶校验算法 */
val = 0U;
for (n = 32U; n; n--) {
SW_READ_BIT_FAST(bit); /* Read RDATA[0:31] */
@ -349,17 +202,7 @@ uint8_t SWD_TransferFast(uint32_t request, uint32_t *data)
}
parity = GetParity(val);
#else
val = 0U;
parity = 0U;
for (n = 32U; n; n--) {
SW_READ_BIT_FAST(bit); /* Read RDATA[0:31] */
parity += bit;
val >>= 1;
val |= bit << 31;
}
#endif
SW_READ_BIT_FAST(bit); /* Read Parity */
if ((parity ^ bit) & 1U) {
@ -380,13 +223,7 @@ uint8_t SWD_TransferFast(uint32_t request, uint32_t *data)
/* Write data */
val = *data;
#if 1 /* armfly 优化奇偶校验算法 */
// parity = GetParity(val);
// for (n = 32U; n; n--) {
// SW_WRITE_BIT_FAST(val); /* Write WDATA[0:31] */
// val >>= 1;
// }
/* armfly 优化奇偶校验算法 */
parity = GetParity(val);
SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();
SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();
@ -396,14 +233,7 @@ uint8_t SWD_TransferFast(uint32_t request, uint32_t *data)
SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();
SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();
SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();SEND_32BIT_ONCE();
#else
parity = 0U;
for (n = 32U; n; n--) {
SW_WRITE_BIT_FAST(val); /* Write WDATA[0:31] */
parity += val;
val >>= 1;
}
#endif
SW_WRITE_BIT_FAST(parity); /* Write Parity Bit */
}
/* Idle cycles */
@ -576,16 +406,11 @@ uint8_t SWD_TransferSlow(uint32_t request, uint32_t *data)
// request: A[3:2] RnW APnDP
// data: DATA[31:0]
// return: ACK[2:0]
uint8_t SWD_TransferFastH7(uint32_t request, uint32_t *data);
uint8_t SWD_Transfer(uint32_t request, uint32_t *data)
{
if (DAP_Data.fast_clock)
{
#if SPI_MODE_ENABLE == 1
return SWD_TransferFastH7(request, data);
#else
return SWD_TransferFast(request, data);
#endif
}
else
{
@ -601,178 +426,6 @@ uint8_t SWD_Transfer(uint32_t request, uint32_t *data)
#undef PIN_DELAY
#define PIN_DELAY() PIN_DELAY_FAST()
void SWD_SendBits(uint8_t _bits, uint32_t _data)
{
#if SPI_MODE_ENABLE == 1
// EIO_SetOutLevel(2, 1);
// SPI2->CFG1 = SPI_MODE_BAUD | _bits;
// SPI2->CR1 = SPI_CR1_SSI | SPI_CR1_HDDIR;
// SPI2->CR1 = SPI_CR1_SPE | SPI_CR1_HDDIR | SPI_CR1_SSI;
// SPI2->CR1 = SPI_CR1_SPE | SPI_CR1_HDDIR | SPI_CR1_SSI | SPI_CR1_CSTART;
SPI2->CFG1 = SPI_MODE_BAUD | (_bits - 1);
SPI2->CR1 = SPI_CR1_HDDIR;
SPI2->CR1 = SPI_CR1_SPE | SPI_CR1_HDDIR;
SPI2->CR1 = SPI_CR1_SPE | SPI_CR1_HDDIR | SPI_CR1_CSTART;
//while ((SPI2->SR & SPI_FLAG_TXE) == 0);
// EIO_SetOutLevel(2, 0);
if (_bits > 16)
{
*((__IO uint32_t *)&SPI2->TXDR) = _data;
}
else if (_bits > 8)
{
*((__IO uint16_t *)&SPI2->TXDR) = _data;
}
else
{
*((__IO uint8_t *)&SPI2->TXDR) = _data;
}
// EIO_SetOutLevel(2, 1);
while ((SPI2->SR & SPI_SR_TXC) == 0);
SPI2->IFCR = SPI_IFCR_EOTC | SPI_IFCR_TXTFC;
SPI2->CR1 &= ~(SPI_CR1_SPE);
// EIO_SetOutLevel(2, 0);
#else
uint8_t i;
for (i = 0; i < _bits; i++)
{
SW_WRITE_BIT_SLOW(_data >> i);
}
#endif
}
uint32_t SWD_ReadBits(uint8_t _bits)
{
#if SPI_MODE_ENABLE == 1
//if (hspi->Instance->SR & (SPI_FLAG_RXWNE|SPI_FLAG_EOT))
// {
// /* Check the RXWNE/FRLVL flag */
// if (hspi->Instance->SR & (SPI_FLAG_RXWNE|SPI_FLAG_FRLVL))
// {
// if (hspi->Instance->SR & SPI_FLAG_RXWNE)
// {
// *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
// hspi->pRxBuffPtr += sizeof(uint32_t);
// hspi->RxXferCount-=2;
// }
// else
// {
// *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
// hspi->pRxBuffPtr += sizeof(uint16_t);
// hspi->RxXferCount--;
// }
// }
// }
// {
// /* Check the RXWNE/FRLVL flag */
// if (hspi->Instance->SR & (SPI_FLAG_RXWNE|SPI_FLAG_FRLVL))
// {
// if (hspi->Instance->SR & SPI_FLAG_RXWNE)
// {
// *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
// hspi->pRxBuffPtr += sizeof(uint32_t);
// hspi->RxXferCount-=4;
// }
// else if ((hspi->Instance->SR & SPI_FLAG_FRLVL) > SPI_FRLVL_QUARTER_FULL)
// {
// *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
// hspi->pRxBuffPtr += sizeof(uint16_t);
// hspi->RxXferCount-=2;
// }
// else
// {
// *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
// hspi->pRxBuffPtr += sizeof(uint8_t);
// hspi->RxXferCount--;
// }
// }
// }
uint32_t ret;
_bits--;
// EIO_SetOutLevel(2, 1); 测试波形用
SPI2->CFG1 = SPI_MODE_BAUD | _bits;
// SPI2->CR1 = SPI_CR1_SSI ;
// SPI2->CR2 = 1;
SPI2->CR1 = SPI_CR1_SPE;// | SPI_CR1_SSI;
SPI2->CR1 = SPI_CR1_SPE | SPI_CR1_CSTART ; //| SPI_CR1_SSI ;
// while ((SPI2->SR & SPI_FLAG_TXE) == 0);
if (_bits > 15)
{
*((__IO uint32_t *)&SPI2->TXDR) = 0;
}
else if (_bits > 7)
{
*((__IO uint16_t *)&SPI2->TXDR) = 0;
}
else
{
*((__IO uint8_t *)&SPI2->TXDR) = 0;
}
while ((SPI2->SR & SPI_SR_TXC) == 0);
SPI2->IFCR = SPI_IFCR_EOTC | SPI_IFCR_TXTFC;
ret = SPI2->RXDR;
SPI2->CR1 &= ~(SPI_CR1_SPE);
// EIO_SetOutLevel(2, 0); 测试波形用
return ret;
#else
uint8_t bit;
uint8_t i;
uint32_t val = 0;
for (i = 0; i < _bits; i++)
{
SW_READ_BIT_SLOW(bit); /* Read RDATA[0:31] */
val >>= 1;
val |= bit << (_bits - 1);
}
return val;
#endif
}
void SWD_DIO_OutDisable(void)
{
#if SPI_MODE_ENABLE == 1
SPI2->CR1 = SPI_CR1_SSI;
BSP_SET_GPIO_0(GPIOG, GPIO_PIN_9); /* PG9 = 0 是输入 */
#else
PIN_SWDIO_OUT_DISABLE();
#endif
}
void SWD_DIO_OutEnable(void)
{
#if SPI_MODE_ENABLE == 1
BSP_SET_GPIO_1(GPIOG, GPIO_PIN_9); /* PG9 = 1 是输出 */
SPI2->CR1 = SPI_CR1_SSI | SPI_CR1_HDDIR;
#else
PIN_SWDIO_OUT_ENABLE();
#endif
}
#undef PIN_DELAY
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
@ -782,34 +435,6 @@ void SWD_DIO_OutEnable(void)
// return: none
#if ((DAP_SWD != 0) || (DAP_JTAG != 0))
void SWJ_Sequence (uint32_t count, const uint8_t *data) {
#if SPI_MODE_ENABLE == 1
uint8_t i;
uint32_t val;
uint8_t rem;
rem = count % 32;
if (rem >= 1 && rem < 4) /* 1,2,3 */
{
;
}
else
{
for (i = 0; i < count / 32; i++)
{
val = *(uint32_t *)data;
data += 4;
SWD_SendBits(32, val);
}
if (rem)
{
val = *(uint32_t *)data; /* 可能多访问内存 */
SWD_SendBits(rem, val);
}
}
#else
uint32_t val;
uint32_t n;
@ -829,265 +454,7 @@ void SWJ_Sequence (uint32_t count, const uint8_t *data) {
val >>= 1;
n--;
}
#endif
}
#endif
uint8_t SWD_TransferFastH7(uint32_t request, uint32_t *data)
{
uint32_t ack;
// uint32_t bit;
uint32_t val;
uint32_t temp1,temp2;
uint32_t parity;
uint32_t n;
/* Packet Request */
// parity = 0U;
// SW_WRITE_BIT(1U); /* Start Bit */
// bit = request >> 0;
// SW_WRITE_BIT(bit); /* APnDP Bit */
// parity += bit;
// bit = request >> 1;
// SW_WRITE_BIT(bit); /* RnW Bit */
// parity += bit;
// bit = request >> 2;
// SW_WRITE_BIT(bit); /* A2 Bit */
// parity += bit;
// bit = request >> 3;
// SW_WRITE_BIT(bit); /* A3 Bit */
// parity += bit;
// SW_WRITE_BIT(parity); /* Parity Bit */
// SW_WRITE_BIT(0U); /* Stop Bit */
// SW_WRITE_BIT(1U); /* Park Bit */
parity = GetParity(request);
val = (1u << 7) | (0 << 6) | (parity << 5) | (request << 1) | (1 << 0);
SWD_SendBits(8, val);
/* Turnaround */
SWD_DIO_OutDisable();
// for (n = DAP_Data.swd_conf.turnaround; n; n--)
// {
// SW_CLOCK_CYCLE();
// }
// /* Acknowledge response */
// SW_READ_BIT(bit);
// ack = bit << 0;
// SW_READ_BIT(bit);
// ack |= bit << 1;
// SW_READ_BIT(bit);
// ack |= bit << 2;
// ack = SWD_ReadBits(3 + DAP_Data.swd_conf.turnaround);
// ack >>= DAP_Data.swd_conf.turnaround;
// if (ack == DAP_TRANSFER_OK)
{ /* OK response */
/* Data transfer */
if (request & DAP_TRANSFER_RnW) /* 读指令 - 32 + 1 bit */
{
ack = SWD_ReadBits(3 + DAP_Data.swd_conf.turnaround);
ack >>= DAP_Data.swd_conf.turnaround;
ack &= 0x07;
/* Read data */
// val = 0U;
// parity = 0U;
// for (n = 32U; n; n--)
// {
// SW_READ_BIT(bit); /* Read RDATA[0:31] */
// parity += bit;
// val >>= 1;
// val |= bit << 31;
// }
// SW_READ_BIT(bit); /* Read Parity */
// if ((parity ^ bit) & 1U)
// {
// ack = DAP_TRANSFER_ERROR;
// }
// if (data) { *data = val; }
//
// /* Turnaround */
// for (n = DAP_Data.swd_conf.turnaround; n; n--)
// {
// SW_CLOCK_CYCLE();
// }
if (ack == DAP_TRANSFER_OK)
{
temp1 = SWD_ReadBits(16);
temp2 = SWD_ReadBits(16 + 1 + DAP_Data.swd_conf.turnaround);
val = temp1 + ((temp2 & 0xFFFF) << 16);
if (temp2 & (1 << 16))
{
parity = 1;
}
else
{
parity = 0;
}
if (parity != GetParity(val))
{
ack = DAP_TRANSFER_ERROR;
}
else
{
*data = val;
}
SWD_DIO_OutEnable();
/* Idle cycles */
n = DAP_Data.transfer.idle_cycles;
if (n)
{
PIN_SWDIO_OUT(0U);
for (; n; n--)
{
SW_CLOCK_CYCLE_FAST();
}
}
PIN_SWDIO_OUT(1U);
return ((uint8_t)ack);
}
}
else // 写指令
{
ack = SWD_ReadBits(3 + DAP_Data.swd_conf.turnaround + 1);
ack >>= DAP_Data.swd_conf.turnaround;
ack &= 0x07;
/* Turnaround */
// for (n = DAP_Data.swd_conf.turnaround; n; n--)
// {
// SW_CLOCK_CYCLE();
// }
if (ack == DAP_TRANSFER_OK)
{
SWD_DIO_OutEnable();
/* Write data */
// val = *data;
// parity = 0U;
// for (n = 32U; n; n--)
// {
// SW_WRITE_BIT(val); /* Write WDATA[0:31] */
// parity += val;
// val >>= 1;
// }
// SW_WRITE_BIT(parity); /* Write Parity Bit */
// /* Idle cycles */
// n = DAP_Data.transfer.idle_cycles;
// if (n)
// {
// PIN_SWDIO_OUT(0U);
// for (; n; n--)
// {
// SW_CLOCK_CYCLE();
// }
// }
// PIN_SWDIO_OUT(1U);
val = *data;
parity = GetParity(val);
SWD_SendBits(16, val);
SWD_SendBits(16 + 1 + DAP_Data.transfer.idle_cycles, (val >> 16) + (parity << 16));
//PIN_SWDIO_OUT(1U); 好像不是必须的。
return ((uint8_t)ack);
}
}
}
if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT))
{
if (request & DAP_TRANSFER_RnW) /* 读异常 */
{
/* WAIT or FAULT response */
// if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U))
// {
// for (n = 32U+1U; n; n--)
// {
// SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */
// }
// }
// /* Turnaround */
// for (n = DAP_Data.swd_conf.turnaround; n; n--)
// {
// SW_CLOCK_CYCLE();
// }
SWD_ReadBits(16);
SWD_ReadBits(16 + 1 + DAP_Data.swd_conf.turnaround);
SWD_DIO_OutEnable();
// if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U))
// {
// PIN_SWDIO_OUT(0U);
// for (n = 32U+1U; n; n--)
// {
// SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */
// }
// }
PIN_SWDIO_OUT(1U);
return ((uint8_t)ack);
}
else /* 写异常 - 前面多发了1个clk */
{
/* WAIT or FAULT response */
// if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U))
// {
// for (n = 32U+1U; n; n--)
// {
// SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */
// }
// }
/* Turnaround */
// for (n = DAP_Data.swd_conf.turnaround; n; n--)
// {
// SW_CLOCK_CYCLE();
// }
SWD_DIO_OutEnable();
// if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U))
// {
// PIN_SWDIO_OUT(0U);
// for (n = 32U+1U; n; n--)
// {
// SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */
// }
// }
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U))
{
SWD_SendBits(16, 0);
SWD_SendBits(16 + 1, 0);
}
PIN_SWDIO_OUT(1U);
return ((uint8_t)ack);
}
}
/* Protocol error */
// for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--)
// {
// SW_CLOCK_CYCLE(); /* Back off data phase */
// }
SWD_ReadBits(16);
SWD_ReadBits(16 + 1 + DAP_Data.swd_conf.turnaround);
SWD_DIO_OutEnable();
PIN_SWDIO_OUT(1U);
return ((uint8_t)ack);
}
#endif /* (DAP_SWD != 0) */

View File

@ -0,0 +1,765 @@
/*
SW_DP_Multi.c 1-4
*/
/*
*********************************************************************************************************
*
* : SWD一拖四驱动程序
* : SW_DP_Multi.c
* : V1.0
* : SWD接口底层驱动函数
* :
*
* V1.0 2020-03-13 armfly
*
* Copyright (C), 2018-2030, www.armfly.com
*
*********************************************************************************************************
*/
/**
* @file SW_DP_Multi.c
* @brief 14 SWD driver
*
* DAPLink Interface Firmware
* Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ----------------------------------------------------------------------
*
* $Date: 20. May 2015
* $Revision: V1.10
*
* Project: CMSIS-DAP Source
* Title: SW_DP.c CMSIS-DAP SW DP I/O
*
*---------------------------------------------------------------------------*/
#include "DAP_config.h"
#include "DAP.h"
#include "SW_DP_Multi.h"
/*
BSP_SET_GPIO_1(SWCLK_TCK_PIN_PORT, SWCLK_TCK_PIN);
D0 PD14 PA15 PI0 - DIR PH8 RESET
D1 PD15 PA8 PH19 - DIR PG8 POWER OFF
D2 PE6 PD0 PB7 - DIR PD9 SWCLK_4
D3 PE5 PD1 PH11 - DIR PG10 SWDIO_4
D4 PE4 PE7 PH12 - DIR PG12 SWDIO_3
D5 PE2 PE8 PI5 - DIR PG7 SWDIO_2
D6 PE9 PD3 PA0 - DIR PD10 SWCLK_3
D7 PE10 PI6 - DIR PI1 SWCLK_2
D8 PE11 PD4 PI3 - DIR PG9 SWDIO_1
D9 PE12 PD5 - DIR PI12 SWCLK_1
*/
#define MUL_GPIO_SWD GPIOE
#define MUL_GPIO_DIR GPIOG
#define MUL_PIN_SWCLK_1 GPIO_PIN_12
#define MUL_PIN_SWDIO_1 GPIO_PIN_11
#define MUL_PIN_DIR_1 GPIO_PIN_9
#define MUL_PIN_SWCLK_2 GPIO_PIN_10
#define MUL_PIN_SWDIO_2 GPIO_PIN_2
#define MUL_PIN_DIR_2 GPIO_PIN_7
#define MUL_PIN_SWCLK_3 GPIO_PIN_9
#define MUL_PIN_SWDIO_3 GPIO_PIN_4
#define MUL_PIN_DIR_3 GPIO_PIN_12
#define MUL_PIN_SWCLK_4 GPIO_PIN_6
#define MUL_PIN_SWDIO_4 GPIO_PIN_5
#define MUL_PIN_DIR_4 GPIO_PIN_10
/* pin bit */
#define MUL_PINB_SWCLK_1 12
#define MUL_PINB_SWDIO_1 11
#define MUL_PINB_DIR_1 9
#define MUL_PINB_SWCLK_2 10
#define MUL_PINB_SWDIO_2 2
#define MUL_PINB_DIR_2 7
#define MUL_PINB_SWCLK_3 9
#define MUL_PINB_SWDIO_3 4
#define MUL_PINB_DIR_3 12
#define MUL_PINB_SWCLK_4 6
#define MUL_PINB_SWDIO_4 5
#define MUL_PINB_DIR_4 10
/* GPIO_MODER寄存器 */
#define MUL_DIO_MODE_MASK_1 ~(3u << (MUL_PINB_SWDIO_1 * 2))
#define MUL_DIO_MODE_MASK_2 ~(3u << (MUL_PINB_SWDIO_2 * 2))
#define MUL_DIO_MODE_MASK_3 ~(3u << (MUL_PINB_SWDIO_3 * 2))
#define MUL_DIO_MODE_MASK_4 ~(3u << (MUL_PINB_SWDIO_4 * 2))
#define MUL_DIO_MODE_OUT_1 (1u << (MUL_PINB_SWDIO_1 * 2))
#define MUL_DIO_MODE_OUT_2 (1u << (MUL_PINB_SWDIO_2 * 2))
#define MUL_DIO_MODE_OUT_3 (1u << (MUL_PINB_SWDIO_3 * 2))
#define MUL_DIO_MODE_OUT_4 (1u << (MUL_PINB_SWDIO_4 * 2))
/* CLK_0_DIO_0 */
#define CLK_0_DIO_0_1 (((uint32_t)MUL_PIN_SWCLK_1 + MUL_PIN_SWDIO_1) << 16)
#define CLK_0_DIO_0_2 (((uint32_t)MUL_PIN_SWCLK_2 + MUL_PIN_SWDIO_2) << 16)
#define CLK_0_DIO_0_3 (((uint32_t)MUL_PIN_SWCLK_3 + MUL_PIN_SWDIO_3) << 16)
#define CLK_0_DIO_0_4 (((uint32_t)MUL_PIN_SWCLK_4 + MUL_PIN_SWDIO_4) << 16)
/* CLK_0_DIO_1 */
#define CLK_0_DIO_1_1 (((uint32_t)MUL_PIN_SWCLK_1 << 16) | MUL_PIN_SWDIO_1)
#define CLK_0_DIO_1_2 (((uint32_t)MUL_PIN_SWCLK_2 << 16) | MUL_PIN_SWDIO_2)
#define CLK_0_DIO_1_3 (((uint32_t)MUL_PIN_SWCLK_3 << 16) | MUL_PIN_SWDIO_3)
#define CLK_0_DIO_1_4 (((uint32_t)MUL_PIN_SWCLK_4 << 16) | MUL_PIN_SWDIO_4)
MUL_SWD_T g_gMulSwd = {0};
/* 4个SWDIO配置为输出 */
static __forceinline void MUL_PIN_SWDIO_OUT_ENABLE(void)
{
BSP_SET_GPIO_1(MUL_GPIO_DIR, g_gMulSwd.DIR_Pins);
MUL_GPIO_SWD->MODER = (MUL_GPIO_SWD->MODER & g_gMulSwd.MODER_Mask) | g_gMulSwd.MODER_Out; /* 输出 */
BSP_SET_GPIO_0(MUL_GPIO_SWD, g_gMulSwd.SWDIO_Pins);
}
/* 4个SWDIO配置为输入 */
static __forceinline void MUL_PIN_SWDIO_OUT_DISABLE(void)
{
BSP_SET_GPIO_0(MUL_GPIO_DIR, g_gMulSwd.DIR_Pins);
MUL_GPIO_SWD->MODER = (MUL_GPIO_SWD->MODER & g_gMulSwd.MODER_Mask); /* 输入 */
BSP_SET_GPIO_0(MUL_GPIO_SWD, g_gMulSwd.SWDIO_Pins);
}
/* 读取4个SWDIO引脚状态 */
static __forceinline uint32_t MUL_PIN_SWDIO_IN(void)
{
uint32_t input;
uint32_t ret = 0;
input = MUL_GPIO_SWD->IDR;
if (input & MUL_PIN_SWDIO_1)
{
ret += 0x00000001;
}
if (input & MUL_PIN_SWDIO_2)
{
ret += 0x00000100;
}
if (input & MUL_PIN_SWDIO_3)
{
ret += 0x00010000;
}
if (input & MUL_PIN_SWDIO_4)
{
ret += 0x01000000;
}
return ret;
}
/* 设置4个SWDIO引脚状态 */
static __forceinline void MUL_PIN_SWDIO_OUT(uint32_t bit)
{
if (bit & 1)
{
BSP_SET_GPIO_1(MUL_GPIO_SWD, g_gMulSwd.SWDIO_Pins);
}
else
{
BSP_SET_GPIO_0(MUL_GPIO_SWD, g_gMulSwd.SWDIO_Pins);
}
}
/* */
static __forceinline void MUL_PIN_SWCLK_SET(void)
{
BSP_SET_GPIO_1(MUL_GPIO_SWD, g_gMulSwd.SWCLK_Pins);
}
/* */
static __forceinline void MUL_PIN_SWCLK_CLR(void)
{
BSP_SET_GPIO_0(MUL_GPIO_SWD, g_gMulSwd.SWCLK_Pins);
}
/* */
void MUL_SEND_32BIT(uint32_t val)
{
uint32_t i;
for (i = 0; i < 32; i++)
{
if (val & 1)
{
MUL_GPIO_SWD->BSRR = g_gMulSwd.CLK_0_DIO_1;
val >>= 1;
MUL_PIN_SWCLK_SET();
}
else
{
MUL_GPIO_SWD->BSRR = g_gMulSwd.CLK_0_DIO_0;
val >>= 1;
MUL_PIN_SWCLK_SET();
}
}
}
/* SPI软件模式低速配置 */
#define PIN_DELAY_S() PIN_DELAY_SLOW(DAP_Data.clock_delay)
#define MUL_SW_CLOCK_CYCLE_SLOW() MUL_PIN_SWCLK_CLR(); PIN_DELAY_S(); MUL_PIN_SWCLK_SET(); PIN_DELAY_S()
#define MUL_SW_WRITE_BIT_SLOW(bit) MUL_PIN_SWDIO_OUT(bit); MUL_PIN_SWCLK_CLR(); PIN_DELAY_S(); MUL_PIN_SWCLK_SET(); PIN_DELAY_S()
#define MUL_SW_READ_BIT_SLOW(bit) MUL_PIN_SWCLK_CLR(); PIN_DELAY_S(); bit = MUL_PIN_SWDIO_IN(); MUL_PIN_SWCLK_SET(); PIN_DELAY_S()
/* SPI软件模式高速配置 */
#define MUL_SW_CLOCK_CYCLE_FAST() MUL_PIN_SWCLK_CLR(); MUL_PIN_SWCLK_SET();
#define MUL_SW_WRITE_BIT_FAST(bit) MUL_PIN_SWDIO_OUT(bit); MUL_PIN_SWCLK_CLR(); MUL_PIN_SWCLK_SET();
#define MUL_SW_READ_BIT_FAST(bit) MUL_PIN_SWCLK_CLR(); bit = MUL_PIN_SWDIO_IN(); MUL_PIN_SWCLK_SET();
extern uint8_t GetParity(uint32_t data);
/*
*********************************************************************************************************
* : MUL_SWD_GPIOConfig
* : GPIO配置
* :
* :
*********************************************************************************************************
*/
void MUL_SWD_GPIOConfig(void)
{
EIO_D0_Config(ES_GPIO_OUT); /* FMC输入功能依然有效 */
EIO_D1_Config(ES_GPIO_OUT);
EIO_D2_Config(ES_GPIO_OUT);
EIO_D3_Config(ES_GPIO_OUT);
EIO_D4_Config(ES_GPIO_OUT);
EIO_D5_Config(ES_GPIO_OUT);
EIO_D6_Config(ES_GPIO_SWD_OUT); /* 用FMC口线做GPIO。因此FMC功能失效 */
EIO_D7_Config(ES_GPIO_SWD_OUT); /* 用FMC口线做GPIO。因此FMC功能失效 */
EIO_D8_Config(ES_GPIO_SWD_OUT); /* 用FMC口线做GPIO。因此FMC功能失效 */
EIO_D9_Config(ES_GPIO_SWD_OUT); /* 用FMC口线做GPIO。因此FMC功能失效 */
}
/*
*********************************************************************************************************
* : MUL_RefreshGpioParam
* : GPIO配置
* :
* :
*********************************************************************************************************
*/
const uint32_t TablePinDIR[4] = {MUL_PIN_DIR_1, MUL_PIN_DIR_2, MUL_PIN_DIR_3, MUL_PIN_DIR_4};
const uint32_t TablePinSWClK[4] = {MUL_PIN_SWCLK_1, MUL_PIN_SWCLK_2, MUL_PIN_SWCLK_3, MUL_PIN_SWCLK_4};
const uint32_t TablePinSWDIO[4] = {MUL_PIN_SWDIO_1, MUL_PIN_SWDIO_2, MUL_PIN_SWDIO_3, MUL_PIN_SWDIO_4};
const uint32_t TableModeMask[4] = {MUL_DIO_MODE_MASK_1, MUL_DIO_MODE_MASK_2, MUL_DIO_MODE_MASK_3, MUL_DIO_MODE_MASK_4};
const uint32_t TableModeOut[4] = {MUL_DIO_MODE_OUT_1, MUL_DIO_MODE_OUT_2, MUL_DIO_MODE_OUT_3, MUL_DIO_MODE_OUT_4};
const uint32_t TableClk0Dio0[4] = {CLK_0_DIO_0_1, CLK_0_DIO_0_2, CLK_0_DIO_0_3, CLK_0_DIO_0_4};
const uint32_t TableClk0Dio1[4] = {CLK_0_DIO_1_1, CLK_0_DIO_1_2, CLK_0_DIO_1_3, CLK_0_DIO_1_4};
void MUL_RefreshGpioParam(void)
{
uint32_t DIR_Pins = 0;
uint32_t SWDIO_Pins = 0;
uint32_t SWCLK_Pins = 0;
uint32_t MODER_Mask = 0xFFFFFFFF;
uint32_t MODER_Out = 0;
uint32_t CLK_0_DIO_0 = 0;
uint32_t CLK_0_DIO_1 = 0;
uint8_t i;
for (i = 0; i < 4; i++)
{
if (g_gMulSwd.Active[i] == 1 && g_gMulSwd.Ignore[i] == 0 && g_gMulSwd.TempIgnore[i] == 0)
{
DIR_Pins |= TablePinDIR[i];
SWCLK_Pins |= TablePinSWClK[i];
SWDIO_Pins |= TablePinSWDIO[i];
MODER_Mask &= TableModeMask[i];
MODER_Out |= TableModeOut[i];
CLK_0_DIO_0 |= TableClk0Dio0[i];
CLK_0_DIO_1 |= TableClk0Dio1[i];
}
}
g_gMulSwd.DIR_Pins = DIR_Pins;
g_gMulSwd.SWCLK_Pins = SWCLK_Pins;
g_gMulSwd.SWDIO_Pins = SWDIO_Pins;
g_gMulSwd.MODER_Mask = MODER_Mask;
g_gMulSwd.MODER_Out = MODER_Out;
g_gMulSwd.CLK_0_DIO_0 = CLK_0_DIO_0;
g_gMulSwd.CLK_0_DIO_1 = CLK_0_DIO_1;
}
/*
*********************************************************************************************************
* : MUL_SWD_TransferFast
* : SWD Transfer I/O.
* : request: A[3:2] RnW APnDP
* data: DATA[31:0] 4.
* : uint8_t指针4s_ack[4]
*********************************************************************************************************
*/
uint8_t* MUL_SWD_TransferFast(uint32_t request, uint32_t *data)
{
static uint8_t s_ack[4];
uint32_t ack;
uint8_t *ack_buf;
uint32_t bit;
uint8_t *bit_buf = (uint8_t *)&bit;
uint32_t val;
uint32_t val_buf[4];
uint32_t pb_buf[4];
uint32_t pb;
uint32_t n;
uint8_t i;
uint8_t route = 0;
for (i = 0; i < 4; i++)
{
g_gMulSwd.TempIgnore[i] = 0;
}
MUL_RefreshGpioParam(); /* 刷新GPIO寄存器变量 */
MUL_PIN_SWDIO_OUT_ENABLE();
/* Packet Request */
pb = 0U;
MUL_SW_WRITE_BIT_FAST(1U); /* Start Bit */
bit = request >> 0;
MUL_SW_WRITE_BIT_FAST(bit); /* APnDP Bit */
pb += bit;
bit = request >> 1;
MUL_SW_WRITE_BIT_FAST(bit); /* RnW Bit */
pb += bit;
bit = request >> 2;
MUL_SW_WRITE_BIT_FAST(bit); /* A2 Bit */
pb += bit;
bit = request >> 3;
MUL_SW_WRITE_BIT_FAST(bit); /* A3 Bit */
pb += bit;
MUL_SW_WRITE_BIT_FAST(pb); /* Parity Bit */
MUL_SW_WRITE_BIT_FAST(0U); /* Stop Bit */
MUL_SW_WRITE_BIT_FAST(1U); /* Park Bit */
/* Turnaround */
MUL_PIN_SWDIO_OUT_DISABLE();
for (n = DAP_Data.swd_conf.turnaround; n; n--)
{
MUL_SW_CLOCK_CYCLE_FAST();
}
/* Acknowledge response */
MUL_SW_READ_BIT_FAST(bit);
ack = bit << 0;
MUL_SW_READ_BIT_FAST(bit);
ack |= bit << 1;
MUL_SW_READ_BIT_FAST(bit);
ack |= bit << 2;
ack_buf = (uint8_t *)&ack; /* 4个芯片同时应答 */
route = 0;
for (i = 0; i < 4; i++)
{
if (g_gMulSwd.Ignore[i] == 0)
{
if (ack_buf[i] == DAP_TRANSFER_OK)
{
route = DAP_TRANSFER_OK; /* 4个芯片有1个OK后面就优先处理OK流程 */
}
else
{
g_gMulSwd.TempIgnore[i] = 1; /* 收到其他应答 */
}
}
}
if (route == DAP_TRANSFER_OK) /* OK response */
{
MUL_RefreshGpioParam(); /* 刷新GPIO寄存器变量 */
if (request & DAP_TRANSFER_RnW) /* 读数据 */
{
/* Read data */
/* armfly 优化奇偶校验算法 */
for (i = 0; i < 4; i++)
{
val_buf[i] = 0;
}
for (n = 32U; n; n--)
{
MUL_SW_READ_BIT_FAST(bit); /* Read RDATA[0:31] */
for (i = 0; i < 4; i++)
{
val_buf[i] >>= 1;
val_buf[i] |= bit_buf[i] << 31;
}
}
for (i = 0; i < 4; i++)
{
pb_buf[i] = GetParity(val_buf[i]);
}
MUL_SW_READ_BIT_FAST(bit); /* Read Parity */
for (i = 0; i < 4; i++)
{
if ((pb_buf[i] ^ bit_buf[i]) & 1U)
{
ack_buf[i] = DAP_TRANSFER_ERROR;
if (data > 0)
{
data[i] = 0;
}
}
else
{
if (data > 0)
{
data[i] = val_buf[i];
}
}
}
/* Turnaround */
for (n = DAP_Data.swd_conf.turnaround; n; n--)
{
MUL_SW_CLOCK_CYCLE_FAST();
}
MUL_PIN_SWDIO_OUT_ENABLE();
}
else /* 写数据 */
{
/* Turnaround */
for (n = DAP_Data.swd_conf.turnaround; n; n--)
{
MUL_SW_CLOCK_CYCLE_FAST();
}
MUL_PIN_SWDIO_OUT_ENABLE();
/* Write data */
val = *data;
/* armfly 优化奇偶校验算法 */
pb = GetParity(val);
MUL_SEND_32BIT(val);
MUL_SW_WRITE_BIT_FAST(pb); /* Write Parity Bit */
}
/* Idle cycles */
n = DAP_Data.transfer.idle_cycles;
if (n)
{
MUL_PIN_SWDIO_OUT(0U);
for (; n; n--)
{
MUL_SW_CLOCK_CYCLE_FAST();
}
}
MUL_PIN_SWDIO_OUT(1U);
}
/* 处理异常 */
for (i = 0; i < 4; i++)
{
g_gMulSwd.TempIgnore[i] = 0;
}
route = 0;
for (i = 0; i < 4; i++)
{
if (g_gMulSwd.Ignore[i] == 0)
{
if (ack_buf[i] == DAP_TRANSFER_WAIT || ack_buf[i] == DAP_TRANSFER_FAULT)
{
route = ack_buf[i];
}
else
{
g_gMulSwd.TempIgnore[i] = 1; /* 收到其他应答 */
}
}
}
if ((route == DAP_TRANSFER_WAIT) || (route == DAP_TRANSFER_FAULT))
{
MUL_RefreshGpioParam(); /* 刷新GPIO寄存器变量 */
/* WAIT or FAULT response */
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U))
{
for (n = 32U+1U; n; n--)
{
MUL_SW_CLOCK_CYCLE_FAST(); /* Dummy Read RDATA[0:31] + Parity */
}
}
/* Turnaround */
for (n = DAP_Data.swd_conf.turnaround; n; n--)
{
MUL_SW_CLOCK_CYCLE_FAST();
}
MUL_PIN_SWDIO_OUT_ENABLE();
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U))
{
MUL_PIN_SWDIO_OUT(0U);
for (n = 32U+1U; n; n--)
{
MUL_SW_CLOCK_CYCLE_FAST(); /* Dummy Write WDATA[0:31] + Parity */
}
}
MUL_PIN_SWDIO_OUT(1U);
}
/* 处理异常 */
for (i = 0; i < 4; i++)
{
g_gMulSwd.TempIgnore[i] = 0;
}
route = 0;
for (i = 0; i < 4; i++)
{
if (g_gMulSwd.Ignore[i] == 0)
{
if (ack_buf[i] == DAP_TRANSFER_WAIT || ack_buf[i] == DAP_TRANSFER_FAULT
|| ack_buf[i] == DAP_TRANSFER_OK)
{
g_gMulSwd.TempIgnore[i] = 1;
}
else
{
g_gMulSwd.TempIgnore[i] = 0; /* 收到其他应答 */
route = DAP_TRANSFER_ERROR;
}
}
}
if (route == DAP_TRANSFER_ERROR)
{
MUL_RefreshGpioParam(); /* 刷新GPIO寄存器变量 */
/* Protocol error */
for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--)
{
MUL_SW_CLOCK_CYCLE_FAST(); /* Back off data phase */
}
MUL_PIN_SWDIO_OUT_ENABLE();
MUL_PIN_SWDIO_OUT(1U);
}
for (i = 0; i < 4; i++)
{
g_gMulSwd.TempIgnore[i] = 0;
s_ack[i] = ack_buf[i];
}
return s_ack;
}
uint8_t MUL_SWD_TransferSlow(uint32_t request, uint32_t *data)
{
uint32_t ack;
uint32_t bit;
uint32_t val;
uint32_t parity;
uint32_t n;
/* Packet Request */
parity = 0U;
MUL_SW_WRITE_BIT_SLOW(1U); /* Start Bit */
bit = request >> 0;
MUL_SW_WRITE_BIT_SLOW(bit); /* APnDP Bit */
parity += bit;
bit = request >> 1;
MUL_SW_WRITE_BIT_SLOW(bit); /* RnW Bit */
parity += bit;
bit = request >> 2;
MUL_SW_WRITE_BIT_SLOW(bit); /* A2 Bit */
parity += bit;
bit = request >> 3;
MUL_SW_WRITE_BIT_SLOW(bit); /* A3 Bit */
parity += bit;
MUL_SW_WRITE_BIT_SLOW(parity); /* Parity Bit */
MUL_SW_WRITE_BIT_SLOW(0U); /* Stop Bit */
MUL_SW_WRITE_BIT_SLOW(1U); /* Park Bit */
/* Turnaround */
MUL_PIN_SWDIO_OUT_DISABLE();
for (n = DAP_Data.swd_conf.turnaround; n; n--) {
MUL_SW_CLOCK_CYCLE_SLOW();
}
/* Acknowledge response */
MUL_SW_READ_BIT_SLOW(bit);
ack = bit << 0;
MUL_SW_READ_BIT_SLOW(bit);
ack |= bit << 1;
MUL_SW_READ_BIT_SLOW(bit);
ack |= bit << 2;
if (ack == DAP_TRANSFER_OK) { /* OK response */
/* Data transfer */
if (request & DAP_TRANSFER_RnW) {
/* Read data */
val = 0U;
parity = 0U;
for (n = 32U; n; n--) {
MUL_SW_READ_BIT_SLOW(bit); /* Read RDATA[0:31] */
parity += bit;
val >>= 1;
val |= bit << 31;
}
MUL_SW_READ_BIT_SLOW(bit); /* Read Parity */
if ((parity ^ bit) & 1U) {
ack = DAP_TRANSFER_ERROR;
}
if (data) { *data = val; }
/* Turnaround */
for (n = DAP_Data.swd_conf.turnaround; n; n--) {
MUL_SW_CLOCK_CYCLE_SLOW();
}
MUL_PIN_SWDIO_OUT_ENABLE();
} else {
/* Turnaround */
for (n = DAP_Data.swd_conf.turnaround; n; n--) {
MUL_SW_CLOCK_CYCLE_SLOW();
}
MUL_PIN_SWDIO_OUT_ENABLE();
/* Write data */
val = *data;
parity = 0U;
for (n = 32U; n; n--) {
MUL_SW_WRITE_BIT_SLOW(val); /* Write WDATA[0:31] */
parity += val;
val >>= 1;
}
MUL_SW_WRITE_BIT_SLOW(parity); /* Write Parity Bit */
}
/* Idle cycles */
n = DAP_Data.transfer.idle_cycles;
if (n) {
MUL_PIN_SWDIO_OUT(0U);
for (; n; n--) {
MUL_SW_CLOCK_CYCLE_SLOW();
}
}
MUL_PIN_SWDIO_OUT(1U);
return ((uint8_t)ack);
}
if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) {
/* WAIT or FAULT response */
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) {
for (n = 32U+1U; n; n--) {
MUL_SW_CLOCK_CYCLE_SLOW(); /* Dummy Read RDATA[0:31] + Parity */
}
}
/* Turnaround */
for (n = DAP_Data.swd_conf.turnaround; n; n--) {
MUL_SW_CLOCK_CYCLE_SLOW();
}
MUL_PIN_SWDIO_OUT_ENABLE();
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) {
MUL_PIN_SWDIO_OUT(0U);
for (n = 32U+1U; n; n--) {
MUL_SW_CLOCK_CYCLE_SLOW(); /* Dummy Write WDATA[0:31] + Parity */
}
}
MUL_PIN_SWDIO_OUT(1U);
return ((uint8_t)ack);
}
/* Protocol error */
for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) {
MUL_SW_CLOCK_CYCLE_SLOW(); /* Back off data phase */
}
MUL_PIN_SWDIO_OUT_ENABLE();
MUL_PIN_SWDIO_OUT(1U);
return ((uint8_t)ack);
}
// SWD Transfer I/O
// request: A[3:2] RnW APnDP
// data: DATA[31:0]
// return: ACK[2:0]
uint8_t* MUL_SWD_Transfer(uint32_t request, uint32_t *data)
{
// if (DAP_Data.fast_clock)
// {
return MUL_SWD_TransferFast(request, data);
// }
// else
// {
// return MUL_SWD_TransferSlow(request, data);
// }
}
/********************************* armfly 优化时序速度 ***************************/
// SWD Transfer I/O
// request: A[3:2] RnW APnDP
// data: DATA[31:0]
// return: ACK[2:0]
#undef PIN_DELAY
#define PIN_DELAY() PIN_DELAY_FAST()
#undef PIN_DELAY
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
// Generate SWJ Sequence
// count: sequence bit count
// data: pointer to sequence bit data
// return: none
#if ((DAP_SWD != 0) || (DAP_JTAG != 0))
void MUL_SWJ_Sequence (uint32_t count, const uint8_t *data) {
uint32_t val;
uint32_t n;
val = 0U;
n = 0U;
while (count--) {
if (n == 0U) {
val = *data++;
n = 8U;
}
if (val & 1U) {
MUL_PIN_SWDIO_OUT(1);
} else {
MUL_PIN_SWDIO_OUT(0);
}
MUL_SW_CLOCK_CYCLE_SLOW();
val >>= 1;
n--;
}
}
#endif

View File

@ -0,0 +1,57 @@
/*
*/
#ifndef __SW_DAP_MULTI_H__
#define __SW_DAP_MULTI_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "flash_blob.h"
#include "target_reset.h"
#ifdef TARGET_MCU_CORTEX_A
#include "debug_ca.h"
#else
#include "debug_cm.h"
#endif
typedef struct
{
uint8_t MultiMode; /* 0表示单机模式, 1表示1拖2, 2表示1拖3, 3表示1拖4 */
uint8_t Active[4];
uint8_t Error[4];
uint8_t AckOk[4];
uint8_t Ignore[4];
uint8_t TempIgnore[4]; /* 临时忽略 */
uint32_t DIR_Pins;
uint32_t SWDIO_Pins;
uint32_t SWCLK_Pins;
uint32_t MODER_Mask;
uint32_t MODER_Out;
uint32_t CLK_0_DIO_0;
uint32_t CLK_0_DIO_1;
uint32_t CoreID[4];
}MUL_SWD_T;
extern MUL_SWD_T g_gMulSwd;
uint8_t *MUL_SWD_Transfer(uint32_t request, uint32_t *data);
void MUL_SWJ_Sequence (uint32_t count, const uint8_t *data);
void MUL_SWD_GPIOConfig(void);
void MUL_RefreshGpioParam(void);
void MUL_SEND_32BIT(uint32_t val);
#ifdef __cplusplus
}
#endif
#endif /* __DAP_H__ */

View File

@ -30,6 +30,7 @@
#include "target_family.h"
#include "prog_if.h"
#include "file_lib.h"
#include "SW_DP_Multi.h"
// Default NVIC and Core debug base addresses
// TODO: Read these addresses from ROM.
@ -60,7 +61,7 @@ typedef struct {
uint32_t xpsr;
} DEBUG_STATE;
static SWD_CONNECT_TYPE reset_connect = CONNECT_NORMAL;
SWD_CONNECT_TYPE reset_connect = CONNECT_NORMAL;
static DAP_STATE dap_state;
static uint32_t soft_reset = SYSRESETREQ;
@ -144,6 +145,11 @@ uint8_t swd_init(void)
// and fixed.
DAP_Setup();
PORT_SWD_SETUP();
if (g_gMulSwd.MultiMode > 0)
{
MUL_SWD_GPIOConfig();
}
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,78 @@
/**
* @file swd_host_mulit.h
* @brief Host driver for accessing the DAP
*
* DAPLink Interface Firmware
* Copyright (c) 2009-2019, ARM Limited, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _SWD_HOST_MULTI_H
#define _SWD_HOST_MULTI_H
#include "flash_blob.h"
#include "target_reset.h"
#ifdef TARGET_MCU_CORTEX_A
#include "debug_ca.h"
#else
#include "debug_cm.h"
#endif
#include "swd_host.h"
#ifdef __cplusplus
extern "C" {
#endif
//typedef enum {
// CONNECT_NORMAL,
// CONNECT_UNDER_RESET,
//} SWD_CONNECT_TYPE;
uint8_t MUL_swd_init(void);
uint8_t MUL_swd_off(void);
uint8_t MUL_swd_init_debug(void);
uint8_t MUL_MUL_swd_clear_errors(void);
uint8_t *MUL_swd_read_dp(uint8_t adr, uint32_t *val);
uint8_t MUL_swd_write_dp(uint8_t adr, uint32_t val);
uint8_t MUL_swd_read_ap(uint32_t adr, uint32_t *val);
uint8_t MUL_swd_write_ap(uint32_t adr, uint32_t val);
uint8_t MUL_swd_read_word(uint32_t addr, uint32_t *val);
uint8_t MUL_swd_write_word(uint32_t addr, uint32_t val);
uint8_t MUL_swd_read_byte(uint32_t addr, uint8_t *val);
uint8_t MUL_swd_write_byte(uint32_t addr, uint8_t val);
uint8_t MUL_swd_read_memory(uint32_t address, uint8_t *data, uint32_t size);
uint8_t MUL_swd_write_memory(uint32_t address, uint8_t *data, uint32_t size);
uint8_t MUL_swd_read_core_register(uint32_t n, uint32_t *val);
uint8_t MUL_swd_write_core_register(uint32_t n, uint32_t val);
uint8_t MUL_swd_flash_syscall_exec(const program_syscall_t *sysCallParam, uint32_t entry, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4);
uint32_t MUL_swd_flash_syscall_exec_ex(const program_syscall_t *sysCallParam, uint32_t entry, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4);
uint8_t MUL_swd_set_target_state_hw(TARGET_RESET_STATE state);
uint8_t MUL_swd_set_target_state_sw(TARGET_RESET_STATE state);
uint8_t *MUL_swd_transfer_retry(uint32_t req, uint32_t *data);
void MUL_int2array(uint8_t *res, uint32_t data, uint8_t len);
void MUL_swd_set_reset_connect(SWD_CONNECT_TYPE type);
void MUL_swd_set_soft_reset(uint32_t soft_reset_type);
uint8_t MUL_swd_read_idcode(uint32_t *id);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -126,28 +126,43 @@ uint8_t target_family_valid(void)
uint8_t target_set_state(TARGET_RESET_STATE state)
{
if (g_board_info.target_set_state) { //target specific
if (g_board_info.target_set_state)
{ //target specific
g_board_info.target_set_state(state);
}
if (g_target_family) {
if (g_target_family->target_set_state) {
if (g_target_family)
{
if (g_target_family->target_set_state)
{
//customize target state
return g_target_family->target_set_state(state);
} else {
if (g_target_family->default_reset_type == kHardwareReset) {
}
else
{
if (g_target_family->default_reset_type == kHardwareReset)
{
return swd_set_target_state_hw(state);
} else if (g_target_family->default_reset_type == kSoftwareReset) {
if (g_board_info.soft_reset_type) { //board has precedence
}
else if (g_target_family->default_reset_type == kSoftwareReset)
{
if (g_board_info.soft_reset_type)
{ //board has precedence
swd_set_soft_reset(g_board_info.soft_reset_type);
} else if (g_target_family->soft_reset_type) {
}
else if (g_target_family->soft_reset_type)
{
swd_set_soft_reset(g_target_family->soft_reset_type);
}
return swd_set_target_state_sw(state);
}else {
}
else
{
return 1;
}
}
}else{
}
else
{
return 0;
}
}

View File

@ -148,7 +148,7 @@ void LuaYeildHook(lua_State *_L, lua_Debug *ar)
LCD_SetEncode(ENCODE_UTF8);
}
ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
ucKeyCode = bsp_GetKey2(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
if (ucKeyCode != KEY_NONE)
{
/* 有键按下 */
@ -168,7 +168,7 @@ void LuaYeildHook(lua_State *_L, lua_Debug *ar)
{
uint8_t ucKeyCode;
ucKeyCode = bsp_GetKey(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
ucKeyCode = bsp_GetKey2(); /* 读取键值, 无键按下时返回 KEY_NONE = 0 */
if (ucKeyCode != KEY_NONE)
{
/* 有键按下 */
@ -180,6 +180,14 @@ void LuaYeildHook(lua_State *_L, lua_Debug *ar)
lua_yield(_L, 0);
break;
case KEY_UP_S:
case KEY_UP_C:
if (g_tProg.AutoStart == 1)
{
;
}
break;
default:
break;
}
@ -718,6 +726,58 @@ int l_my_print(lua_State* L)
return 0;
}
/*
*********************************************************************************************************
* : get_key
* :
* :
* :
*********************************************************************************************************
*/
static int get_key(lua_State* L)
{
uint8_t key;
key = bsp_GetKey();
lua_pushnumber(L, key);
return 1;
}
/*
*********************************************************************************************************
* : put_key
* :
* :
* :
*********************************************************************************************************
*/
static int put_key(lua_State* L)
{
uint8_t key;
if (lua_type(L, 1) == LUA_TNUMBER) /* 判断第1个参数 */
{
key = luaL_checknumber(L, 1);
}
bsp_PutKey(key);
return 0;
}
/*
*********************************************************************************************************
* : clear_key
* :
* :
* :
*********************************************************************************************************
*/
static int clear_key(lua_State* L)
{
bsp_ClearKey();
return 0;
}
/*
*********************************************************************************************************
* : lua_RegisterFunc
@ -738,6 +798,9 @@ static void lua_RegisterFunc(void)
lua_register(g_Lua, "read_clock", read_clock);
lua_register(g_Lua, "get_runtime", get_runtime);
lua_register(g_Lua, "check_runtime", check_runtime);
lua_register(g_Lua, "get_key", get_key);
lua_register(g_Lua, "put_key", put_key);
lua_register(g_Lua, "clear_key", clear_key);
/* 注册接口函数 */
lua_gpio_RegisterFun();
@ -756,4 +819,4 @@ static void lua_RegisterFunc(void)
lua_uart_RegisterFun();
}
/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/

View File

@ -62,18 +62,19 @@ static int lua_GpioCfg(lua_State* L)
return 1;
}
if (_dir == 0)
{
EIO_ConfigPort(_no, ES_GPIO_IN);
}
else if (_dir == 1)
{
EIO_ConfigPort(_no, ES_GPIO_OUT);
}
else if (_dir == 2)
{
EIO_ConfigPort(_no, ES_FMC_OUT);
}
// if (_dir == 0)
// {
// EIO_ConfigPort(_no, ES_GPIO_IN);
// }
// else if (_dir == 1)
// {
// EIO_ConfigPort(_no, ES_GPIO_OUT);
// }
// else if (_dir == 2)
// {
// EIO_ConfigPort(_no, ES_FMC_OUT);
// }
EIO_ConfigPort(_no, (EIO_SELECT_E)_dir);
return 1;
}

View File

@ -9,12 +9,14 @@
#include "target_reset.h"
#include "target_config.h"
#include "swd_host.h"
#include "swd_host_multi.h"
#include "Systick_Handler.h"
#include "main.h"
#include "target_family.h"
#include "stm8_flash.h"
#include "stm8_swim.h"
#include "swd_flash.h"
#include "SW_DP_Multi.h"
/* 为了避免和DAP驱动中的函数混淆本模块函数名前缀用 h7swd */
@ -103,7 +105,7 @@ static int h7_ReladLuaVar(lua_State* L)
/*
*********************************************************************************************************
* : h7swd_Init
* : ID
* : swd
* :
* :
*********************************************************************************************************
@ -114,8 +116,15 @@ static int h7swd_Init(lua_State* L)
{
sysTickInit(); /* 这是DAP驱动中的初始化函数,全局变量初始化 */
if (g_gMulSwd.MultiMode == 0)
{
swd_init_debug(); /* 进入swd debug状态 */
}
else
{
MUL_swd_init_debug(); /* 进入swd debug状态 */
}
}
else if (g_tProg.ChipType == CHIP_SWIM_STM8)
{
SWIM_InitHard(); /* 进入swd debug状态 */
@ -141,8 +150,11 @@ static int h7swd_Init(lua_State* L)
static int h7swd_ReadID(lua_State* L)
{
uint32_t id;
uint32_t id_buf[4];
if (g_tProg.ChipType == CHIP_SWD_ARM)
{
if (g_gMulSwd.MultiMode == 0)
{
if (swd_read_idcode(&id) == 0)
{
@ -153,6 +165,18 @@ static int h7swd_ReadID(lua_State* L)
lua_pushnumber(L, id); /* 成功,返回ID */
}
}
else
{
if (MUL_swd_read_idcode(id_buf) == 0)
{
lua_pushnumber(L, 0); /* 出错 */
}
else
{
lua_pushnumber(L, id); /* 成功,返回ID */
}
}
}
else if (g_tProg.ChipType == CHIP_SWIM_STM8)
{
id = 0x00000800; /* STM8没有ID, 填一个固定值 */
@ -271,6 +295,8 @@ static int h7swd_ReadMemory(lua_State* L)
}
if (g_tProg.ChipType == CHIP_SWD_ARM)
{
if (g_gMulSwd.MultiMode == 0) /* 单机模式 */
{
if (swd_read_memory(addr, s_lua_read_buf, num) == 0)
{
@ -283,6 +309,20 @@ static int h7swd_ReadMemory(lua_State* L)
lua_pushlstring(L, (char *)s_lua_read_buf, num);
}
else /* 1拖4模式 */
{
if (MUL_swd_read_memory(addr, s_lua_read_buf, num) == 0)
{
lua_pushnumber(L, 0); /* 出错 */
}
else
{
lua_pushnumber(L, 1); /* 成功 */
}
lua_pushlstring(L, (char *)s_lua_read_buf, num);
}
}
else if (g_tProg.ChipType == CHIP_SWIM_STM8)
{
if (SWIM_ReadBuf(addr, s_lua_read_buf, num) == 0)
@ -498,6 +538,8 @@ static int h7_reset(lua_State* L)
static int h7_DetectIC(lua_State* L)
{
if (g_tProg.ChipType == CHIP_SWD_ARM)
{
if (g_gMulSwd.MultiMode == 0)
{
uint8_t i;
uint32_t id = 0;
@ -523,6 +565,35 @@ static int h7_DetectIC(lua_State* L)
lua_pushnumber(L, id); /* 成功,返回ID */
return 1;
}
else /* 1拖4模式 */
{
uint8_t i;
uint32_t id[4] = {0};
sysTickInit(); /* 这是DAP驱动中的初始化函数,全局变量初始化 */
for (i = 0; i < 3; i++)
{
bsp_DelayUS(5 * 1000); /* 延迟5ms */
MUL_swd_init_debug(); /* 进入swd debug状态 */
if (MUL_swd_read_idcode(id) == 0)
{
//id = 0; /* 出错继续检测 */
}
else
{
break;
}
}
lua_pushnumber(L, id[0]); /* 成功,返回ID */
lua_pushnumber(L, id[1]); /* 成功,返回ID */
lua_pushnumber(L, id[2]); /* 成功,返回ID */
lua_pushnumber(L, id[3]); /* 成功,返回ID */
return 4;
}
}
else if (g_tProg.ChipType == CHIP_SWIM_STM8)
{
uint32_t id;

View File

@ -45,6 +45,7 @@ static int lua_uart_cfg(lua_State* L);
static int lua_uart_send(lua_State* L);
static int lua_uart_recive(lua_State* L);
static int lua_uart_clear_rx_fifo(lua_State* L);
static int lua_uart_WriteReg16(lua_State* L);
static int lua_uart_WriteReg32(lua_State* L);
@ -75,6 +76,7 @@ void lua_uart_RegisterFun(void)
lua_register(g_Lua, "uart_cfg", lua_uart_cfg);
lua_register(g_Lua, "uart_send", lua_uart_send);
lua_register(g_Lua, "uart_recive", lua_uart_recive);
lua_register(g_Lua, "uart_clear_rx", lua_uart_clear_rx_fifo);
lua_register(g_Lua, "modbus_write_u16", lua_uart_WriteReg16);
lua_register(g_Lua, "modbus_write_u32", lua_uart_WriteReg32);
@ -303,7 +305,7 @@ static int lua_uart_recive(lua_State* L)
}
time1 = bsp_GetRunTime();
timeout = luaL_checknumber(L, 2);
timeout = luaL_checknumber(L, 3);
len = 0;
while (1)
{
@ -333,6 +335,37 @@ static int lua_uart_recive(lua_State* L)
return 2; /* 返回2个参数 */
}
/*
*********************************************************************************************************
* : lua_uart_clear_rx_fifo
* :
* : prot, maxlen, timeout
* : len, readdata
*********************************************************************************************************
*/
static int lua_uart_clear_rx_fifo(lua_State* L)
{
COM_PORT_E port; /* com号: 支持 COM1, COM4, COM7, COM8 */
if (lua_type(L, 1) == LUA_TNUMBER) /* 判断第1个参数 : com 端口 */
{
port = (COM_PORT_E)luaL_checknumber(L, 1);
if (VALID_PORT(port))
{
;
}
else
{
LUA_ERR_PARAM_PRINT("\r\nerror : %s,%s,%d\r\n", "uart_recive", "port=",port);
return 0;
}
}
comClearRxFifo(port); /* 清除接收缓冲区 */
return 0; /* 返回0个参数 */
}
/*
*********************************************************************************************************
* : uart_ReadModbusAck
@ -475,6 +508,21 @@ static int lua_uart_WriteReg16(lua_State* L)
return 0;
}
if (regnum == 1) /* 1个寄存器使用0x06功能 */
{
txbuf[pos++] = addr485;
txbuf[pos++] = 0x06;
txbuf[pos++] = regaddr >> 8;
txbuf[pos++] = regaddr;
txbuf[pos++] = value[0] >> 8;
txbuf[pos++] = value[0];
crc = CRC16_Modbus(txbuf, pos);
txbuf[pos++] = crc >> 8;
txbuf[pos++] = crc;
}
else /* 多个寄存器使用0x10功能 */
{
txbuf[pos++] = addr485;
txbuf[pos++] = 0x10;
txbuf[pos++] = regaddr >> 8;
@ -493,7 +541,7 @@ static int lua_uart_WriteReg16(lua_State* L)
crc = CRC16_Modbus(txbuf, pos);
txbuf[pos++] = crc >> 8;
txbuf[pos++] = crc;
}
comSendBuf((COM_PORT_E)port, txbuf, pos);
errcode = ERR_TIMEOUT;
@ -503,6 +551,7 @@ static int lua_uart_WriteReg16(lua_State* L)
lua_pushnumber(L, RSP_OK); /* 成功返回0 */
return 1;
}
if (rxlen == 5 && (rxbuf[1] & 0x80)) /* 错误应答 */
{
/* 01 86 02 C1 C2 */

View File

@ -1,197 +0,0 @@
# Makefile for building Lua
# See ../doc/readme.html for installation and customization instructions.
# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
# Your platform. See PLATS for possible values.
PLAT= none
CC= gcc -std=gnu99
CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_5_2 $(SYSCFLAGS) $(MYCFLAGS)
LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
LIBS= -lm $(SYSLIBS) $(MYLIBS)
AR= ar rcu
RANLIB= ranlib
RM= rm -f
SYSCFLAGS=
SYSLDFLAGS=
SYSLIBS=
MYCFLAGS=
MYLDFLAGS=
MYLIBS=
MYOBJS=
# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris
LUA_A= liblua.a
CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \
ltm.o lundump.o lvm.o lzio.o
LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \
lmathlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o loadlib.o linit.o
BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS)
LUA_T= lua
LUA_O= lua.o
LUAC_T= luac
LUAC_O= luac.o
ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O)
ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
ALL_A= $(LUA_A)
# Targets start here.
default: $(PLAT)
all: $(ALL_T)
o: $(ALL_O)
a: $(ALL_A)
$(LUA_A): $(BASE_O)
$(AR) $@ $(BASE_O)
$(RANLIB) $@
$(LUA_T): $(LUA_O) $(LUA_A)
$(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
$(LUAC_T): $(LUAC_O) $(LUA_A)
$(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS)
clean:
$(RM) $(ALL_T) $(ALL_O)
depend:
@$(CC) $(CFLAGS) -MM l*.c
echo:
@echo "PLAT= $(PLAT)"
@echo "CC= $(CC)"
@echo "CFLAGS= $(CFLAGS)"
@echo "LDFLAGS= $(SYSLDFLAGS)"
@echo "LIBS= $(LIBS)"
@echo "AR= $(AR)"
@echo "RANLIB= $(RANLIB)"
@echo "RM= $(RM)"
# Convenience targets for popular platforms
ALL= all
none:
@echo "Please do 'make PLATFORM' where PLATFORM is one of these:"
@echo " $(PLATS)"
aix:
$(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall"
bsd:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E"
c89:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_C89" CC="gcc -std=c89"
@echo ''
@echo '*** C89 does not guarantee 64-bit integers for Lua.'
@echo ''
freebsd:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX -DLUA_USE_READLINE -I/usr/include/edit" SYSLIBS="-Wl,-E -ledit" CC="cc"
generic: $(ALL)
linux:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
macosx:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline"
mingw:
$(MAKE) "LUA_A=lua53.dll" "LUA_T=lua.exe" \
"AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \
"SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe
$(MAKE) "LUAC_T=luac.exe" luac.exe
posix:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX"
solaris:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN -D_REENTRANT" SYSLIBS="-ldl"
# list targets that do not create files (but not all makes understand .PHONY)
.PHONY: all $(PLATS) default o a clean depend echo none
# DO NOT DELETE
lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \
ltable.h lundump.h lvm.h
lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h
lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
ldo.h lgc.h lstring.h ltable.h lvm.h
lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h
ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \
ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h
ldo.o: ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \
lparser.h lstring.h ltable.h lundump.h lvm.h
ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \
ltm.h lzio.h lmem.h lundump.h
lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \
lgc.h lstate.h ltm.h lzio.h lmem.h
lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h
liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h \
lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h llex.h lparser.h \
lstring.h ltable.h
lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h
loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \
ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \
lvm.h
lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h
loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
ldo.h lfunc.h lstring.h lgc.h ltable.h
lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \
lstring.h ltable.h
lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h
lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h
lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
luac.o: luac.c lprefix.h lua.h luaconf.h lauxlib.h lobject.h llimits.h \
lstate.h ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h
lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \
lundump.h
lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \
ltable.h lvm.h
lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \
lobject.h ltm.h lzio.h
# (end of Makefile)

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +0,0 @@
/*
** $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

@ -1,264 +0,0 @@
/*
** $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"
/* 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 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);
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)
/*
** {======================================================
** 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;
/* }====================================================== */
/* 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)
#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
#endif
/* print a newline and flush the output */
#if !defined(lua_writeline)
#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout))
#endif
/* print an error message */
#if !defined(lua_writestringerror)
#define lua_writestringerror(s,p) \
(fprintf(stderr, (s), (p)), fflush(stderr))
#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
/* }============================================================ */
#endif

View File

@ -1,498 +0,0 @@
/*
** $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",
"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;
}
static const luaL_Reg base_funcs[] = {
{"assert", luaB_assert},
{"collectgarbage", luaB_collectgarbage},
{"dofile", luaB_dofile},
{"error", luaB_error},
{"getmetatable", luaB_getmetatable},
{"ipairs", luaB_ipairs},
{"loadfile", luaB_loadfile},
{"load", luaB_load},
#if defined(LUA_COMPAT_LOADSTRING)
{"loadstring", luaB_load},
#endif
{"next", luaB_next},
{"pairs", luaB_pairs},
{"pcall", luaB_pcall},
{"print", luaB_print},
{"rawequal", luaB_rawequal},
{"rawlen", luaB_rawlen},
{"rawget", luaB_rawget},
{"rawset", luaB_rawset},
{"select", luaB_select},
{"setmetatable", luaB_setmetatable},
{"tonumber", luaB_tonumber},
{"tostring", luaB_tostring},
{"type", luaB_type},
{"xpcall", luaB_xpcall},
/* placeholders */
{"_G", NULL},
{"_VERSION", NULL},
{NULL, NULL}
};
LUAMOD_API int luaopen_base (lua_State *L) {
/* open lib into global table */
lua_pushglobaltable(L);
luaL_setfuncs(L, base_funcs, 0);
/* set global _G */
lua_pushvalue(L, -1);
lua_setfield(L, -2, "_G");
/* set global _VERSION */
lua_pushliteral(L, LUA_VERSION);
lua_setfield(L, -2, "_VERSION");
return 1;
}

View File

@ -1,233 +0,0 @@
/*
** $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 1;
}
#else /* }{ */
LUAMOD_API int luaopen_bit32 (lua_State *L) {
return luaL_error(L, "library 'bit32' has been deprecated");
}
#endif /* } */

File diff suppressed because it is too large Load Diff

View File

@ -1,88 +0,0 @@
/*
** $Id: lcode.h,v 1.64.1.1 2017/04/19 17:20:42 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
#ifndef lcode_h
#define lcode_h
#include "llex.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
/*
** Marks the end of a patch list. It is an invalid value both as an absolute
** address, and as a list link (would link an element to itself).
*/
#define NO_JUMP (-1)
/*
** grep "ORDER OPR" if you change these enums (ORDER OP)
*/
typedef enum BinOpr {
OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW,
OPR_DIV,
OPR_IDIV,
OPR_BAND, OPR_BOR, OPR_BXOR,
OPR_SHL, OPR_SHR,
OPR_CONCAT,
OPR_EQ, OPR_LT, OPR_LE,
OPR_NE, OPR_GT, OPR_GE,
OPR_AND, OPR_OR,
OPR_NOBINOPR
} BinOpr;
typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
/* get (pointer to) instruction of given 'expdesc' */
#define getinstruction(fs,e) ((fs)->f->code[(e)->u.info])
#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
#define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t)
LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k);
LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
LUAI_FUNC int luaK_intK (FuncState *fs, lua_Integer n);
LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_jump (FuncState *fs);
LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level);
LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
LUAI_FUNC int luaK_getlabel (FuncState *fs);
LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line);
LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1,
expdesc *v2, int line);
LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
#endif

View File

@ -1,168 +0,0 @@
/*
** $Id: lcorolib.c,v 1.10.1.1 2017/04/19 17:20:42 roberto Exp $
** Coroutine Library
** See Copyright Notice in lua.h
*/
#define lcorolib_c
#define LUA_LIB
#include "lprefix.h"
#include <stdlib.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
static lua_State *getco (lua_State *L) {
lua_State *co = lua_tothread(L, 1);
luaL_argcheck(L, co, 1, "thread expected");
return co;
}
static int auxresume (lua_State *L, lua_State *co, int narg) {
int status;
if (!lua_checkstack(co, narg)) {
lua_pushliteral(L, "too many arguments to resume");
return -1; /* error flag */
}
if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
lua_pushliteral(L, "cannot resume dead coroutine");
return -1; /* error flag */
}
lua_xmove(L, co, narg);
status = lua_resume(co, L, narg);
if (status == LUA_OK || status == LUA_YIELD) {
int nres = lua_gettop(co);
if (!lua_checkstack(L, nres + 1)) {
lua_pop(co, nres); /* remove results anyway */
lua_pushliteral(L, "too many results to resume");
return -1; /* error flag */
}
lua_xmove(co, L, nres); /* move yielded values */
return nres;
}
else {
lua_xmove(co, L, 1); /* move error message */
return -1; /* error flag */
}
}
static int luaB_coresume (lua_State *L) {
lua_State *co = getco(L);
int r;
r = auxresume(L, co, lua_gettop(L) - 1);
if (r < 0) {
lua_pushboolean(L, 0);
lua_insert(L, -2);
return 2; /* return false + error message */
}
else {
lua_pushboolean(L, 1);
lua_insert(L, -(r + 1));
return r + 1; /* return true + 'resume' returns */
}
}
static int luaB_auxwrap (lua_State *L) {
lua_State *co = lua_tothread(L, lua_upvalueindex(1));
int r = auxresume(L, co, lua_gettop(L));
if (r < 0) {
if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */
luaL_where(L, 1); /* add extra info */
lua_insert(L, -2);
lua_concat(L, 2);
}
return lua_error(L); /* propagate error */
}
return r;
}
static int luaB_cocreate (lua_State *L) {
lua_State *NL;
luaL_checktype(L, 1, LUA_TFUNCTION);
NL = lua_newthread(L);
lua_pushvalue(L, 1); /* move function to top */
lua_xmove(L, NL, 1); /* move function from L to NL */
return 1;
}
static int luaB_cowrap (lua_State *L) {
luaB_cocreate(L);
lua_pushcclosure(L, luaB_auxwrap, 1);
return 1;
}
static int luaB_yield (lua_State *L) {
return lua_yield(L, lua_gettop(L));
}
static int luaB_costatus (lua_State *L) {
lua_State *co = getco(L);
if (L == co) lua_pushliteral(L, "running");
else {
switch (lua_status(co)) {
case LUA_YIELD:
lua_pushliteral(L, "suspended");
break;
case LUA_OK: {
lua_Debug ar;
if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
lua_pushliteral(L, "normal"); /* it is running */
else if (lua_gettop(co) == 0)
lua_pushliteral(L, "dead");
else
lua_pushliteral(L, "suspended"); /* initial state */
break;
}
default: /* some error occurred */
lua_pushliteral(L, "dead");
break;
}
}
return 1;
}
static int luaB_yieldable (lua_State *L) {
lua_pushboolean(L, lua_isyieldable(L));
return 1;
}
static int luaB_corunning (lua_State *L) {
int ismain = lua_pushthread(L);
lua_pushboolean(L, ismain);
return 2;
}
static const luaL_Reg co_funcs[] = {
{"create", luaB_cocreate},
{"resume", luaB_coresume},
{"running", luaB_corunning},
{"status", luaB_costatus},
{"wrap", luaB_cowrap},
{"yield", luaB_yield},
{"isyieldable", luaB_yieldable},
{NULL, NULL}
};
LUAMOD_API int luaopen_coroutine (lua_State *L) {
luaL_newlib(L, co_funcs);
return 1;
}

View File

@ -1,55 +0,0 @@
/*
** $Id: lctype.c,v 1.12.1.1 2017/04/19 17:20:42 roberto Exp $
** 'ctype' functions for Lua
** See Copyright Notice in lua.h
*/
#define lctype_c
#define LUA_CORE
#include "lprefix.h"
#include "lctype.h"
#if !LUA_USE_CTYPE /* { */
#include <limits.h>
LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = {
0x00, /* EOZ */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */
0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */
0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05,
0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */
0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
#endif /* } */

View File

@ -1,95 +0,0 @@
/*
** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $
** 'ctype' functions for Lua
** See Copyright Notice in lua.h
*/
#ifndef lctype_h
#define lctype_h
#include "lua.h"
/*
** WARNING: the functions defined here do not necessarily correspond
** to the similar functions in the standard C ctype.h. They are
** optimized for the specific needs of Lua
*/
#if !defined(LUA_USE_CTYPE)
#if 'A' == 65 && '0' == 48
/* ASCII case: can use its own tables; faster and fixed */
#define LUA_USE_CTYPE 0
#else
/* must use standard C ctype */
#define LUA_USE_CTYPE 1
#endif
#endif
#if !LUA_USE_CTYPE /* { */
#include <limits.h>
#include "llimits.h"
#define ALPHABIT 0
#define DIGITBIT 1
#define PRINTBIT 2
#define SPACEBIT 3
#define XDIGITBIT 4
#define MASK(B) (1 << (B))
/*
** add 1 to char to allow index -1 (EOZ)
*/
#define testprop(c,p) (luai_ctype_[(c)+1] & (p))
/*
** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_'
*/
#define lislalpha(c) testprop(c, MASK(ALPHABIT))
#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
#define lisdigit(c) testprop(c, MASK(DIGITBIT))
#define lisspace(c) testprop(c, MASK(SPACEBIT))
#define lisprint(c) testprop(c, MASK(PRINTBIT))
#define lisxdigit(c) testprop(c, MASK(XDIGITBIT))
/*
** this 'ltolower' only works for alphabetic characters
*/
#define ltolower(c) ((c) | ('A' ^ 'a'))
/* two more entries for 0 and -1 (EOZ) */
LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2];
#else /* }{ */
/*
** use standard C ctypes
*/
#include <ctype.h>
#define lislalpha(c) (isalpha(c) || (c) == '_')
#define lislalnum(c) (isalnum(c) || (c) == '_')
#define lisdigit(c) (isdigit(c))
#define lisspace(c) (isspace(c))
#define lisprint(c) (isprint(c))
#define lisxdigit(c) (isxdigit(c))
#define ltolower(c) (tolower(c))
#endif /* } */
#endif

View File

@ -1,456 +0,0 @@
/*
** $Id: ldblib.c,v 1.151.1.1 2017/04/19 17:20:42 roberto Exp $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
#define ldblib_c
#define LUA_LIB
#include "lprefix.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
/*
** The hook table at registry[&HOOKKEY] maps threads to their current
** hook function. (We only need the unique address of 'HOOKKEY'.)
*/
static const int HOOKKEY = 0;
/*
** If L1 != L, L1 can be in any state, and therefore there are no
** guarantees about its stack space; any push in L1 must be
** checked.
*/
static void checkstack (lua_State *L, lua_State *L1, int n) {
if (L != L1 && !lua_checkstack(L1, n))
luaL_error(L, "stack overflow");
}
static int db_getregistry (lua_State *L) {
lua_pushvalue(L, LUA_REGISTRYINDEX);
return 1;
}
static int db_getmetatable (lua_State *L) {
luaL_checkany(L, 1);
if (!lua_getmetatable(L, 1)) {
lua_pushnil(L); /* no metatable */
}
return 1;
}
static int db_setmetatable (lua_State *L) {
int t = lua_type(L, 2);
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
"nil or table expected");
lua_settop(L, 2);
lua_setmetatable(L, 1);
return 1; /* return 1st argument */
}
static int db_getuservalue (lua_State *L) {
if (lua_type(L, 1) != LUA_TUSERDATA)
lua_pushnil(L);
else
lua_getuservalue(L, 1);
return 1;
}
static int db_setuservalue (lua_State *L) {
luaL_checktype(L, 1, LUA_TUSERDATA);
luaL_checkany(L, 2);
lua_settop(L, 2);
lua_setuservalue(L, 1);
return 1;
}
/*
** Auxiliary function used by several library functions: check for
** an optional thread as function's first argument and set 'arg' with
** 1 if this argument is present (so that functions can skip it to
** access their other arguments)
*/
static lua_State *getthread (lua_State *L, int *arg) {
if (lua_isthread(L, 1)) {
*arg = 1;
return lua_tothread(L, 1);
}
else {
*arg = 0;
return L; /* function will operate over current thread */
}
}
/*
** Variations of 'lua_settable', used by 'db_getinfo' to put results
** from 'lua_getinfo' into result table. Key is always a string;
** value can be a string, an int, or a boolean.
*/
static void settabss (lua_State *L, const char *k, const char *v) {
lua_pushstring(L, v);
lua_setfield(L, -2, k);
}
static void settabsi (lua_State *L, const char *k, int v) {
lua_pushinteger(L, v);
lua_setfield(L, -2, k);
}
static void settabsb (lua_State *L, const char *k, int v) {
lua_pushboolean(L, v);
lua_setfield(L, -2, k);
}
/*
** In function 'db_getinfo', the call to 'lua_getinfo' may push
** results on the stack; later it creates the result table to put
** these objects. Function 'treatstackoption' puts the result from
** 'lua_getinfo' on top of the result table so that it can call
** 'lua_setfield'.
*/
static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
if (L == L1)
lua_rotate(L, -2, 1); /* exchange object and table */
else
lua_xmove(L1, L, 1); /* move object to the "main" stack */
lua_setfield(L, -2, fname); /* put object into table */
}
/*
** Calls 'lua_getinfo' and collects all results in a new table.
** L1 needs stack space for an optional input (function) plus
** two optional outputs (function and line table) from function
** 'lua_getinfo'.
*/
static int db_getinfo (lua_State *L) {
lua_Debug ar;
int arg;
lua_State *L1 = getthread(L, &arg);
const char *options = luaL_optstring(L, arg+2, "flnStu");
checkstack(L, L1, 3);
if (lua_isfunction(L, arg + 1)) { /* info about a function? */
options = lua_pushfstring(L, ">%s", options); /* add '>' to 'options' */
lua_pushvalue(L, arg + 1); /* move function to 'L1' stack */
lua_xmove(L, L1, 1);
}
else { /* stack level */
if (!lua_getstack(L1, (int)luaL_checkinteger(L, arg + 1), &ar)) {
lua_pushnil(L); /* level out of range */
return 1;
}
}
if (!lua_getinfo(L1, options, &ar))
return luaL_argerror(L, arg+2, "invalid option");
lua_newtable(L); /* table to collect results */
if (strchr(options, 'S')) {
settabss(L, "source", ar.source);
settabss(L, "short_src", ar.short_src);
settabsi(L, "linedefined", ar.linedefined);
settabsi(L, "lastlinedefined", ar.lastlinedefined);
settabss(L, "what", ar.what);
}
if (strchr(options, 'l'))
settabsi(L, "currentline", ar.currentline);
if (strchr(options, 'u')) {
settabsi(L, "nups", ar.nups);
settabsi(L, "nparams", ar.nparams);
settabsb(L, "isvararg", ar.isvararg);
}
if (strchr(options, 'n')) {
settabss(L, "name", ar.name);
settabss(L, "namewhat", ar.namewhat);
}
if (strchr(options, 't'))
settabsb(L, "istailcall", ar.istailcall);
if (strchr(options, 'L'))
treatstackoption(L, L1, "activelines");
if (strchr(options, 'f'))
treatstackoption(L, L1, "func");
return 1; /* return table */
}
static int db_getlocal (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
const char *name;
int nvar = (int)luaL_checkinteger(L, arg + 2); /* local-variable index */
if (lua_isfunction(L, arg + 1)) { /* function argument? */
lua_pushvalue(L, arg + 1); /* push function */
lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */
return 1; /* return only name (there is no value) */
}
else { /* stack-level argument */
int level = (int)luaL_checkinteger(L, arg + 1);
if (!lua_getstack(L1, level, &ar)) /* out of range? */
return luaL_argerror(L, arg+1, "level out of range");
checkstack(L, L1, 1);
name = lua_getlocal(L1, &ar, nvar);
if (name) {
lua_xmove(L1, L, 1); /* move local value */
lua_pushstring(L, name); /* push name */
lua_rotate(L, -2, 1); /* re-order */
return 2;
}
else {
lua_pushnil(L); /* no name (nor value) */
return 1;
}
}
}
static int db_setlocal (lua_State *L) {
int arg;
const char *name;
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
int level = (int)luaL_checkinteger(L, arg + 1);
int nvar = (int)luaL_checkinteger(L, arg + 2);
if (!lua_getstack(L1, level, &ar)) /* out of range? */
return luaL_argerror(L, arg+1, "level out of range");
luaL_checkany(L, arg+3);
lua_settop(L, arg+3);
checkstack(L, L1, 1);
lua_xmove(L, L1, 1);
name = lua_setlocal(L1, &ar, nvar);
if (name == NULL)
lua_pop(L1, 1); /* pop value (if not popped by 'lua_setlocal') */
lua_pushstring(L, name);
return 1;
}
/*
** get (if 'get' is true) or set an upvalue from a closure
*/
static int auxupvalue (lua_State *L, int get) {
const char *name;
int n = (int)luaL_checkinteger(L, 2); /* upvalue index */
luaL_checktype(L, 1, LUA_TFUNCTION); /* closure */
name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
if (name == NULL) return 0;
lua_pushstring(L, name);
lua_insert(L, -(get+1)); /* no-op if get is false */
return get + 1;
}
static int db_getupvalue (lua_State *L) {
return auxupvalue(L, 1);
}
static int db_setupvalue (lua_State *L) {
luaL_checkany(L, 3);
return auxupvalue(L, 0);
}
/*
** Check whether a given upvalue from a given closure exists and
** returns its index
*/
static int checkupval (lua_State *L, int argf, int argnup) {
int nup = (int)luaL_checkinteger(L, argnup); /* upvalue index */
luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */
luaL_argcheck(L, (lua_getupvalue(L, argf, nup) != NULL), argnup,
"invalid upvalue index");
return nup;
}
static int db_upvalueid (lua_State *L) {
int n = checkupval(L, 1, 2);
lua_pushlightuserdata(L, lua_upvalueid(L, 1, n));
return 1;
}
static int db_upvaluejoin (lua_State *L) {
int n1 = checkupval(L, 1, 2);
int n2 = checkupval(L, 3, 4);
luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected");
luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected");
lua_upvaluejoin(L, 1, n1, 3, n2);
return 0;
}
/*
** Call hook function registered at hook table for the current
** thread (if there is one)
*/
static void hookf (lua_State *L, lua_Debug *ar) {
static const char *const hooknames[] =
{"call", "return", "line", "count", "tail call"};
lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY);
lua_pushthread(L);
if (lua_rawget(L, -2) == LUA_TFUNCTION) { /* is there a hook function? */
lua_pushstring(L, hooknames[(int)ar->event]); /* push event name */
if (ar->currentline >= 0)
lua_pushinteger(L, ar->currentline); /* push current line */
else lua_pushnil(L);
lua_assert(lua_getinfo(L, "lS", ar));
lua_call(L, 2, 0); /* call hook function */
}
}
/*
** Convert a string mask (for 'sethook') into a bit mask
*/
static int makemask (const char *smask, int count) {
int mask = 0;
if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
if (strchr(smask, 'r')) mask |= LUA_MASKRET;
if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
if (count > 0) mask |= LUA_MASKCOUNT;
return mask;
}
/*
** Convert a bit mask (for 'gethook') into a string mask
*/
static char *unmakemask (int mask, char *smask) {
int i = 0;
if (mask & LUA_MASKCALL) smask[i++] = 'c';
if (mask & LUA_MASKRET) smask[i++] = 'r';
if (mask & LUA_MASKLINE) smask[i++] = 'l';
smask[i] = '\0';
return smask;
}
static int db_sethook (lua_State *L) {
int arg, mask, count;
lua_Hook func;
lua_State *L1 = getthread(L, &arg);
if (lua_isnoneornil(L, arg+1)) { /* no hook? */
lua_settop(L, arg+1);
func = NULL; mask = 0; count = 0; /* turn off hooks */
}
else {
const char *smask = luaL_checkstring(L, arg+2);
luaL_checktype(L, arg+1, LUA_TFUNCTION);
count = (int)luaL_optinteger(L, arg + 3, 0);
func = hookf; mask = makemask(smask, count);
}
if (lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY) == LUA_TNIL) {
lua_createtable(L, 0, 2); /* create a hook table */
lua_pushvalue(L, -1);
lua_rawsetp(L, LUA_REGISTRYINDEX, &HOOKKEY); /* set it in position */
lua_pushstring(L, "k");
lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */
lua_pushvalue(L, -1);
lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */
}
checkstack(L, L1, 1);
lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */
lua_pushvalue(L, arg + 1); /* value (hook function) */
lua_rawset(L, -3); /* hooktable[L1] = new Lua hook */
lua_sethook(L1, func, mask, count);
return 0;
}
static int db_gethook (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
char buff[5];
int mask = lua_gethookmask(L1);
lua_Hook hook = lua_gethook(L1);
if (hook == NULL) /* no hook? */
lua_pushnil(L);
else if (hook != hookf) /* external hook? */
lua_pushliteral(L, "external hook");
else { /* hook table must exist */
lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY);
checkstack(L, L1, 1);
lua_pushthread(L1); lua_xmove(L1, L, 1);
lua_rawget(L, -2); /* 1st result = hooktable[L1] */
lua_remove(L, -2); /* remove hook table */
}
lua_pushstring(L, unmakemask(mask, buff)); /* 2nd result = mask */
lua_pushinteger(L, lua_gethookcount(L1)); /* 3rd result = count */
return 3;
}
static int db_debug (lua_State *L) {
for (;;) {
char buffer[250];
lua_writestringerror("%s", "lua_debug> ");
if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
strcmp(buffer, "cont\n") == 0)
return 0;
if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
lua_pcall(L, 0, 0, 0))
lua_writestringerror("%s\n", lua_tostring(L, -1));
lua_settop(L, 0); /* remove eventual returns */
}
}
static int db_traceback (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
const char *msg = lua_tostring(L, arg + 1);
if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */
lua_pushvalue(L, arg + 1); /* return it untouched */
else {
int level = (int)luaL_optinteger(L, arg + 2, (L == L1) ? 1 : 0);
luaL_traceback(L, L1, msg, level);
}
return 1;
}
static const luaL_Reg dblib[] = {
{"debug", db_debug},
{"getuservalue", db_getuservalue},
{"gethook", db_gethook},
{"getinfo", db_getinfo},
{"getlocal", db_getlocal},
{"getregistry", db_getregistry},
{"getmetatable", db_getmetatable},
{"getupvalue", db_getupvalue},
{"upvaluejoin", db_upvaluejoin},
{"upvalueid", db_upvalueid},
{"setuservalue", db_setuservalue},
{"sethook", db_sethook},
{"setlocal", db_setlocal},
{"setmetatable", db_setmetatable},
{"setupvalue", db_setupvalue},
{"traceback", db_traceback},
{NULL, NULL}
};
LUAMOD_API int luaopen_debug (lua_State *L) {
luaL_newlib(L, dblib);
return 1;
}

View File

@ -1,702 +0,0 @@
/*
** $Id: ldebug.c,v 2.121.1.2 2017/07/10 17:21:50 roberto Exp $
** Debug Interface
** See Copyright Notice in lua.h
*/
#define ldebug_c
#define LUA_CORE
#include "lprefix.h"
#include <stdarg.h>
#include <stddef.h>
#include <string.h>
#include "lua.h"
#include "lapi.h"
#include "lcode.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lvm.h"
#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL)
/* Active Lua function (given call info) */
#define ci_func(ci) (clLvalue((ci)->func))
static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
const char **name);
static int currentpc (CallInfo *ci) {
lua_assert(isLua(ci));
return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
}
static int currentline (CallInfo *ci) {
return getfuncline(ci_func(ci)->p, currentpc(ci));
}
/*
** If function yielded, its 'func' can be in the 'extra' field. The
** next function restores 'func' to its correct value for debugging
** purposes. (It exchanges 'func' and 'extra'; so, when called again,
** after debugging, it also "re-restores" ** 'func' to its altered value.
*/
static void swapextra (lua_State *L) {
if (L->status == LUA_YIELD) {
CallInfo *ci = L->ci; /* get function that yielded */
StkId temp = ci->func; /* exchange its 'func' and 'extra' values */
ci->func = restorestack(L, ci->extra);
ci->extra = savestack(L, temp);
}
}
/*
** This function can be called asynchronously (e.g. during a signal).
** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by
** 'resethookcount') are for debug only, and it is no problem if they
** get arbitrary values (causes at most one wrong hook call). 'hookmask'
** is an atomic value. We assume that pointers are atomic too (e.g., gcc
** ensures that for all platforms where it runs). Moreover, 'hook' is
** always checked before being called (see 'luaD_hook').
*/
LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
if (func == NULL || mask == 0) { /* turn off hooks? */
mask = 0;
func = NULL;
}
if (isLua(L->ci))
L->oldpc = L->ci->u.l.savedpc;
L->hook = func;
L->basehookcount = count;
resethookcount(L);
L->hookmask = cast_byte(mask);
}
LUA_API lua_Hook lua_gethook (lua_State *L) {
return L->hook;
}
LUA_API int lua_gethookmask (lua_State *L) {
return L->hookmask;
}
LUA_API int lua_gethookcount (lua_State *L) {
return L->basehookcount;
}
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
int status;
CallInfo *ci;
if (level < 0) return 0; /* invalid (negative) level */
lua_lock(L);
for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
level--;
if (level == 0 && ci != &L->base_ci) { /* level found? */
status = 1;
ar->i_ci = ci;
}
else status = 0; /* no such level */
lua_unlock(L);
return status;
}
static const char *upvalname (Proto *p, int uv) {
TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
if (s == NULL) return "?";
else return getstr(s);
}
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
int nparams = clLvalue(ci->func)->p->numparams;
if (n >= cast_int(ci->u.l.base - ci->func) - nparams)
return NULL; /* no such vararg */
else {
*pos = ci->func + nparams + n;
return "(*vararg)"; /* generic name for any vararg */
}
}
static const char *findlocal (lua_State *L, CallInfo *ci, int n,
StkId *pos) {
const char *name = NULL;
StkId base;
if (isLua(ci)) {
if (n < 0) /* access to vararg values? */
return findvararg(ci, -n, pos);
else {
base = ci->u.l.base;
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
}
}
else
base = ci->func + 1;
if (name == NULL) { /* no 'standard' name? */
StkId limit = (ci == L->ci) ? L->top : ci->next->func;
if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */
name = "(*temporary)"; /* generic name for any valid slot */
else
return NULL; /* no name */
}
*pos = base + (n - 1);
return name;
}
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
const char *name;
lua_lock(L);
swapextra(L);
if (ar == NULL) { /* information about non-active function? */
if (!isLfunction(L->top - 1)) /* not a Lua function? */
name = NULL;
else /* consider live variables at function start (parameters) */
name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
}
else { /* active function; get information through 'ar' */
StkId pos = NULL; /* to avoid warnings */
name = findlocal(L, ar->i_ci, n, &pos);
if (name) {
setobj2s(L, L->top, pos);
api_incr_top(L);
}
}
swapextra(L);
lua_unlock(L);
return name;
}
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
StkId pos = NULL; /* to avoid warnings */
const char *name;
lua_lock(L);
swapextra(L);
name = findlocal(L, ar->i_ci, n, &pos);
if (name) {
setobjs2s(L, pos, L->top - 1);
L->top--; /* pop value */
}
swapextra(L);
lua_unlock(L);
return name;
}
static void funcinfo (lua_Debug *ar, Closure *cl) {
if (noLuaClosure(cl)) {
ar->source = "=[C]";
ar->linedefined = -1;
ar->lastlinedefined = -1;
ar->what = "C";
}
else {
Proto *p = cl->l.p;
ar->source = p->source ? getstr(p->source) : "=?";
ar->linedefined = p->linedefined;
ar->lastlinedefined = p->lastlinedefined;
ar->what = (ar->linedefined == 0) ? "main" : "Lua";
}
luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
}
static void collectvalidlines (lua_State *L, Closure *f) {
if (noLuaClosure(f)) {
setnilvalue(L->top);
api_incr_top(L);
}
else {
int i;
TValue v;
int *lineinfo = f->l.p->lineinfo;
Table *t = luaH_new(L); /* new table to store active lines */
sethvalue(L, L->top, t); /* push it on stack */
api_incr_top(L);
setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */
luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */
}
}
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
if (ci == NULL) /* no 'ci'? */
return NULL; /* no info */
else if (ci->callstatus & CIST_FIN) { /* is this a finalizer? */
*name = "__gc";
return "metamethod"; /* report it as such */
}
/* calling function is a known Lua function? */
else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
return funcnamefromcode(L, ci->previous, name);
else return NULL; /* no way to find a name */
}
static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
Closure *f, CallInfo *ci) {
int status = 1;
for (; *what; what++) {
switch (*what) {
case 'S': {
funcinfo(ar, f);
break;
}
case 'l': {
ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1;
break;
}
case 'u': {
ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
if (noLuaClosure(f)) {
ar->isvararg = 1;
ar->nparams = 0;
}
else {
ar->isvararg = f->l.p->is_vararg;
ar->nparams = f->l.p->numparams;
}
break;
}
case 't': {
ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
break;
}
case 'n': {
ar->namewhat = getfuncname(L, ci, &ar->name);
if (ar->namewhat == NULL) {
ar->namewhat = ""; /* not found */
ar->name = NULL;
}
break;
}
case 'L':
case 'f': /* handled by lua_getinfo */
break;
default: status = 0; /* invalid option */
}
}
return status;
}
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
int status;
Closure *cl;
CallInfo *ci;
StkId func;
lua_lock(L);
swapextra(L);
if (*what == '>') {
ci = NULL;
func = L->top - 1;
api_check(L, ttisfunction(func), "function expected");
what++; /* skip the '>' */
L->top--; /* pop function */
}
else {
ci = ar->i_ci;
func = ci->func;
lua_assert(ttisfunction(ci->func));
}
cl = ttisclosure(func) ? clvalue(func) : NULL;
status = auxgetinfo(L, what, ar, cl, ci);
if (strchr(what, 'f')) {
setobjs2s(L, L->top, func);
api_incr_top(L);
}
swapextra(L); /* correct before option 'L', which can raise a mem. error */
if (strchr(what, 'L'))
collectvalidlines(L, cl);
lua_unlock(L);
return status;
}
/*
** {======================================================
** Symbolic Execution
** =======================================================
*/
static const char *getobjname (Proto *p, int lastpc, int reg,
const char **name);
/*
** find a "name" for the RK value 'c'
*/
static void kname (Proto *p, int pc, int c, const char **name) {
if (ISK(c)) { /* is 'c' a constant? */
TValue *kvalue = &p->k[INDEXK(c)];
if (ttisstring(kvalue)) { /* literal constant? */
*name = svalue(kvalue); /* it is its own name */
return;
}
/* else no reasonable name found */
}
else { /* 'c' is a register */
const char *what = getobjname(p, pc, c, name); /* search for 'c' */
if (what && *what == 'c') { /* found a constant name? */
return; /* 'name' already filled */
}
/* else no reasonable name found */
}
*name = "?"; /* no reasonable name found */
}
static int filterpc (int pc, int jmptarget) {
if (pc < jmptarget) /* is code conditional (inside a jump)? */
return -1; /* cannot know who sets that register */
else return pc; /* current position sets that register */
}
/*
** try to find last instruction before 'lastpc' that modified register 'reg'
*/
static int findsetreg (Proto *p, int lastpc, int reg) {
int pc;
int setreg = -1; /* keep last instruction that changed 'reg' */
int jmptarget = 0; /* any code before this address is conditional */
for (pc = 0; pc < lastpc; pc++) {
Instruction i = p->code[pc];
OpCode op = GET_OPCODE(i);
int a = GETARG_A(i);
switch (op) {
case OP_LOADNIL: {
int b = GETARG_B(i);
if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */
setreg = filterpc(pc, jmptarget);
break;
}
case OP_TFORCALL: {
if (reg >= a + 2) /* affect all regs above its base */
setreg = filterpc(pc, jmptarget);
break;
}
case OP_CALL:
case OP_TAILCALL: {
if (reg >= a) /* affect all registers above base */
setreg = filterpc(pc, jmptarget);
break;
}
case OP_JMP: {
int b = GETARG_sBx(i);
int dest = pc + 1 + b;
/* jump is forward and do not skip 'lastpc'? */
if (pc < dest && dest <= lastpc) {
if (dest > jmptarget)
jmptarget = dest; /* update 'jmptarget' */
}
break;
}
default:
if (testAMode(op) && reg == a) /* any instruction that set A */
setreg = filterpc(pc, jmptarget);
break;
}
}
return setreg;
}
static const char *getobjname (Proto *p, int lastpc, int reg,
const char **name) {
int pc;
*name = luaF_getlocalname(p, reg + 1, lastpc);
if (*name) /* is a local? */
return "local";
/* else try symbolic execution */
pc = findsetreg(p, lastpc, reg);
if (pc != -1) { /* could find instruction? */
Instruction i = p->code[pc];
OpCode op = GET_OPCODE(i);
switch (op) {
case OP_MOVE: {
int b = GETARG_B(i); /* move from 'b' to 'a' */
if (b < GETARG_A(i))
return getobjname(p, pc, b, name); /* get name for 'b' */
break;
}
case OP_GETTABUP:
case OP_GETTABLE: {
int k = GETARG_C(i); /* key index */
int t = GETARG_B(i); /* table index */
const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
? luaF_getlocalname(p, t + 1, pc)
: upvalname(p, t);
kname(p, pc, k, name);
return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
}
case OP_GETUPVAL: {
*name = upvalname(p, GETARG_B(i));
return "upvalue";
}
case OP_LOADK:
case OP_LOADKX: {
int b = (op == OP_LOADK) ? GETARG_Bx(i)
: GETARG_Ax(p->code[pc + 1]);
if (ttisstring(&p->k[b])) {
*name = svalue(&p->k[b]);
return "constant";
}
break;
}
case OP_SELF: {
int k = GETARG_C(i); /* key index */
kname(p, pc, k, name);
return "method";
}
default: break; /* go through to return NULL */
}
}
return NULL; /* could not find reasonable name */
}
/*
** Try to find a name for a function based on the code that called it.
** (Only works when function was called by a Lua function.)
** Returns what the name is (e.g., "for iterator", "method",
** "metamethod") and sets '*name' to point to the name.
*/
static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
const char **name) {
TMS tm = (TMS)0; /* (initial value avoids warnings) */
Proto *p = ci_func(ci)->p; /* calling function */
int pc = currentpc(ci); /* calling instruction index */
Instruction i = p->code[pc]; /* calling instruction */
if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
*name = "?";
return "hook";
}
switch (GET_OPCODE(i)) {
case OP_CALL:
case OP_TAILCALL:
return getobjname(p, pc, GETARG_A(i), name); /* get function name */
case OP_TFORCALL: { /* for iterator */
*name = "for iterator";
return "for iterator";
}
/* other instructions can do calls through metamethods */
case OP_SELF: case OP_GETTABUP: case OP_GETTABLE:
tm = TM_INDEX;
break;
case OP_SETTABUP: case OP_SETTABLE:
tm = TM_NEWINDEX;
break;
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: {
int offset = cast_int(GET_OPCODE(i)) - cast_int(OP_ADD); /* ORDER OP */
tm = cast(TMS, offset + cast_int(TM_ADD)); /* ORDER TM */
break;
}
case OP_UNM: tm = TM_UNM; break;
case OP_BNOT: tm = TM_BNOT; break;
case OP_LEN: tm = TM_LEN; break;
case OP_CONCAT: tm = TM_CONCAT; break;
case OP_EQ: tm = TM_EQ; break;
case OP_LT: tm = TM_LT; break;
case OP_LE: tm = TM_LE; break;
default:
return NULL; /* cannot find a reasonable name */
}
*name = getstr(G(L)->tmname[tm]);
return "metamethod";
}
/* }====================================================== */
/*
** The subtraction of two potentially unrelated pointers is
** not ISO C, but it should not crash a program; the subsequent
** checks are ISO C and ensure a correct result.
*/
static int isinstack (CallInfo *ci, const TValue *o) {
ptrdiff_t i = o - ci->u.l.base;
return (0 <= i && i < (ci->top - ci->u.l.base) && ci->u.l.base + i == o);
}
/*
** Checks whether value 'o' came from an upvalue. (That can only happen
** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on
** upvalues.)
*/
static const char *getupvalname (CallInfo *ci, const TValue *o,
const char **name) {
LClosure *c = ci_func(ci);
int i;
for (i = 0; i < c->nupvalues; i++) {
if (c->upvals[i]->v == o) {
*name = upvalname(c->p, i);
return "upvalue";
}
}
return NULL;
}
static const char *varinfo (lua_State *L, const TValue *o) {
const char *name = NULL; /* to avoid warnings */
CallInfo *ci = L->ci;
const char *kind = NULL;
if (isLua(ci)) {
kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
if (!kind && isinstack(ci, o)) /* no? try a register */
kind = getobjname(ci_func(ci)->p, currentpc(ci),
cast_int(o - ci->u.l.base), &name);
}
return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : "";
}
l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
const char *t = luaT_objtypename(L, o);
luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o));
}
l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) {
if (ttisstring(p1) || cvt2str(p1)) p1 = p2;
luaG_typeerror(L, p1, "concatenate");
}
l_noret luaG_opinterror (lua_State *L, const TValue *p1,
const TValue *p2, const char *msg) {
lua_Number temp;
if (!tonumber(p1, &temp)) /* first operand is wrong? */
p2 = p1; /* now second is wrong */
luaG_typeerror(L, p2, msg);
}
/*
** Error when both values are convertible to numbers, but not to integers
*/
l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) {
lua_Integer temp;
if (!tointeger(p1, &temp))
p2 = p1;
luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2));
}
l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
const char *t1 = luaT_objtypename(L, p1);
const char *t2 = luaT_objtypename(L, p2);
if (strcmp(t1, t2) == 0)
luaG_runerror(L, "attempt to compare two %s values", t1);
else
luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
}
/* add src:line information to 'msg' */
const char *luaG_addinfo (lua_State *L, const char *msg, TString *src,
int line) {
char buff[LUA_IDSIZE];
if (src)
luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
else { /* no source available; use "?" instead */
buff[0] = '?'; buff[1] = '\0';
}
return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
}
l_noret luaG_errormsg (lua_State *L) {
if (L->errfunc != 0) { /* is there an error handling function? */
StkId errfunc = restorestack(L, L->errfunc);
setobjs2s(L, L->top, L->top - 1); /* move argument */
setobjs2s(L, L->top - 1, errfunc); /* push function */
L->top++; /* assume EXTRA_STACK */
luaD_callnoyield(L, L->top - 2, 1); /* call it */
}
luaD_throw(L, LUA_ERRRUN);
}
l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
CallInfo *ci = L->ci;
const char *msg;
va_list argp;
luaC_checkGC(L); /* error message uses memory */
va_start(argp, fmt);
msg = luaO_pushvfstring(L, fmt, argp); /* format message */
va_end(argp);
if (isLua(ci)) /* if Lua function, add source:line information */
luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci));
//printf("%s", msg);
luaG_errormsg(L);
}
void luaG_traceexec (lua_State *L) {
CallInfo *ci = L->ci;
lu_byte mask = L->hookmask;
int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT));
if (counthook)
resethookcount(L); /* reset count */
else if (!(mask & LUA_MASKLINE))
return; /* no line hook and count != 0; nothing to be done */
if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */
ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */
return; /* do not call hook again (VM yielded, so it did not move) */
}
if (counthook)
luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */
if (mask & LUA_MASKLINE) {
Proto *p = ci_func(ci)->p;
int npc = pcRel(ci->u.l.savedpc, p);
int newline = getfuncline(p, npc);
if (npc == 0 || /* call linehook when enter a new function, */
ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */
newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */
luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */
}
L->oldpc = ci->u.l.savedpc;
if (L->status == LUA_YIELD) { /* did hook yield? */
if (counthook)
L->hookcount = 1; /* undo decrement to zero */
ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */
ci->func = L->top - 1; /* protect stack below results */
luaD_throw(L, LUA_YIELD);
}
}

View File

@ -1,39 +0,0 @@
/*
** $Id: ldebug.h,v 2.14.1.1 2017/04/19 17:20:42 roberto Exp $
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/
#ifndef ldebug_h
#define ldebug_h
#include "lstate.h"
#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1)
#define resethookcount(L) (L->hookcount = L->basehookcount)
LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
const char *opname);
LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1,
const TValue *p2);
LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1,
const TValue *p2,
const char *msg);
LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1,
const TValue *p2);
LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
const TValue *p2);
LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg,
TString *src, int line);
LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
LUAI_FUNC void luaG_traceexec (lua_State *L);
#endif

View File

@ -1,807 +0,0 @@
/*
** $Id: ldo.c,v 2.157.1.1 2017/04/19 17:20:42 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
#define ldo_c
#define LUA_CORE
#include "lprefix.h"
#include <setjmp.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "lua.h"
#include "lapi.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lundump.h"
#include "lvm.h"
#include "lzio.h"
#define errorstatus(s) ((s) > LUA_YIELD)
/*
** {======================================================
** Error-recovery functions
** =======================================================
*/
/*
** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By
** default, Lua handles errors with exceptions when compiling as
** C++ code, with _longjmp/_setjmp when asked to use them, and with
** longjmp/setjmp otherwise.
*/
#if !defined(LUAI_THROW) /* { */
#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) /* { */
/* C++ exceptions */
#define LUAI_THROW(L,c) throw(c)
#define LUAI_TRY(L,c,a) \
try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; }
#define luai_jmpbuf int /* dummy variable */
#elif defined(LUA_USE_POSIX) /* }{ */
/* in POSIX, try _longjmp/_setjmp (more efficient) */
#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
#define luai_jmpbuf jmp_buf
#else /* }{ */
/* ISO C handling with long jumps */
#define LUAI_THROW(L,c) longjmp((c)->b, 1)
#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
#define luai_jmpbuf jmp_buf
#endif /* } */
#endif /* } */
/* chain list of long jump buffers */
struct lua_longjmp {
struct lua_longjmp *previous;
luai_jmpbuf b;
volatile int status; /* error code */
};
static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
switch (errcode) {
case LUA_ERRMEM: { /* memory error? */
setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
break;
}
case LUA_ERRERR: {
setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
break;
}
default: {
setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
break;
}
}
L->top = oldtop + 1;
}
l_noret luaD_throw (lua_State *L, int errcode) {
if (L->errorJmp) { /* thread has an error handler? */
L->errorJmp->status = errcode; /* set status */
/* armfly 2019-04-17 print debug */
printf("throw errcode=%d\r\n", errcode);
LUAI_THROW(L, L->errorJmp); /* jump to it */
}
else { /* thread has no error handler */
global_State *g = G(L);
L->status = cast_byte(errcode); /* mark it as dead */
if (g->mainthread->errorJmp) { /* main thread has a handler? */
setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */
luaD_throw(g->mainthread, errcode); /* re-throw in main thread */
}
else { /* no handler at all; abort */
if (g->panic) { /* panic function? */
seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */
if (L->ci->top < L->top)
L->ci->top = L->top; /* pushing msg. can break this invariant */
lua_unlock(L);
g->panic(L); /* call panic function (last chance to jump out) */
}
abort();
}
}
}
int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
unsigned short oldnCcalls = L->nCcalls;
struct lua_longjmp lj;
lj.status = LUA_OK;
lj.previous = L->errorJmp; /* chain new error handler */
L->errorJmp = &lj;
LUAI_TRY(L, &lj,
(*f)(L, ud);
);
L->errorJmp = lj.previous; /* restore old error handler */
L->nCcalls = oldnCcalls;
return lj.status;
}
/* }====================================================== */
/*
** {==================================================================
** Stack reallocation
** ===================================================================
*/
static void correctstack (lua_State *L, TValue *oldstack) {
CallInfo *ci;
UpVal *up;
L->top = (L->top - oldstack) + L->stack;
for (up = L->openupval; up != NULL; up = up->u.open.next)
up->v = (up->v - oldstack) + L->stack;
for (ci = L->ci; ci != NULL; ci = ci->previous) {
ci->top = (ci->top - oldstack) + L->stack;
ci->func = (ci->func - oldstack) + L->stack;
if (isLua(ci))
ci->u.l.base = (ci->u.l.base - oldstack) + L->stack;
}
}
/* some space for error handling */
#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
void luaD_reallocstack (lua_State *L, int newsize) {
TValue *oldstack = L->stack;
int lim = L->stacksize;
lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK);
luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue);
for (; lim < newsize; lim++)
setnilvalue(L->stack + lim); /* erase new segment */
L->stacksize = newsize;
L->stack_last = L->stack + newsize - EXTRA_STACK;
correctstack(L, oldstack);
}
void luaD_growstack (lua_State *L, int n) {
int size = L->stacksize;
if (size > LUAI_MAXSTACK) /* error after extra size? */
luaD_throw(L, LUA_ERRERR);
else {
int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK;
int newsize = 2 * size;
if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK;
if (newsize < needed) newsize = needed;
if (newsize > LUAI_MAXSTACK) { /* stack overflow? */
luaD_reallocstack(L, ERRORSTACKSIZE);
luaG_runerror(L, "stack overflow");
}
else
luaD_reallocstack(L, newsize);
}
}
static int stackinuse (lua_State *L) {
CallInfo *ci;
StkId lim = L->top;
for (ci = L->ci; ci != NULL; ci = ci->previous) {
if (lim < ci->top) lim = ci->top;
}
lua_assert(lim <= L->stack_last);
return cast_int(lim - L->stack) + 1; /* part of stack in use */
}
void luaD_shrinkstack (lua_State *L) {
int inuse = stackinuse(L);
int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
if (goodsize > LUAI_MAXSTACK)
goodsize = LUAI_MAXSTACK; /* respect stack limit */
if (L->stacksize > LUAI_MAXSTACK) /* had been handling stack overflow? */
luaE_freeCI(L); /* free all CIs (list grew because of an error) */
else
luaE_shrinkCI(L); /* shrink list */
/* if thread is currently not handling a stack overflow and its
good size is smaller than current size, shrink its stack */
if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) &&
goodsize < L->stacksize)
luaD_reallocstack(L, goodsize);
else /* don't change stack */
condmovestack(L,{},{}); /* (change only for debugging) */
}
void luaD_inctop (lua_State *L) {
luaD_checkstack(L, 1);
L->top++;
}
/* }================================================================== */
/*
** Call a hook for the given event. Make sure there is a hook to be
** called. (Both 'L->hook' and 'L->hookmask', which triggers this
** function, can be changed asynchronously by signals.)
*/
void luaD_hook (lua_State *L, int event, int line) {
lua_Hook hook = L->hook;
if (hook && L->allowhook) { /* make sure there is a hook */
CallInfo *ci = L->ci;
ptrdiff_t top = savestack(L, L->top);
ptrdiff_t ci_top = savestack(L, ci->top);
lua_Debug ar;
ar.event = event;
ar.currentline = line;
ar.i_ci = ci;
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
ci->top = L->top + LUA_MINSTACK;
lua_assert(ci->top <= L->stack_last);
L->allowhook = 0; /* cannot call hooks inside a hook */
ci->callstatus |= CIST_HOOKED;
lua_unlock(L);
(*hook)(L, &ar);
lua_lock(L);
lua_assert(!L->allowhook);
L->allowhook = 1;
ci->top = restorestack(L, ci_top);
L->top = restorestack(L, top);
ci->callstatus &= ~CIST_HOOKED;
}
}
static void callhook (lua_State *L, CallInfo *ci) {
int hook = LUA_HOOKCALL;
ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */
if (isLua(ci->previous) &&
GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) {
ci->callstatus |= CIST_TAIL;
hook = LUA_HOOKTAILCALL;
}
luaD_hook(L, hook, -1);
ci->u.l.savedpc--; /* correct 'pc' */
}
static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
int i;
int nfixargs = p->numparams;
StkId base, fixed;
/* move fixed parameters to final position */
fixed = L->top - actual; /* first fixed argument */
base = L->top; /* final position of first argument */
for (i = 0; i < nfixargs && i < actual; i++) {
setobjs2s(L, L->top++, fixed + i);
setnilvalue(fixed + i); /* erase original copy (for GC) */
}
for (; i < nfixargs; i++)
setnilvalue(L->top++); /* complete missing arguments */
return base;
}
/*
** Check whether __call metafield of 'func' is a function. If so, put
** it in stack below original 'func' so that 'luaD_precall' can call
** it. Raise an error if __call metafield is not a function.
*/
static void tryfuncTM (lua_State *L, StkId func) {
const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
StkId p;
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);
L->top++; /* slot ensured by caller */
setobj2s(L, func, tm); /* tag method is the new function to be called */
}
/*
** Given 'nres' results at 'firstResult', move 'wanted' of them to 'res'.
** Handle most typical cases (zero results for commands, one result for
** expressions, multiple results for tail calls/single parameters)
** separated.
*/
static int moveresults (lua_State *L, const TValue *firstResult, StkId res,
int nres, int wanted) {
switch (wanted) { /* handle typical cases separately */
case 0: break; /* nothing to move */
case 1: { /* one result needed */
if (nres == 0) /* no results? */
firstResult = luaO_nilobject; /* adjust with nil */
setobjs2s(L, res, firstResult); /* move it to proper place */
break;
}
case LUA_MULTRET: {
int i;
for (i = 0; i < nres; i++) /* move all results to correct place */
setobjs2s(L, res + i, firstResult + i);
L->top = res + nres;
return 0; /* wanted == LUA_MULTRET */
}
default: {
int i;
if (wanted <= nres) { /* enough results? */
for (i = 0; i < wanted; i++) /* move wanted results to correct place */
setobjs2s(L, res + i, firstResult + i);
}
else { /* not enough results; use all of them plus nils */
for (i = 0; i < nres; i++) /* move all results to correct place */
setobjs2s(L, res + i, firstResult + i);
for (; i < wanted; i++) /* complete wanted number of results */
setnilvalue(res + i);
}
break;
}
}
L->top = res + wanted; /* top points after the last result */
return 1;
}
/*
** Finishes a function call: calls hook if necessary, removes CallInfo,
** moves current number of results to proper place; returns 0 iff call
** wanted multiple (variable number of) results.
*/
int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, int nres) {
StkId res;
int wanted = ci->nresults;
if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
if (L->hookmask & LUA_MASKRET) {
ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */
luaD_hook(L, LUA_HOOKRET, -1);
firstResult = restorestack(L, fr);
}
L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */
}
res = ci->func; /* res == final position of 1st result */
L->ci = ci->previous; /* back to caller */
/* move results to proper place */
return moveresults(L, firstResult, res, nres, wanted);
}
#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
/* macro to check stack size, preserving 'p' */
#define checkstackp(L,n,p) \
luaD_checkstackaux(L, n, \
ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \
luaC_checkGC(L), /* stack grow uses memory */ \
p = restorestack(L, t__)) /* 'pos' part: restore 'p' */
/*
** Prepares a function call: checks the stack, creates a new CallInfo
** entry, fills in the relevant information, calls hook if needed.
** If function is a C function, does the call, too. (Otherwise, leave
** the execution ('luaV_execute') to the caller, to allow stackless
** calls.) Returns true iff function has been executed (C function).
*/
int luaD_precall (lua_State *L, StkId func, int nresults) {
lua_CFunction f;
CallInfo *ci;
switch (ttype(func)) {
case LUA_TCCL: /* C closure */
f = clCvalue(func)->f;
goto Cfunc;
case LUA_TLCF: /* light C function */
f = fvalue(func);
Cfunc: {
int n; /* number of returns */
checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
ci = next_ci(L); /* now 'enter' new function */
ci->nresults = nresults;
ci->func = func;
ci->top = L->top + LUA_MINSTACK;
lua_assert(ci->top <= L->stack_last);
ci->callstatus = 0;
if (L->hookmask & LUA_MASKCALL)
luaD_hook(L, LUA_HOOKCALL, -1);
lua_unlock(L);
n = (*f)(L); /* do the actual call */
lua_lock(L);
api_checknelems(L, n);
luaD_poscall(L, ci, L->top - n, n);
return 1;
}
case LUA_TLCL: { /* Lua function: prepare its call */
StkId base;
Proto *p = clLvalue(func)->p;
int n = cast_int(L->top - func) - 1; /* number of real arguments */
int fsize = p->maxstacksize; /* frame size */
checkstackp(L, fsize, func);
if (p->is_vararg)
base = adjust_varargs(L, p, n);
else { /* non vararg function */
for (; n < p->numparams; n++)
setnilvalue(L->top++); /* complete missing arguments */
base = func + 1;
}
ci = next_ci(L); /* now 'enter' new function */
ci->nresults = nresults;
ci->func = func;
ci->u.l.base = base;
L->top = ci->top = base + fsize;
lua_assert(ci->top <= L->stack_last);
ci->u.l.savedpc = p->code; /* starting point */
ci->callstatus = CIST_LUA;
if (L->hookmask & LUA_MASKCALL)
callhook(L, ci);
return 0;
}
default: { /* not a function */
checkstackp(L, 1, func); /* ensure space for metamethod */
tryfuncTM(L, func); /* try to get '__call' metamethod */
return luaD_precall(L, func, nresults); /* now it must be a function */
}
}
}
/*
** Check appropriate error for stack overflow ("regular" overflow or
** overflow while handling stack overflow). If 'nCalls' is larger than
** LUAI_MAXCCALLS (which means it is handling a "regular" overflow) but
** smaller than 9/8 of LUAI_MAXCCALLS, does not report an error (to
** allow overflow handling to work)
*/
static void stackerror (lua_State *L) {
if (L->nCcalls == LUAI_MAXCCALLS)
luaG_runerror(L, "C stack overflow");
else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
}
/*
** Call a function (C or Lua). The function to be called is at *func.
** 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)
stackerror(L);
if (!luaD_precall(L, func, nResults)) /* is a Lua function? */
luaV_execute(L); /* call it */
L->nCcalls--;
}
/*
** Similar to 'luaD_call', but does not allow yields during the call
*/
void luaD_callnoyield (lua_State *L, StkId func, int nResults) {
L->nny++;
luaD_call(L, func, nResults);
L->nny--;
}
/*
** Completes the execution of an interrupted C function, calling its
** continuation function.
*/
static void finishCcall (lua_State *L, int status) {
CallInfo *ci = L->ci;
int n;
/* must have a continuation and must be able to call it */
lua_assert(ci->u.c.k != NULL && L->nny == 0);
/* error status can only happen in a protected call */
lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD);
if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */
ci->callstatus &= ~CIST_YPCALL; /* continuation is also inside it */
L->errfunc = ci->u.c.old_errfunc; /* with the same error function */
}
/* finish 'lua_callk'/'lua_pcall'; CIST_YPCALL and 'errfunc' already
handled */
adjustresults(L, ci->nresults);
lua_unlock(L);
n = (*ci->u.c.k)(L, status, ci->u.c.ctx); /* call continuation function */
lua_lock(L);
api_checknelems(L, n);
luaD_poscall(L, ci, L->top - n, n); /* finish 'luaD_precall' */
}
/*
** Executes "full continuation" (everything in the stack) of a
** previously interrupted coroutine until the stack is empty (or another
** interruption long-jumps out of the loop). If the coroutine is
** recovering from an error, 'ud' points to the error status, which must
** be passed to the first continuation function (otherwise the default
** status is LUA_YIELD).
*/
static void unroll (lua_State *L, void *ud) {
if (ud != NULL) /* error status? */
finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */
while (L->ci != &L->base_ci) { /* something in the stack */
if (!isLua(L->ci)) /* C function? */
finishCcall(L, LUA_YIELD); /* complete its execution */
else { /* Lua function */
luaV_finishOp(L); /* finish interrupted instruction */
luaV_execute(L); /* execute down to higher C 'boundary' */
}
}
}
/*
** Try to find a suspended protected call (a "recover point") for the
** given thread.
*/
static CallInfo *findpcall (lua_State *L) {
CallInfo *ci;
for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */
if (ci->callstatus & CIST_YPCALL)
return ci;
}
return NULL; /* no pending pcall */
}
/*
** Recovers from an error in a coroutine. Finds a recover point (if
** there is one) and completes the execution of the interrupted
** 'luaD_pcall'. If there is no recover point, returns zero.
*/
static int recover (lua_State *L, int status) {
StkId oldtop;
CallInfo *ci = findpcall(L);
if (ci == NULL) return 0; /* no recovery point */
/* "finish" luaD_pcall */
oldtop = restorestack(L, ci->extra);
luaF_close(L, oldtop);
seterrorobj(L, status, oldtop);
L->ci = ci;
L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */
L->nny = 0; /* should be zero to be yieldable */
luaD_shrinkstack(L);
L->errfunc = ci->u.c.old_errfunc;
return 1; /* continue running the coroutine */
}
/*
** Signal an error in the call to 'lua_resume', not in the execution
** of the coroutine itself. (Such errors should not be handled by any
** coroutine error handler and should not kill the coroutine.)
*/
static int resume_error (lua_State *L, const char *msg, int narg) {
L->top -= narg; /* remove args from the stack */
setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */
api_incr_top(L);
lua_unlock(L);
return LUA_ERRRUN;
}
/*
** Do the work for 'lua_resume' in protected mode. Most of the work
** depends on the status of the coroutine: initial state, suspended
** inside a hook, or regularly suspended (optionally with a continuation
** function), plus erroneous cases: non-suspended coroutine or dead
** coroutine.
*/
static void resume (lua_State *L, void *ud) {
int n = *(cast(int*, ud)); /* number of arguments */
StkId firstArg = L->top - n; /* first argument */
CallInfo *ci = L->ci;
if (L->status == LUA_OK) { /* starting a coroutine? */
if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
luaV_execute(L); /* call it */
}
else { /* resuming from previous yield */
lua_assert(L->status == LUA_YIELD);
L->status = LUA_OK; /* mark that it is running (again) */
ci->func = restorestack(L, ci->extra);
if (isLua(ci)) /* yielded inside a hook? */
luaV_execute(L); /* just continue running Lua code */
else { /* 'common' yield */
if (ci->u.c.k != NULL) { /* does it have a continuation function? */
lua_unlock(L);
n = (*ci->u.c.k)(L, LUA_YIELD, ci->u.c.ctx); /* call continuation */
lua_lock(L);
api_checknelems(L, n);
firstArg = L->top - n; /* yield results come from continuation */
}
luaD_poscall(L, ci, firstArg, n); /* finish 'luaD_precall' */
}
unroll(L, NULL); /* run continuation */
}
}
LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
int status;
unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */
lua_lock(L);
if (L->status == LUA_OK) { /* may be starting a coroutine */
if (L->ci != &L->base_ci) /* not in base level? */
return resume_error(L, "cannot resume non-suspended coroutine", nargs);
}
else if (L->status != LUA_YIELD)
return resume_error(L, "cannot resume dead coroutine", nargs);
L->nCcalls = (from) ? from->nCcalls + 1 : 1;
if (L->nCcalls >= LUAI_MAXCCALLS)
return resume_error(L, "C stack overflow", nargs);
luai_userstateresume(L, nargs);
L->nny = 0; /* allow yields */
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
status = luaD_rawrunprotected(L, resume, &nargs);
if (status == -1) /* error calling 'lua_resume'? */
status = LUA_ERRRUN;
else { /* continue running after recoverable errors */
while (errorstatus(status) && recover(L, status)) {
/* unroll continuation */
status = luaD_rawrunprotected(L, unroll, &status);
}
if (errorstatus(status)) { /* unrecoverable error? */
L->status = cast_byte(status); /* mark thread as 'dead' */
seterrorobj(L, status, L->top); /* push error message */
L->ci->top = L->top;
}
else lua_assert(status == L->status); /* normal end or yield */
}
L->nny = oldnny; /* restore 'nny' */
L->nCcalls--;
lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));
lua_unlock(L);
return status;
}
LUA_API int lua_isyieldable (lua_State *L) {
return (L->nny == 0);
}
LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
lua_KFunction k) {
CallInfo *ci = L->ci;
luai_userstateyield(L, nresults);
lua_lock(L);
api_checknelems(L, nresults);
if (L->nny > 0) {
if (L != G(L)->mainthread)
luaG_runerror(L, "attempt to yield across a C-call boundary");
else
luaG_runerror(L, "attempt to yield from outside a coroutine");
}
L->status = LUA_YIELD;
ci->extra = savestack(L, ci->func); /* save current 'func' */
if (isLua(ci)) { /* inside a hook? */
api_check(L, k == NULL, "hooks cannot continue after yielding");
}
else {
if ((ci->u.c.k = k) != NULL) /* is there a continuation? */
ci->u.c.ctx = ctx; /* save context */
ci->func = L->top - nresults - 1; /* protect stack below results */
luaD_throw(L, LUA_YIELD);
}
lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */
lua_unlock(L);
return 0; /* return to 'luaD_hook' */
}
int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t old_top, ptrdiff_t ef) {
int status;
CallInfo *old_ci = L->ci;
lu_byte old_allowhooks = L->allowhook;
unsigned short old_nny = L->nny;
ptrdiff_t old_errfunc = L->errfunc;
L->errfunc = ef;
status = luaD_rawrunprotected(L, func, u);
if (status != LUA_OK) { /* an error occurred? */
StkId oldtop = restorestack(L, old_top);
luaF_close(L, oldtop); /* close possible pending closures */
seterrorobj(L, status, oldtop);
L->ci = old_ci;
L->allowhook = old_allowhooks;
L->nny = old_nny;
luaD_shrinkstack(L);
}
L->errfunc = old_errfunc;
return status;
}
/*
** Execute a protected parser.
*/
struct SParser { /* data to 'f_parser' */
ZIO *z;
Mbuffer buff; /* dynamic structure used by the scanner */
Dyndata dyd; /* dynamic structures used by the parser */
const char *mode;
const char *name;
};
static void checkmode (lua_State *L, const char *mode, const char *x) {
if (mode && strchr(mode, x[0]) == NULL) {
luaO_pushfstring(L,
"attempt to load a %s chunk (mode is '%s')", x, mode);
luaD_throw(L, LUA_ERRSYNTAX);
}
}
static void f_parser (lua_State *L, void *ud) {
LClosure *cl;
struct SParser *p = cast(struct SParser *, ud);
int c = zgetc(p->z); /* read first character */
if (c == LUA_SIGNATURE[0]) {
checkmode(L, p->mode, "binary");
cl = luaU_undump(L, p->z, p->name);
}
else {
checkmode(L, p->mode, "text");
cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
}
lua_assert(cl->nupvalues == cl->p->sizeupvalues);
luaF_initupvals(L, cl);
}
int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
const char *mode) {
struct SParser p;
int status;
L->nny++; /* cannot yield during parsing */
p.z = z; p.name = name; p.mode = mode;
p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0;
p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
p.dyd.label.arr = NULL; p.dyd.label.size = 0;
luaZ_initbuffer(L, &p.buff);
status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
luaZ_freebuffer(L, &p.buff);
luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size);
luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size);
luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size);
L->nny--;
return status;
}

View File

@ -1,58 +0,0 @@
/*
** $Id: ldo.h,v 2.29.1.1 2017/04/19 17:20:42 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
#ifndef ldo_h
#define ldo_h
#include "lobject.h"
#include "lstate.h"
#include "lzio.h"
/*
** Macro to check stack size and grow stack if needed. Parameters
** 'pre'/'pos' allow the macro to preserve a pointer into the
** stack across reallocations, doing the work only when needed.
** 'condmovestack' is used in heavy tests to force a stack reallocation
** at every check.
*/
#define luaD_checkstackaux(L,n,pre,pos) \
if (L->stack_last - L->top <= (n)) \
{ pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); }
/* In general, 'pre'/'pos' are empty (nothing to save) */
#define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0)
#define savestack(L,p) ((char *)(p) - (char *)L->stack)
#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
/* type of protected functions, to be ran by 'runprotected' */
typedef void (*Pfunc) (lua_State *L, void *ud);
LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
const char *mode);
LUAI_FUNC void luaD_hook (lua_State *L, int event, int line);
LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t oldtop, ptrdiff_t ef);
LUAI_FUNC int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult,
int nres);
LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
LUAI_FUNC void luaD_growstack (lua_State *L, int n);
LUAI_FUNC void luaD_shrinkstack (lua_State *L);
LUAI_FUNC void luaD_inctop (lua_State *L);
LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode);
LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
#endif

View File

@ -1,215 +0,0 @@
/*
** $Id: ldump.c,v 2.37.1.1 2017/04/19 17:20:42 roberto Exp $
** save precompiled Lua chunks
** See Copyright Notice in lua.h
*/
#define ldump_c
#define LUA_CORE
#include "lprefix.h"
#include <stddef.h>
#include "lua.h"
#include "lobject.h"
#include "lstate.h"
#include "lundump.h"
typedef struct {
lua_State *L;
lua_Writer writer;
void *data;
int strip;
int status;
} DumpState;
/*
** All high-level dumps go through DumpVector; you can change it to
** change the endianness of the result
*/
#define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D)
#define DumpLiteral(s,D) DumpBlock(s, sizeof(s) - sizeof(char), D)
static void DumpBlock (const void *b, size_t size, DumpState *D) {
if (D->status == 0 && size > 0) {
lua_unlock(D->L);
D->status = (*D->writer)(D->L, b, size, D->data);
lua_lock(D->L);
}
}
#define DumpVar(x,D) DumpVector(&x,1,D)
static void DumpByte (int y, DumpState *D) {
lu_byte x = (lu_byte)y;
DumpVar(x, D);
}
static void DumpInt (int x, DumpState *D) {
DumpVar(x, D);
}
static void DumpNumber (lua_Number x, DumpState *D) {
DumpVar(x, D);
}
static void DumpInteger (lua_Integer x, DumpState *D) {
DumpVar(x, D);
}
static void DumpString (const TString *s, DumpState *D) {
if (s == NULL)
DumpByte(0, D);
else {
size_t size = tsslen(s) + 1; /* include trailing '\0' */
const char *str = getstr(s);
if (size < 0xFF)
DumpByte(cast_int(size), D);
else {
DumpByte(0xFF, D);
DumpVar(size, D);
}
DumpVector(str, size - 1, D); /* no need to save '\0' */
}
}
static void DumpCode (const Proto *f, DumpState *D) {
DumpInt(f->sizecode, D);
DumpVector(f->code, f->sizecode, D);
}
static void DumpFunction(const Proto *f, TString *psource, DumpState *D);
static void DumpConstants (const Proto *f, DumpState *D) {
int i;
int n = f->sizek;
DumpInt(n, D);
for (i = 0; i < n; i++) {
const TValue *o = &f->k[i];
DumpByte(ttype(o), D);
switch (ttype(o)) {
case LUA_TNIL:
break;
case LUA_TBOOLEAN:
DumpByte(bvalue(o), D);
break;
case LUA_TNUMFLT:
DumpNumber(fltvalue(o), D);
break;
case LUA_TNUMINT:
DumpInteger(ivalue(o), D);
break;
case LUA_TSHRSTR:
case LUA_TLNGSTR:
DumpString(tsvalue(o), D);
break;
default:
lua_assert(0);
}
}
}
static void DumpProtos (const Proto *f, DumpState *D) {
int i;
int n = f->sizep;
DumpInt(n, D);
for (i = 0; i < n; i++)
DumpFunction(f->p[i], f->source, D);
}
static void DumpUpvalues (const Proto *f, DumpState *D) {
int i, n = f->sizeupvalues;
DumpInt(n, D);
for (i = 0; i < n; i++) {
DumpByte(f->upvalues[i].instack, D);
DumpByte(f->upvalues[i].idx, D);
}
}
static void DumpDebug (const Proto *f, DumpState *D) {
int i, n;
n = (D->strip) ? 0 : f->sizelineinfo;
DumpInt(n, D);
DumpVector(f->lineinfo, n, D);
n = (D->strip) ? 0 : f->sizelocvars;
DumpInt(n, D);
for (i = 0; i < n; i++) {
DumpString(f->locvars[i].varname, D);
DumpInt(f->locvars[i].startpc, D);
DumpInt(f->locvars[i].endpc, D);
}
n = (D->strip) ? 0 : f->sizeupvalues;
DumpInt(n, D);
for (i = 0; i < n; i++)
DumpString(f->upvalues[i].name, D);
}
static void DumpFunction (const Proto *f, TString *psource, DumpState *D) {
if (D->strip || f->source == psource)
DumpString(NULL, D); /* no debug info or same source as its parent */
else
DumpString(f->source, D);
DumpInt(f->linedefined, D);
DumpInt(f->lastlinedefined, D);
DumpByte(f->numparams, D);
DumpByte(f->is_vararg, D);
DumpByte(f->maxstacksize, D);
DumpCode(f, D);
DumpConstants(f, D);
DumpUpvalues(f, D);
DumpProtos(f, D);
DumpDebug(f, D);
}
static void DumpHeader (DumpState *D) {
DumpLiteral(LUA_SIGNATURE, D);
DumpByte(LUAC_VERSION, D);
DumpByte(LUAC_FORMAT, D);
DumpLiteral(LUAC_DATA, D);
DumpByte(sizeof(int), D);
DumpByte(sizeof(size_t), D);
DumpByte(sizeof(Instruction), D);
DumpByte(sizeof(lua_Integer), D);
DumpByte(sizeof(lua_Number), D);
DumpInteger(LUAC_INT, D);
DumpNumber(LUAC_NUM, D);
}
/*
** dump Lua function as precompiled chunk
*/
int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
int strip) {
DumpState D;
D.L = L;
D.writer = w;
D.data = data;
D.strip = strip;
D.status = 0;
DumpHeader(&D);
DumpByte(f->sizeupvalues, &D);
DumpFunction(f, NULL, &D);
return D.status;
}

View File

@ -1,151 +0,0 @@
/*
** $Id: lfunc.c,v 2.45.1.1 2017/04/19 17:39:34 roberto Exp $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
#define lfunc_c
#define LUA_CORE
#include "lprefix.h"
#include <stddef.h>
#include "lua.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
CClosure *luaF_newCclosure (lua_State *L, int n) {
GCObject *o = luaC_newobj(L, LUA_TCCL, sizeCclosure(n));
CClosure *c = gco2ccl(o);
c->nupvalues = cast_byte(n);
return c;
}
LClosure *luaF_newLclosure (lua_State *L, int n) {
GCObject *o = luaC_newobj(L, LUA_TLCL, sizeLclosure(n));
LClosure *c = gco2lcl(o);
c->p = NULL;
c->nupvalues = cast_byte(n);
while (n--) c->upvals[n] = NULL;
return c;
}
/*
** fill a closure with new closed upvalues
*/
void luaF_initupvals (lua_State *L, LClosure *cl) {
int i;
for (i = 0; i < cl->nupvalues; i++) {
UpVal *uv = luaM_new(L, UpVal);
uv->refcount = 1;
uv->v = &uv->u.value; /* make it closed */
setnilvalue(uv->v);
cl->upvals[i] = uv;
}
}
UpVal *luaF_findupval (lua_State *L, StkId level) {
UpVal **pp = &L->openupval;
UpVal *p;
UpVal *uv;
lua_assert(isintwups(L) || L->openupval == NULL);
while (*pp != NULL && (p = *pp)->v >= level) {
lua_assert(upisopen(p));
if (p->v == level) /* found a corresponding upvalue? */
return p; /* return it */
pp = &p->u.open.next;
}
/* not found: create a new upvalue */
uv = luaM_new(L, UpVal);
uv->refcount = 0;
uv->u.open.next = *pp; /* link it to list of open upvalues */
uv->u.open.touched = 1;
*pp = uv;
uv->v = level; /* current value lives in the stack */
if (!isintwups(L)) { /* thread not in list of threads with upvalues? */
L->twups = G(L)->twups; /* link it to the list */
G(L)->twups = L;
}
return uv;
}
void luaF_close (lua_State *L, StkId level) {
UpVal *uv;
while (L->openupval != NULL && (uv = L->openupval)->v >= level) {
lua_assert(upisopen(uv));
L->openupval = uv->u.open.next; /* remove from 'open' list */
if (uv->refcount == 0) /* no references? */
luaM_free(L, uv); /* free upvalue */
else {
setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */
uv->v = &uv->u.value; /* now current value lives here */
luaC_upvalbarrier(L, uv);
}
}
}
Proto *luaF_newproto (lua_State *L) {
GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto));
Proto *f = gco2p(o);
f->k = NULL;
f->sizek = 0;
f->p = NULL;
f->sizep = 0;
f->code = NULL;
f->cache = NULL;
f->sizecode = 0;
f->lineinfo = NULL;
f->sizelineinfo = 0;
f->upvalues = NULL;
f->sizeupvalues = 0;
f->numparams = 0;
f->is_vararg = 0;
f->maxstacksize = 0;
f->locvars = NULL;
f->sizelocvars = 0;
f->linedefined = 0;
f->lastlinedefined = 0;
f->source = NULL;
return f;
}
void luaF_freeproto (lua_State *L, Proto *f) {
luaM_freearray(L, f->code, f->sizecode);
luaM_freearray(L, f->p, f->sizep);
luaM_freearray(L, f->k, f->sizek);
luaM_freearray(L, f->lineinfo, f->sizelineinfo);
luaM_freearray(L, f->locvars, f->sizelocvars);
luaM_freearray(L, f->upvalues, f->sizeupvalues);
luaM_free(L, f);
}
/*
** Look for n-th local variable at line 'line' in function 'func'.
** Returns NULL if not found.
*/
const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
int i;
for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
if (pc < f->locvars[i].endpc) { /* is variable active? */
local_number--;
if (local_number == 0)
return getstr(f->locvars[i].varname);
}
}
return NULL; /* not found */
}

View File

@ -1,61 +0,0 @@
/*
** $Id: lfunc.h,v 2.15.1.1 2017/04/19 17:39:34 roberto Exp $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
#ifndef lfunc_h
#define lfunc_h
#include "lobject.h"
#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
cast(int, sizeof(TValue)*((n)-1)))
#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
cast(int, sizeof(TValue *)*((n)-1)))
/* test whether thread is in 'twups' list */
#define isintwups(L) (L->twups != L)
/*
** maximum number of upvalues in a closure (both C and Lua). (Value
** must fit in a VM register.)
*/
#define MAXUPVAL 255
/*
** Upvalues for Lua closures
*/
struct UpVal {
TValue *v; /* points to stack or to its own value */
lu_mem refcount; /* reference counter */
union {
struct { /* (when open) */
UpVal *next; /* linked list */
int touched; /* mark to avoid cycles with dead threads */
} open;
TValue value; /* the value (when closed) */
} u;
};
#define upisopen(up) ((up)->v != &(up)->u.value)
LUAI_FUNC Proto *luaF_newproto (lua_State *L);
LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems);
LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems);
LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl);
LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
LUAI_FUNC void luaF_close (lua_State *L, StkId level);
LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
int pc);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,147 +0,0 @@
/*
** $Id: lgc.h,v 2.91.1.1 2017/04/19 17:39:34 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
#ifndef lgc_h
#define lgc_h
#include "lobject.h"
#include "lstate.h"
/*
** Collectable objects may have one of three colors: white, which
** means the object is not marked; gray, which means the
** object is marked, but its references may be not marked; and
** black, which means that the object and all its references are marked.
** The main invariant of the garbage collector, while marking objects,
** is that a black object can never point to a white one. Moreover,
** any gray object must be in a "gray list" (gray, grayagain, weak,
** allweak, ephemeron) so that it can be visited again before finishing
** the collection cycle. These lists have no meaning when the invariant
** is not being enforced (e.g., sweep phase).
*/
/* how much to allocate before next GC step */
#if !defined(GCSTEPSIZE)
/* ~100 small strings */
#define GCSTEPSIZE (cast_int(100 * sizeof(TString)))
#endif
/*
** Possible states of the Garbage Collector
*/
#define GCSpropagate 0
#define GCSatomic 1
#define GCSswpallgc 2
#define GCSswpfinobj 3
#define GCSswptobefnz 4
#define GCSswpend 5
#define GCScallfin 6
#define GCSpause 7
#define issweepphase(g) \
(GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend)
/*
** macro to tell when main invariant (white objects cannot point to black
** ones) must be kept. During a collection, the sweep
** phase may break the invariant, as objects turned white may point to
** still-black objects. The invariant is restored when sweep ends and
** all objects are white again.
*/
#define keepinvariant(g) ((g)->gcstate <= GCSatomic)
/*
** some useful bit tricks
*/
#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
#define setbits(x,m) ((x) |= (m))
#define testbits(x,m) ((x) & (m))
#define bitmask(b) (1<<(b))
#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
#define l_setbit(x,b) setbits(x, bitmask(b))
#define resetbit(x,b) resetbits(x, bitmask(b))
#define testbit(x,b) testbits(x, bitmask(b))
/* Layout for bit use in 'marked' field: */
#define WHITE0BIT 0 /* object is white (type 0) */
#define WHITE1BIT 1 /* object is white (type 1) */
#define BLACKBIT 2 /* object is black */
#define FINALIZEDBIT 3 /* object has been marked for finalization */
/* bit 7 is currently used by tests (luaL_checkmemory) */
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
#define iswhite(x) testbits((x)->marked, WHITEBITS)
#define isblack(x) testbit((x)->marked, BLACKBIT)
#define isgray(x) /* neither white nor black */ \
(!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT)))
#define tofinalize(x) testbit((x)->marked, FINALIZEDBIT)
#define otherwhite(g) ((g)->currentwhite ^ WHITEBITS)
#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow)))
#define isdead(g,v) isdeadm(otherwhite(g), (v)->marked)
#define changewhite(x) ((x)->marked ^= WHITEBITS)
#define gray2black(x) l_setbit((x)->marked, BLACKBIT)
#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
/*
** Does one step of collection when debt becomes positive. 'pre'/'pos'
** allows some adjustments to be done only when needed. macro
** 'condchangemem' is used only for heavy tests (forcing a full
** GC cycle on every opportunity)
*/
#define luaC_condGC(L,pre,pos) \
{ if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \
condchangemem(L,pre,pos); }
/* more often than not, 'pre'/'pos' are empty */
#define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0)
#define luaC_barrier(L,p,v) ( \
(iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \
luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0))
#define luaC_barrierback(L,p,v) ( \
(iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \
luaC_barrierback_(L,p) : cast_void(0))
#define luaC_objbarrier(L,p,o) ( \
(isblack(p) && iswhite(o)) ? \
luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0))
#define luaC_upvalbarrier(L,uv) ( \
(iscollectable((uv)->v) && !upisopen(uv)) ? \
luaC_upvalbarrier_(L,uv) : cast_void(0))
LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o);
LUAI_FUNC void luaC_freeallobjects (lua_State *L);
LUAI_FUNC void luaC_step (lua_State *L);
LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz);
LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o);
LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv);
LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv);
#endif

View File

@ -1,68 +0,0 @@
/*
** $Id: linit.c,v 1.39.1.1 2017/04/19 17:20:42 roberto Exp $
** Initialization of libraries for lua.c and other clients
** See Copyright Notice in lua.h
*/
#define linit_c
#define LUA_LIB
/*
** If you embed Lua in your program and need to open the standard
** libraries, call luaL_openlibs in your program. If you need a
** different set of libraries, copy this file to your project and edit
** it to suit your needs.
**
** You can also *preload* libraries, so that a later 'require' can
** open the library, which is already linked to the application.
** For that, do the following code:
**
** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
** lua_pushcfunction(L, luaopen_modname);
** lua_setfield(L, -2, modname);
** lua_pop(L, 1); // remove PRELOAD table
*/
#include "lprefix.h"
#include <stddef.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
/*
** these libs are loaded by lua.c and are readily available to any Lua
** program
*/
static const luaL_Reg loadedlibs[] = {
{"_G", luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_COLIBNAME, luaopen_coroutine},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_UTF8LIBNAME, luaopen_utf8},
{LUA_DBLIBNAME, luaopen_debug},
#if defined(LUA_COMPAT_BITLIB)
{LUA_BITLIBNAME, luaopen_bit32},
#endif
{NULL, NULL}
};
LUALIB_API void luaL_openlibs (lua_State *L) {
const luaL_Reg *lib;
/* "require" functions from 'loadedlibs' and set results to global table */
for (lib = loadedlibs; lib->func; lib++) {
luaL_requiref(L, lib->name, lib->func, 1);
lua_pop(L, 1); /* remove lib */
}
}

View File

@ -1,776 +0,0 @@
/*
** $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

@ -1,678 +0,0 @@
/*
** $Id: llex.c,v 2.96.1.1 2017/04/19 17:20:42 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
#define llex_c
#define LUA_CORE
#include "lprefix.h"
#include <locale.h>
#include <string.h>
#include "lua.h"
#include "lctype.h"
#include "ldebug.h"
#include "ldo.h"
#include "lgc.h"
#include "llex.h"
#include "lobject.h"
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "lzio.h"
#define next(ls) (ls->current = zgetc(ls->z))
#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
/* ORDER RESERVED */
static const char *const luaX_tokens[] = {
"and", "break", "do", "else", "elseif",
"end", "false", "for", "function", "goto", "if",
"in", "local", "nil", "not", "or", "repeat",
"return", "then", "true", "until", "while",
"//", "..", "...", "==", ">=", "<=", "~=",
"<<", ">>", "::", "<eof>",
"<number>", "<integer>", "<name>", "<string>"};
#define save_and_next(ls) (save(ls, ls->current), next(ls))
static l_noret lexerror(LexState *ls, const char *msg, int token);
static void save(LexState *ls, int c)
{
Mbuffer *b = ls->buff;
if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b))
{
size_t newsize;
if (luaZ_sizebuffer(b) >= MAX_SIZE / 2)
lexerror(ls, "lexical element too long", 0);
newsize = luaZ_sizebuffer(b) * 2;
luaZ_resizebuffer(ls->L, b, newsize);
}
b->buffer[luaZ_bufflen(b)++] = cast(char, c);
}
void luaX_init(lua_State *L)
{
int i;
TString *e = luaS_newliteral(L, LUA_ENV); /* create env name */
luaC_fix(L, obj2gco(e)); /* never collect this name */
for (i = 0; i < NUM_RESERVED; i++)
{
TString *ts = luaS_new(L, luaX_tokens[i]);
luaC_fix(L, obj2gco(ts)); /* reserved words are never collected */
ts->extra = cast_byte(i + 1); /* reserved word */
}
}
const char *luaX_token2str(LexState *ls, int token)
{
if (token < FIRST_RESERVED)
{ /* single-byte symbols? */
lua_assert(token == cast_uchar(token));
return luaO_pushfstring(ls->L, "'%c'", token);
}
else
{
const char *s = luaX_tokens[token - FIRST_RESERVED];
if (token < TK_EOS) /* fixed format (symbols and reserved words)? */
return luaO_pushfstring(ls->L, "'%s'", s);
else /* names, strings, and numerals */
return s;
}
}
static const char *txtToken(LexState *ls, int token)
{
switch (token)
{
case TK_NAME:
case TK_STRING:
case TK_FLT:
case TK_INT:
save(ls, '\0');
return luaO_pushfstring(ls->L, "'%s'", luaZ_buffer(ls->buff));
default:
return luaX_token2str(ls, token);
}
}
static l_noret lexerror(LexState *ls, const char *msg, int token)
{
msg = luaG_addinfo(ls->L, msg, ls->source, ls->linenumber);
if (token)
luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
luaD_throw(ls->L, LUA_ERRSYNTAX);
}
l_noret luaX_syntaxerror(LexState *ls, const char *msg)
{
lexerror(ls, msg, ls->t.token);
}
/*
** creates a new string and anchors it in scanner's table so that
** it will not be collected until the end of the compilation
** (by that time it should be anchored somewhere)
*/
TString *luaX_newstring(LexState *ls, const char *str, size_t l)
{
lua_State *L = ls->L;
TValue *o; /* entry for 'str' */
TString *ts = luaS_newlstr(L, str, l); /* create new string */
setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */
o = luaH_set(L, ls->h, L->top - 1);
if (ttisnil(o))
{ /* not in use yet? */
/* boolean value does not need GC barrier;
table has no metatable, so it does not need to invalidate cache */
setbvalue(o, 1); /* t[string] = true */
luaC_checkGC(L);
}
else
{ /* string already present */
ts = tsvalue(keyfromval(o)); /* re-use value previously stored */
}
L->top--; /* remove string from stack */
return ts;
}
/*
** increment line number and skips newline sequence (any of
** \n, \r, \n\r, or \r\n)
*/
static void inclinenumber(LexState *ls)
{
int old = ls->current;
lua_assert(currIsNewline(ls));
next(ls); /* skip '\n' or '\r' */
if (currIsNewline(ls) && ls->current != old)
next(ls); /* skip '\n\r' or '\r\n' */
if (++ls->linenumber >= MAX_INT)
lexerror(ls, "chunk has too many lines", 0);
}
void luaX_setinput(lua_State *L, LexState *ls, ZIO *z, TString *source,
int firstchar)
{
ls->t.token = 0;
ls->L = L;
ls->current = firstchar;
ls->lookahead.token = TK_EOS; /* no look-ahead token */
ls->z = z;
ls->fs = NULL;
ls->linenumber = 1;
ls->lastline = 1;
ls->source = source;
ls->envn = luaS_newliteral(L, LUA_ENV); /* get env name */
luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
}
/*
** =======================================================
** LEXICAL ANALYZER
** =======================================================
*/
static int check_next1(LexState *ls, int c)
{
if (ls->current == c)
{
next(ls);
return 1;
}
else
return 0;
}
/*
** Check whether current char is in set 'set' (with two chars) and
** saves it
*/
static int check_next2(LexState *ls, const char *set)
{
lua_assert(set[2] == '\0');
if (ls->current == set[0] || ls->current == set[1])
{
save_and_next(ls);
return 1;
}
else
return 0;
}
/* LUA_NUMBER */
/*
** this function is quite liberal in what it accepts, as 'luaO_str2num'
** will reject ill-formed numerals.
*/
static int read_numeral(LexState *ls, SemInfo *seminfo)
{
TValue obj;
const char *expo = "Ee";
int first = ls->current;
lua_assert(lisdigit(ls->current));
save_and_next(ls);
if (first == '0' && check_next2(ls, "xX")) /* hexadecimal? */
expo = "Pp";
for (;;)
{
if (check_next2(ls, expo)) /* exponent part? */
check_next2(ls, "-+"); /* optional exponent sign */
if (lisxdigit(ls->current))
save_and_next(ls);
else if (ls->current == '.')
save_and_next(ls);
else
break;
}
save(ls, '\0');
if (luaO_str2num(luaZ_buffer(ls->buff), &obj) == 0) /* format error? */
lexerror(ls, "malformed number", TK_FLT);
if (ttisinteger(&obj))
{
seminfo->i = ivalue(&obj);
return TK_INT;
}
else
{
lua_assert(ttisfloat(&obj));
seminfo->r = fltvalue(&obj);
return TK_FLT;
}
}
/*
** skip a sequence '[=*[' or ']=*]'; if sequence is well formed, return
** its number of '='s; otherwise, return a negative number (-1 iff there
** are no '='s after initial bracket)
*/
static int skip_sep(LexState *ls)
{
int count = 0;
int s = ls->current;
lua_assert(s == '[' || s == ']');
save_and_next(ls);
while (ls->current == '=')
{
save_and_next(ls);
count++;
}
return (ls->current == s) ? count : (-count) - 1;
}
static void read_long_string(LexState *ls, SemInfo *seminfo, int sep)
{
int line = ls->linenumber; /* initial line (for error message) */
save_and_next(ls); /* skip 2nd '[' */
if (currIsNewline(ls)) /* string starts with a newline? */
inclinenumber(ls); /* skip it */
for (;;)
{
switch (ls->current)
{
case EOZ:
{ /* error */
const char *what = (seminfo ? "string" : "comment");
const char *msg = luaO_pushfstring(ls->L,
"unfinished long %s (starting at line %d)", what, line);
lexerror(ls, msg, TK_EOS);
break; /* to avoid warnings */
}
case ']':
{
if (skip_sep(ls) == sep)
{
save_and_next(ls); /* skip 2nd ']' */
goto endloop;
}
break;
}
case '\n':
case '\r':
{
save(ls, '\n');
inclinenumber(ls);
if (!seminfo)
luaZ_resetbuffer(ls->buff); /* avoid wasting space */
break;
}
default:
{
if (seminfo)
save_and_next(ls);
else
next(ls);
}
}
}
endloop:
if (seminfo)
seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
luaZ_bufflen(ls->buff) - 2 * (2 + sep));
}
static void esccheck(LexState *ls, int c, const char *msg)
{
if (!c)
{
if (ls->current != EOZ)
save_and_next(ls); /* add current to buffer for error message */
lexerror(ls, msg, TK_STRING);
}
}
static int gethexa(LexState *ls)
{
save_and_next(ls);
esccheck(ls, lisxdigit(ls->current), "hexadecimal digit expected");
return luaO_hexavalue(ls->current);
}
static int readhexaesc(LexState *ls)
{
int r = gethexa(ls);
r = (r << 4) + gethexa(ls);
luaZ_buffremove(ls->buff, 2); /* remove saved chars from buffer */
return r;
}
static unsigned long readutf8esc(LexState *ls)
{
unsigned long r;
int i = 4; /* chars to be removed: '\', 'u', '{', and first digit */
save_and_next(ls); /* skip 'u' */
esccheck(ls, ls->current == '{', "missing '{'");
r = gethexa(ls); /* must have at least one digit */
while ((save_and_next(ls), lisxdigit(ls->current)))
{
i++;
r = (r << 4) + luaO_hexavalue(ls->current);
esccheck(ls, r <= 0x10FFFF, "UTF-8 value too large");
}
esccheck(ls, ls->current == '}', "missing '}'");
next(ls); /* skip '}' */
luaZ_buffremove(ls->buff, i); /* remove saved chars from buffer */
return r;
}
static void utf8esc(LexState *ls)
{
char buff[UTF8BUFFSZ];
int n = luaO_utf8esc(buff, readutf8esc(ls));
for (; n > 0; n--) /* add 'buff' to string */
save(ls, buff[UTF8BUFFSZ - n]);
}
static int readdecesc(LexState *ls)
{
int i;
int r = 0; /* result accumulator */
for (i = 0; i < 3 && lisdigit(ls->current); i++)
{ /* read up to 3 digits */
r = 10 * r + ls->current - '0';
save_and_next(ls);
}
esccheck(ls, r <= UCHAR_MAX, "decimal escape too large");
luaZ_buffremove(ls->buff, i); /* remove read digits from buffer */
return r;
}
static void read_string(LexState *ls, int del, SemInfo *seminfo)
{
save_and_next(ls); /* keep delimiter (for error messages) */
while (ls->current != del)
{
switch (ls->current)
{
case EOZ:
lexerror(ls, "unfinished string", TK_EOS);
break; /* to avoid warnings */
case '\n':
case '\r':
lexerror(ls, "unfinished string", TK_STRING);
break; /* to avoid warnings */
case '\\':
{ /* escape sequences */
int c; /* final character to be saved */
save_and_next(ls); /* keep '\\' for error messages */
switch (ls->current)
{
case 'a':
c = '\a';
goto read_save;
case 'b':
c = '\b';
goto read_save;
case 'f':
c = '\f';
goto read_save;
case 'n':
c = '\n';
goto read_save;
case 'r':
c = '\r';
goto read_save;
case 't':
c = '\t';
goto read_save;
case 'v':
c = '\v';
goto read_save;
case 'x':
c = readhexaesc(ls);
goto read_save;
case 'u':
utf8esc(ls);
goto no_save;
case '\n':
case '\r':
inclinenumber(ls);
c = '\n';
goto only_save;
case '\\':
case '\"':
case '\'':
c = ls->current;
goto read_save;
case EOZ:
goto no_save; /* will raise an error next loop */
case 'z':
{ /* zap following span of spaces */
luaZ_buffremove(ls->buff, 1); /* remove '\\' */
next(ls); /* skip the 'z' */
while (lisspace(ls->current))
{
if (currIsNewline(ls))
inclinenumber(ls);
else
next(ls);
}
goto no_save;
}
default:
{
esccheck(ls, lisdigit(ls->current), "invalid escape sequence");
c = readdecesc(ls); /* digital escape '\ddd' */
goto only_save;
}
}
read_save:
next(ls);
/* go through */
only_save:
luaZ_buffremove(ls->buff, 1); /* remove '\\' */
save(ls, c);
/* go through */
no_save:
break;
}
default:
save_and_next(ls);
}
}
save_and_next(ls); /* skip delimiter */
seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
luaZ_bufflen(ls->buff) - 2);
}
static int llex(LexState *ls, SemInfo *seminfo)
{
luaZ_resetbuffer(ls->buff);
for (;;)
{
switch (ls->current)
{
case '\n':
case '\r':
{ /* line breaks */
inclinenumber(ls);
break;
}
case ' ':
case '\f':
case '\t':
case '\v':
{ /* spaces */
next(ls);
break;
}
case '-':
{ /* '-' or '--' (comment) */
next(ls);
if (ls->current != '-')
return '-';
/* else is a comment */
next(ls);
if (ls->current == '[')
{ /* long comment? */
int sep = skip_sep(ls);
luaZ_resetbuffer(ls->buff); /* 'skip_sep' may dirty the buffer */
if (sep >= 0)
{
read_long_string(ls, NULL, sep); /* skip long comment */
luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */
break;
}
}
/* else short comment */
while (!currIsNewline(ls) && ls->current != EOZ)
next(ls); /* skip until end of line (or end of file) */
break;
}
case '[':
{ /* long string or simply '[' */
int sep = skip_sep(ls);
if (sep >= 0)
{
read_long_string(ls, seminfo, sep);
return TK_STRING;
}
else if (sep != -1) /* '[=...' missing second bracket */
lexerror(ls, "invalid long string delimiter", TK_STRING);
return '[';
}
case '=':
{
next(ls);
if (check_next1(ls, '='))
return TK_EQ;
else
return '=';
}
case '<':
{
next(ls);
if (check_next1(ls, '='))
return TK_LE;
else if (check_next1(ls, '<'))
return TK_SHL;
else
return '<';
}
case '>':
{
next(ls);
if (check_next1(ls, '='))
return TK_GE;
else if (check_next1(ls, '>'))
return TK_SHR;
else
return '>';
}
case '/':
{
next(ls);
if (check_next1(ls, '/'))
return TK_IDIV;
else
return '/';
}
case '~':
{
next(ls);
if (check_next1(ls, '='))
return TK_NE;
else
return '~';
}
case ':':
{
next(ls);
if (check_next1(ls, ':'))
return TK_DBCOLON;
else
return ':';
}
case '"':
case '\'':
{ /* short literal strings */
read_string(ls, ls->current, seminfo);
return TK_STRING;
}
case '.':
{ /* '.', '..', '...', or number */
save_and_next(ls);
if (check_next1(ls, '.'))
{
if (check_next1(ls, '.'))
return TK_DOTS; /* '...' */
else
return TK_CONCAT; /* '..' */
}
else if (!lisdigit(ls->current))
return '.';
else
return read_numeral(ls, seminfo);
}
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
return read_numeral(ls, seminfo);
}
case EOZ:
{
return TK_EOS;
}
default:
{
if (lislalpha(ls->current))
{ /* identifier or reserved word? */
TString *ts;
do
{
save_and_next(ls);
} while (lislalnum(ls->current));
ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
luaZ_bufflen(ls->buff));
seminfo->ts = ts;
if (isreserved(ts)) /* reserved word? */
return ts->extra - 1 + FIRST_RESERVED;
else
{
return TK_NAME;
}
}
else
{ /* single-char tokens (+ - / ...) */
int c = ls->current;
next(ls);
return c;
}
}
}
}
}
void luaX_next(LexState *ls)
{
ls->lastline = ls->linenumber;
if (ls->lookahead.token != TK_EOS)
{ /* is there a look-ahead token? */
ls->t = ls->lookahead; /* use this one */
ls->lookahead.token = TK_EOS; /* and discharge it */
}
else
ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */
}
int luaX_lookahead(LexState *ls)
{
lua_assert(ls->lookahead.token == TK_EOS);
ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
return ls->lookahead.token;
}

View File

@ -1,109 +0,0 @@
/*
** $Id: llex.h,v 1.79.1.1 2017/04/19 17:20:42 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
#ifndef llex_h
#define llex_h
#include "lobject.h"
#include "lzio.h"
#define FIRST_RESERVED 257
#if !defined(LUA_ENV)
#define LUA_ENV "_ENV"
#endif
/*
* WARNING: if you change the order of this enumeration,
* grep "ORDER RESERVED"
*/
enum RESERVED
{
/* terminal symbols denoted by reserved words */
TK_AND = FIRST_RESERVED,
TK_BREAK,
TK_DO,
TK_ELSE,
TK_ELSEIF,
TK_END,
TK_FALSE,
TK_FOR,
TK_FUNCTION,
TK_GOTO,
TK_IF,
TK_IN,
TK_LOCAL,
TK_NIL,
TK_NOT,
TK_OR,
TK_REPEAT,
TK_RETURN,
TK_THEN,
TK_TRUE,
TK_UNTIL,
TK_WHILE,
/* other terminal symbols */
TK_IDIV,
TK_CONCAT,
TK_DOTS,
TK_EQ,
TK_GE,
TK_LE,
TK_NE,
TK_SHL,
TK_SHR,
TK_DBCOLON,
TK_EOS,
TK_FLT,
TK_INT,
TK_NAME,
TK_STRING
};
/* number of reserved words */
#define NUM_RESERVED (cast(int, TK_WHILE - FIRST_RESERVED + 1))
typedef union {
lua_Number r;
lua_Integer i;
TString *ts;
} SemInfo; /* semantics information */
typedef struct Token
{
int token;
SemInfo seminfo;
} Token;
/* state of the lexer plus state of the parser when shared by all
functions */
typedef struct LexState
{
int current; /* current character (charint) */
int linenumber; /* input line counter */
int lastline; /* line of last token 'consumed' */
Token t; /* current token */
Token lookahead; /* look ahead token */
struct FuncState *fs; /* current function (parser) */
struct lua_State *L;
ZIO *z; /* input stream */
Mbuffer *buff; /* buffer for tokens */
Table *h; /* to avoid collection/reuse strings */
struct Dyndata *dyd; /* dynamic structures used by the parser */
TString *source; /* current source name */
TString *envn; /* environment variable name */
} LexState;
LUAI_FUNC void luaX_init(lua_State *L);
LUAI_FUNC void luaX_setinput(lua_State *L, LexState *ls, ZIO *z,
TString *source, int firstchar);
LUAI_FUNC TString *luaX_newstring(LexState *ls, const char *str, size_t l);
LUAI_FUNC void luaX_next(LexState *ls);
LUAI_FUNC int luaX_lookahead(LexState *ls);
LUAI_FUNC l_noret luaX_syntaxerror(LexState *ls, const char *s);
LUAI_FUNC const char *luaX_token2str(LexState *ls, int token);
#endif

View File

@ -1,310 +0,0 @@
/*
** $Id: llimits.h,v 1.141.1.1 2017/04/19 17:20:42 roberto Exp $
** Limits, basic types, and some other 'installation-dependent' definitions
** See Copyright Notice in lua.h
*/
#ifndef llimits_h
#define llimits_h
#include <limits.h>
#include <stddef.h>
#include "lua.h"
/*
** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count
** the total memory used by Lua (in bytes). Usually, 'size_t' and
** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines.
*/
#if defined(LUAI_MEM) /* { external definitions? */
typedef LUAI_UMEM lu_mem;
typedef LUAI_MEM l_mem;
#elif LUAI_BITSINT >= 32 /* }{ */
typedef size_t lu_mem;
typedef ptrdiff_t l_mem;
#else /* 16-bit ints */ /* }{ */
typedef unsigned long lu_mem;
typedef long l_mem;
#endif /* } */
/* chars used as small naturals (so that 'char' is reserved for characters) */
typedef unsigned char lu_byte;
/* maximum value for size_t */
#define MAX_SIZET ((size_t)(~(size_t)0))
/* maximum size visible for Lua (must be representable in a lua_Integer */
#define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \
: (size_t)(LUA_MAXINTEGER))
#define MAX_LUMEM ((lu_mem)(~(lu_mem)0))
#define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1))
#define MAX_INT INT_MAX /* maximum value of an int */
/*
** conversion of pointer to unsigned integer:
** this is for hashing only; there is no problem if the integer
** cannot hold the whole pointer value
*/
#define point2uint(p) ((unsigned int)((size_t)(p)&UINT_MAX))
/* type to ensure maximum alignment */
#if defined(LUAI_USER_ALIGNMENT_T)
typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
#else
typedef union {
lua_Number n;
double u;
void *s;
lua_Integer i;
long l;
} L_Umaxalign;
#endif
/* types of 'usual argument conversions' for lua_Number and lua_Integer */
typedef LUAI_UACNUMBER l_uacNumber;
typedef LUAI_UACINT l_uacInt;
/* internal assertions for in-house debugging */
#if defined(lua_assert)
#define check_exp(c, e) (lua_assert(c), (e))
/* to avoid problems with conditions too long */
#define lua_longassert(c) ((c) ? (void)0 : lua_assert(0))
#else
#define lua_assert(c) ((void)0)
#define check_exp(c, e) (e)
#define lua_longassert(c) ((void)0)
#endif
/*
** assertion for checking API calls
*/
#if !defined(luai_apicheck)
#define luai_apicheck(l, e) lua_assert(e)
#endif
#define api_check(l, e, msg) luai_apicheck(l, (e) && msg)
/* macro to avoid warnings about unused variables */
#if !defined(UNUSED)
#define UNUSED(x) ((void)(x))
#endif
/* type casts (a macro highlights casts in the code) */
#define cast(t, exp) ((t)(exp))
#define cast_void(i) cast(void, (i))
#define cast_byte(i) cast(lu_byte, (i))
#define cast_num(i) cast(lua_Number, (i))
#define cast_int(i) cast(int, (i))
#define cast_uchar(i) cast(unsigned char, (i))
/* cast a signed lua_Integer to lua_Unsigned */
#if !defined(l_castS2U)
#define l_castS2U(i) ((lua_Unsigned)(i))
#endif
/*
** cast a lua_Unsigned to a signed lua_Integer; this cast is
** not strict ISO C, but two-complement architectures should
** work fine.
*/
#if !defined(l_castU2S)
#define l_castU2S(i) ((lua_Integer)(i))
#endif
/*
** non-return type
*/
#if defined(__GNUC__)
#define l_noret void __attribute__((noreturn))
#elif defined(_MSC_VER) && _MSC_VER >= 1200
#define l_noret void __declspec(noreturn)
#else
#define l_noret void
#endif
/*
** maximum depth for nested C calls and syntactical nested non-terminals
** in a program. (Value must fit in an unsigned short int.)
*/
#if !defined(LUAI_MAXCCALLS)
#define LUAI_MAXCCALLS 200
#endif
/*
** type for virtual-machine instructions;
** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
*/
#if LUAI_BITSINT >= 32
typedef unsigned int Instruction;
#else
typedef unsigned long Instruction;
#endif
/*
** Maximum length for short strings, that is, strings that are
** internalized. (Cannot be smaller than reserved words or tags for
** metamethods, as these strings must be internalized;
** #("function") = 8, #("__newindex") = 10.)
*/
#if !defined(LUAI_MAXSHORTLEN)
#define LUAI_MAXSHORTLEN 40
#endif
/*
** Initial size for the string table (must be power of 2).
** The Lua core alone registers ~50 strings (reserved words +
** metaevent keys + a few others). Libraries would typically add
** a few dozens more.
*/
#if !defined(MINSTRTABSIZE)
#define MINSTRTABSIZE 128
#endif
/*
** Size of cache for strings in the API. 'N' is the number of
** sets (better be a prime) and "M" is the size of each set (M == 1
** makes a direct cache.)
*/
#if !defined(STRCACHE_N)
#define STRCACHE_N 53
#define STRCACHE_M 2
#endif
/* minimum size for string buffer */
#if !defined(LUA_MINBUFFER)
#define LUA_MINBUFFER 32
#endif
/*
** macros that are executed whenever program enters the Lua core
** ('lua_lock') and leaves the core ('lua_unlock')
*/
#if !defined(lua_lock)
#define lua_lock(L) ((void)0)
#define lua_unlock(L) ((void)0)
#endif
/*
** macro executed during Lua functions at points where the
** function can yield.
*/
#if !defined(luai_threadyield)
#define luai_threadyield(L) \
{ \
lua_unlock(L); \
lua_lock(L); \
}
#endif
/*
** these macros allow user-specific actions on threads when you defined
** LUAI_EXTRASPACE and need to do something extra when a thread is
** created/deleted/resumed/yielded.
*/
#if !defined(luai_userstateopen)
#define luai_userstateopen(L) ((void)L)
#endif
#if !defined(luai_userstateclose)
#define luai_userstateclose(L) ((void)L)
#endif
#if !defined(luai_userstatethread)
#define luai_userstatethread(L, L1) ((void)L)
#endif
#if !defined(luai_userstatefree)
#define luai_userstatefree(L, L1) ((void)L)
#endif
#if !defined(luai_userstateresume)
#define luai_userstateresume(L, n) ((void)L)
#endif
#if !defined(luai_userstateyield)
#define luai_userstateyield(L, n) ((void)L)
#endif
/*
** The luai_num* macros define the primitive operations over numbers.
*/
/* floor division (defined as 'floor(a/b)') */
#if !defined(luai_numidiv)
#define luai_numidiv(L, a, b) ((void)L, l_floor(luai_numdiv(L, a, b)))
#endif
/* float division */
#if !defined(luai_numdiv)
#define luai_numdiv(L, a, b) ((a) / (b))
#endif
/*
** modulo: defined as 'a - floor(a/b)*b'; this definition gives NaN when
** 'b' is huge, but the result should be 'a'. 'fmod' gives the result of
** 'a - trunc(a/b)*b', and therefore must be corrected when 'trunc(a/b)
** ~= floor(a/b)'. That happens when the division has a non-integer
** negative result, which is equivalent to the test below.
*/
#if !defined(luai_nummod)
#define luai_nummod(L, a, b, m) \
{ \
(m) = l_mathop(fmod)(a, b); \
if ((m) * (b) < 0) \
(m) += (b); \
}
#endif
/* exponentiation */
#if !defined(luai_numpow)
#define luai_numpow(L, a, b) ((void)L, l_mathop(pow)(a, b))
#endif
/* the others are quite standard operations */
#if !defined(luai_numadd)
#define luai_numadd(L, a, b) ((a) + (b))
#define luai_numsub(L, a, b) ((a) - (b))
#define luai_nummul(L, a, b) ((a) * (b))
#define luai_numunm(L, a) (-(a))
#define luai_numeq(a, b) ((a) == (b))
#define luai_numlt(a, b) ((a) < (b))
#define luai_numle(a, b) ((a) <= (b))
#define luai_numisnan(a) (!luai_numeq((a), (a)))
#endif
/*
** macro to control inclusion of some hard tests on stack reallocation
*/
#if !defined(HARDSTACKTESTS)
#define condmovestack(L, pre, pos) ((void)0)
#else
/* realloc stack keeping its size */
#define condmovestack(L, pre, pos) \
{ \
int sz_ = (L)->stacksize; \
pre; \
luaD_reallocstack((L), sz_); \
pos; \
}
#endif
#if !defined(HARDMEMTESTS)
#define condchangemem(L, pre, pos) ((void)0)
#else
#define condchangemem(L, pre, pos) \
{ \
if (G(L)->gcrunning) \
{ \
pre; \
luaC_fullgc(L, 0); \
pos; \
} \
}
#endif
#endif

View File

@ -1,440 +0,0 @@
/*
** $Id: lmathlib.c,v 1.119.1.1 2017/04/19 17:20:42 roberto Exp $
** Standard mathematical library
** See Copyright Notice in lua.h
*/
#define lmathlib_c
#define LUA_LIB
#include "lprefix.h"
#include <stdlib.h>
#include <math.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#undef PI
#define PI (l_mathop(3.141592653589793238462643383279502884))
#if !defined(l_rand) /* { */
#if defined(LUA_USE_POSIX)
#define l_rand() random()
#define l_srand(x) srandom(x)
#define L_RANDMAX 2147483647 /* (2^31 - 1), following POSIX */
#else
#define l_rand() rand()
#define l_srand(x) srand(x)
#define L_RANDMAX RAND_MAX
#endif
#endif /* } */
static int math_abs(lua_State *L)
{
if (lua_isinteger(L, 1))
{
lua_Integer n = lua_tointeger(L, 1);
if (n < 0)
n = (lua_Integer)(0u - (lua_Unsigned)n);
lua_pushinteger(L, n);
}
else
lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1)));
return 1;
}
static int math_sin(lua_State *L)
{
lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1)));
return 1;
}
static int math_cos(lua_State *L)
{
lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1)));
return 1;
}
static int math_tan(lua_State *L)
{
lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1)));
return 1;
}
static int math_asin(lua_State *L)
{
lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1)));
return 1;
}
static int math_acos(lua_State *L)
{
lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1)));
return 1;
}
static int math_atan(lua_State *L)
{
lua_Number y = luaL_checknumber(L, 1);
lua_Number x = luaL_optnumber(L, 2, 1);
lua_pushnumber(L, l_mathop(atan2)(y, x));
return 1;
}
static int math_toint(lua_State *L)
{
int valid;
lua_Integer n = lua_tointegerx(L, 1, &valid);
if (valid)
lua_pushinteger(L, n);
else
{
luaL_checkany(L, 1);
lua_pushnil(L); /* value is not convertible to integer */
}
return 1;
}
static void pushnumint(lua_State *L, lua_Number d)
{
lua_Integer n;
if (lua_numbertointeger(d, &n)) /* does 'd' fit in an integer? */
lua_pushinteger(L, n); /* result is integer */
else
lua_pushnumber(L, d); /* result is float */
}
static int math_floor(lua_State *L)
{
if (lua_isinteger(L, 1))
lua_settop(L, 1); /* integer is its own floor */
else
{
lua_Number d = l_mathop(floor)(luaL_checknumber(L, 1));
pushnumint(L, d);
}
return 1;
}
static int math_ceil(lua_State *L)
{
if (lua_isinteger(L, 1))
lua_settop(L, 1); /* integer is its own ceil */
else
{
lua_Number d = l_mathop(ceil)(luaL_checknumber(L, 1));
pushnumint(L, d);
}
return 1;
}
static int math_fmod(lua_State *L)
{
if (lua_isinteger(L, 1) && lua_isinteger(L, 2))
{
lua_Integer d = lua_tointeger(L, 2);
if ((lua_Unsigned)d + 1u <= 1u)
{ /* special cases: -1 or 0 */
luaL_argcheck(L, d != 0, 2, "zero");
lua_pushinteger(L, 0); /* avoid overflow with 0x80000... / -1 */
}
else
lua_pushinteger(L, lua_tointeger(L, 1) % d);
}
else
lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1),
luaL_checknumber(L, 2)));
return 1;
}
/*
** next function does not use 'modf', avoiding problems with 'double*'
** (which is not compatible with 'float*') when lua_Number is not
** 'double'.
*/
static int math_modf(lua_State *L)
{
if (lua_isinteger(L, 1))
{
lua_settop(L, 1); /* number is its own integer part */
lua_pushnumber(L, 0); /* no fractional part */
}
else
{
lua_Number n = luaL_checknumber(L, 1);
/* integer part (rounds toward zero) */
lua_Number ip = (n < 0) ? l_mathop(ceil)(n) : l_mathop(floor)(n);
pushnumint(L, ip);
/* fractional part (test needed for inf/-inf) */
lua_pushnumber(L, (n == ip) ? l_mathop(0.0) : (n - ip));
}
return 2;
}
static int math_sqrt(lua_State *L)
{
lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1)));
return 1;
}
static int math_ult(lua_State *L)
{
lua_Integer a = luaL_checkinteger(L, 1);
lua_Integer b = luaL_checkinteger(L, 2);
lua_pushboolean(L, (lua_Unsigned)a < (lua_Unsigned)b);
return 1;
}
static int math_log(lua_State *L)
{
lua_Number x = luaL_checknumber(L, 1);
lua_Number res;
if (lua_isnoneornil(L, 2))
res = l_mathop(log)(x);
else
{
lua_Number base = luaL_checknumber(L, 2);
#if !defined(LUA_USE_C89)
if (base == l_mathop(2.0))
res = l_mathop(log2)(x);
else
#endif
if (base == l_mathop(10.0))
res = l_mathop(log10)(x);
else
res = l_mathop(log)(x) / l_mathop(log)(base);
}
lua_pushnumber(L, res);
return 1;
}
static int math_exp(lua_State *L)
{
lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1)));
return 1;
}
static int math_deg(lua_State *L)
{
lua_pushnumber(L, luaL_checknumber(L, 1) * (l_mathop(180.0) / PI));
return 1;
}
static int math_rad(lua_State *L)
{
lua_pushnumber(L, luaL_checknumber(L, 1) * (PI / l_mathop(180.0)));
return 1;
}
static int math_min(lua_State *L)
{
int n = lua_gettop(L); /* number of arguments */
int imin = 1; /* index of current minimum value */
int i;
luaL_argcheck(L, n >= 1, 1, "value expected");
for (i = 2; i <= n; i++)
{
if (lua_compare(L, i, imin, LUA_OPLT))
imin = i;
}
lua_pushvalue(L, imin);
return 1;
}
static int math_max(lua_State *L)
{
int n = lua_gettop(L); /* number of arguments */
int imax = 1; /* index of current maximum value */
int i;
luaL_argcheck(L, n >= 1, 1, "value expected");
for (i = 2; i <= n; i++)
{
if (lua_compare(L, imax, i, LUA_OPLT))
imax = i;
}
lua_pushvalue(L, imax);
return 1;
}
/*
** This function uses 'double' (instead of 'lua_Number') to ensure that
** all bits from 'l_rand' can be represented, and that 'RANDMAX + 1.0'
** will keep full precision (ensuring that 'r' is always less than 1.0.)
*/
static int math_random(lua_State *L)
{
lua_Integer low, up;
double r = (double)l_rand() * (1.0 / ((double)L_RANDMAX + 1.0));
switch (lua_gettop(L))
{ /* check number of arguments */
case 0:
{ /* no arguments */
lua_pushnumber(L, (lua_Number)r); /* Number between 0 and 1 */
return 1;
}
case 1:
{ /* only upper limit */
low = 1;
up = luaL_checkinteger(L, 1);
break;
}
case 2:
{ /* lower and upper limits */
low = luaL_checkinteger(L, 1);
up = luaL_checkinteger(L, 2);
break;
}
default:
return luaL_error(L, "wrong number of arguments");
}
/* random integer in the interval [low, up] */
luaL_argcheck(L, low <= up, 1, "interval is empty");
luaL_argcheck(L, low >= 0 || up <= LUA_MAXINTEGER + low, 1,
"interval too large");
r *= (double)(up - low) + 1.0;
lua_pushinteger(L, (lua_Integer)r + low);
return 1;
}
static int math_randomseed(lua_State *L)
{
l_srand((unsigned int)(lua_Integer)luaL_checknumber(L, 1));
(void)l_rand(); /* discard first value to avoid undesirable correlations */
return 0;
}
static int math_type(lua_State *L)
{
if (lua_type(L, 1) == LUA_TNUMBER)
{
if (lua_isinteger(L, 1))
lua_pushliteral(L, "integer");
else
lua_pushliteral(L, "float");
}
else
{
luaL_checkany(L, 1);
lua_pushnil(L);
}
return 1;
}
/*
** {==================================================================
** Deprecated functions (for compatibility only)
** ===================================================================
*/
#if defined(LUA_COMPAT_MATHLIB)
static int math_cosh(lua_State *L)
{
lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1)));
return 1;
}
static int math_sinh(lua_State *L)
{
lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1)));
return 1;
}
static int math_tanh(lua_State *L)
{
lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1)));
return 1;
}
static int math_pow(lua_State *L)
{
lua_Number x = luaL_checknumber(L, 1);
lua_Number y = luaL_checknumber(L, 2);
lua_pushnumber(L, l_mathop(pow)(x, y));
return 1;
}
static int math_frexp(lua_State *L)
{
int e;
lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e));
lua_pushinteger(L, e);
return 2;
}
static int math_ldexp(lua_State *L)
{
lua_Number x = luaL_checknumber(L, 1);
int ep = (int)luaL_checkinteger(L, 2);
lua_pushnumber(L, l_mathop(ldexp)(x, ep));
return 1;
}
static int math_log10(lua_State *L)
{
lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1)));
return 1;
}
#endif
/* }================================================================== */
static const luaL_Reg mathlib[] = {
{"abs", math_abs},
{"acos", math_acos},
{"asin", math_asin},
{"atan", math_atan},
{"ceil", math_ceil},
{"cos", math_cos},
{"deg", math_deg},
{"exp", math_exp},
{"tointeger", math_toint},
{"floor", math_floor},
{"fmod", math_fmod},
{"ult", math_ult},
{"log", math_log},
{"max", math_max},
{"min", math_min},
{"modf", math_modf},
{"rad", math_rad},
{"random", math_random},
{"randomseed", math_randomseed},
{"sin", math_sin},
{"sqrt", math_sqrt},
{"tan", math_tan},
{"type", math_type},
#if defined(LUA_COMPAT_MATHLIB)
{"atan2", math_atan},
{"cosh", math_cosh},
{"sinh", math_sinh},
{"tanh", math_tanh},
{"pow", math_pow},
{"frexp", math_frexp},
{"ldexp", math_ldexp},
{"log10", math_log10},
#endif
/* placeholders */
{"pi", NULL},
{"huge", NULL},
{"maxinteger", NULL},
{"mininteger", NULL},
{NULL, NULL}};
/*
** Open math library
*/
LUAMOD_API int luaopen_math(lua_State *L)
{
luaL_newlib(L, mathlib);
lua_pushnumber(L, PI);
lua_setfield(L, -2, "pi");
lua_pushnumber(L, (lua_Number)HUGE_VAL);
lua_setfield(L, -2, "huge");
lua_pushinteger(L, LUA_MAXINTEGER);
lua_setfield(L, -2, "maxinteger");
lua_pushinteger(L, LUA_MININTEGER);
lua_setfield(L, -2, "mininteger");
return 1;
}

View File

@ -1,97 +0,0 @@
/*
** $Id: lmem.c,v 1.91.1.1 2017/04/19 17:20:42 roberto Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
#define lmem_c
#define LUA_CORE
#include "lprefix.h"
#include <stddef.h>
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
/*
** About the realloc function:
** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
** ('osize' is the old size, 'nsize' is the new size)
**
** * frealloc(ud, NULL, x, s) creates a new block of size 's' (no
** matter 'x').
**
** * frealloc(ud, p, x, 0) frees the block 'p'
** (in this specific case, frealloc must return NULL);
** particularly, frealloc(ud, NULL, 0, 0) does nothing
** (which is equivalent to free(NULL) in ISO C)
**
** frealloc returns NULL if it cannot create or reallocate the area
** (any reallocation to an equal or smaller size cannot fail!)
*/
#define MINSIZEARRAY 4
void *luaM_growaux_(lua_State *L, void *block, int *size, size_t size_elems,
int limit, const char *what)
{
void *newblock;
int newsize;
if (*size >= limit / 2)
{ /* cannot double it? */
if (*size >= limit) /* cannot grow even a little? */
luaG_runerror(L, "too many %s (limit is %d)", what, limit);
newsize = limit; /* still have at least one free place */
}
else
{
newsize = (*size) * 2;
if (newsize < MINSIZEARRAY)
newsize = MINSIZEARRAY; /* minimum size */
}
newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
*size = newsize; /* update only when everything else is OK */
return newblock;
}
l_noret luaM_toobig(lua_State *L)
{
luaG_runerror(L, "memory allocation error: block too big");
}
/*
** generic allocation routine.
*/
void *luaM_realloc_(lua_State *L, void *block, size_t osize, size_t nsize)
{
void *newblock;
global_State *g = G(L);
size_t realosize = (block) ? osize : 0;
lua_assert((realosize == 0) == (block == NULL));
#if defined(HARDMEMTESTS)
if (nsize > realosize && g->gcrunning)
luaC_fullgc(L, 1); /* force a GC whenever possible */
#endif
newblock = (*g->frealloc)(g->ud, block, osize, nsize);
if (newblock == NULL && nsize > 0)
{
lua_assert(nsize > realosize); /* cannot fail when shrinking a block */
if (g->version)
{ /* is state fully built? */
luaC_fullgc(L, 1); /* try to free some memory... */
newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
}
if (newblock == NULL)
luaD_throw(L, LUA_ERRMEM);
}
lua_assert((nsize == 0) == (newblock == NULL));
g->GCdebt = (g->GCdebt + nsize) - realosize;
return newblock;
}

View File

@ -1,67 +0,0 @@
/*
** $Id: lmem.h,v 1.43.1.1 2017/04/19 17:20:42 roberto Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
#ifndef lmem_h
#define lmem_h
#include <stddef.h>
#include "llimits.h"
#include "lua.h"
/*
** This macro reallocs a vector 'b' from 'on' to 'n' elements, where
** each element has size 'e'. In case of arithmetic overflow of the
** product 'n'*'e', it raises an error (calling 'luaM_toobig'). Because
** 'e' is always constant, it avoids the runtime division MAX_SIZET/(e).
**
** (The macro is somewhat complex to avoid warnings: The 'sizeof'
** comparison avoids a runtime comparison when overflow cannot occur.
** The compiler should be able to optimize the real test by itself, but
** when it does it, it may give a warning about "comparison is always
** false due to limited range of data type"; the +1 tricks the compiler,
** avoiding this warning but also this optimization.)
*/
#define luaM_reallocv(L, b, on, n, e) \
(((sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET / (e)) \
? luaM_toobig(L) \
: cast_void(0)), \
luaM_realloc_(L, (b), (on) * (e), (n) * (e)))
/*
** Arrays of chars do not need any test
*/
#define luaM_reallocvchar(L, b, on, n) \
cast(char *, luaM_realloc_(L, (b), (on) * sizeof(char), (n) * sizeof(char)))
#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
#define luaM_freearray(L, b, n) luaM_realloc_(L, (b), (n) * sizeof(*(b)), 0)
#define luaM_malloc(L, s) luaM_realloc_(L, NULL, 0, (s))
#define luaM_new(L, t) cast(t *, luaM_malloc(L, sizeof(t)))
#define luaM_newvector(L, n, t) \
cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
#define luaM_newobject(L, tag, s) luaM_realloc_(L, NULL, tag, (s))
#define luaM_growvector(L, v, nelems, size, t, limit, e) \
if ((nelems) + 1 > (size)) \
((v) = cast(t *, luaM_growaux_(L, v, &(size), sizeof(t), limit, e)))
#define luaM_reallocvector(L, v, oldn, n, t) \
((v) = cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
LUAI_FUNC l_noret luaM_toobig(lua_State *L);
/* not to be called directly */
LUAI_FUNC void *luaM_realloc_(lua_State *L, void *block, size_t oldsize,
size_t size);
LUAI_FUNC void *luaM_growaux_(lua_State *L, void *block, int *size,
size_t size_elem, int limit,
const char *what);
#endif

View File

@ -1,801 +0,0 @@
/*
** $Id: loadlib.c,v 1.130.1.1 2017/04/19 17:20:42 roberto Exp $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
** This module contains an implementation of loadlib for Unix systems
** that have dlfcn, an implementation for Windows, and a stub for other
** systems.
*/
#define loadlib_c
#define LUA_LIB
#include "lprefix.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
/*
** LUA_IGMARK is a mark to ignore all before it when building the
** luaopen_ function name.
*/
#if !defined(LUA_IGMARK)
#define LUA_IGMARK "-"
#endif
/*
** LUA_CSUBSEP is the character that replaces dots in submodule names
** when searching for a C loader.
** LUA_LSUBSEP is the character that replaces dots in submodule names
** when searching for a Lua loader.
*/
#if !defined(LUA_CSUBSEP)
#define LUA_CSUBSEP LUA_DIRSEP
#endif
#if !defined(LUA_LSUBSEP)
#define LUA_LSUBSEP LUA_DIRSEP
#endif
/* prefix for open functions in C libraries */
#define LUA_POF "luaopen_"
/* separator for open functions in C libraries */
#define LUA_OFSEP "_"
/*
** unique key for table in the registry that keeps handles
** for all loaded C libraries
*/
static const int CLIBS = 0;
#define LIB_FAIL "open"
#define setprogdir(L) ((void)0)
/*
** system-dependent functions
*/
/*
** unload library 'lib'
*/
static void lsys_unloadlib(void *lib);
/*
** load C library in file 'path'. If 'seeglb', load with all names in
** the library global.
** Returns the library; in case of error, returns NULL plus an
** error string in the stack.
*/
static void *lsys_load(lua_State *L, const char *path, int seeglb);
/*
** Try to find a function named 'sym' in library 'lib'.
** Returns the function; in case of error, returns NULL plus an
** error string in the stack.
*/
static lua_CFunction lsys_sym(lua_State *L, void *lib, const char *sym);
#if defined(LUA_USE_DLOPEN) /* { */
/*
** {========================================================================
** This is an implementation of loadlib based on the dlfcn interface.
** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
** as an emulation layer on top of native functions.
** =========================================================================
*/
#include <dlfcn.h>
/*
** Macro to convert pointer-to-void* to pointer-to-function. This cast
** is undefined according to ISO C, but POSIX assumes that it works.
** (The '__extension__' in gnu compilers is only to avoid warnings.)
*/
#if defined(__GNUC__)
#define cast_func(p) (__extension__(lua_CFunction)(p))
#else
#define cast_func(p) ((lua_CFunction)(p))
#endif
static void lsys_unloadlib(void *lib)
{
dlclose(lib);
}
static void *lsys_load(lua_State *L, const char *path, int seeglb)
{
void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
if (lib == NULL)
lua_pushstring(L, dlerror());
return lib;
}
static lua_CFunction lsys_sym(lua_State *L, void *lib, const char *sym)
{
lua_CFunction f = cast_func(dlsym(lib, sym));
if (f == NULL)
lua_pushstring(L, dlerror());
return f;
}
/* }====================================================== */
#elif defined(LUA_DL_DLL) /* }{ */
/*
** {======================================================================
** This is an implementation of loadlib for Windows using native functions.
** =======================================================================
*/
#include <windows.h>
/*
** optional flags for LoadLibraryEx
*/
#if !defined(LUA_LLE_FLAGS)
#define LUA_LLE_FLAGS 0
#endif
#undef setprogdir
/*
** Replace in the path (on the top of the stack) any occurrence
** of LUA_EXEC_DIR with the executable's path.
*/
static void setprogdir(lua_State *L)
{
char buff[MAX_PATH + 1];
char *lb;
DWORD nsize = sizeof(buff) / sizeof(char);
DWORD n = GetModuleFileNameA(NULL, buff, nsize); /* get exec. name */
if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
luaL_error(L, "unable to get ModuleFileName");
else
{
*lb = '\0'; /* cut name on the last '\\' to get the path */
luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
lua_remove(L, -2); /* remove original string */
}
}
static void pusherror(lua_State *L)
{
int error = GetLastError();
char buffer[128];
if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error, 0, buffer, sizeof(buffer) / sizeof(char), NULL))
lua_pushstring(L, buffer);
else
lua_pushfstring(L, "system error %d\n", error);
}
static void lsys_unloadlib(void *lib)
{
FreeLibrary((HMODULE)lib);
}
static void *lsys_load(lua_State *L, const char *path, int seeglb)
{
HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
(void)(seeglb); /* not used: symbols are 'global' by default */
if (lib == NULL)
pusherror(L);
return lib;
}
static lua_CFunction lsys_sym(lua_State *L, void *lib, const char *sym)
{
lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym);
if (f == NULL)
pusherror(L);
return f;
}
/* }====================================================== */
#else /* }{ */
/*
** {======================================================
** Fallback for other systems
** =======================================================
*/
#undef LIB_FAIL
#define LIB_FAIL "absent"
#define DLMSG "dynamic libraries not enabled; check your Lua installation"
static void lsys_unloadlib(void *lib)
{
(void)(lib); /* not used */
}
static void *lsys_load(lua_State *L, const char *path, int seeglb)
{
(void)(path);
(void)(seeglb); /* not used */
lua_pushliteral(L, DLMSG);
return NULL;
}
static lua_CFunction lsys_sym(lua_State *L, void *lib, const char *sym)
{
(void)(lib);
(void)(sym); /* not used */
lua_pushliteral(L, DLMSG);
return NULL;
}
/* }====================================================== */
#endif /* } */
/*
** {==================================================================
** Set Paths
** ===================================================================
*/
/*
** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment
** variables that Lua check to set its paths.
*/
#if !defined(LUA_PATH_VAR)
#define LUA_PATH_VAR "LUA_PATH"
#endif
#if !defined(LUA_CPATH_VAR)
#define LUA_CPATH_VAR "LUA_CPATH"
#endif
#define AUXMARK "\1" /* auxiliary mark */
/*
** return registry.LUA_NOENV as a boolean
*/
static int noenv(lua_State *L)
{
int b;
lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
b = lua_toboolean(L, -1);
lua_pop(L, 1); /* remove value */
return b;
}
/*
** Set a path
*/
static void setpath(lua_State *L, const char *fieldname,
const char *envname,
const char *dft)
{
const char *nver = lua_pushfstring(L, "%s%s", envname, LUA_VERSUFFIX);
const char *path = getenv(nver); /* use versioned name */
if (path == NULL) /* no environment variable? */
path = getenv(envname); /* try unversioned name */
if (path == NULL || noenv(L)) /* no environment variable? */
lua_pushstring(L, dft); /* use default */
else
{
/* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
luaL_gsub(L, path, AUXMARK, dft);
lua_remove(L, -2); /* remove result from 1st 'gsub' */
}
setprogdir(L);
lua_setfield(L, -3, fieldname); /* package[fieldname] = path value */
lua_pop(L, 1); /* pop versioned variable name */
}
/* }================================================================== */
/*
** return registry.CLIBS[path]
*/
static void *checkclib(lua_State *L, const char *path)
{
void *plib;
lua_rawgetp(L, LUA_REGISTRYINDEX, &CLIBS);
lua_getfield(L, -1, path);
plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */
lua_pop(L, 2); /* pop CLIBS table and 'plib' */
return plib;
}
/*
** registry.CLIBS[path] = plib -- for queries
** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries
*/
static void addtoclib(lua_State *L, const char *path, void *plib)
{
lua_rawgetp(L, LUA_REGISTRYINDEX, &CLIBS);
lua_pushlightuserdata(L, plib);
lua_pushvalue(L, -1);
lua_setfield(L, -3, path); /* CLIBS[path] = plib */
lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */
lua_pop(L, 1); /* pop CLIBS table */
}
/*
** __gc tag method for CLIBS table: calls 'lsys_unloadlib' for all lib
** handles in list CLIBS
*/
static int gctm(lua_State *L)
{
lua_Integer n = luaL_len(L, 1);
for (; n >= 1; n--)
{ /* for each handle, in reverse order */
lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */
lsys_unloadlib(lua_touserdata(L, -1));
lua_pop(L, 1); /* pop handle */
}
return 0;
}
/* error codes for 'lookforfunc' */
#define ERRLIB 1
#define ERRFUNC 2
/*
** Look for a C function named 'sym' in a dynamically loaded library
** 'path'.
** First, check whether the library is already loaded; if not, try
** to load it.
** Then, if 'sym' is '*', return true (as library has been loaded).
** Otherwise, look for symbol 'sym' in the library and push a
** C function with that symbol.
** Return 0 and 'true' or a function in the stack; in case of
** errors, return an error code and an error message in the stack.
*/
static int lookforfunc(lua_State *L, const char *path, const char *sym)
{
void *reg = checkclib(L, path); /* check loaded C libraries */
if (reg == NULL)
{ /* must load library? */
reg = lsys_load(L, path, *sym == '*'); /* global symbols if 'sym'=='*' */
if (reg == NULL)
return ERRLIB; /* unable to load library */
addtoclib(L, path, reg);
}
if (*sym == '*')
{ /* loading only library (no function)? */
lua_pushboolean(L, 1); /* return 'true' */
return 0; /* no errors */
}
else
{
lua_CFunction f = lsys_sym(L, reg, sym);
if (f == NULL)
return ERRFUNC; /* unable to find function */
lua_pushcfunction(L, f); /* else create new function */
return 0; /* no errors */
}
}
static int ll_loadlib(lua_State *L)
{
const char *path = luaL_checkstring(L, 1);
const char *init = luaL_checkstring(L, 2);
int stat = lookforfunc(L, path, init);
if (stat == 0) /* no errors? */
return 1; /* return the loaded function */
else
{ /* error; error message is on stack top */
lua_pushnil(L);
lua_insert(L, -2);
lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
return 3; /* return nil, error message, and where */
}
}
/*
** {======================================================
** 'require' function
** =======================================================
*/
static int readable(const char *filename)
{
FILE *f = fopen(filename, "r"); /* try to open file */
if (f == NULL)
return 0; /* open failed */
fclose(f);
return 1;
}
static const char *pushnexttemplate(lua_State *L, const char *path)
{
const char *l;
while (*path == *LUA_PATH_SEP)
path++; /* skip separators */
if (*path == '\0')
return NULL; /* no more templates */
l = strchr(path, *LUA_PATH_SEP); /* find next separator */
if (l == NULL)
l = path + strlen(path);
lua_pushlstring(L, path, l - path); /* template */
return l;
}
static const char *searchpath(lua_State *L, const char *name,
const char *path,
const char *sep,
const char *dirsep)
{
luaL_Buffer msg; /* to build error message */
luaL_buffinit(L, &msg);
if (*sep != '\0') /* non-empty separator? */
name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
while ((path = pushnexttemplate(L, path)) != NULL)
{
const char *filename = luaL_gsub(L, lua_tostring(L, -1),
LUA_PATH_MARK, name);
lua_remove(L, -2); /* remove path template */
if (readable(filename)) /* does file exist and is readable? */
return filename; /* return that file name */
lua_pushfstring(L, "\n\tno file '%s'", filename);
lua_remove(L, -2); /* remove file name */
luaL_addvalue(&msg); /* concatenate error msg. entry */
}
luaL_pushresult(&msg); /* create error message */
return NULL; /* not found */
}
static int ll_searchpath(lua_State *L)
{
const char *f = searchpath(L, luaL_checkstring(L, 1),
luaL_checkstring(L, 2),
luaL_optstring(L, 3, "."),
luaL_optstring(L, 4, LUA_DIRSEP));
if (f != NULL)
return 1;
else
{ /* error message is on top of the stack */
lua_pushnil(L);
lua_insert(L, -2);
return 2; /* return nil + error message */
}
}
static const char *findfile(lua_State *L, const char *name,
const char *pname,
const char *dirsep)
{
const char *path;
lua_getfield(L, lua_upvalueindex(1), pname);
path = lua_tostring(L, -1);
if (path == NULL)
luaL_error(L, "'package.%s' must be a string", pname);
return searchpath(L, name, path, ".", dirsep);
}
static int checkload(lua_State *L, int stat, const char *filename)
{
if (stat)
{ /* module loaded successfully? */
lua_pushstring(L, filename); /* will be 2nd argument to module */
return 2; /* return open function and file name */
}
else
return luaL_error(L, "error loading module '%s' from file '%s':\n\t%s",
lua_tostring(L, 1), filename, lua_tostring(L, -1));
}
static int searcher_Lua(lua_State *L)
{
const char *filename;
const char *name = luaL_checkstring(L, 1);
filename = findfile(L, name, "path", LUA_LSUBSEP);
if (filename == NULL)
return 1; /* module not found in this path */
return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename);
}
/*
** Try to find a load function for module 'modname' at file 'filename'.
** First, change '.' to '_' in 'modname'; then, if 'modname' has
** the form X-Y (that is, it has an "ignore mark"), build a function
** name "luaopen_X" and look for it. (For compatibility, if that
** fails, it also tries "luaopen_Y".) If there is no ignore mark,
** look for a function named "luaopen_modname".
*/
static int loadfunc(lua_State *L, const char *filename, const char *modname)
{
const char *openfunc;
const char *mark;
modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
mark = strchr(modname, *LUA_IGMARK);
if (mark)
{
int stat;
openfunc = lua_pushlstring(L, modname, mark - modname);
openfunc = lua_pushfstring(L, LUA_POF "%s", openfunc);
stat = lookforfunc(L, filename, openfunc);
if (stat != ERRFUNC)
return stat;
modname = mark + 1; /* else go ahead and try old-style name */
}
openfunc = lua_pushfstring(L, LUA_POF "%s", modname);
return lookforfunc(L, filename, openfunc);
}
static int searcher_C(lua_State *L)
{
const char *name = luaL_checkstring(L, 1);
const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP);
if (filename == NULL)
return 1; /* module not found in this path */
return checkload(L, (loadfunc(L, filename, name) == 0), filename);
}
static int searcher_Croot(lua_State *L)
{
const char *filename;
const char *name = luaL_checkstring(L, 1);
const char *p = strchr(name, '.');
int stat;
if (p == NULL)
return 0; /* is root */
lua_pushlstring(L, name, p - name);
filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
if (filename == NULL)
return 1; /* root not found */
if ((stat = loadfunc(L, filename, name)) != 0)
{
if (stat != ERRFUNC)
return checkload(L, 0, filename); /* real error */
else
{ /* open function not found */
lua_pushfstring(L, "\n\tno module '%s' in file '%s'", name, filename);
return 1;
}
}
lua_pushstring(L, filename); /* will be 2nd argument to module */
return 2;
}
static int searcher_preload(lua_State *L)
{
const char *name = luaL_checkstring(L, 1);
lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
if (lua_getfield(L, -1, name) == LUA_TNIL) /* not found? */
lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
return 1;
}
static void findloader(lua_State *L, const char *name)
{
int i;
luaL_Buffer msg; /* to build error message */
luaL_buffinit(L, &msg);
/* push 'package.searchers' to index 3 in the stack */
if (lua_getfield(L, lua_upvalueindex(1), "searchers") != LUA_TTABLE)
luaL_error(L, "'package.searchers' must be a table");
/* iterate over available searchers to find a loader */
for (i = 1;; i++)
{
if (lua_rawgeti(L, 3, i) == LUA_TNIL)
{ /* no more searchers? */
lua_pop(L, 1); /* remove nil */
luaL_pushresult(&msg); /* create error message */
luaL_error(L, "module '%s' not found:%s", name, lua_tostring(L, -1));
}
lua_pushstring(L, name);
lua_call(L, 1, 2); /* call it */
if (lua_isfunction(L, -2)) /* did it find a loader? */
return; /* module loader found */
else if (lua_isstring(L, -2))
{ /* searcher returned error message? */
lua_pop(L, 1); /* remove extra return */
luaL_addvalue(&msg); /* concatenate error message */
}
else
lua_pop(L, 2); /* remove both returns */
}
}
static int ll_require(lua_State *L)
{
const char *name = luaL_checkstring(L, 1);
lua_settop(L, 1); /* LOADED table will be at index 2 */
lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
lua_getfield(L, 2, name); /* LOADED[name] */
if (lua_toboolean(L, -1)) /* is it there? */
return 1; /* package is already loaded */
/* else must load package */
lua_pop(L, 1); /* remove 'getfield' result */
findloader(L, name);
lua_pushstring(L, name); /* pass name as argument to module loader */
lua_insert(L, -2); /* name is 1st argument (before search data) */
lua_call(L, 2, 1); /* run loader to load module */
if (!lua_isnil(L, -1)) /* non-nil return? */
lua_setfield(L, 2, name); /* LOADED[name] = returned value */
if (lua_getfield(L, 2, name) == LUA_TNIL)
{ /* module set no value? */
lua_pushboolean(L, 1); /* use true as result */
lua_pushvalue(L, -1); /* extra copy to be returned */
lua_setfield(L, 2, name); /* LOADED[name] = true */
}
return 1;
}
/* }====================================================== */
/*
** {======================================================
** 'module' function
** =======================================================
*/
#if defined(LUA_COMPAT_MODULE)
/*
** changes the environment variable of calling function
*/
static void set_env(lua_State *L)
{
lua_Debug ar;
if (lua_getstack(L, 1, &ar) == 0 ||
lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
lua_iscfunction(L, -1))
luaL_error(L, "'module' not called from a Lua function");
lua_pushvalue(L, -2); /* copy new environment table to top */
lua_setupvalue(L, -2, 1);
lua_pop(L, 1); /* remove function */
}
static void dooptions(lua_State *L, int n)
{
int i;
for (i = 2; i <= n; i++)
{
if (lua_isfunction(L, i))
{ /* avoid 'calling' extra info. */
lua_pushvalue(L, i); /* get option (a function) */
lua_pushvalue(L, -2); /* module */
lua_call(L, 1, 0);
}
}
}
static void modinit(lua_State *L, const char *modname)
{
const char *dot;
lua_pushvalue(L, -1);
lua_setfield(L, -2, "_M"); /* module._M = module */
lua_pushstring(L, modname);
lua_setfield(L, -2, "_NAME");
dot = strrchr(modname, '.'); /* look for last dot in module name */
if (dot == NULL)
dot = modname;
else
dot++;
/* set _PACKAGE as package name (full module name minus last part) */
lua_pushlstring(L, modname, dot - modname);
lua_setfield(L, -2, "_PACKAGE");
}
static int ll_module(lua_State *L)
{
const char *modname = luaL_checkstring(L, 1);
int lastarg = lua_gettop(L); /* last parameter */
luaL_pushmodule(L, modname, 1); /* get/create module table */
/* check whether table already has a _NAME field */
if (lua_getfield(L, -1, "_NAME") != LUA_TNIL)
lua_pop(L, 1); /* table is an initialized module */
else
{ /* no; initialize it */
lua_pop(L, 1);
modinit(L, modname);
}
lua_pushvalue(L, -1);
set_env(L);
dooptions(L, lastarg);
return 1;
}
static int ll_seeall(lua_State *L)
{
luaL_checktype(L, 1, LUA_TTABLE);
if (!lua_getmetatable(L, 1))
{
lua_createtable(L, 0, 1); /* create new metatable */
lua_pushvalue(L, -1);
lua_setmetatable(L, 1);
}
lua_pushglobaltable(L);
lua_setfield(L, -2, "__index"); /* mt.__index = _G */
return 0;
}
#endif
/* }====================================================== */
static const luaL_Reg pk_funcs[] = {
{"loadlib", ll_loadlib},
{"searchpath", ll_searchpath},
#if defined(LUA_COMPAT_MODULE)
{"seeall", ll_seeall},
#endif
/* placeholders */
{"preload", NULL},
{"cpath", NULL},
{"path", NULL},
{"searchers", NULL},
{"loaded", NULL},
{NULL, NULL}};
static const luaL_Reg ll_funcs[] = {
#if defined(LUA_COMPAT_MODULE)
{"module", ll_module},
#endif
{"require", ll_require},
{NULL, NULL}};
static void createsearcherstable(lua_State *L)
{
static const lua_CFunction searchers[] =
{searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL};
int i;
/* create 'searchers' table */
lua_createtable(L, sizeof(searchers) / sizeof(searchers[0]) - 1, 0);
/* fill it with predefined searchers */
for (i = 0; searchers[i] != NULL; i++)
{
lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */
lua_pushcclosure(L, searchers[i], 1);
lua_rawseti(L, -2, i + 1);
}
#if defined(LUA_COMPAT_LOADERS)
lua_pushvalue(L, -1); /* make a copy of 'searchers' table */
lua_setfield(L, -3, "loaders"); /* put it in field 'loaders' */
#endif
lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */
}
/*
** create table CLIBS to keep track of loaded C libraries,
** setting a finalizer to close all libraries when closing state.
*/
static void createclibstable(lua_State *L)
{
lua_newtable(L); /* create CLIBS table */
lua_createtable(L, 0, 1); /* create metatable for CLIBS */
lua_pushcfunction(L, gctm);
lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */
lua_setmetatable(L, -2);
lua_rawsetp(L, LUA_REGISTRYINDEX, &CLIBS); /* set CLIBS table in registry */
}
LUAMOD_API int luaopen_package(lua_State *L)
{
createclibstable(L);
luaL_newlib(L, pk_funcs); /* create 'package' table */
createsearcherstable(L);
/* set paths */
setpath(L, "path", LUA_PATH_VAR, LUA_PATH_DEFAULT);
setpath(L, "cpath", LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
/* store config information */
lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
lua_setfield(L, -2, "config");
/* set field 'loaded' */
luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
lua_setfield(L, -2, "loaded");
/* set field 'preload' */
luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
lua_setfield(L, -2, "preload");
lua_pushglobaltable(L);
lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */
luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */
lua_pop(L, 1); /* pop global table */
return 1; /* return 'package' table */
}

View File

@ -1,629 +0,0 @@
/*
** $Id: lobject.c,v 2.113.1.1 2017/04/19 17:29:57 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
#define lobject_c
#define LUA_CORE
#include "lprefix.h"
#include <locale.h>
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lua.h"
#include "lctype.h"
#include "ldebug.h"
#include "ldo.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "lvm.h"
LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
/*
** converts an integer to a "floating point byte", represented as
** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
** eeeee != 0 and (xxx) otherwise.
*/
int luaO_int2fb(unsigned int x)
{
int e = 0; /* exponent */
if (x < 8)
return x;
while (x >= (8 << 4))
{ /* coarse steps */
x = (x + 0xf) >> 4; /* x = ceil(x / 16) */
e += 4;
}
while (x >= (8 << 1))
{ /* fine steps */
x = (x + 1) >> 1; /* x = ceil(x / 2) */
e++;
}
return ((e + 1) << 3) | (cast_int(x) - 8);
}
/* converts back */
int luaO_fb2int(int x)
{
return (x < 8) ? x : ((x & 7) + 8) << ((x >> 3) - 1);
}
/*
** Computes ceil(log2(x))
*/
int luaO_ceillog2(unsigned int x)
{
static const lu_byte log_2[256] = {/* log_2[i] = ceil(log2(i - 1)) */
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 = 0;
x--;
while (x >= 256)
{
l += 8;
x >>= 8;
}
return l + log_2[x];
}
static lua_Integer intarith(lua_State *L, int op, lua_Integer v1,
lua_Integer v2)
{
switch (op)
{
case LUA_OPADD:
return intop(+, v1, v2);
case LUA_OPSUB:
return intop(-, v1, v2);
case LUA_OPMUL:
return intop(*, v1, v2);
case LUA_OPMOD:
return luaV_mod(L, v1, v2);
case LUA_OPIDIV:
return luaV_div(L, v1, v2);
case LUA_OPBAND:
return intop(&, v1, v2);
case LUA_OPBOR:
return intop(|, v1, v2);
case LUA_OPBXOR:
return intop (^, v1, v2);
case LUA_OPSHL:
return luaV_shiftl(v1, v2);
case LUA_OPSHR:
return luaV_shiftl(v1, -v2);
case LUA_OPUNM:
return intop(-, 0, v1);
case LUA_OPBNOT:
return intop (^, ~l_castS2U(0), v1);
default:
lua_assert(0);
return 0;
}
}
static lua_Number numarith(lua_State *L, int op, lua_Number v1,
lua_Number v2)
{
switch (op)
{
case LUA_OPADD:
return luai_numadd(L, v1, v2);
case LUA_OPSUB:
return luai_numsub(L, v1, v2);
case LUA_OPMUL:
return luai_nummul(L, v1, v2);
case LUA_OPDIV:
return luai_numdiv(L, v1, v2);
case LUA_OPPOW:
return luai_numpow(L, v1, v2);
case LUA_OPIDIV:
return luai_numidiv(L, v1, v2);
case LUA_OPUNM:
return luai_numunm(L, v1);
case LUA_OPMOD:
{
lua_Number m;
luai_nummod(L, v1, v2, m);
return m;
}
default:
lua_assert(0);
return 0;
}
}
void luaO_arith(lua_State *L, int op, const TValue *p1, const TValue *p2,
TValue *res)
{
switch (op)
{
case LUA_OPBAND:
case LUA_OPBOR:
case LUA_OPBXOR:
case LUA_OPSHL:
case LUA_OPSHR:
case LUA_OPBNOT:
{ /* operate only on integers */
lua_Integer i1;
lua_Integer i2;
if (tointeger(p1, &i1) && tointeger(p2, &i2))
{
setivalue(res, intarith(L, op, i1, i2));
return;
}
else
break; /* go to the end */
}
case LUA_OPDIV:
case LUA_OPPOW:
{ /* operate only on floats */
lua_Number n1;
lua_Number n2;
if (tonumber(p1, &n1) && tonumber(p2, &n2))
{
setfltvalue(res, numarith(L, op, n1, n2));
return;
}
else
break; /* go to the end */
}
default:
{ /* other operations */
lua_Number n1;
lua_Number n2;
if (ttisinteger(p1) && ttisinteger(p2))
{
setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2)));
return;
}
else if (tonumber(p1, &n1) && tonumber(p2, &n2))
{
setfltvalue(res, numarith(L, op, n1, n2));
return;
}
else
break; /* go to the end */
}
}
/* could not perform raw operation; try metamethod */
lua_assert(L != NULL); /* should not fail when folding (compile time) */
luaT_trybinTM(L, p1, p2, res, cast(TMS, (op - LUA_OPADD) + TM_ADD));
}
int luaO_hexavalue(int c)
{
if (lisdigit(c))
return c - '0';
else
return (ltolower(c) - 'a') + 10;
}
static int isneg(const char **s)
{
if (**s == '-')
{
(*s)++;
return 1;
}
else if (**s == '+')
(*s)++;
return 0;
}
/*
** {==================================================================
** Lua's implementation for 'lua_strx2number'
** ===================================================================
*/
#if !defined(lua_strx2number)
/* maximum number of significant digits to read (to avoid overflows
even with single floats) */
#define MAXSIGDIG 30
/*
** convert an hexadecimal numeric string to a number, following
** C99 specification for 'strtod'
*/
static lua_Number lua_strx2number(const char *s, char **endptr)
{
int dot = lua_getlocaledecpoint();
lua_Number r = 0.0; /* result (accumulator) */
int sigdig = 0; /* number of significant digits */
int nosigdig = 0; /* number of non-significant digits */
int e = 0; /* exponent correction */
int neg; /* 1 if number is negative */
int hasdot = 0; /* true after seen a dot */
*endptr = cast(char *, s); /* nothing is valid yet */
while (lisspace(cast_uchar(*s)))
s++; /* skip initial spaces */
neg = isneg(&s); /* check signal */
if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
return 0.0; /* invalid format (no '0x') */
for (s += 2;; s++)
{ /* skip '0x' and read numeral */
if (*s == dot)
{
if (hasdot)
break; /* second dot? stop loop */
else
hasdot = 1;
}
else if (lisxdigit(cast_uchar(*s)))
{
if (sigdig == 0 && *s == '0') /* non-significant digit (zero)? */
nosigdig++;
else if (++sigdig <= MAXSIGDIG) /* can read it without overflow? */
r = (r * cast_num(16.0)) + luaO_hexavalue(*s);
else
e++; /* too many digits; ignore, but still count for exponent */
if (hasdot)
e--; /* decimal digit? correct exponent */
}
else
break; /* neither a dot nor a digit */
}
if (nosigdig + sigdig == 0) /* no digits? */
return 0.0; /* invalid format */
*endptr = cast(char *, s); /* valid up to here */
e *= 4; /* each digit multiplies/divides value by 2^4 */
if (*s == 'p' || *s == 'P')
{ /* exponent part? */
int exp1 = 0; /* exponent value */
int neg1; /* exponent signal */
s++; /* skip 'p' */
neg1 = isneg(&s); /* signal */
if (!lisdigit(cast_uchar(*s)))
return 0.0; /* invalid; must have at least one digit */
while (lisdigit(cast_uchar(*s))) /* read exponent */
exp1 = exp1 * 10 + *(s++) - '0';
if (neg1)
exp1 = -exp1;
e += exp1;
*endptr = cast(char *, s); /* valid up to here */
}
if (neg)
r = -r;
return l_mathop(ldexp)(r, e);
}
#endif
/* }====================================================== */
/* maximum length of a numeral */
#if !defined(L_MAXLENNUM)
#define L_MAXLENNUM 200
#endif
static const char *l_str2dloc(const char *s, lua_Number *result, int mode)
{
char *endptr;
*result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */
: lua_str2number(s, &endptr);
if (endptr == s)
return NULL; /* nothing recognized? */
while (lisspace(cast_uchar(*endptr)))
endptr++; /* skip trailing spaces */
return (*endptr == '\0') ? endptr : NULL; /* OK if no trailing characters */
}
/*
** Convert string 's' to a Lua number (put in 'result'). Return NULL
** on fail or the address of the ending '\0' on success.
** 'pmode' points to (and 'mode' contains) special things in the string:
** - 'x'/'X' means an hexadecimal numeral
** - 'n'/'N' means 'inf' or 'nan' (which should be rejected)
** - '.' just optimizes the search for the common case (nothing special)
** This function accepts both the current locale or a dot as the radix
** mark. If the convertion fails, it may mean number has a dot but
** locale accepts something else. In that case, the code copies 's'
** to a buffer (because 's' is read-only), changes the dot to the
** current locale radix mark, and tries to convert again.
*/
static const char *l_str2d(const char *s, lua_Number *result)
{
const char *endptr;
const char *pmode = strpbrk(s, ".xXnN");
int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0;
if (mode == 'n') /* reject 'inf' and 'nan' */
return NULL;
endptr = l_str2dloc(s, result, mode); /* try to convert */
if (endptr == NULL)
{ /* failed? may be a different locale */
char buff[L_MAXLENNUM + 1];
const char *pdot = strchr(s, '.');
if (strlen(s) > L_MAXLENNUM || pdot == NULL)
return NULL; /* string too long or no dot; fail */
strcpy(buff, s); /* copy string to buffer */
buff[pdot - s] = lua_getlocaledecpoint(); /* correct decimal point */
endptr = l_str2dloc(buff, result, mode); /* try again */
if (endptr != NULL)
endptr = s + (endptr - buff); /* make relative to 's' */
}
return endptr;
}
#define MAXBY10 cast(lua_Unsigned, LUA_MAXINTEGER / 10)
#define MAXLASTD cast_int(LUA_MAXINTEGER % 10)
static const char *l_str2int(const char *s, lua_Integer *result)
{
lua_Unsigned a = 0;
int empty = 1;
int neg;
while (lisspace(cast_uchar(*s)))
s++; /* skip initial spaces */
neg = isneg(&s);
if (s[0] == '0' &&
(s[1] == 'x' || s[1] == 'X'))
{ /* hex? */
s += 2; /* skip '0x' */
for (; lisxdigit(cast_uchar(*s)); s++)
{
a = a * 16 + luaO_hexavalue(*s);
empty = 0;
}
}
else
{ /* decimal */
for (; lisdigit(cast_uchar(*s)); s++)
{
int d = *s - '0';
if (a >= MAXBY10 && (a > MAXBY10 || d > MAXLASTD + neg)) /* overflow? */
return NULL; /* do not accept it (as integer) */
a = a * 10 + d;
empty = 0;
}
}
while (lisspace(cast_uchar(*s)))
s++; /* skip trailing spaces */
if (empty || *s != '\0')
return NULL; /* something wrong in the numeral */
else
{
*result = l_castU2S((neg) ? 0u - a : a);
return s;
}
}
size_t luaO_str2num(const char *s, TValue *o)
{
lua_Integer i;
lua_Number n;
const char *e;
if ((e = l_str2int(s, &i)) != NULL)
{ /* try as an integer */
setivalue(o, i);
}
else if ((e = l_str2d(s, &n)) != NULL)
{ /* else try as a float */
setfltvalue(o, n);
}
else
return 0; /* conversion failed */
return (e - s) + 1; /* success; return string size */
}
int luaO_utf8esc(char *buff, unsigned long x)
{
int n = 1; /* number of bytes put in buffer (backwards) */
lua_assert(x <= 0x10FFFF);
if (x < 0x80) /* ascii? */
buff[UTF8BUFFSZ - 1] = cast(char, x);
else
{ /* need continuation bytes */
unsigned int mfb = 0x3f; /* maximum that fits in first byte */
do
{ /* add continuation bytes */
buff[UTF8BUFFSZ - (n++)] = cast(char, 0x80 | (x & 0x3f));
x >>= 6; /* remove added bits */
mfb >>= 1; /* now there is one less bit available in first byte */
} while (x > mfb); /* still needs continuation byte? */
buff[UTF8BUFFSZ - n] = cast(char, (~mfb << 1) | x); /* add first byte */
}
return n;
}
/* maximum length of the conversion of a number to a string */
#define MAXNUMBER2STR 50
/*
** Convert a number object to a string
*/
void luaO_tostring(lua_State *L, StkId obj)
{
char buff[MAXNUMBER2STR];
size_t len;
lua_assert(ttisnumber(obj));
if (ttisinteger(obj))
len = lua_integer2str(buff, sizeof(buff), ivalue(obj));
else
{
len = lua_number2str(buff, sizeof(buff), fltvalue(obj));
#if !defined(LUA_COMPAT_FLOATSTRING)
if (buff[strspn(buff, "-0123456789")] == '\0')
{ /* looks like an int? */
buff[len++] = lua_getlocaledecpoint();
buff[len++] = '0'; /* adds '.0' to result */
}
#endif
}
setsvalue2s(L, obj, luaS_newlstr(L, buff, len));
}
static void pushstr(lua_State *L, const char *str, size_t l)
{
setsvalue2s(L, L->top, luaS_newlstr(L, str, l));
luaD_inctop(L);
}
/*
** this function handles only '%d', '%c', '%f', '%p', and '%s'
conventional formats, plus Lua-specific '%I' and '%U'
*/
const char *luaO_pushvfstring(lua_State *L, const char *fmt, va_list argp)
{
int n = 0;
for (;;)
{
const char *e = strchr(fmt, '%');
if (e == NULL)
break;
pushstr(L, fmt, e - fmt);
switch (*(e + 1))
{
case 's':
{ /* zero-terminated string */
const char *s = va_arg(argp, char *);
if (s == NULL)
s = "(null)";
pushstr(L, s, strlen(s));
break;
}
case 'c':
{ /* an 'int' as a character */
char buff = cast(char, va_arg(argp, int));
if (lisprint(cast_uchar(buff)))
pushstr(L, &buff, 1);
else /* non-printable character; print its code */
luaO_pushfstring(L, "<\\%d>", cast_uchar(buff));
break;
}
case 'd':
{ /* an 'int' */
setivalue(L->top, va_arg(argp, int));
goto top2str;
}
case 'I':
{ /* a 'lua_Integer' */
setivalue(L->top, cast(lua_Integer, va_arg(argp, l_uacInt)));
goto top2str;
}
case 'f':
{ /* a 'lua_Number' */
setfltvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
top2str: /* convert the top element to a string */
luaD_inctop(L);
luaO_tostring(L, L->top - 1);
break;
}
case 'p':
{ /* a pointer */
char buff[4 * sizeof(void *) + 8]; /* should be enough space for a '%p' */
void *p = va_arg(argp, void *);
int l = lua_pointer2str(buff, sizeof(buff), p);
pushstr(L, buff, l);
break;
}
case 'U':
{ /* an 'int' as a UTF-8 sequence */
char buff[UTF8BUFFSZ];
int l = luaO_utf8esc(buff, cast(long, va_arg(argp, long)));
pushstr(L, buff + UTF8BUFFSZ - l, l);
break;
}
case '%':
{
pushstr(L, "%", 1);
break;
}
default:
{
luaG_runerror(L, "invalid option '%%%c' to 'lua_pushfstring'",
*(e + 1));
}
}
n += 2;
fmt = e + 2;
}
luaD_checkstack(L, 1);
pushstr(L, fmt, strlen(fmt));
if (n > 0)
luaV_concat(L, n + 1);
return svalue(L->top - 1);
}
const char *luaO_pushfstring(lua_State *L, const char *fmt, ...)
{
const char *msg;
va_list argp;
va_start(argp, fmt);
msg = luaO_pushvfstring(L, fmt, argp);
va_end(argp);
printf("%s", msg);
return msg;
}
/* number of chars of a literal string without the ending \0 */
#define LL(x) (sizeof(x) / sizeof(char) - 1)
#define RETS "..."
#define PRE "[string \""
#define POS "\"]"
#define addstr(a, b, l) (memcpy(a, b, (l) * sizeof(char)), a += (l))
void luaO_chunkid(char *out, const char *source, size_t bufflen)
{
size_t l = strlen(source);
if (*source == '=')
{ /* 'literal' source */
if (l <= bufflen) /* small enough? */
memcpy(out, source + 1, l * sizeof(char));
else
{ /* truncate it */
addstr(out, source + 1, bufflen - 1);
*out = '\0';
}
}
else if (*source == '@')
{ /* file name */
if (l <= bufflen) /* small enough? */
memcpy(out, source + 1, l * sizeof(char));
else
{ /* add '...' before rest of name */
addstr(out, RETS, LL(RETS));
bufflen -= LL(RETS);
memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char));
}
}
else
{ /* string; format as [string "source"] */
const char *nl = strchr(source, '\n'); /* find first new line (if any) */
addstr(out, PRE, LL(PRE)); /* add prefix */
bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */
if (l < bufflen && nl == NULL)
{ /* small one-line source? */
addstr(out, source, l); /* keep it */
}
else
{
if (nl != NULL)
l = nl - source; /* stop at first newline */
if (l > bufflen)
l = bufflen;
addstr(out, source, l);
addstr(out, RETS, LL(RETS));
}
memcpy(out, POS, (LL(POS) + 1) * sizeof(char));
}
}

View File

@ -1,578 +0,0 @@
/*
** $Id: lobject.h,v 2.117.1.1 2017/04/19 17:39:34 roberto Exp $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
#ifndef lobject_h
#define lobject_h
#include <stdarg.h>
#include "llimits.h"
#include "lua.h"
/*
** Extra tags for non-values
*/
#define LUA_TPROTO LUA_NUMTAGS /* function prototypes */
#define LUA_TDEADKEY (LUA_NUMTAGS + 1) /* removed keys in tables */
/*
** number of all possible tags (including LUA_TNONE but excluding DEADKEY)
*/
#define LUA_TOTALTAGS (LUA_TPROTO + 2)
/*
** tags for Tagged Values have the following use of bits:
** bits 0-3: actual tag (a LUA_T* value)
** bits 4-5: variant bits
** bit 6: whether value is collectable
*/
/*
** LUA_TFUNCTION variants:
** 0 - Lua function
** 1 - light C function
** 2 - regular C function (closure)
*/
/* Variant tags for functions */
#define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */
#define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */
#define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */
/* Variant tags for strings */
#define LUA_TSHRSTR (LUA_TSTRING | (0 << 4)) /* short strings */
#define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */
/* Variant tags for numbers */
#define LUA_TNUMFLT (LUA_TNUMBER | (0 << 4)) /* float numbers */
#define LUA_TNUMINT (LUA_TNUMBER | (1 << 4)) /* integer numbers */
/* Bit mark for collectable types */
#define BIT_ISCOLLECTABLE (1 << 6)
/* mark a tag as collectable */
#define ctb(t) ((t) | BIT_ISCOLLECTABLE)
/*
** Common type for all collectable objects
*/
typedef struct 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 type has only the common header
*/
struct GCObject
{
CommonHeader;
};
/*
** Tagged Values. This is the basic representation of values in Lua,
** an actual value plus a tag with its type.
*/
/*
** Union of all Lua values
*/
typedef union Value {
GCObject *gc; /* collectable objects */
void *p; /* light userdata */
int b; /* booleans */
lua_CFunction f; /* light C functions */
lua_Integer i; /* integer numbers */
lua_Number n; /* float numbers */
} Value;
#define TValuefields \
Value value_; \
int tt_
typedef struct lua_TValue
{
TValuefields;
} TValue;
/* macro defining a nil value */
#define NILCONSTANT {NULL}, LUA_TNIL
#define val_(o) ((o)->value_)
/* raw type tag of a TValue */
#define rttype(o) ((o)->tt_)
/* tag with no variants (bits 0-3) */
#define novariant(x) ((x)&0x0F)
/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
#define ttype(o) (rttype(o) & 0x3F)
/* type tag of a TValue with no variants (bits 0-3) */
#define ttnov(o) (novariant(rttype(o)))
/* Macros to test type */
#define checktag(o, t) (rttype(o) == (t))
#define checktype(o, t) (ttnov(o) == (t))
#define ttisnumber(o) checktype((o), LUA_TNUMBER)
#define ttisfloat(o) checktag((o), LUA_TNUMFLT)
#define ttisinteger(o) checktag((o), LUA_TNUMINT)
#define ttisnil(o) checktag((o), LUA_TNIL)
#define ttisboolean(o) checktag((o), LUA_TBOOLEAN)
#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA)
#define ttisstring(o) checktype((o), LUA_TSTRING)
#define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR))
#define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR))
#define ttistable(o) checktag((o), ctb(LUA_TTABLE))
#define ttisfunction(o) checktype(o, LUA_TFUNCTION)
#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION)
#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL))
#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL))
#define ttislcf(o) checktag((o), LUA_TLCF)
#define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA))
#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))
#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY)
/* Macros to access values */
#define ivalue(o) check_exp(ttisinteger(o), val_(o).i)
#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n)
#define nvalue(o) check_exp(ttisnumber(o), \
(ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o)))
#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
#define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc))
#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc))
#define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc))
#define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc))
#define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc))
#define fvalue(o) check_exp(ttislcf(o), val_(o).f)
#define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc))
#define bvalue(o) check_exp(ttisboolean(o), val_(o).b)
#define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc))
/* a dead value may get the 'gc' field, but cannot access its contents */
#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))
#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE)
/* Macros for internal tests */
#define righttt(obj) (ttype(obj) == gcvalue(obj)->tt)
#define checkliveness(L, obj) \
lua_longassert(!iscollectable(obj) || \
(righttt(obj) && (L == NULL || !isdead(G(L), gcvalue(obj)))))
/* Macros to set values */
#define settt_(o, t) ((o)->tt_ = (t))
#define setfltvalue(obj, x) \
{ \
TValue *io = (obj); \
val_(io).n = (x); \
settt_(io, LUA_TNUMFLT); \
}
#define chgfltvalue(obj, x) \
{ \
TValue *io = (obj); \
lua_assert(ttisfloat(io)); \
val_(io).n = (x); \
}
#define setivalue(obj, x) \
{ \
TValue *io = (obj); \
val_(io).i = (x); \
settt_(io, LUA_TNUMINT); \
}
#define chgivalue(obj, x) \
{ \
TValue *io = (obj); \
lua_assert(ttisinteger(io)); \
val_(io).i = (x); \
}
#define setnilvalue(obj) settt_(obj, LUA_TNIL)
#define setfvalue(obj, x) \
{ \
TValue *io = (obj); \
val_(io).f = (x); \
settt_(io, LUA_TLCF); \
}
#define setpvalue(obj, x) \
{ \
TValue *io = (obj); \
val_(io).p = (x); \
settt_(io, LUA_TLIGHTUSERDATA); \
}
#define setbvalue(obj, x) \
{ \
TValue *io = (obj); \
val_(io).b = (x); \
settt_(io, LUA_TBOOLEAN); \
}
#define setgcovalue(L, obj, x) \
{ \
TValue *io = (obj); \
GCObject *i_g = (x); \
val_(io).gc = i_g; \
settt_(io, ctb(i_g->tt)); \
}
#define setsvalue(L, obj, x) \
{ \
TValue *io = (obj); \
TString *x_ = (x); \
val_(io).gc = obj2gco(x_); \
settt_(io, ctb(x_->tt)); \
checkliveness(L, io); \
}
#define setuvalue(L, obj, x) \
{ \
TValue *io = (obj); \
Udata *x_ = (x); \
val_(io).gc = obj2gco(x_); \
settt_(io, ctb(LUA_TUSERDATA)); \
checkliveness(L, io); \
}
#define setthvalue(L, obj, x) \
{ \
TValue *io = (obj); \
lua_State *x_ = (x); \
val_(io).gc = obj2gco(x_); \
settt_(io, ctb(LUA_TTHREAD)); \
checkliveness(L, io); \
}
#define setclLvalue(L, obj, x) \
{ \
TValue *io = (obj); \
LClosure *x_ = (x); \
val_(io).gc = obj2gco(x_); \
settt_(io, ctb(LUA_TLCL)); \
checkliveness(L, io); \
}
#define setclCvalue(L, obj, x) \
{ \
TValue *io = (obj); \
CClosure *x_ = (x); \
val_(io).gc = obj2gco(x_); \
settt_(io, ctb(LUA_TCCL)); \
checkliveness(L, io); \
}
#define sethvalue(L, obj, x) \
{ \
TValue *io = (obj); \
Table *x_ = (x); \
val_(io).gc = obj2gco(x_); \
settt_(io, ctb(LUA_TTABLE)); \
checkliveness(L, io); \
}
#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY)
#define setobj(L, obj1, obj2) \
{ \
TValue *io1 = (obj1); \
*io1 = *(obj2); \
(void)L; \
checkliveness(L, io1); \
}
/*
** different types of assignments, according to destination
*/
/* from stack to (same) stack */
#define setobjs2s setobj
/* to stack (not from same stack) */
#define setobj2s setobj
#define setsvalue2s setsvalue
#define sethvalue2s sethvalue
#define setptvalue2s setptvalue
/* from table to same table */
#define setobjt2t setobj
/* to new object */
#define setobj2n setobj
#define setsvalue2n setsvalue
/* to table (define it as an expression to be used in macros) */
#define setobj2t(L, o1, o2) ((void)L, *(o1) = *(o2), checkliveness(L, (o1)))
/*
** {======================================================
** types and prototypes
** =======================================================
*/
typedef TValue *StkId; /* index to stack elements */
/*
** Header for string value; string bytes follow the end of this structure
** (aligned according to 'UTString'; see next).
*/
typedef struct TString
{
CommonHeader;
lu_byte extra; /* reserved words for short strings; "has hash" for longs */
lu_byte shrlen; /* length for short strings */
unsigned int hash;
union {
size_t lnglen; /* length for long strings */
struct TString *hnext; /* linked list for hash table */
} u;
} TString;
/*
** Ensures that address after this type is always fully aligned.
*/
typedef union UTString {
L_Umaxalign dummy; /* ensures maximum alignment for strings */
TString tsv;
} UTString;
/*
** Get the actual string (array of bytes) from a 'TString'.
** (Access to 'extra' ensures that value is really a 'TString'.)
*/
#define getstr(ts) \
check_exp(sizeof((ts)->extra), cast(char *, (ts)) + sizeof(UTString))
/* get the actual string (array of bytes) from a Lua value */
#define svalue(o) getstr(tsvalue(o))
/* get string length from 'TString *s' */
#define tsslen(s) ((s)->tt == LUA_TSHRSTR ? (s)->shrlen : (s)->u.lnglen)
/* get string length from 'TValue *o' */
#define vslen(o) tsslen(tsvalue(o))
/*
** Header for userdata; memory area follows the end of this structure
** (aligned according to 'UUdata'; see next).
*/
typedef struct Udata
{
CommonHeader;
lu_byte ttuv_; /* user value's tag */
struct Table *metatable;
size_t len; /* number of bytes */
union Value user_; /* user value */
} Udata;
/*
** Ensures that address after this type is always fully aligned.
*/
typedef union UUdata {
L_Umaxalign dummy; /* ensures maximum alignment for 'local' udata */
Udata uv;
} UUdata;
/*
** Get the address of memory block inside 'Udata'.
** (Access to 'ttuv_' ensures that value is really a 'Udata'.)
*/
#define getudatamem(u) \
check_exp(sizeof((u)->ttuv_), (cast(char *, (u)) + sizeof(UUdata)))
#define setuservalue(L, u, o) \
{ \
const TValue *io = (o); \
Udata *iu = (u); \
iu->user_ = io->value_; \
iu->ttuv_ = rttype(io); \
checkliveness(L, io); \
}
#define getuservalue(L, u, o) \
{ \
TValue *io = (o); \
const Udata *iu = (u); \
io->value_ = iu->user_; \
settt_(io, iu->ttuv_); \
checkliveness(L, io); \
}
/*
** Description of an upvalue for function prototypes
*/
typedef struct Upvaldesc
{
TString *name; /* upvalue name (for debug information) */
lu_byte instack; /* whether it is in stack (register) */
lu_byte idx; /* index of upvalue (in stack or in outer function's list) */
} Upvaldesc;
/*
** Description of a local variable for function prototypes
** (used for debug information)
*/
typedef struct LocVar
{
TString *varname;
int startpc; /* first point where variable is active */
int endpc; /* first point where variable is dead */
} LocVar;
/*
** Function Prototypes
*/
typedef struct Proto
{
CommonHeader;
lu_byte numparams; /* number of fixed parameters */
lu_byte is_vararg;
lu_byte maxstacksize; /* number of registers needed by this function */
int sizeupvalues; /* size of 'upvalues' */
int sizek; /* size of 'k' */
int sizecode;
int sizelineinfo;
int sizep; /* size of 'p' */
int sizelocvars;
int linedefined; /* debug information */
int lastlinedefined; /* debug information */
TValue *k; /* constants used by the function */
Instruction *code; /* opcodes */
struct Proto **p; /* functions defined inside the function */
int *lineinfo; /* map from opcodes to source lines (debug information) */
LocVar *locvars; /* information about local variables (debug information) */
Upvaldesc *upvalues; /* upvalue information */
struct LClosure *cache; /* last-created closure with this prototype */
TString *source; /* used for debug information */
GCObject *gclist;
} Proto;
/*
** Lua Upvalues
*/
typedef struct UpVal UpVal;
/*
** Closures
*/
#define ClosureHeader \
CommonHeader; \
lu_byte nupvalues; \
GCObject *gclist
typedef struct CClosure
{
ClosureHeader;
lua_CFunction f;
TValue upvalue[1]; /* list of upvalues */
} CClosure;
typedef struct LClosure
{
ClosureHeader;
struct Proto *p;
UpVal *upvals[1]; /* list of upvalues */
} LClosure;
typedef union Closure {
CClosure c;
LClosure l;
} Closure;
#define isLfunction(o) ttisLclosure(o)
#define getproto(o) (clLvalue(o)->p)
/*
** Tables
*/
typedef union TKey {
struct
{
TValuefields;
int next; /* for chaining (offset for next node) */
} nk;
TValue tvk;
} TKey;
/* copy a value into a key without messing up field 'next' */
#define setnodekey(L, key, obj) \
{ \
TKey *k_ = (key); \
const TValue *io_ = (obj); \
k_->nk.value_ = io_->value_; \
k_->nk.tt_ = io_->tt_; \
(void)L; \
checkliveness(L, io_); \
}
typedef struct Node
{
TValue i_val;
TKey i_key;
} 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 */
unsigned int sizearray; /* size of 'array' array */
TValue *array; /* array part */
Node *node;
Node *lastfree; /* any free position is before this position */
struct Table *metatable;
GCObject *gclist;
} Table;
/*
** 'module' operation for hashing (size is always a power of 2)
*/
#define lmod(s, size) \
(check_exp((size & (size - 1)) == 0, (cast(int, (s) & ((size)-1)))))
#define twoto(x) (1 << (x))
#define sizenode(t) (twoto((t)->lsizenode))
/*
** (address of) a fixed nil value
*/
#define luaO_nilobject (&luaO_nilobject_)
LUAI_DDEC const TValue luaO_nilobject_;
/* size of buffer for 'luaO_utf8esc' function */
#define UTF8BUFFSZ 8
LUAI_FUNC int luaO_int2fb(unsigned int x);
LUAI_FUNC int luaO_fb2int(int x);
LUAI_FUNC int luaO_utf8esc(char *buff, unsigned long x);
LUAI_FUNC int luaO_ceillog2(unsigned int x);
LUAI_FUNC void luaO_arith(lua_State *L, int op, const TValue *p1,
const TValue *p2, TValue *res);
LUAI_FUNC size_t luaO_str2num(const char *s, TValue *o);
LUAI_FUNC int luaO_hexavalue(int c);
LUAI_FUNC void luaO_tostring(lua_State *L, StkId obj);
LUAI_FUNC const char *luaO_pushvfstring(lua_State *L, const char *fmt,
va_list argp);
LUAI_FUNC const char *luaO_pushfstring(lua_State *L, const char *fmt, ...);
LUAI_FUNC void luaO_chunkid(char *out, const char *source, size_t len);
#endif

View File

@ -1,165 +0,0 @@
/*
** $Id: lopcodes.c,v 1.55.1.1 2017/04/19 17:20:42 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
#define lopcodes_c
#define LUA_CORE
#include "lprefix.h"
#include <stddef.h>
#include "lopcodes.h"
/* ORDER OP */
LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES + 1] = {
"MOVE",
"LOADK",
"LOADKX",
"LOADBOOL",
"LOADNIL",
"GETUPVAL",
"GETTABUP",
"GETTABLE",
"SETTABUP",
"SETUPVAL",
"SETTABLE",
"NEWTABLE",
"SELF",
"ADD",
"SUB",
"MUL",
"MOD",
"POW",
"DIV",
"IDIV",
"BAND",
"BOR",
"BXOR",
"SHL",
"SHR",
"UNM",
"BNOT",
"NOT",
"LEN",
"CONCAT",
"JMP",
"EQ",
"LT",
"LE",
"TEST",
"TESTSET",
"CALL",
"TAILCALL",
"RETURN",
"FORLOOP",
"FORPREP",
"TFORCALL",
"TFORLOOP",
"SETLIST",
"CLOSURE",
"VARARG",
"EXTRAARG",
NULL};
#define opmode(t, a, b, c, m) (((t) << 7) | ((a) << 6) | ((b) << 4) | ((c) << 2) | (m))
LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
/* T A B C mode opcode */
opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
,
opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
,
opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */
,
opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
,
opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */
,
opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
,
opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */
,
opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
,
opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */
,
opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
,
opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
,
opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
,
opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
,
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
,
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
,
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
,
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
,
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
,
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
,
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */
,
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */
,
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */
,
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */
,
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHL */
,
opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHR */
,
opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
,
opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_BNOT */
,
opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
,
opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
,
opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
,
opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
,
opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
,
opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
,
opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
,
opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */
,
opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
,
opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
,
opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
,
opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
,
opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
,
opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
,
opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */
,
opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */
,
opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
,
opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
,
opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
,
opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */
};

View File

@ -1,281 +0,0 @@
/*
** $Id: lopcodes.h,v 1.149.1.1 2017/04/19 17:20:42 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
#ifndef lopcodes_h
#define lopcodes_h
#include "llimits.h"
/*===========================================================================
We assume that instructions are unsigned numbers.
All instructions have an opcode in the first 6 bits.
Instructions can have the following fields:
'A' : 8 bits
'B' : 9 bits
'C' : 9 bits
'Ax' : 26 bits ('A', 'B', and 'C' together)
'Bx' : 18 bits ('B' and 'C' together)
'sBx' : signed Bx
A signed argument is represented in excess K; that is, the number
value is the unsigned value minus K. K is exactly the maximum value
for that argument (so that -max is represented by 0, and +max is
represented by 2*max), which is half the maximum for the corresponding
unsigned argument.
===========================================================================*/
enum OpMode
{
iABC,
iABx,
iAsBx,
iAx
}; /* basic instruction format */
/*
** size and position of opcode arguments.
*/
#define SIZE_C 9
#define SIZE_B 9
#define SIZE_Bx (SIZE_C + SIZE_B)
#define SIZE_A 8
#define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A)
#define SIZE_OP 6
#define POS_OP 0
#define POS_A (POS_OP + SIZE_OP)
#define POS_C (POS_A + SIZE_A)
#define POS_B (POS_C + SIZE_C)
#define POS_Bx POS_C
#define POS_Ax POS_A
/*
** limits for opcode arguments.
** we use (signed) int to manipulate most arguments,
** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
*/
#if SIZE_Bx < LUAI_BITSINT - 1
#define MAXARG_Bx ((1 << SIZE_Bx) - 1)
#define MAXARG_sBx (MAXARG_Bx >> 1) /* 'sBx' is signed */
#else
#define MAXARG_Bx MAX_INT
#define MAXARG_sBx MAX_INT
#endif
#if SIZE_Ax < LUAI_BITSINT - 1
#define MAXARG_Ax ((1 << SIZE_Ax) - 1)
#else
#define MAXARG_Ax MAX_INT
#endif
#define MAXARG_A ((1 << SIZE_A) - 1)
#define MAXARG_B ((1 << SIZE_B) - 1)
#define MAXARG_C ((1 << SIZE_C) - 1)
/* creates a mask with 'n' 1 bits at position 'p' */
#define MASK1(n, p) ((~((~(Instruction)0) << (n))) << (p))
/* creates a mask with 'n' 0 bits at position 'p' */
#define MASK0(n, p) (~MASK1(n, p))
/*
** the following macros help to manipulate instructions
*/
#define GET_OPCODE(i) (cast(OpCode, ((i) >> POS_OP) & MASK1(SIZE_OP, 0)))
#define SET_OPCODE(i, o) ((i) = (((i)&MASK0(SIZE_OP, POS_OP)) | \
((cast(Instruction, o) << POS_OP) & MASK1(SIZE_OP, POS_OP))))
#define getarg(i, pos, size) (cast(int, ((i) >> pos) & MASK1(size, 0)))
#define setarg(i, v, pos, size) ((i) = (((i)&MASK0(size, pos)) | \
((cast(Instruction, v) << pos) & MASK1(size, pos))))
#define GETARG_A(i) getarg(i, POS_A, SIZE_A)
#define SETARG_A(i, v) setarg(i, v, POS_A, SIZE_A)
#define GETARG_B(i) getarg(i, POS_B, SIZE_B)
#define SETARG_B(i, v) setarg(i, v, POS_B, SIZE_B)
#define GETARG_C(i) getarg(i, POS_C, SIZE_C)
#define SETARG_C(i, v) setarg(i, v, POS_C, SIZE_C)
#define GETARG_Bx(i) getarg(i, POS_Bx, SIZE_Bx)
#define SETARG_Bx(i, v) setarg(i, v, POS_Bx, SIZE_Bx)
#define GETARG_Ax(i) getarg(i, POS_Ax, SIZE_Ax)
#define SETARG_Ax(i, v) setarg(i, v, POS_Ax, SIZE_Ax)
#define GETARG_sBx(i) (GETARG_Bx(i) - MAXARG_sBx)
#define SETARG_sBx(i, b) SETARG_Bx((i), cast(unsigned int, (b) + MAXARG_sBx))
#define CREATE_ABC(o, a, b, c) ((cast(Instruction, o) << POS_OP) | (cast(Instruction, a) << POS_A) | (cast(Instruction, b) << POS_B) | (cast(Instruction, c) << POS_C))
#define CREATE_ABx(o, a, bc) ((cast(Instruction, o) << POS_OP) | (cast(Instruction, a) << POS_A) | (cast(Instruction, bc) << POS_Bx))
#define CREATE_Ax(o, a) ((cast(Instruction, o) << POS_OP) | (cast(Instruction, a) << POS_Ax))
/*
** Macros to operate RK indices
*/
/* this bit 1 means constant (0 means register) */
#define BITRK (1 << (SIZE_B - 1))
/* test whether value is a constant */
#define ISK(x) ((x)&BITRK)
/* gets the index of the constant */
#define INDEXK(r) ((int)(r) & ~BITRK)
#if !defined(MAXINDEXRK) /* (for debugging only) */
#define MAXINDEXRK (BITRK - 1)
#endif
/* code a constant index as a RK value */
#define RKASK(x) ((x) | BITRK)
/*
** invalid register that fits in 8 bits
*/
#define NO_REG MAXARG_A
/*
** R(x) - register
** Kst(x) - constant (in constant table)
** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
*/
/*
** grep "ORDER OP" if you change these enums
*/
typedef enum
{
/*----------------------------------------------------------------------
name args description
------------------------------------------------------------------------*/
OP_MOVE, /* A B R(A) := R(B) */
OP_LOADK, /* A Bx R(A) := Kst(Bx) */
OP_LOADKX, /* A R(A) := Kst(extra arg) */
OP_LOADBOOL, /* A B C R(A) := (Bool)B; if (C) pc++ */
OP_LOADNIL, /* A B R(A), R(A+1), ..., R(A+B) := nil */
OP_GETUPVAL, /* A B R(A) := UpValue[B] */
OP_GETTABUP, /* A B C R(A) := UpValue[B][RK(C)] */
OP_GETTABLE, /* A B C R(A) := R(B)[RK(C)] */
OP_SETTABUP, /* A B C UpValue[A][RK(B)] := RK(C) */
OP_SETUPVAL, /* A B UpValue[B] := R(A) */
OP_SETTABLE, /* A B C R(A)[RK(B)] := RK(C) */
OP_NEWTABLE, /* A B C R(A) := {} (size = B,C) */
OP_SELF, /* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
OP_ADD, /* A B C R(A) := RK(B) + RK(C) */
OP_SUB, /* A B C R(A) := RK(B) - RK(C) */
OP_MUL, /* A B C R(A) := RK(B) * RK(C) */
OP_MOD, /* A B C R(A) := RK(B) % RK(C) */
OP_POW, /* A B C R(A) := RK(B) ^ RK(C) */
OP_DIV, /* A B C R(A) := RK(B) / RK(C) */
OP_IDIV, /* A B C R(A) := RK(B) // RK(C) */
OP_BAND, /* A B C R(A) := RK(B) & RK(C) */
OP_BOR, /* A B C R(A) := RK(B) | RK(C) */
OP_BXOR, /* A B C R(A) := RK(B) ~ RK(C) */
OP_SHL, /* A B C R(A) := RK(B) << RK(C) */
OP_SHR, /* A B C R(A) := RK(B) >> RK(C) */
OP_UNM, /* A B R(A) := -R(B) */
OP_BNOT, /* A B R(A) := ~R(B) */
OP_NOT, /* A B R(A) := not R(B) */
OP_LEN, /* A B R(A) := length of R(B) */
OP_CONCAT, /* A B C R(A) := R(B).. ... ..R(C) */
OP_JMP, /* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
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_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)) */
OP_RETURN, /* A B return R(A), ... ,R(A+B-2) (see note) */
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_TFORCALL, /* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
OP_TFORLOOP, /* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
OP_SETLIST, /* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
OP_CLOSURE, /* A Bx R(A) := closure(KPROTO[Bx]) */
OP_VARARG, /* A B R(A), R(A+1), ..., R(A+B-2) = vararg */
OP_EXTRAARG /* Ax extra (larger) argument for previous opcode */
} OpCode;
#define NUM_OPCODES (cast(int, OP_EXTRAARG) + 1)
/*===========================================================================
Notes:
(*) In OP_CALL, if (B == 0) then B = top. If (C == 0), then 'top' is
set to last_result+1, so next open instruction (OP_CALL, OP_RETURN,
OP_SETLIST) may use 'top'.
(*) In OP_VARARG, if (B == 0) then use actual number of varargs and
set top (like in OP_CALL with C == 0).
(*) In OP_RETURN, if (B == 0) then return up to 'top'.
(*) In OP_SETLIST, if (B == 0) then B = 'top'; if (C == 0) then next
'instruction' is EXTRAARG(real C).
(*) In OP_LOADKX, the next 'instruction' is always EXTRAARG.
(*) For comparisons, A specifies what condition the test should accept
(true or false).
(*) All 'skips' (pc++) assume that next instruction is a jump.
===========================================================================*/
/*
** masks for instruction properties. The format is:
** bits 0-1: op mode
** bits 2-3: C arg mode
** bits 4-5: B arg mode
** bit 6: instruction set register A
** bit 7: operator is a test (next instruction must be a jump)
*/
enum OpArgMask
{
OpArgN, /* argument is not used */
OpArgU, /* argument is used */
OpArgR, /* argument is a register or a jump offset */
OpArgK /* argument is a constant or register/constant */
};
LUAI_DDEC const lu_byte luaP_opmodes[NUM_OPCODES];
#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
#define testAMode(m) (luaP_opmodes[m] & (1 << 6))
#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES + 1]; /* opcode names */
/* number of list items to accumulate before a SETLIST instruction */
#define LFIELDS_PER_FLUSH 50
#endif

View File

@ -1,420 +0,0 @@
/*
** $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(LUA_USE_POSIX) /* { */
#include <unistd.h>
#define LUA_TMPNAMBUFSIZE 32
#if !defined(LUA_TMPNAMTEMPLATE)
#define LUA_TMPNAMTEMPLATE "/tmp/lua_XXXXXX"
#endif
#define lua_tmpnam(b, e) \
{ \
strcpy(b, LUA_TMPNAMTEMPLATE); \
e = mkstemp(b); \
if (e != -1) \
close(e); \
e = (e == -1); \
}
#else /* }{ */
/* ISO C definitions */
#define LUA_TMPNAMBUFSIZE L_tmpnam
#define lua_tmpnam(b, e) \
{ \
e = (tmpnam(b) == NULL); \
}
#endif /* } */
#endif /* } */
/* }================================================================== */
static int os_execute(lua_State *L)
{
const char *cmd = luaL_optstring(L, 1, NULL);
int stat = system(cmd);
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;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,133 +0,0 @@
/*
** $Id: lparser.h,v 1.76.1.1 2017/04/19 17:20:42 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
#ifndef lparser_h
#define lparser_h
#include "llimits.h"
#include "lobject.h"
#include "lzio.h"
/*
** Expression and variable descriptor.
** Code generation for variables and expressions can be delayed to allow
** optimizations; An 'expdesc' structure describes a potentially-delayed
** variable/expression. It has a description of its "main" value plus a
** list of conditional jumps that can also produce its value (generated
** by short-circuit operators 'and'/'or').
*/
/* kinds of variables/expressions */
typedef enum {
VVOID, /* when 'expdesc' describes the last expression a list,
this kind means an empty list (so, no expression) */
VNIL, /* constant nil */
VTRUE, /* constant true */
VFALSE, /* constant false */
VK, /* constant in 'k'; info = index of constant in 'k' */
VKFLT, /* floating constant; nval = numerical float value */
VKINT, /* integer constant; nval = numerical integer value */
VNONRELOC, /* expression has its value in a fixed register;
info = result register */
VLOCAL, /* local variable; info = local register */
VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */
VINDEXED, /* indexed variable;
ind.vt = whether 't' is register or upvalue;
ind.t = table register or upvalue;
ind.idx = key's R/K index */
VJMP, /* expression is a test/comparison;
info = pc of corresponding jump instruction */
VRELOCABLE, /* expression can put result in any register;
info = instruction pc */
VCALL, /* expression is a function call; info = instruction pc */
VVARARG /* vararg expression; info = instruction pc */
} expkind;
#define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED)
#define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL)
typedef struct expdesc {
expkind k;
union {
lua_Integer ival; /* for VKINT */
lua_Number nval; /* for VKFLT */
int info; /* for generic use */
struct { /* for indexed variables (VINDEXED) */
short idx; /* index (R/K) */
lu_byte t; /* table (register or upvalue) */
lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
} ind;
} u;
int t; /* patch list of 'exit when true' */
int f; /* patch list of 'exit when false' */
} expdesc;
/* description of active local variable */
typedef struct Vardesc {
short idx; /* variable index in stack */
} Vardesc;
/* description of pending goto statements and label statements */
typedef struct Labeldesc {
TString *name; /* label identifier */
int pc; /* position in code */
int line; /* line where it appeared */
lu_byte nactvar; /* local level where it appears in current block */
} Labeldesc;
/* list of labels or gotos */
typedef struct Labellist {
Labeldesc *arr; /* array */
int n; /* number of entries in use */
int size; /* array size */
} Labellist;
/* dynamic structures used by the parser */
typedef struct Dyndata {
struct { /* list of active local variables */
Vardesc *arr;
int n;
int size;
} actvar;
Labellist gt; /* list of pending gotos */
Labellist label; /* list of active labels */
} Dyndata;
/* control of blocks */
struct BlockCnt; /* defined in lparser.c */
/* state needed to generate code for a given function */
typedef struct FuncState {
Proto *f; /* current function header */
struct FuncState *prev; /* enclosing function */
struct LexState *ls; /* lexical state */
struct BlockCnt *bl; /* chain of current blocks */
int pc; /* next position to code (equivalent to 'ncode') */
int lasttarget; /* 'label' of last 'jump label' */
int jpc; /* list of pending jumps to 'pc' */
int nk; /* number of elements in 'k' */
int np; /* number of elements in 'p' */
int firstlocal; /* index of first local var (in Dyndata array) */
short nlocvars; /* number of elements in 'f->locvars' */
lu_byte nactvar; /* number of active local variables */
lu_byte nups; /* number of upvalues */
lu_byte freereg; /* first free register */
} FuncState;
LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
Dyndata *dyd, const char *name, int firstchar);
#endif

View File

@ -1,45 +0,0 @@
/*
** $Id: lprefix.h,v 1.2.1.1 2017/04/19 17:20:42 roberto Exp $
** Definitions for Lua code that must come before any other header file
** See Copyright Notice in lua.h
*/
#ifndef lprefix_h
#define lprefix_h
/*
** Allows POSIX/XSI stuff
*/
#if !defined(LUA_USE_C89) /* { */
#if !defined(_XOPEN_SOURCE)
#define _XOPEN_SOURCE 600
#elif _XOPEN_SOURCE == 0
#undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */
#endif
/*
** Allows manipulation of large files in gcc and some other compilers
*/
#if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS)
#define _LARGEFILE_SOURCE 1
#define _FILE_OFFSET_BITS 64
#endif
#endif /* } */
/*
** Windows stuff
*/
#if defined(_WIN32) /* { */
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */
#endif
#endif /* } */
#endif

View File

@ -1,348 +0,0 @@
/*
** $Id: lstate.c,v 2.133.1.1 2017/04/19 17:39:34 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
#define lstate_c
#define LUA_CORE
#include "lprefix.h"
#include <stddef.h>
#include <string.h>
#include "lua.h"
#include "lapi.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "llex.h"
#include "lmem.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#if !defined(LUAI_GCPAUSE)
#define LUAI_GCPAUSE 200 /* 200% */
#endif
#if !defined(LUAI_GCMUL)
#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
#endif
/*
** a macro to help the creation of a unique random seed when a state is
** created; the seed is used to randomize hashes.
*/
#if !defined(luai_makeseed)
#include <time.h>
#define luai_makeseed() cast(unsigned int, time(NULL))
#endif
/*
** thread state + extra space
*/
typedef struct LX
{
lu_byte extra_[LUA_EXTRASPACE];
lua_State l;
} LX;
/*
** Main thread combines a thread state and the global state
*/
typedef struct LG
{
LX l;
global_State g;
} LG;
#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
/*
** Compute an initial seed as random as possible. Rely on Address Space
** Layout Randomization (if present) to increase randomness..
*/
#define addbuff(b, p, e) \
{ \
size_t t = cast(size_t, e); \
memcpy(b + p, &t, sizeof(t)); \
p += sizeof(t); \
}
static unsigned int makeseed(lua_State *L)
{
char buff[4 * sizeof(size_t)];
unsigned int h = luai_makeseed();
int p = 0;
addbuff(buff, p, L); /* heap variable */
addbuff(buff, p, &h); /* local variable */
addbuff(buff, p, luaO_nilobject); /* global variable */
addbuff(buff, p, &lua_newstate); /* public function */
lua_assert(p == sizeof(buff));
return luaS_hash(buff, p, h);
}
/*
** set GCdebt to a new value keeping the value (totalbytes + GCdebt)
** invariant (and avoiding underflows in 'totalbytes')
*/
void luaE_setdebt(global_State *g, l_mem debt)
{
l_mem tb = gettotalbytes(g);
lua_assert(tb > 0);
if (debt < tb - MAX_LMEM)
debt = tb - MAX_LMEM; /* will make 'totalbytes == MAX_LMEM' */
g->totalbytes = tb - debt;
g->GCdebt = debt;
}
CallInfo *luaE_extendCI(lua_State *L)
{
CallInfo *ci = luaM_new(L, CallInfo);
lua_assert(L->ci->next == NULL);
L->ci->next = ci;
ci->previous = L->ci;
ci->next = NULL;
L->nci++;
return ci;
}
/*
** free all CallInfo structures not in use by a thread
*/
void luaE_freeCI(lua_State *L)
{
CallInfo *ci = L->ci;
CallInfo *next = ci->next;
ci->next = NULL;
while ((ci = next) != NULL)
{
next = ci->next;
luaM_free(L, ci);
L->nci--;
}
}
/*
** free half of the CallInfo structures not in use by a thread
*/
void luaE_shrinkCI(lua_State *L)
{
CallInfo *ci = L->ci;
CallInfo *next2; /* next's next */
/* while there are two nexts */
while (ci->next != NULL && (next2 = ci->next->next) != NULL)
{
luaM_free(L, ci->next); /* free next */
L->nci--;
ci->next = next2; /* remove 'next' from the list */
next2->previous = ci;
ci = next2; /* keep next's next */
}
}
static void stack_init(lua_State *L1, lua_State *L)
{
int i;
CallInfo *ci;
/* initialize stack array */
L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
L1->stacksize = BASIC_STACK_SIZE;
for (i = 0; i < BASIC_STACK_SIZE; i++)
setnilvalue(L1->stack + i); /* erase new stack */
L1->top = L1->stack;
L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
/* initialize first ci */
ci = &L1->base_ci;
ci->next = ci->previous = NULL;
ci->callstatus = 0;
ci->func = L1->top;
setnilvalue(L1->top++); /* 'function' entry for this 'ci' */
ci->top = L1->top + LUA_MINSTACK;
L1->ci = ci;
}
static void freestack(lua_State *L)
{
if (L->stack == NULL)
return; /* stack not completely built yet */
L->ci = &L->base_ci; /* free the entire 'ci' list */
luaE_freeCI(L);
lua_assert(L->nci == 0);
luaM_freearray(L, L->stack, L->stacksize); /* free stack array */
}
/*
** Create registry table and its predefined values
*/
static void init_registry(lua_State *L, global_State *g)
{
TValue temp;
/* create registry */
Table *registry = luaH_new(L);
sethvalue(L, &g->l_registry, registry);
luaH_resize(L, registry, LUA_RIDX_LAST, 0);
/* registry[LUA_RIDX_MAINTHREAD] = L */
setthvalue(L, &temp, L); /* temp = L */
luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp);
/* registry[LUA_RIDX_GLOBALS] = table of globals */
sethvalue(L, &temp, luaH_new(L)); /* temp = new table (global table) */
luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp);
}
/*
** open parts of the state that may cause memory-allocation errors.
** ('g->version' != NULL flags that the state was completely build)
*/
static void f_luaopen(lua_State *L, void *ud)
{
global_State *g = G(L);
UNUSED(ud);
stack_init(L, L); /* init stack */
init_registry(L, g);
luaS_init(L);
luaT_init(L);
luaX_init(L);
g->gcrunning = 1; /* allow gc */
g->version = lua_version(NULL);
luai_userstateopen(L);
}
/*
** preinitialize a thread with consistent values without allocating
** any memory (to avoid errors)
*/
static void preinit_thread(lua_State *L, global_State *g)
{
G(L) = g;
L->stack = NULL;
L->ci = NULL;
L->nci = 0;
L->stacksize = 0;
L->twups = L; /* thread has no upvalues */
L->errorJmp = NULL;
L->nCcalls = 0;
L->hook = NULL;
L->hookmask = 0;
L->basehookcount = 0;
L->allowhook = 1;
resethookcount(L);
L->openupval = NULL;
L->nny = 1;
L->status = LUA_OK;
L->errfunc = 0;
}
static void close_state(lua_State *L)
{
global_State *g = G(L);
luaF_close(L, L->stack); /* close all upvalues for this thread */
luaC_freeallobjects(L); /* collect all objects */
if (g->version) /* closing a fully built state? */
luai_userstateclose(L);
luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
freestack(L);
lua_assert(gettotalbytes(g) == sizeof(LG));
(*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
}
LUA_API lua_State *lua_newthread(lua_State *L)
{
global_State *g = G(L);
lua_State *L1;
lua_lock(L);
luaC_checkGC(L);
/* create new thread */
L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l;
L1->marked = luaC_white(g);
L1->tt = LUA_TTHREAD;
/* link it on list 'allgc' */
L1->next = g->allgc;
g->allgc = obj2gco(L1);
/* anchor it on L stack */
setthvalue(L, L->top, L1);
api_incr_top(L);
preinit_thread(L1, g);
L1->hookmask = L->hookmask;
L1->basehookcount = L->basehookcount;
L1->hook = L->hook;
resethookcount(L1);
/* initialize L1 extra space */
memcpy(lua_getextraspace(L1), lua_getextraspace(g->mainthread),
LUA_EXTRASPACE);
luai_userstatethread(L, L1);
stack_init(L1, L); /* init stack */
lua_unlock(L);
return L1;
}
void luaE_freethread(lua_State *L, lua_State *L1)
{
LX *l = fromstate(L1);
luaF_close(L1, L1->stack); /* close all upvalues for this thread */
lua_assert(L1->openupval == NULL);
luai_userstatefree(L, L1);
freestack(L1);
luaM_free(L, l);
}
LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
{
int i;
lua_State *L;
global_State *g;
LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
if (l == NULL)
return NULL;
L = &l->l.l;
g = &l->g;
L->next = NULL;
L->tt = LUA_TTHREAD;
g->currentwhite = bitmask(WHITE0BIT);
L->marked = luaC_white(g);
preinit_thread(L, g);
g->frealloc = f;
g->ud = ud;
g->mainthread = L;
g->seed = makeseed(L);
g->gcrunning = 0; /* no GC while building state */
g->GCestimate = 0;
g->strt.size = g->strt.nuse = 0;
g->strt.hash = NULL;
setnilvalue(&g->l_registry);
g->panic = NULL;
g->version = NULL;
g->gcstate = GCSpause;
g->gckind = KGC_NORMAL;
g->allgc = g->finobj = g->tobefnz = g->fixedgc = NULL;
g->sweepgc = NULL;
g->gray = g->grayagain = NULL;
g->weak = g->ephemeron = g->allweak = NULL;
g->twups = NULL;
g->totalbytes = sizeof(LG);
g->GCdebt = 0;
g->gcfinnum = 0;
g->gcpause = LUAI_GCPAUSE;
g->gcstepmul = LUAI_GCMUL;
for (i = 0; i < LUA_NUMTAGS; i++)
g->mt[i] = NULL;
if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK)
{
/* memory allocation error: free partial state */
close_state(L);
L = NULL;
}
return L;
}
LUA_API void lua_close(lua_State *L)
{
L = G(L)->mainthread; /* only the main thread can be closed */
lua_lock(L);
close_state(L);
}

View File

@ -1,241 +0,0 @@
/*
** $Id: lstate.h,v 2.133.1.1 2017/04/19 17:39:34 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
#ifndef lstate_h
#define lstate_h
#include "lua.h"
#include "lobject.h"
#include "ltm.h"
#include "lzio.h"
/*
** Some notes about garbage-collected objects: All objects in Lua must
** be kept somehow accessible until being freed, so all objects always
** belong to one (and only one) of these lists, using field 'next' of
** the 'CommonHeader' for the link:
**
** 'allgc': all objects not marked for finalization;
** 'finobj': all objects marked for finalization;
** 'tobefnz': all objects ready to be finalized;
** 'fixedgc': all objects that are not to be collected (currently
** only small strings, such as reserved words).
**
** Moreover, there is another set of lists that control gray objects.
** These lists are linked by fields 'gclist'. (All objects that
** can become gray have such a field. The field is not the same
** in all objects, but it always has this name.) Any gray object
** must belong to one of these lists, and all objects in these lists
** must be gray:
**
** 'gray': regular gray objects, still waiting to be visited.
** 'grayagain': objects that must be revisited at the atomic phase.
** That includes
** - black objects got in a write barrier;
** - all kinds of weak tables during propagation phase;
** - all threads.
** 'weak': tables with weak values to be cleared;
** 'ephemeron': ephemeron tables with white->white entries;
** 'allweak': tables with weak keys and/or weak values to be cleared.
** The last three lists are used only during the atomic phase.
*/
struct lua_longjmp; /* defined in ldo.c */
/*
** Atomic type (relative to signals) to better ensure that 'lua_sethook'
** is thread safe
*/
#if !defined(l_signalT)
#include <signal.h>
#define l_signalT sig_atomic_t
#endif
/* extra stack space to handle TM calls and some other extras */
#define EXTRA_STACK 5
#define BASIC_STACK_SIZE (2 * LUA_MINSTACK)
/* kinds of Garbage Collection */
#define KGC_NORMAL 0
#define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */
typedef struct stringtable
{
TString **hash;
int nuse; /* number of elements */
int size;
} stringtable;
/*
** Information about a call.
** When a thread yields, 'func' is adjusted to pretend that the
** top function has only the yielded values in its stack; in that
** case, the actual 'func' value is saved in field 'extra'.
** When a function calls another with a continuation, 'extra' keeps
** the function index so that, in case of errors, the continuation
** function can be called with the correct top.
*/
typedef struct CallInfo
{
StkId func; /* function index in the stack */
StkId top; /* top for this function */
struct CallInfo *previous, *next; /* dynamic call link */
union {
struct
{ /* only for Lua functions */
StkId base; /* base for this function */
const Instruction *savedpc;
} l;
struct
{ /* only for C functions */
lua_KFunction k; /* continuation in case of yields */
ptrdiff_t old_errfunc;
lua_KContext ctx; /* context info. in case of yields */
} c;
} u;
ptrdiff_t extra;
short nresults; /* expected number of results from this function */
unsigned short callstatus;
} CallInfo;
/*
** Bits in CallInfo status
*/
#define CIST_OAH (1 << 0) /* original value of 'allowhook' */
#define CIST_LUA (1 << 1) /* call is running a Lua function */
#define CIST_HOOKED (1 << 2) /* call is running a debug hook */
#define CIST_FRESH (1 << 3) /* call is running on a fresh invocation \
of luaV_execute */
#define CIST_YPCALL (1 << 4) /* call is a yieldable protected call */
#define CIST_TAIL (1 << 5) /* call was tail called */
#define CIST_HOOKYIELD (1 << 6) /* last hook called yielded */
#define CIST_LEQ (1 << 7) /* using __lt for __le */
#define CIST_FIN (1 << 8) /* call is running a finalizer */
#define isLua(ci) ((ci)->callstatus & CIST_LUA)
/* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */
#define setoah(st, v) ((st) = ((st) & ~CIST_OAH) | (v))
#define getoah(st) ((st)&CIST_OAH)
/*
** 'global state', shared by all threads of this state
*/
typedef struct global_State
{
lua_Alloc frealloc; /* function to reallocate memory */
void *ud; /* auxiliary data to 'frealloc' */
l_mem totalbytes; /* number of bytes currently allocated - GCdebt */
l_mem GCdebt; /* bytes allocated not yet compensated by the collector */
lu_mem GCmemtrav; /* memory traversed by the GC */
lu_mem GCestimate; /* an estimate of the non-garbage memory in use */
stringtable strt; /* hash table for strings */
TValue l_registry;
unsigned int seed; /* randomized seed for hashes */
lu_byte currentwhite;
lu_byte gcstate; /* state of garbage collector */
lu_byte gckind; /* kind of GC running */
lu_byte gcrunning; /* true if GC is running */
GCObject *allgc; /* list of all collectable objects */
GCObject **sweepgc; /* current position of sweep in list */
GCObject *finobj; /* list of collectable objects with finalizers */
GCObject *gray; /* list of gray objects */
GCObject *grayagain; /* list of objects to be traversed atomically */
GCObject *weak; /* list of tables with weak values */
GCObject *ephemeron; /* list of ephemeron tables (weak keys) */
GCObject *allweak; /* list of all-weak tables */
GCObject *tobefnz; /* list of userdata to be GC */
GCObject *fixedgc; /* list of objects not to be collected */
struct lua_State *twups; /* list of threads with open upvalues */
unsigned int gcfinnum; /* number of finalizers to call in each GC step */
int gcpause; /* size of pause between successive GCs */
int gcstepmul; /* GC 'granularity' */
lua_CFunction panic; /* to be called in unprotected errors */
struct lua_State *mainthread;
const lua_Number *version; /* pointer to version number */
TString *memerrmsg; /* memory-error message */
TString *tmname[TM_N]; /* array with tag-method names */
struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */
} global_State;
/*
** 'per thread' state
*/
struct lua_State
{
CommonHeader;
unsigned short nci; /* number of items in 'ci' list */
lu_byte status;
StkId top; /* first free slot in the stack */
global_State *l_G;
CallInfo *ci; /* call info for current function */
const Instruction *oldpc; /* last pc traced */
StkId stack_last; /* last free slot in the stack */
StkId stack; /* stack base */
UpVal *openupval; /* list of open upvalues in this stack */
GCObject *gclist;
struct lua_State *twups; /* list of threads with open upvalues */
struct lua_longjmp *errorJmp; /* current error recover point */
CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
volatile lua_Hook hook;
ptrdiff_t errfunc; /* current error handling function (stack index) */
int stacksize;
int basehookcount;
int hookcount;
unsigned short nny; /* number of non-yieldable calls in stack */
unsigned short nCcalls; /* number of nested C calls */
l_signalT hookmask;
lu_byte allowhook;
};
#define G(L) (L->l_G)
/*
** Union of all collectable objects (only for conversions)
*/
union GCUnion {
GCObject gc; /* common header */
struct TString ts;
struct Udata u;
union Closure cl;
struct Table h;
struct Proto p;
struct lua_State th; /* thread */
};
#define cast_u(o) cast(union GCUnion *, (o))
/* macros to convert a GCObject into a specific value */
#define gco2ts(o) \
check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts))
#define gco2u(o) check_exp((o)->tt == LUA_TUSERDATA, &((cast_u(o))->u))
#define gco2lcl(o) check_exp((o)->tt == LUA_TLCL, &((cast_u(o))->cl.l))
#define gco2ccl(o) check_exp((o)->tt == LUA_TCCL, &((cast_u(o))->cl.c))
#define gco2cl(o) \
check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl))
#define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h))
#define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p))
#define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th))
/* macro to convert a Lua object into a GCObject */
#define obj2gco(v) \
check_exp(novariant((v)->tt) < LUA_TDEADKEY, (&(cast_u(v)->gc)))
/* actual number of total bytes allocated */
#define gettotalbytes(g) cast(lu_mem, (g)->totalbytes + (g)->GCdebt)
LUAI_FUNC void luaE_setdebt(global_State *g, l_mem debt);
LUAI_FUNC void luaE_freethread(lua_State *L, lua_State *L1);
LUAI_FUNC CallInfo *luaE_extendCI(lua_State *L);
LUAI_FUNC void luaE_freeCI(lua_State *L);
LUAI_FUNC void luaE_shrinkCI(lua_State *L);
#endif

View File

@ -1,254 +0,0 @@
/*
** $Id: lstring.c,v 2.56.1.1 2017/04/19 17:20:42 roberto Exp $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
#define lstring_c
#define LUA_CORE
#include "lprefix.h"
#include <string.h>
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#define MEMERRMSG "not enough memory"
/*
** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to
** compute its hash
*/
#if !defined(LUAI_HASHLIMIT)
#define LUAI_HASHLIMIT 5
#endif
/*
** equality for long strings
*/
int luaS_eqlngstr(TString *a, TString *b)
{
size_t len = a->u.lnglen;
lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR);
return (a == b) || /* same instance or... */
((len == b->u.lnglen) && /* equal length and ... */
(memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */
}
unsigned int luaS_hash(const char *str, size_t l, unsigned int seed)
{
unsigned int h = seed ^ cast(unsigned int, l);
size_t step = (l >> LUAI_HASHLIMIT) + 1;
for (; l >= step; l -= step)
h ^= ((h << 5) + (h >> 2) + cast_byte(str[l - 1]));
return h;
}
unsigned int luaS_hashlongstr(TString *ts)
{
lua_assert(ts->tt == LUA_TLNGSTR);
if (ts->extra == 0)
{ /* no hash? */
ts->hash = luaS_hash(getstr(ts), ts->u.lnglen, ts->hash);
ts->extra = 1; /* now it has its hash */
}
return ts->hash;
}
/*
** resizes the string table
*/
void luaS_resize(lua_State *L, int newsize)
{
int i;
stringtable *tb = &G(L)->strt;
if (newsize > tb->size)
{ /* grow table if needed */
luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *);
for (i = tb->size; i < newsize; i++)
tb->hash[i] = NULL;
}
for (i = 0; i < tb->size; i++)
{ /* rehash */
TString *p = tb->hash[i];
tb->hash[i] = NULL;
while (p)
{ /* for each node in the list */
TString *hnext = p->u.hnext; /* save next */
unsigned int h = lmod(p->hash, newsize); /* new position */
p->u.hnext = tb->hash[h]; /* chain it */
tb->hash[h] = p;
p = hnext;
}
}
if (newsize < tb->size)
{ /* shrink table if needed */
/* vanishing slice should be empty */
lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL);
luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *);
}
tb->size = newsize;
}
/*
** Clear API string cache. (Entries cannot be empty, so fill them with
** a non-collectable string.)
*/
void luaS_clearcache(global_State *g)
{
int i, j;
for (i = 0; i < STRCACHE_N; i++)
for (j = 0; j < STRCACHE_M; j++)
{
if (iswhite(g->strcache[i][j])) /* will entry be collected? */
g->strcache[i][j] = g->memerrmsg; /* replace it with something fixed */
}
}
/*
** Initialize the string table and the string cache
*/
void luaS_init(lua_State *L)
{
global_State *g = G(L);
int i, j;
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
/* pre-create memory-error message */
g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */
for (i = 0; i < STRCACHE_N; i++) /* fill cache with valid strings */
for (j = 0; j < STRCACHE_M; j++)
g->strcache[i][j] = g->memerrmsg;
}
/*
** creates a new string object
*/
static TString *createstrobj(lua_State *L, size_t l, int tag, unsigned int h)
{
TString *ts;
GCObject *o;
size_t totalsize; /* total size of TString object */
totalsize = sizelstring(l);
o = luaC_newobj(L, tag, totalsize);
ts = gco2ts(o);
ts->hash = h;
ts->extra = 0;
getstr(ts)[l] = '\0'; /* ending 0 */
return ts;
}
TString *luaS_createlngstrobj(lua_State *L, size_t l)
{
TString *ts = createstrobj(L, l, LUA_TLNGSTR, G(L)->seed);
ts->u.lnglen = l;
return ts;
}
void luaS_remove(lua_State *L, TString *ts)
{
stringtable *tb = &G(L)->strt;
TString **p = &tb->hash[lmod(ts->hash, tb->size)];
while (*p != ts) /* find previous element */
p = &(*p)->u.hnext;
*p = (*p)->u.hnext; /* remove element from its list */
tb->nuse--;
}
/*
** checks whether short string exists and reuses it or creates a new one
*/
static TString *internshrstr(lua_State *L, const char *str, size_t l)
{
TString *ts;
global_State *g = G(L);
unsigned int h = luaS_hash(str, l, g->seed);
TString **list = &g->strt.hash[lmod(h, g->strt.size)];
lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */
for (ts = *list; ts != NULL; ts = ts->u.hnext)
{
if (l == ts->shrlen &&
(memcmp(str, getstr(ts), l * sizeof(char)) == 0))
{
/* found! */
if (isdead(g, ts)) /* dead (but not collected yet)? */
changewhite(ts); /* resurrect it */
return ts;
}
}
if (g->strt.nuse >= g->strt.size && g->strt.size <= MAX_INT / 2)
{
luaS_resize(L, g->strt.size * 2);
list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
}
ts = createstrobj(L, l, LUA_TSHRSTR, h);
memcpy(getstr(ts), str, l * sizeof(char));
ts->shrlen = cast_byte(l);
ts->u.hnext = *list;
*list = ts;
g->strt.nuse++;
return ts;
}
/*
** new string (with explicit length)
*/
TString *luaS_newlstr(lua_State *L, const char *str, size_t l)
{
if (l <= LUAI_MAXSHORTLEN) /* short string? */
return internshrstr(L, str, l);
else
{
TString *ts;
if (l >= (MAX_SIZE - sizeof(TString)) / sizeof(char))
luaM_toobig(L);
ts = luaS_createlngstrobj(L, l);
memcpy(getstr(ts), str, l * sizeof(char));
return ts;
}
}
/*
** Create or reuse a zero-terminated string, first checking in the
** cache (using the string address as a key). The cache can contain
** only zero-terminated strings, so it is safe to use 'strcmp' to
** check hits.
*/
TString *luaS_new(lua_State *L, const char *str)
{
unsigned int i = point2uint(str) % STRCACHE_N; /* hash */
int j;
TString **p = G(L)->strcache[i];
for (j = 0; j < STRCACHE_M; j++)
{
if (strcmp(str, getstr(p[j])) == 0) /* hit? */
return p[j]; /* that is it */
}
/* normal route */
for (j = STRCACHE_M - 1; j > 0; j--)
p[j] = p[j - 1]; /* move out last element */
/* new element is first in the list */
p[0] = luaS_newlstr(L, str, strlen(str));
return p[0];
}
Udata *luaS_newudata(lua_State *L, size_t s)
{
Udata *u;
GCObject *o;
if (s > MAX_SIZE - sizeof(Udata))
luaM_toobig(L);
o = luaC_newobj(L, LUA_TUSERDATA, sizeludata(s));
u = gco2u(o);
u->len = s;
u->metatable = NULL;
setuservalue(L, u, luaO_nilobject);
return u;
}

View File

@ -1,44 +0,0 @@
/*
** $Id: lstring.h,v 1.61.1.1 2017/04/19 17:20:42 roberto Exp $
** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h
*/
#ifndef lstring_h
#define lstring_h
#include "lgc.h"
#include "lobject.h"
#include "lstate.h"
#define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char))
#define sizeludata(l) (sizeof(union UUdata) + (l))
#define sizeudata(u) sizeludata((u)->len)
#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
(sizeof(s) / sizeof(char)) - 1))
/*
** test whether a string is a reserved word
*/
#define isreserved(s) ((s)->tt == LUA_TSHRSTR && (s)->extra > 0)
/*
** equality for short strings, which are always internalized
*/
#define eqshrstr(a, b) check_exp((a)->tt == LUA_TSHRSTR, (a) == (b))
LUAI_FUNC unsigned int luaS_hash(const char *str, size_t l, unsigned int seed);
LUAI_FUNC unsigned int luaS_hashlongstr(TString *ts);
LUAI_FUNC int luaS_eqlngstr(TString *a, TString *b);
LUAI_FUNC void luaS_resize(lua_State *L, int newsize);
LUAI_FUNC void luaS_clearcache(global_State *g);
LUAI_FUNC void luaS_init(lua_State *L);
LUAI_FUNC void luaS_remove(lua_State *L, TString *ts);
LUAI_FUNC Udata *luaS_newudata(lua_State *L, size_t s);
LUAI_FUNC TString *luaS_newlstr(lua_State *L, const char *str, size_t l);
LUAI_FUNC TString *luaS_new(lua_State *L, const char *str);
LUAI_FUNC TString *luaS_createlngstrobj(lua_State *L, size_t l);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,749 +0,0 @@
/*
** $Id: ltable.c,v 2.118.1.4 2018/06/08 16:22:51 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
#define ltable_c
#define LUA_CORE
#include "lprefix.h"
/*
** Implementation of tables (aka arrays, objects, or hash tables).
** Tables keep its elements in two parts: an array part and a hash part.
** Non-negative integer keys are all candidates to be kept in the array
** part. The actual size of the array is the largest 'n' such that
** more than half the slots between 1 and n are in use.
** Hash uses a mix of chained scatter table with Brent's variation.
** A main invariant of these tables is that, if an element is not
** in its main position (i.e. the 'original' position that its hash gives
** to it), then the colliding element is in its own main position.
** Hence even when the load factor reaches 100%, performance remains good.
*/
#include <math.h>
#include <limits.h>
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "lvm.h"
/*
** Maximum size of array part (MAXASIZE) is 2^MAXABITS. MAXABITS is
** the largest integer such that MAXASIZE fits in an unsigned int.
*/
#define MAXABITS cast_int(sizeof(int) * CHAR_BIT - 1)
#define MAXASIZE (1u << MAXABITS)
/*
** Maximum size of hash part is 2^MAXHBITS. MAXHBITS is the largest
** integer such that 2^MAXHBITS fits in a signed int. (Note that the
** maximum number of elements in a table, 2^MAXABITS + 2^MAXHBITS, still
** fits comfortably in an unsigned int.)
*/
#define MAXHBITS (MAXABITS - 1)
#define hashpow2(t, n) (gnode(t, lmod((n), sizenode(t))))
#define hashstr(t, str) hashpow2(t, (str)->hash)
#define hashboolean(t, p) hashpow2(t, p)
#define hashint(t, i) hashpow2(t, i)
/*
** for some types, it is better to avoid modulus by power of 2, as
** they tend to have many 2 factors.
*/
#define hashmod(t, n) (gnode(t, ((n) % ((sizenode(t) - 1) | 1))))
#define hashpointer(t, p) hashmod(t, point2uint(p))
#define dummynode (&dummynode_)
static const Node dummynode_ = {
{NILCONSTANT}, /* value */
{{NILCONSTANT, 0}} /* key */
};
/*
** Hash for floating-point numbers.
** The main computation should be just
** n = frexp(n, &i); return (n * INT_MAX) + i
** but there are some numerical subtleties.
** In a two-complement representation, INT_MAX does not has an exact
** representation as a float, but INT_MIN does; because the absolute
** value of 'frexp' is smaller than 1 (unless 'n' is inf/NaN), the
** absolute value of the product 'frexp * -INT_MIN' is smaller or equal
** to INT_MAX. Next, the use of 'unsigned int' avoids overflows when
** adding 'i'; the use of '~u' (instead of '-u') avoids problems with
** INT_MIN.
*/
#if !defined(l_hashfloat)
static int l_hashfloat(lua_Number n)
{
int i;
lua_Integer ni;
n = l_mathop(frexp)(n, &i) * -cast_num(INT_MIN);
if (!lua_numbertointeger(n, &ni))
{ /* is 'n' inf/-inf/NaN? */
lua_assert(luai_numisnan(n) || l_mathop(fabs)(n) == cast_num(HUGE_VAL));
return 0;
}
else
{ /* normal case */
unsigned int u = cast(unsigned int, i) + cast(unsigned int, ni);
return cast_int(u <= cast(unsigned int, INT_MAX) ? u : ~u);
}
}
#endif
/*
** returns the 'main' position of an element in a table (that is, the index
** of its hash value)
*/
static Node *mainposition(const Table *t, const TValue *key)
{
switch (ttype(key))
{
case LUA_TNUMINT:
return hashint(t, ivalue(key));
case LUA_TNUMFLT:
return hashmod(t, l_hashfloat(fltvalue(key)));
case LUA_TSHRSTR:
return hashstr(t, tsvalue(key));
case LUA_TLNGSTR:
return hashpow2(t, luaS_hashlongstr(tsvalue(key)));
case LUA_TBOOLEAN:
return hashboolean(t, bvalue(key));
case LUA_TLIGHTUSERDATA:
return hashpointer(t, pvalue(key));
case LUA_TLCF:
return hashpointer(t, fvalue(key));
default:
lua_assert(!ttisdeadkey(key));
return hashpointer(t, gcvalue(key));
}
}
/*
** returns the index for 'key' if 'key' is an appropriate key to live in
** the array part of the table, 0 otherwise.
*/
static unsigned int arrayindex(const TValue *key)
{
if (ttisinteger(key))
{
lua_Integer k = ivalue(key);
if (0 < k && (lua_Unsigned)k <= MAXASIZE)
return cast(unsigned int, k); /* 'key' is an appropriate array index */
}
return 0; /* 'key' did not match some condition */
}
/*
** returns the index of a 'key' for table traversals. First goes all
** elements in the array part, then elements in the hash part. The
** beginning of a traversal is signaled by 0.
*/
static unsigned int findindex(lua_State *L, Table *t, StkId key)
{
unsigned int i;
if (ttisnil(key))
return 0; /* first iteration */
i = arrayindex(key);
if (i != 0 && i <= t->sizearray) /* is 'key' inside array part? */
return i; /* yes; that's the index */
else
{
int nx;
Node *n = mainposition(t, key);
for (;;)
{ /* check whether 'key' is somewhere in the chain */
/* key may be dead already, but it is ok to use it in 'next' */
if (luaV_rawequalobj(gkey(n), key) ||
(ttisdeadkey(gkey(n)) && iscollectable(key) &&
deadvalue(gkey(n)) == gcvalue(key)))
{
i = cast_int(n - gnode(t, 0)); /* key index in hash table */
/* hash elements are numbered after array ones */
return (i + 1) + t->sizearray;
}
nx = gnext(n);
if (nx == 0)
luaG_runerror(L, "invalid key to 'next'"); /* key not found */
else
n += nx;
}
}
}
int luaH_next(lua_State *L, Table *t, StkId key)
{
unsigned int i = findindex(L, t, key); /* find original element */
for (; i < t->sizearray; i++)
{ /* try first array part */
if (!ttisnil(&t->array[i]))
{ /* a non-nil value? */
setivalue(key, i + 1);
setobj2s(L, key + 1, &t->array[i]);
return 1;
}
}
for (i -= t->sizearray; cast_int(i) < sizenode(t); i++)
{ /* hash part */
if (!ttisnil(gval(gnode(t, i))))
{ /* a non-nil value? */
setobj2s(L, key, gkey(gnode(t, i)));
setobj2s(L, key + 1, gval(gnode(t, i)));
return 1;
}
}
return 0; /* no more elements */
}
/*
** {=============================================================
** Rehash
** ==============================================================
*/
/*
** Compute the optimal size for the array part of table 't'. 'nums' is a
** "count array" where 'nums[i]' is the number of integers in the table
** between 2^(i - 1) + 1 and 2^i. 'pna' enters with the total number of
** integer keys in the table and leaves with the number of keys that
** will go to the array part; return the optimal size.
*/
static unsigned int computesizes(unsigned int nums[], unsigned int *pna)
{
int i;
unsigned int twotoi; /* 2^i (candidate for optimal size) */
unsigned int a = 0; /* number of elements smaller than 2^i */
unsigned int na = 0; /* number of elements to go to array part */
unsigned int optimal = 0; /* optimal size for array part */
/* loop while keys can fill more than half of total size */
for (i = 0, twotoi = 1;
twotoi > 0 && *pna > twotoi / 2;
i++, twotoi *= 2)
{
if (nums[i] > 0)
{
a += nums[i];
if (a > twotoi / 2)
{ /* more than half elements present? */
optimal = twotoi; /* optimal size (till now) */
na = a; /* all elements up to 'optimal' will go to array part */
}
}
}
lua_assert((optimal == 0 || optimal / 2 < na) && na <= optimal);
*pna = na;
return optimal;
}
static int countint(const TValue *key, unsigned int *nums)
{
unsigned int k = arrayindex(key);
if (k != 0)
{ /* is 'key' an appropriate array index? */
nums[luaO_ceillog2(k)]++; /* count as such */
return 1;
}
else
return 0;
}
/*
** Count keys in array part of table 't': Fill 'nums[i]' with
** number of keys that will go into corresponding slice and return
** total number of non-nil keys.
*/
static unsigned int numusearray(const Table *t, unsigned int *nums)
{
int lg;
unsigned int ttlg; /* 2^lg */
unsigned int ause = 0; /* summation of 'nums' */
unsigned int i = 1; /* count to traverse all array keys */
/* traverse each slice */
for (lg = 0, ttlg = 1; lg <= MAXABITS; lg++, ttlg *= 2)
{
unsigned int lc = 0; /* counter */
unsigned int lim = ttlg;
if (lim > t->sizearray)
{
lim = t->sizearray; /* adjust upper limit */
if (i > lim)
break; /* no more elements to count */
}
/* count elements in range (2^(lg - 1), 2^lg] */
for (; i <= lim; i++)
{
if (!ttisnil(&t->array[i - 1]))
lc++;
}
nums[lg] += lc;
ause += lc;
}
return ause;
}
static int numusehash(const Table *t, unsigned int *nums, unsigned int *pna)
{
int totaluse = 0; /* total number of elements */
int ause = 0; /* elements added to 'nums' (can go to array part) */
int i = sizenode(t);
while (i--)
{
Node *n = &t->node[i];
if (!ttisnil(gval(n)))
{
ause += countint(gkey(n), nums);
totaluse++;
}
}
*pna += ause;
return totaluse;
}
static void setarrayvector(lua_State *L, Table *t, unsigned int size)
{
unsigned int i;
luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
for (i = t->sizearray; i < size; i++)
setnilvalue(&t->array[i]);
t->sizearray = size;
}
static void setnodevector(lua_State *L, Table *t, unsigned int size)
{
if (size == 0)
{ /* no elements to hash part? */
t->node = cast(Node *, dummynode); /* use common 'dummynode' */
t->lsizenode = 0;
t->lastfree = NULL; /* signal that it is using dummy node */
}
else
{
int i;
int lsize = luaO_ceillog2(size);
if (lsize > MAXHBITS)
luaG_runerror(L, "table overflow");
size = twoto(lsize);
t->node = luaM_newvector(L, size, Node);
for (i = 0; i < (int)size; i++)
{
Node *n = gnode(t, i);
gnext(n) = 0;
setnilvalue(wgkey(n));
setnilvalue(gval(n));
}
t->lsizenode = cast_byte(lsize);
t->lastfree = gnode(t, size); /* all positions are free */
}
}
typedef struct
{
Table *t;
unsigned int nhsize;
} AuxsetnodeT;
static void auxsetnode(lua_State *L, void *ud)
{
AuxsetnodeT *asn = cast(AuxsetnodeT *, ud);
setnodevector(L, asn->t, asn->nhsize);
}
void luaH_resize(lua_State *L, Table *t, unsigned int nasize,
unsigned int nhsize)
{
unsigned int i;
int j;
AuxsetnodeT asn;
unsigned int oldasize = t->sizearray;
int oldhsize = allocsizenode(t);
Node *nold = t->node; /* save old hash ... */
if (nasize > oldasize) /* array part must grow? */
setarrayvector(L, t, nasize);
/* create new hash part with appropriate size */
asn.t = t;
asn.nhsize = nhsize;
if (luaD_rawrunprotected(L, auxsetnode, &asn) != LUA_OK)
{ /* mem. error? */
setarrayvector(L, t, oldasize); /* array back to its original size */
luaD_throw(L, LUA_ERRMEM); /* rethrow memory error */
}
if (nasize < oldasize)
{ /* array part must shrink? */
t->sizearray = nasize;
/* re-insert elements from vanishing slice */
for (i = nasize; i < oldasize; i++)
{
if (!ttisnil(&t->array[i]))
luaH_setint(L, t, i + 1, &t->array[i]);
}
/* shrink array */
luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
}
/* re-insert elements from hash part */
for (j = oldhsize - 1; j >= 0; j--)
{
Node *old = nold + j;
if (!ttisnil(gval(old)))
{
/* doesn't need barrier/invalidate cache, as entry was
already present in the table */
setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old));
}
}
if (oldhsize > 0) /* not the dummy node? */
luaM_freearray(L, nold, cast(size_t, oldhsize)); /* free old hash */
}
void luaH_resizearray(lua_State *L, Table *t, unsigned int nasize)
{
int nsize = allocsizenode(t);
luaH_resize(L, t, nasize, nsize);
}
/*
** nums[i] = number of keys 'k' where 2^(i - 1) < k <= 2^i
*/
static void rehash(lua_State *L, Table *t, const TValue *ek)
{
unsigned int asize; /* optimal size for array part */
unsigned int na; /* number of keys in the array part */
unsigned int nums[MAXABITS + 1];
int i;
int totaluse;
for (i = 0; i <= MAXABITS; i++)
nums[i] = 0; /* reset counts */
na = numusearray(t, nums); /* count keys in array part */
totaluse = na; /* all those keys are integer keys */
totaluse += numusehash(t, nums, &na); /* count keys in hash part */
/* count extra key */
na += countint(ek, nums);
totaluse++;
/* compute new size for array part */
asize = computesizes(nums, &na);
/* resize the table to new computed sizes */
luaH_resize(L, t, asize, totaluse - na);
}
/*
** }=============================================================
*/
Table *luaH_new(lua_State *L)
{
GCObject *o = luaC_newobj(L, LUA_TTABLE, sizeof(Table));
Table *t = gco2t(o);
t->metatable = NULL;
t->flags = cast_byte(~0);
t->array = NULL;
t->sizearray = 0;
setnodevector(L, t, 0);
return t;
}
void luaH_free(lua_State *L, Table *t)
{
if (!isdummy(t))
luaM_freearray(L, t->node, cast(size_t, sizenode(t)));
luaM_freearray(L, t->array, t->sizearray);
luaM_free(L, t);
}
static Node *getfreepos(Table *t)
{
if (!isdummy(t))
{
while (t->lastfree > t->node)
{
t->lastfree--;
if (ttisnil(gkey(t->lastfree)))
return t->lastfree;
}
}
return NULL; /* could not find a free place */
}
/*
** inserts a new key into a hash table; first, check whether key'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 new key in its main position; otherwise (colliding node is in its main
** position), new key goes to an empty position.
*/
TValue *luaH_newkey(lua_State *L, Table *t, const TValue *key)
{
Node *mp;
TValue aux;
if (ttisnil(key))
luaG_runerror(L, "table index is nil");
else if (ttisfloat(key))
{
lua_Integer k;
if (luaV_tointeger(key, &k, 0))
{ /* does index fit in an integer? */
setivalue(&aux, k);
key = &aux; /* insert it as an integer */
}
else if (luai_numisnan(fltvalue(key)))
luaG_runerror(L, "table index is NaN");
}
mp = mainposition(t, key);
if (!ttisnil(gval(mp)) || isdummy(t))
{ /* main position is taken? */
Node *othern;
Node *f = getfreepos(t); /* get a free place */
if (f == NULL)
{ /* cannot find a free place? */
rehash(L, t, key); /* grow table */
/* whatever called 'newkey' takes care of TM cache */
return luaH_set(L, t, key); /* insert key into grown table */
}
lua_assert(!isdummy(t));
othern = mainposition(t, gkey(mp));
if (othern != mp)
{ /* is colliding node out of its main position? */
/* yes; move colliding node into free position */
while (othern + gnext(othern) != mp) /* find previous */
othern += gnext(othern);
gnext(othern) = cast_int(f - othern); /* rechain to point to 'f' */
*f = *mp; /* copy colliding node into free pos. (mp->next also goes) */
if (gnext(mp) != 0)
{
gnext(f) += cast_int(mp - f); /* correct 'next' */
gnext(mp) = 0; /* now 'mp' is free */
}
setnilvalue(gval(mp));
}
else
{ /* colliding node is in its own main position */
/* new node will go into free position */
if (gnext(mp) != 0)
gnext(f) = cast_int((mp + gnext(mp)) - f); /* chain new position */
else
lua_assert(gnext(f) == 0);
gnext(mp) = cast_int(f - mp);
mp = f;
}
}
setnodekey(L, &mp->i_key, key);
luaC_barrierback(L, t, key);
lua_assert(ttisnil(gval(mp)));
return gval(mp);
}
/*
** search function for integers
*/
const TValue *luaH_getint(Table *t, lua_Integer key)
{
/* (1 <= key && key <= t->sizearray) */
if (l_castS2U(key) - 1 < t->sizearray)
return &t->array[key - 1];
else
{
Node *n = hashint(t, key);
for (;;)
{ /* check whether 'key' is somewhere in the chain */
if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key)
return gval(n); /* that's it */
else
{
int nx = gnext(n);
if (nx == 0)
break;
n += nx;
}
}
return luaO_nilobject;
}
}
/*
** search function for short strings
*/
const TValue *luaH_getshortstr(Table *t, TString *key)
{
Node *n = hashstr(t, key);
lua_assert(key->tt == LUA_TSHRSTR);
for (;;)
{ /* check whether 'key' is somewhere in the chain */
const TValue *k = gkey(n);
if (ttisshrstring(k) && eqshrstr(tsvalue(k), key))
return gval(n); /* that's it */
else
{
int nx = gnext(n);
if (nx == 0)
return luaO_nilobject; /* not found */
n += nx;
}
}
}
/*
** "Generic" get version. (Not that generic: not valid for integers,
** which may be in array part, nor for floats with integral values.)
*/
static const TValue *getgeneric(Table *t, const TValue *key)
{
Node *n = mainposition(t, key);
for (;;)
{ /* check whether 'key' is somewhere in the chain */
if (luaV_rawequalobj(gkey(n), key))
return gval(n); /* that's it */
else
{
int nx = gnext(n);
if (nx == 0)
return luaO_nilobject; /* not found */
n += nx;
}
}
}
const TValue *luaH_getstr(Table *t, TString *key)
{
if (key->tt == LUA_TSHRSTR)
return luaH_getshortstr(t, key);
else
{ /* for long strings, use generic case */
TValue ko;
setsvalue(cast(lua_State *, NULL), &ko, key);
return getgeneric(t, &ko);
}
}
/*
** main search function
*/
const TValue *luaH_get(Table *t, const TValue *key)
{
switch (ttype(key))
{
case LUA_TSHRSTR:
return luaH_getshortstr(t, tsvalue(key));
case LUA_TNUMINT:
return luaH_getint(t, ivalue(key));
case LUA_TNIL:
return luaO_nilobject;
case LUA_TNUMFLT:
{
lua_Integer k;
if (luaV_tointeger(key, &k, 0)) /* index is int? */
return luaH_getint(t, k); /* use specialized version */
/* else... */
} /* FALLTHROUGH */
default:
return getgeneric(t, key);
}
}
/*
** beware: when using this function you probably need to check a GC
** barrier and invalidate the TM cache.
*/
TValue *luaH_set(lua_State *L, Table *t, const TValue *key)
{
const TValue *p = luaH_get(t, key);
if (p != luaO_nilobject)
return cast(TValue *, p);
else
return luaH_newkey(L, t, key);
}
void luaH_setint(lua_State *L, Table *t, lua_Integer key, TValue *value)
{
const TValue *p = luaH_getint(t, key);
TValue *cell;
if (p != luaO_nilobject)
cell = cast(TValue *, p);
else
{
TValue k;
setivalue(&k, key);
cell = luaH_newkey(L, t, &k);
}
setobj2t(L, cell, value);
}
static lua_Unsigned unbound_search(Table *t, lua_Unsigned j)
{
lua_Unsigned i = j; /* i is zero or a present index */
j++;
/* find 'i' and 'j' such that i is present and j is not */
while (!ttisnil(luaH_getint(t, j)))
{
i = j;
if (j > l_castS2U(LUA_MAXINTEGER) / 2)
{ /* overflow? */
/* table was built with bad purposes: resort to linear search */
i = 1;
while (!ttisnil(luaH_getint(t, i)))
i++;
return i - 1;
}
j *= 2;
}
/* now do a binary search between them */
while (j - i > 1)
{
lua_Unsigned m = (i + j) / 2;
if (ttisnil(luaH_getint(t, m)))
j = m;
else
i = m;
}
return i;
}
/*
** Try to find a boundary in table 't'. A 'boundary' is an integer index
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
*/
lua_Unsigned luaH_getn(Table *t)
{
unsigned int 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;
while (j - i > 1)
{
unsigned int m = (i + j) / 2;
if (ttisnil(&t->array[m - 1]))
j = m;
else
i = m;
}
return i;
}
/* else must find a boundary in hash part */
else if (isdummy(t)) /* hash part is empty? */
return j; /* that is easy... */
else
return unbound_search(t, j);
}
#if defined(LUA_DEBUG)
Node *luaH_mainposition(const Table *t, const TValue *key)
{
return mainposition(t, key);
}
int luaH_isdummy(const Table *t) { return isdummy(t); }
#endif

View File

@ -1,58 +0,0 @@
/*
** $Id: ltable.h,v 2.23.1.2 2018/05/24 19:39:05 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
#ifndef ltable_h
#define ltable_h
#include "lobject.h"
#define gnode(t, i) (&(t)->node[i])
#define gval(n) (&(n)->i_val)
#define gnext(n) ((n)->i_key.nk.next)
/* 'const' to avoid wrong writings that can mess up field 'next' */
#define gkey(n) cast(const TValue *, (&(n)->i_key.tvk))
/*
** writable version of 'gkey'; allows updates to individual fields,
** but not to the whole (which has incompatible type)
*/
#define wgkey(n) (&(n)->i_key.nk)
#define invalidateTMcache(t) ((t)->flags = 0)
/* true when 't' is using 'dummynode' as its hash part */
#define isdummy(t) ((t)->lastfree == NULL)
/* allocated size for hash nodes */
#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t))
/* returns the key, given the value of a table entry */
#define keyfromval(v) \
(gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val))))
LUAI_FUNC const TValue *luaH_getint(Table *t, lua_Integer key);
LUAI_FUNC void luaH_setint(lua_State *L, Table *t, lua_Integer key,
TValue *value);
LUAI_FUNC const TValue *luaH_getshortstr(Table *t, TString *key);
LUAI_FUNC const TValue *luaH_getstr(Table *t, TString *key);
LUAI_FUNC const TValue *luaH_get(Table *t, const TValue *key);
LUAI_FUNC TValue *luaH_newkey(lua_State *L, Table *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);
LUAI_FUNC void luaH_resize(lua_State *L, Table *t, unsigned int nasize,
unsigned int nhsize);
LUAI_FUNC void luaH_resizearray(lua_State *L, Table *t, unsigned 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 lua_Unsigned luaH_getn(Table *t);
#if defined(LUA_DEBUG)
LUAI_FUNC Node *luaH_mainposition(const Table *t, const TValue *key);
LUAI_FUNC int luaH_isdummy(const Table *t);
#endif
#endif

View File

@ -1,469 +0,0 @@
/*
** $Id: ltablib.c,v 1.93.1.1 2017/04/19 17:20:42 roberto Exp $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
#define ltablib_c
#define LUA_LIB
#include "lprefix.h"
#include <limits.h>
#include <stddef.h>
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
/*
** Operations that an object must define to mimic a table
** (some functions only need some of them)
*/
#define TAB_R 1 /* read */
#define TAB_W 2 /* write */
#define TAB_L 4 /* length */
#define TAB_RW (TAB_R | TAB_W) /* read/write */
#define aux_getn(L, n, w) (checktab(L, n, (w) | TAB_L), luaL_len(L, n))
static int checkfield(lua_State *L, const char *key, int n)
{
lua_pushstring(L, key);
return (lua_rawget(L, -n) != LUA_TNIL);
}
/*
** Check that 'arg' either is a table or can behave like one (that is,
** has a metatable with the required metamethods)
*/
static void checktab(lua_State *L, int arg, int what)
{
if (lua_type(L, arg) != LUA_TTABLE)
{ /* is it not a table? */
int n = 1; /* number of elements to pop */
if (lua_getmetatable(L, arg) && /* must have metatable */
(!(what & TAB_R) || checkfield(L, "__index", ++n)) &&
(!(what & TAB_W) || checkfield(L, "__newindex", ++n)) &&
(!(what & TAB_L) || checkfield(L, "__len", ++n)))
{
lua_pop(L, n); /* pop metatable and tested metamethods */
}
else
luaL_checktype(L, arg, LUA_TTABLE); /* force an error */
}
}
#if defined(LUA_COMPAT_MAXN)
static int maxn(lua_State *L)
{
lua_Number max = 0;
luaL_checktype(L, 1, LUA_TTABLE);
lua_pushnil(L); /* first key */
while (lua_next(L, 1))
{
lua_pop(L, 1); /* remove value */
if (lua_type(L, -1) == LUA_TNUMBER)
{
lua_Number v = lua_tonumber(L, -1);
if (v > max)
max = v;
}
}
lua_pushnumber(L, max);
return 1;
}
#endif
static int tinsert(lua_State *L)
{
lua_Integer e = aux_getn(L, 1, TAB_RW) + 1; /* first empty element */
lua_Integer pos; /* where to insert new element */
switch (lua_gettop(L))
{
case 2:
{ /* called with only 2 arguments */
pos = e; /* insert new element at the end */
break;
}
case 3:
{
lua_Integer i;
pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */
luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds");
for (i = e; i > pos; i--)
{ /* move up elements */
lua_geti(L, 1, i - 1);
lua_seti(L, 1, i); /* t[i] = t[i - 1] */
}
break;
}
default:
{
return luaL_error(L, "wrong number of arguments to 'insert'");
}
}
lua_seti(L, 1, pos); /* t[pos] = v */
return 0;
}
static int tremove(lua_State *L)
{
lua_Integer size = aux_getn(L, 1, TAB_RW);
lua_Integer pos = luaL_optinteger(L, 2, size);
if (pos != size) /* validate 'pos' if given */
luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds");
lua_geti(L, 1, pos); /* result = t[pos] */
for (; pos < size; pos++)
{
lua_geti(L, 1, pos + 1);
lua_seti(L, 1, pos); /* t[pos] = t[pos + 1] */
}
lua_pushnil(L);
lua_seti(L, 1, pos); /* t[pos] = nil */
return 1;
}
/*
** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever
** possible, copy in increasing order, which is better for rehashing.
** "possible" means destination after original range, or smaller
** than origin, or copying to another table.
*/
static int tmove(lua_State *L)
{
lua_Integer f = luaL_checkinteger(L, 2);
lua_Integer e = luaL_checkinteger(L, 3);
lua_Integer t = luaL_checkinteger(L, 4);
int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */
checktab(L, 1, TAB_R);
checktab(L, tt, TAB_W);
if (e >= f)
{ /* otherwise, nothing to move */
lua_Integer n, i;
luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3,
"too many elements to move");
n = e - f + 1; /* number of elements to move */
luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4,
"destination wrap around");
if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ)))
{
for (i = 0; i < n; i++)
{
lua_geti(L, 1, f + i);
lua_seti(L, tt, t + i);
}
}
else
{
for (i = n - 1; i >= 0; i--)
{
lua_geti(L, 1, f + i);
lua_seti(L, tt, t + i);
}
}
}
lua_pushvalue(L, tt); /* return destination table */
return 1;
}
static void addfield(lua_State *L, luaL_Buffer *b, lua_Integer i)
{
lua_geti(L, 1, i);
if (!lua_isstring(L, -1))
luaL_error(L, "invalid value (%s) at index %d in table for 'concat'",
luaL_typename(L, -1), i);
luaL_addvalue(b);
}
static int tconcat(lua_State *L)
{
luaL_Buffer b;
lua_Integer last = aux_getn(L, 1, TAB_R);
size_t lsep;
const char *sep = luaL_optlstring(L, 2, "", &lsep);
lua_Integer i = luaL_optinteger(L, 3, 1);
last = luaL_optinteger(L, 4, last);
luaL_buffinit(L, &b);
for (; i < last; i++)
{
addfield(L, &b, i);
luaL_addlstring(&b, sep, lsep);
}
if (i == last) /* add last value (if interval was not empty) */
addfield(L, &b, i);
luaL_pushresult(&b);
return 1;
}
/*
** {======================================================
** Pack/unpack
** =======================================================
*/
static int pack(lua_State *L)
{
int i;
int n = lua_gettop(L); /* number of elements to pack */
lua_createtable(L, n, 1); /* create result table */
lua_insert(L, 1); /* put it at index 1 */
for (i = n; i >= 1; i--) /* assign elements */
lua_seti(L, 1, i);
lua_pushinteger(L, n);
lua_setfield(L, 1, "n"); /* t.n = number of elements */
return 1; /* return table */
}
static int unpack(lua_State *L)
{
lua_Unsigned n;
lua_Integer i = luaL_optinteger(L, 2, 1);
lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1));
if (i > e)
return 0; /* empty range */
n = (lua_Unsigned)e - i; /* number of elements minus 1 (avoid overflows) */
if (n >= (unsigned int)INT_MAX || !lua_checkstack(L, (int)(++n)))
return luaL_error(L, "too many results to unpack");
for (; i < e; i++)
{ /* push arg[i..e - 1] (to avoid overflows) */
lua_geti(L, 1, i);
}
lua_geti(L, 1, e); /* push last element */
return (int)n;
}
/* }====================================================== */
/*
** {======================================================
** Quicksort
** (based on 'Algorithms in MODULA-3', Robert Sedgewick;
** Addison-Wesley, 1993.)
** =======================================================
*/
/* type for array indices */
typedef unsigned int IdxT;
/*
** Produce a "random" 'unsigned int' to randomize pivot choice. This
** macro is used only when 'sort' detects a big imbalance in the result
** of a partition. (If you don't want/need this "randomness", ~0 is a
** good choice.)
*/
#if !defined(l_randomizePivot) /* { */
#include <time.h>
/* size of 'e' measured in number of 'unsigned int's */
#define sof(e) (sizeof(e) / sizeof(unsigned int))
/*
** Use 'time' and 'clock' as sources of "randomness". Because we don't
** know the types 'clock_t' and 'time_t', we cannot cast them to
** anything without risking overflows. A safe way to use their values
** is to copy them to an array of a known type and use the array values.
*/
static unsigned int l_randomizePivot(void)
{
clock_t c = clock();
time_t t = time(NULL);
unsigned int buff[sof(c) + sof(t)];
unsigned int i, rnd = 0;
memcpy(buff, &c, sof(c) * sizeof(unsigned int));
memcpy(buff + sof(c), &t, sof(t) * sizeof(unsigned int));
for (i = 0; i < sof(buff); i++)
rnd += buff[i];
return rnd;
}
#endif /* } */
/* arrays larger than 'RANLIMIT' may use randomized pivots */
#define RANLIMIT 100u
static void set2(lua_State *L, IdxT i, IdxT j)
{
lua_seti(L, 1, i);
lua_seti(L, 1, j);
}
/*
** Return true iff value at stack index 'a' is less than the value at
** index 'b' (according to the order of the sort).
*/
static int sort_comp(lua_State *L, int a, int b)
{
if (lua_isnil(L, 2)) /* no function? */
return lua_compare(L, a, b, LUA_OPLT); /* a < b */
else
{ /* function */
int res;
lua_pushvalue(L, 2); /* push function */
lua_pushvalue(L, a - 1); /* -1 to compensate function */
lua_pushvalue(L, b - 2); /* -2 to compensate function and 'a' */
lua_call(L, 2, 1); /* call function */
res = lua_toboolean(L, -1); /* get result */
lua_pop(L, 1); /* pop result */
return res;
}
}
/*
** Does the partition: Pivot P is at the top of the stack.
** precondition: a[lo] <= P == a[up-1] <= a[up],
** so it only needs to do the partition from lo + 1 to up - 2.
** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up]
** returns 'i'.
*/
static IdxT partition(lua_State *L, IdxT lo, IdxT up)
{
IdxT i = lo; /* will be incremented before first use */
IdxT j = up - 1; /* will be decremented before first use */
/* loop invariant: a[lo .. i] <= P <= a[j .. up] */
for (;;)
{
/* next loop: repeat ++i while a[i] < P */
while (lua_geti(L, 1, ++i), sort_comp(L, -1, -2))
{
if (i == up - 1) /* a[i] < P but a[up - 1] == P ?? */
luaL_error(L, "invalid order function for sorting");
lua_pop(L, 1); /* remove a[i] */
}
/* after the loop, a[i] >= P and a[lo .. i - 1] < P */
/* next loop: repeat --j while P < a[j] */
while (lua_geti(L, 1, --j), sort_comp(L, -3, -1))
{
if (j < i) /* j < i but a[j] > P ?? */
luaL_error(L, "invalid order function for sorting");
lua_pop(L, 1); /* remove a[j] */
}
/* after the loop, a[j] <= P and a[j + 1 .. up] >= P */
if (j < i)
{ /* no elements out of place? */
/* a[lo .. i - 1] <= P <= a[j + 1 .. i .. up] */
lua_pop(L, 1); /* pop a[j] */
/* swap pivot (a[up - 1]) with a[i] to satisfy pos-condition */
set2(L, up - 1, i);
return i;
}
/* otherwise, swap a[i] - a[j] to restore invariant and repeat */
set2(L, i, j);
}
}
/*
** Choose an element in the middle (2nd-3th quarters) of [lo,up]
** "randomized" by 'rnd'
*/
static IdxT choosePivot(IdxT lo, IdxT up, unsigned int rnd)
{
IdxT r4 = (up - lo) / 4; /* range/4 */
IdxT p = rnd % (r4 * 2) + (lo + r4);
lua_assert(lo + r4 <= p && p <= up - r4);
return p;
}
/*
** QuickSort algorithm (recursive function)
*/
static void auxsort(lua_State *L, IdxT lo, IdxT up,
unsigned int rnd)
{
while (lo < up)
{ /* loop for tail recursion */
IdxT p; /* Pivot index */
IdxT n; /* to be used later */
/* sort elements 'lo', 'p', and 'up' */
lua_geti(L, 1, lo);
lua_geti(L, 1, up);
if (sort_comp(L, -1, -2)) /* a[up] < a[lo]? */
set2(L, lo, up); /* swap a[lo] - a[up] */
else
lua_pop(L, 2); /* remove both values */
if (up - lo == 1) /* only 2 elements? */
return; /* already sorted */
if (up - lo < RANLIMIT || rnd == 0) /* small interval or no randomize? */
p = (lo + up) / 2; /* middle element is a good pivot */
else /* for larger intervals, it is worth a random pivot */
p = choosePivot(lo, up, rnd);
lua_geti(L, 1, p);
lua_geti(L, 1, lo);
if (sort_comp(L, -2, -1)) /* a[p] < a[lo]? */
set2(L, p, lo); /* swap a[p] - a[lo] */
else
{
lua_pop(L, 1); /* remove a[lo] */
lua_geti(L, 1, up);
if (sort_comp(L, -1, -2)) /* a[up] < a[p]? */
set2(L, p, up); /* swap a[up] - a[p] */
else
lua_pop(L, 2);
}
if (up - lo == 2) /* only 3 elements? */
return; /* already sorted */
lua_geti(L, 1, p); /* get middle element (Pivot) */
lua_pushvalue(L, -1); /* push Pivot */
lua_geti(L, 1, up - 1); /* push a[up - 1] */
set2(L, p, up - 1); /* swap Pivot (a[p]) with a[up - 1] */
p = partition(L, lo, up);
/* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */
if (p - lo < up - p)
{ /* lower interval is smaller? */
auxsort(L, lo, p - 1, rnd); /* call recursively for lower interval */
n = p - lo; /* size of smaller interval */
lo = p + 1; /* tail call for [p + 1 .. up] (upper interval) */
}
else
{
auxsort(L, p + 1, up, rnd); /* call recursively for upper interval */
n = up - p; /* size of smaller interval */
up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */
}
if ((up - lo) / 128 > n) /* partition too imbalanced? */
rnd = l_randomizePivot(); /* try a new randomization */
} /* tail call auxsort(L, lo, up, rnd) */
}
static int sort(lua_State *L)
{
lua_Integer n = aux_getn(L, 1, TAB_RW);
if (n > 1)
{ /* non-trivial interval? */
luaL_argcheck(L, n < INT_MAX, 1, "array too big");
if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */
lua_settop(L, 2); /* make sure there are two arguments */
auxsort(L, 1, (IdxT)n, 0);
}
return 0;
}
/* }====================================================== */
static const luaL_Reg tab_funcs[] = {
{"concat", tconcat},
#if defined(LUA_COMPAT_MAXN)
{"maxn", maxn},
#endif
{"insert", tinsert},
{"pack", pack},
{"unpack", unpack},
{"remove", tremove},
{"move", tmove},
{"sort", sort},
{NULL, NULL}};
LUAMOD_API int luaopen_table(lua_State *L)
{
luaL_newlib(L, tab_funcs);
#if defined(LUA_COMPAT_UNPACK)
/* _G.unpack = table.unpack */
lua_getfield(L, -1, "unpack");
lua_setglobal(L, "unpack");
#endif
return 1;
}

View File

@ -1,175 +0,0 @@
/*
** $Id: ltm.c,v 2.38.1.1 2017/04/19 17:39:34 roberto Exp $
** Tag methods
** See Copyright Notice in lua.h
*/
#define ltm_c
#define LUA_CORE
#include "lprefix.h"
#include <string.h>
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lvm.h"
static const char udatatypename[] = "userdata";
LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = {
"no value",
"nil", "boolean", udatatypename, "number",
"string", "table", "function", udatatypename, "thread",
"proto" /* this last case is used for tests only */
};
void luaT_init(lua_State *L)
{
static const char *const luaT_eventname[] = {/* ORDER TM */
"__index", "__newindex",
"__gc", "__mode", "__len", "__eq",
"__add", "__sub", "__mul", "__mod", "__pow",
"__div", "__idiv",
"__band", "__bor", "__bxor", "__shl", "__shr",
"__unm", "__bnot", "__lt", "__le",
"__concat", "__call"};
int i;
for (i = 0; i < TM_N; i++)
{
G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */
}
}
/*
** function to be used with macro "fasttm": optimized for absence of
** tag methods
*/
const TValue *luaT_gettm(Table *events, TMS event, TString *ename)
{
const TValue *tm = luaH_getshortstr(events, ename);
lua_assert(event <= TM_EQ);
if (ttisnil(tm))
{ /* no tag method? */
events->flags |= cast_byte(1u << event); /* cache this fact */
return NULL;
}
else
return tm;
}
const TValue *luaT_gettmbyobj(lua_State *L, const TValue *o, TMS event)
{
Table *mt;
switch (ttnov(o))
{
case LUA_TTABLE:
mt = hvalue(o)->metatable;
break;
case LUA_TUSERDATA:
mt = uvalue(o)->metatable;
break;
default:
mt = G(L)->mt[ttnov(o)];
}
return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : luaO_nilobject);
}
/*
** Return the name of the type of an object. For tables and userdata
** with metatable, use their '__name' metafield, if present.
*/
const char *luaT_objtypename(lua_State *L, const TValue *o)
{
Table *mt;
if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) ||
(ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL))
{
const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name"));
if (ttisstring(name)) /* is '__name' a string? */
return getstr(tsvalue(name)); /* use it as type name */
}
return ttypename(ttnov(o)); /* else use standard type name */
}
void luaT_callTM(lua_State *L, const TValue *f, const TValue *p1,
const TValue *p2, TValue *p3, int hasres)
{
ptrdiff_t result = savestack(L, p3);
StkId func = L->top;
setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */
setobj2s(L, func + 1, p1); /* 1st argument */
setobj2s(L, func + 2, p2); /* 2nd argument */
L->top += 3;
if (!hasres) /* no result? 'p3' is third argument */
setobj2s(L, L->top++, p3); /* 3rd argument */
/* metamethod may yield only when called from Lua code */
if (isLua(L->ci))
luaD_call(L, func, hasres);
else
luaD_callnoyield(L, func, hasres);
if (hasres)
{ /* if has result, move it to its place */
p3 = restorestack(L, result);
setobjs2s(L, p3, --L->top);
}
}
int luaT_callbinTM(lua_State *L, const TValue *p1, const TValue *p2,
StkId res, TMS event)
{
const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
if (ttisnil(tm))
tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
if (ttisnil(tm))
return 0;
luaT_callTM(L, tm, p1, p2, res, 1);
return 1;
}
void luaT_trybinTM(lua_State *L, const TValue *p1, const TValue *p2,
StkId res, TMS event)
{
if (!luaT_callbinTM(L, p1, p2, res, event))
{
switch (event)
{
case TM_CONCAT:
luaG_concaterror(L, p1, p2);
/* call never returns, but to avoid warnings: */ /* FALLTHROUGH */
case TM_BAND:
case TM_BOR:
case TM_BXOR:
case TM_SHL:
case TM_SHR:
case TM_BNOT:
{
lua_Number dummy;
if (tonumber(p1, &dummy) && tonumber(p2, &dummy))
luaG_tointerror(L, p1, p2);
else
luaG_opinterror(L, p1, p2, "perform bitwise operation on");
}
/* calls never return, but to avoid warnings: */ /* FALLTHROUGH */
default:
luaG_opinterror(L, p1, p2, "perform arithmetic on");
}
}
}
int luaT_callorderTM(lua_State *L, const TValue *p1, const TValue *p2,
TMS event)
{
if (!luaT_callbinTM(L, p1, p2, L->top, event))
return -1; /* no metamethod */
else
return !l_isfalse(L->top);
}

View File

@ -1,69 +0,0 @@
/*
** $Id: ltm.h,v 2.22.1.1 2017/04/19 17:20:42 roberto Exp $
** Tag methods
** See Copyright Notice in lua.h
*/
#ifndef ltm_h
#define ltm_h
#include "lobject.h"
/*
* WARNING: if you change the order of this enumeration,
* grep "ORDER TM" and "ORDER OP"
*/
typedef enum
{
TM_INDEX,
TM_NEWINDEX,
TM_GC,
TM_MODE,
TM_LEN,
TM_EQ, /* last tag method with fast access */
TM_ADD,
TM_SUB,
TM_MUL,
TM_MOD,
TM_POW,
TM_DIV,
TM_IDIV,
TM_BAND,
TM_BOR,
TM_BXOR,
TM_SHL,
TM_SHR,
TM_UNM,
TM_BNOT,
TM_LT,
TM_LE,
TM_CONCAT,
TM_CALL,
TM_N /* number of elements in the enum */
} TMS;
#define gfasttm(g, et, e) ((et) == NULL ? NULL : ((et)->flags & (1u << (e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
#define fasttm(l, et, e) gfasttm(G(l), et, e)
#define ttypename(x) luaT_typenames_[(x) + 1]
LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS];
LUAI_FUNC const char *luaT_objtypename(lua_State *L, const TValue *o);
LUAI_FUNC const TValue *luaT_gettm(Table *events, TMS event, TString *ename);
LUAI_FUNC const TValue *luaT_gettmbyobj(lua_State *L, const TValue *o,
TMS event);
LUAI_FUNC void luaT_init(lua_State *L);
LUAI_FUNC void luaT_callTM(lua_State *L, const TValue *f, const TValue *p1,
const TValue *p2, TValue *p3, int hasres);
LUAI_FUNC int luaT_callbinTM(lua_State *L, const TValue *p1, const TValue *p2,
StkId res, TMS event);
LUAI_FUNC void luaT_trybinTM(lua_State *L, const TValue *p1, const TValue *p2,
StkId res, TMS event);
LUAI_FUNC int luaT_callorderTM(lua_State *L, const TValue *p1,
const TValue *p2, TMS event);
#endif

View File

@ -1,642 +0,0 @@
/*
** $Id: lua.c,v 1.230.1.1 2017/04/19 17:29:57 roberto Exp $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
#define lua_c
#include "lprefix.h"
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#if !defined(LUA_PROMPT)
#define LUA_PROMPT "> "
#define LUA_PROMPT2 ">> "
#endif
#if !defined(LUA_PROGNAME)
#define LUA_PROGNAME "lua"
#endif
#if !defined(LUA_MAXINPUT)
#define LUA_MAXINPUT 512
#endif
#if !defined(LUA_INIT_VAR)
#define LUA_INIT_VAR "LUA_INIT"
#endif
#define LUA_INITVARVERSION LUA_INIT_VAR LUA_VERSUFFIX
/*
** lua_stdin_is_tty detects whether the standard input is a 'tty' (that
** is, whether we're running lua interactively).
*/
#if !defined(lua_stdin_is_tty) /* { */
#if defined(LUA_USE_POSIX) /* { */
#include <unistd.h>
#define lua_stdin_is_tty() isatty(0)
#elif defined(LUA_USE_WINDOWS) /* }{ */
#include <io.h>
#include <windows.h>
#define lua_stdin_is_tty() _isatty(_fileno(stdin))
#else /* }{ */
/* ISO C definition */
#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
#endif /* } */
#endif /* } */
/*
** lua_readline defines how to show a prompt and then read a line from
** the standard input.
** lua_saveline defines how to "save" a read line in a "history".
** lua_freeline defines how to free a line read by lua_readline.
*/
#if !defined(lua_readline) /* { */
#if defined(LUA_USE_READLINE) /* { */
#include <readline/readline.h>
#include <readline/history.h>
#define lua_readline(L, b, p) ((void)L, ((b) = readline(p)) != NULL)
#define lua_saveline(L, line) ((void)L, add_history(line))
#define lua_freeline(L, b) ((void)L, free(b))
#else /* }{ */
#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, line) \
{ \
(void)L; \
(void)line; \
}
#define lua_freeline(L, b) \
{ \
(void)L; \
(void)b; \
}
#endif /* } */
#endif /* } */
static lua_State *globalL = NULL;
static const char *progname = LUA_PROGNAME;
/*
** Hook set by signal function to stop the interpreter.
*/
static void lstop(lua_State *L, lua_Debug *ar)
{
(void)ar; /* unused arg. */
lua_sethook(L, NULL, 0, 0); /* reset hook */
luaL_error(L, "interrupted!");
}
/*
** Function to be called at a C signal. Because a C signal cannot
** just change a Lua state (as there is no proper synchronization),
** this function only sets a hook that, when called, will stop the
** interpreter.
*/
static void laction(int i)
{
signal(i, SIG_DFL); /* if another SIGINT happens, terminate process */
lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1);
}
static void print_usage(const char *badoption)
{
lua_writestringerror("%s: ", progname);
if (badoption[1] == 'e' || badoption[1] == 'l')
lua_writestringerror("'%s' needs argument\n", badoption);
else
lua_writestringerror("unrecognized option '%s'\n", badoption);
lua_writestringerror(
"usage: %s [options] [script [args]]\n"
"Available options are:\n"
" -e stat execute string 'stat'\n"
" -i enter interactive mode after executing 'script'\n"
" -l name require library 'name' into global 'name'\n"
" -v show version information\n"
" -E ignore environment variables\n"
" -- stop handling options\n"
" - stop handling options and execute stdin\n",
progname);
}
/*
** Prints an error message, adding the program name in front of it
** (if present)
*/
static void l_message(const char *pname, const char *msg)
{
if (pname)
lua_writestringerror("%s: ", pname);
lua_writestringerror("%s\n", msg);
}
/*
** Check whether 'status' is not OK and, if so, prints the error
** message on the top of the stack. It assumes that the error object
** is a string, as it was either generated by Lua or by 'msghandler'.
*/
static int report(lua_State *L, int status)
{
if (status != LUA_OK)
{
const char *msg = lua_tostring(L, -1);
l_message(progname, msg);
lua_pop(L, 1); /* remove message */
}
return status;
}
/*
** Message handler used to run all chunks
*/
static int msghandler(lua_State *L)
{
const char *msg = lua_tostring(L, 1);
if (msg == NULL)
{ /* is error object not a string? */
if (luaL_callmeta(L, 1, "__tostring") && /* does it have a metamethod */
lua_type(L, -1) == LUA_TSTRING) /* that produces a string? */
return 1; /* that is the message */
else
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 */
}
/*
** Interface to 'lua_pcall', which sets appropriate message function
** and C-signal handler. Used to run all chunks.
*/
static int docall(lua_State *L, int narg, int nres)
{
int status;
int base = lua_gettop(L) - narg; /* function index */
lua_pushcfunction(L, msghandler); /* push message handler */
lua_insert(L, base); /* put it under function and args */
globalL = L; /* to be available to 'laction' */
signal(SIGINT, laction); /* set C-signal handler */
status = lua_pcall(L, narg, nres, base);
signal(SIGINT, SIG_DFL); /* reset C-signal handler */
lua_remove(L, base); /* remove message handler from the stack */
return status;
}
static void print_version(void)
{
lua_writestring(LUA_COPYRIGHT, strlen(LUA_COPYRIGHT));
lua_writeline();
}
/*
** Create the 'arg' table, which stores all arguments from the
** command line ('argv'). It should be aligned so that, at index 0,
** it has 'argv[script]', which is the script name. The arguments
** to the script (everything after 'script') go to positive indices;
** other arguments (before the script name) go to negative indices.
** If there is no script name, assume interpreter's name as base.
*/
static void createargtable(lua_State *L, char **argv, int argc, int script)
{
int i, narg;
if (script == argc)
script = 0; /* no script name? */
narg = argc - (script + 1); /* number of positive indices */
lua_createtable(L, narg, script + 1);
for (i = 0; i < argc; i++)
{
lua_pushstring(L, argv[i]);
lua_rawseti(L, -2, i - script);
}
lua_setglobal(L, "arg");
}
static int dochunk(lua_State *L, int status)
{
if (status == LUA_OK)
status = docall(L, 0, 0);
return report(L, status);
}
static int dofile(lua_State *L, const char *name)
{
return dochunk(L, luaL_loadfile(L, name));
}
static int dostring(lua_State *L, const char *s, const char *name)
{
return dochunk(L, luaL_loadbuffer(L, s, strlen(s), name));
}
/*
** Calls 'require(name)' and stores the result in a global variable
** with the given name.
*/
static int dolibrary(lua_State *L, const char *name)
{
int status;
lua_getglobal(L, "require");
lua_pushstring(L, name);
status = docall(L, 1, 1); /* call 'require(name)' */
if (status == LUA_OK)
lua_setglobal(L, name); /* global[name] = require return */
return report(L, status);
}
/*
** Returns the string to be used as a prompt by the interpreter.
*/
static const char *get_prompt(lua_State *L, int firstline)
{
const char *p;
lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2");
p = lua_tostring(L, -1);
if (p == NULL)
p = (firstline ? LUA_PROMPT : LUA_PROMPT2);
return p;
}
/* mark in error messages for incomplete statements */
#define EOFMARK "<eof>"
#define marklen (sizeof(EOFMARK) / sizeof(char) - 1)
/*
** Check whether 'status' signals a syntax error and the error
** message at the top of the stack ends with the above mark for
** incomplete statements.
*/
static int incomplete(lua_State *L, int status)
{
if (status == LUA_ERRSYNTAX)
{
size_t lmsg;
const char *msg = lua_tolstring(L, -1, &lmsg);
if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0)
{
lua_pop(L, 1);
return 1;
}
}
return 0; /* else... */
}
/*
** Prompt the user, read a line, and push it into the Lua stack.
*/
static int pushline(lua_State *L, int firstline)
{
char buffer[LUA_MAXINPUT];
char *b = buffer;
size_t l;
const char *prmt = get_prompt(L, firstline);
int readstatus = lua_readline(L, b, prmt);
if (readstatus == 0)
return 0; /* no input (prompt will be popped by caller) */
lua_pop(L, 1); /* remove prompt */
l = strlen(b);
if (l > 0 && b[l - 1] == '\n') /* line ends with newline? */
b[--l] = '\0'; /* remove it */
if (firstline && b[0] == '=') /* for compatibility with 5.2, ... */
lua_pushfstring(L, "return %s", b + 1); /* change '=' to 'return' */
else
lua_pushlstring(L, b, l);
lua_freeline(L, b);
return 1;
}
/*
** Try to compile line on the stack as 'return <line>;'; on return, stack
** has either compiled chunk or original line (if compilation failed).
*/
static int addreturn(lua_State *L)
{
const char *line = lua_tostring(L, -1); /* original line */
const char *retline = lua_pushfstring(L, "return %s;", line);
int status = luaL_loadbuffer(L, retline, strlen(retline), "=stdin");
if (status == LUA_OK)
{
lua_remove(L, -2); /* remove modified line */
if (line[0] != '\0') /* non empty? */
lua_saveline(L, line); /* keep history */
}
else
lua_pop(L, 2); /* pop result from 'luaL_loadbuffer' and modified line */
return status;
}
/*
** Read multiple lines until a complete Lua statement
*/
static int multiline(lua_State *L)
{
for (;;)
{ /* repeat until gets a complete statement */
size_t len;
const char *line = lua_tolstring(L, 1, &len); /* get what it has */
int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */
if (!incomplete(L, status) || !pushline(L, 0))
{
lua_saveline(L, line); /* keep history */
return status; /* cannot or should not try to add continuation line */
}
lua_pushliteral(L, "\n"); /* add newline... */
lua_insert(L, -2); /* ...between the two lines */
lua_concat(L, 3); /* join them */
}
}
/*
** Read a line and try to load (compile) it first as an expression (by
** adding "return " in front of it) and second as a statement. Return
** the final status of load/call with the resulting function (if any)
** in the top of the stack.
*/
static int loadline(lua_State *L)
{
int status;
lua_settop(L, 0);
if (!pushline(L, 1))
return -1; /* no input */
if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */
status = multiline(L); /* try as command, maybe with continuation lines */
lua_remove(L, 1); /* remove line from the stack */
lua_assert(lua_gettop(L) == 1);
return status;
}
/*
** Prints (calling the Lua 'print' function) any values on the stack
*/
static void l_print(lua_State *L)
{
int n = lua_gettop(L);
if (n > 0)
{ /* any result to be printed? */
luaL_checkstack(L, LUA_MINSTACK, "too many results to print");
lua_getglobal(L, "print");
lua_insert(L, 1);
if (lua_pcall(L, n, 0, 0) != LUA_OK)
l_message(progname, lua_pushfstring(L, "error calling 'print' (%s)",
lua_tostring(L, -1)));
}
}
/*
** Do the REPL: repeatedly read (load) a line, evaluate (call) it, and
** print any results.
*/
static void doREPL(lua_State *L)
{
int status;
const char *oldprogname = progname;
progname = NULL; /* no 'progname' on errors in interactive mode */
while ((status = loadline(L)) != -1)
{
if (status == LUA_OK)
status = docall(L, 0, LUA_MULTRET);
if (status == LUA_OK)
l_print(L);
else
report(L, status);
}
lua_settop(L, 0); /* clear stack */
lua_writeline();
progname = oldprogname;
}
/*
** Push on the stack the contents of table 'arg' from 1 to #arg
*/
static int pushargs(lua_State *L)
{
int i, n;
if (lua_getglobal(L, "arg") != LUA_TTABLE)
luaL_error(L, "'arg' is not a table");
n = (int)luaL_len(L, -1);
luaL_checkstack(L, n + 3, "too many arguments to script");
for (i = 1; i <= n; i++)
lua_rawgeti(L, -i, i);
lua_remove(L, -i); /* remove table from the stack */
return n;
}
static int handle_script(lua_State *L, char **argv)
{
int status;
const char *fname = argv[0];
if (strcmp(fname, "-") == 0 && strcmp(argv[-1], "--") != 0)
fname = NULL; /* stdin */
status = luaL_loadfile(L, fname);
if (status == LUA_OK)
{
int n = pushargs(L); /* push arguments to script */
status = docall(L, n, LUA_MULTRET);
}
return report(L, status);
}
/* bits of various argument indicators in 'args' */
#define has_error 1 /* bad option */
#define has_i 2 /* -i */
#define has_v 4 /* -v */
#define has_e 8 /* -e */
#define has_E 16 /* -E */
/*
** Traverses all arguments from 'argv', returning a mask with those
** needed before running any Lua code (or an error code if it finds
** any invalid argument). 'first' returns the first not-handled argument
** (either the script name or a bad argument in case of error).
*/
static int collectargs(char **argv, int *first)
{
int args = 0;
int i;
for (i = 1; argv[i] != NULL; i++)
{
*first = i;
if (argv[i][0] != '-') /* not an option? */
return args; /* stop handling options */
switch (argv[i][1])
{ /* else check option */
case '-': /* '--' */
if (argv[i][2] != '\0') /* extra characters after '--'? */
return has_error; /* invalid option */
*first = i + 1;
return args;
case '\0': /* '-' */
return args; /* script "name" is '-' */
case 'E':
if (argv[i][2] != '\0') /* extra characters after 1st? */
return has_error; /* invalid option */
args |= has_E;
break;
case 'i':
args |= has_i; /* (-i implies -v) */ /* FALLTHROUGH */
case 'v':
if (argv[i][2] != '\0') /* extra characters after 1st? */
return has_error; /* invalid option */
args |= has_v;
break;
case 'e':
args |= has_e; /* FALLTHROUGH */
case 'l': /* both options need an argument */
if (argv[i][2] == '\0')
{ /* no concatenated argument? */
i++; /* try next 'argv' */
if (argv[i] == NULL || argv[i][0] == '-')
return has_error; /* no next argument or it is another option */
}
break;
default: /* invalid option */
return has_error;
}
}
*first = i; /* no script name */
return args;
}
/*
** Processes options 'e' and 'l', which involve running Lua code.
** Returns 0 if some code raises an error.
*/
static int runargs(lua_State *L, char **argv, int n)
{
int i;
for (i = 1; i < n; i++)
{
int option = argv[i][1];
lua_assert(argv[i][0] == '-'); /* already checked */
if (option == 'e' || option == 'l')
{
int status;
const char *extra = argv[i] + 2; /* both options need an argument */
if (*extra == '\0')
extra = argv[++i];
lua_assert(extra != NULL);
status = (option == 'e')
? dostring(L, extra, "=(command line)")
: dolibrary(L, extra);
if (status != LUA_OK)
return 0;
}
}
return 1;
}
static int handle_luainit(lua_State *L)
{
const char *name = "=" LUA_INITVARVERSION;
const char *init = getenv(name + 1);
if (init == NULL)
{
name = "=" LUA_INIT_VAR;
init = getenv(name + 1); /* try alternative name */
}
if (init == NULL)
return LUA_OK;
else if (init[0] == '@')
return dofile(L, init + 1);
else
return dostring(L, init, name);
}
/*
** Main body of stand-alone interpreter (to be called in protected mode).
** Reads the options and handles them all.
*/
static int pmain(lua_State *L)
{
int argc = (int)lua_tointeger(L, 1);
char **argv = (char **)lua_touserdata(L, 2);
int script;
int args = collectargs(argv, &script);
luaL_checkversion(L); /* check that interpreter has correct version */
if (argv[0] && argv[0][0])
progname = argv[0];
if (args == has_error)
{ /* bad arg? */
print_usage(argv[script]); /* 'script' has index of bad arg. */
return 0;
}
if (args & has_v) /* option '-v'? */
print_version();
if (args & has_E)
{ /* option '-E'? */
lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */
lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
}
luaL_openlibs(L); /* open standard libraries */
createargtable(L, argv, argc, script); /* create table 'arg' */
if (!(args & has_E))
{ /* no option '-E'? */
if (handle_luainit(L) != LUA_OK) /* run LUA_INIT */
return 0; /* error running LUA_INIT */
}
if (!runargs(L, argv, script)) /* execute arguments -e and -l */
return 0; /* something failed */
if (script < argc && /* execute main script (if there is one) */
handle_script(L, argv + script) != LUA_OK)
return 0;
if (args & has_i) /* -i option? */
doREPL(L); /* do read-eval-print loop */
else if (script == argc && !(args & (has_e | has_v)))
{ /* no arguments? */
if (lua_stdin_is_tty())
{ /* running in interactive mode? */
print_version();
doREPL(L); /* do read-eval-print loop */
}
else
dofile(L, NULL); /* executes stdin as a file */
}
lua_pushboolean(L, 1); /* signal no errors */
return 1;
}
int main(int argc, char **argv)
{
int status, result;
lua_State *L = luaL_newstate(); /* create state */
if (L == NULL)
{
l_message(argv[0], "cannot create state: not enough memory");
return EXIT_FAILURE;
}
lua_pushcfunction(L, &pmain); /* to call 'pmain' in protected mode */
lua_pushinteger(L, argc); /* 1st argument */
lua_pushlightuserdata(L, argv); /* 2nd argument */
status = lua_pcall(L, 2, 1, 0); /* do the call */
result = lua_toboolean(L, -1); /* get result */
report(L, status);
lua_close(L);
return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
}

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