当前位置: 首页 > news >正文

Lua的环境与热更

一、global_State,lua_State与G表

Lua支持多线程环境,使用 lua_State 结构来表示一个独立的 Lua 线程(或协程)。每个线程都需要一个独立的全局环境。而lua_State 中的l_G指针,指向一个global_State结构,这个就是我们常说的G表,也就是一个全局变量和虚拟机全局资源的集合。

struct lua_State {CommonHeader;lu_byte status;StkId top;  /* first free slot in the stack */StkId base;  /* base of current function */global_State *l_G;CallInfo *ci;  /* call info for current function */const Instruction *savedpc;  /* `savedpc' of current function */StkId stack_last;  /* last free slot in the stack */StkId stack;  /* stack base */CallInfo *end_ci;  /* points after end of ci array*/CallInfo *base_ci;  /* array of CallInfo's */int stacksize;int size_ci;  /* size of array `base_ci' */unsigned short nCcalls;  /* number of nested C calls */unsigned short baseCcalls;  /* nested C calls when resuming coroutine */lu_byte hookmask;lu_byte allowhook;int basehookcount;int hookcount;lua_Hook hook;TValue l_gt;  /* table of globals */TValue env;  /* temporary place for environments */GCObject *openupval;  /* list of open upvalues in this stack */GCObject *gclist;struct lua_longjmp *errorJmp;  /* current error recover point */ptrdiff_t errfunc;  /* current error handling function (stack index) */
};

下面看看global_State,它是 Lua 虚拟机全局的状态结构体,存储了与整个 Lua 虚拟机相关的全局数据和资源。它是为整个 Lua 实例共享的数据结构,而非单个线程或协程。

typedef struct global_State {stringtable strt;  /* hash table for strings */lua_Alloc frealloc;  /* function to reallocate memory */void *ud;         /* auxiliary data to `frealloc' */lu_byte currentwhite;lu_byte gcstate;  /* state of garbage collector */int sweepstrgc;  /* position of sweep in `strt' */GCObject *rootgc;  /* list of all collectable objects */GCObject **sweepgc;  /* position of sweep in `rootgc' */GCObject *gray;  /* list of gray objects */GCObject *grayagain;  /* list of objects to be traversed atomically */GCObject *weak;  /* list of weak tables (to be cleared) */GCObject *tmudata;  /* last element of list of userdata to be GC */Mbuffer buff;  /* temporary buffer for string concatentation */lu_mem GCthreshold;lu_mem totalbytes;  /* number of bytes currently allocated */lu_mem estimate;  /* an estimate of number of bytes actually in use */lu_mem gcdept;  /* how much GC is `behind schedule' */int gcpause;  /* size of pause between successive GCs */int gcstepmul;  /* GC `granularity' */lua_CFunction panic;  /* to be called in unprotected errors */TValue l_registry;struct lua_State *mainthread;UpVal uvhead;  /* head of double-linked list of all open upvalues */struct Table *mt[NUM_TAGS];  /* metatables for basic types */TString *tmname[TM_N];  /* array with tag-method names */
} global_State;

再进一步讲,lua_state 是暴露给用户的数据类型,既表示一个 lua 程序的执行状态,也指代 lua 的一个线程(在官方文档中)。每个线程拥有独立的数据栈以及函数调用栈,还有独立的调试钩子和错误处理设置。所以我们不应当简单的把lua_state 看成一个静态的数据集,它是一个lua 线程的执行状态。所有的lua C API 都是围绕这个状态机:
或把数据压入堆栈,或取出,或执行栈顶的函数,或继续上次被中断的执行过程。

从 lua 的使用者的角度看,global_state 是不可见的。我们无法用公开的 api 取到它的指针,也不需要引用它。但分析lua 的实现就不能绕开这个部分。
global_state  里面有对主线程的引用,有注册表管理所有全局数据,有全局字符串表,有内存管理函数,有GC 需要的把所有对象串联起来的相关信息,以及一切 lua 在工作时需要的工作内存。

二、_ENV 是什么

_ENV其实代表的是当前函数的环境,一个环境就是一个表,该函数被限定为只能访问该表中的域,或在函数体内自己定义的变量。

在 Lua 中,会为每个代码段增加一个预定义上值,即 _ENV 。他是一个外部局部变量,会将代码段中使用的 “全局变量” 存在这个 _ENV 中。

Lua 编译器会将以下代码段进行转换,全局变量都会被带上 _ENV

local i = 10
j = 100
k = j + i
print(i, j, k)

会被转换为

local i = 10
_ENV.j = 100
_ENV.k = _ENV.j + i
print(i, _ENV.j, _ENV.k)

 对于上面的代码段, _ENV 的存在点,可以理解为如下

local _ENV = 初始化
return function (...)local i = 10_ENV.j = 100_ENV.k = _ENV.j + iprint(i, _ENV.j, _ENV.k)
end

这里可以注意到 _ENV 是一个代码段外部的局部变量 ,但是他会进行初始化,理论上他可以是任意的表,但是为了维护全局的概念,所以这里会使用 _G 进行初始化,这样就让我们无感知的使用到了全局。

我们可以将 _ENV 和 _G 进行打印,在不进行修改的情况下,_ENV 和 _G 两者其实都是同一个表

doprint(_ENV, _G)     --> table: 0x6000007d4200	table: 0x6000007d4200
end
那么我们通常去查找一个全局变量时,其实是在当前函数环境,也就是当前函数的env表中查找(准确来说是到函数对应的Closure(闭包)指针中的env表去查询数据)。这里提到的“当前函数环境”,指的不一定是某一个具体的函数,也可能是一个 Lua文件。
早期的Lua 提供了几个 API 来读取当前函数的环境,分别是 getfenv和 set env
因此,如果执行以下代码:
setfenv(1,{})
print(a)
实际上找不到 Lua 标准库提供的 print 函数,并且会提示报错 attempt to call global ’print’(a  nil
value )。 原因就是首先使用 setfenv将当前函数的env表置为一个空表 , env 表中查找不到这个名字的函数。
下面来看看函数的 env 表是如何创建的 在创建一个 Closure 对象时,都会调用 getcurrenv
函数来获取当前的环境表:
(lapi.c) 
79 static Table *getcurrenv (lua_State *L) { 
80     if (L- >ci == L- >base_ci) /* no enclosing function? */ 
81         return hvalue(gt(L)); /* use global table as environment */ 
82     else { 
83         Closure unc = curr_func(L); 
84         return func ->c.env; 
85     } 
86 }
它将区分如下两种情况。
1.如果该函数不是内嵌函数,那么直接返回G表
2.否则,如果是内嵌函数,就返回其母函数的 env表
在创建一个新的Closure(闭包) 时,会调用这个函数返回的结果,对新的 Closure 的环境进行赋值
这里可以看出, env 表会逐层继承。

三、Lua的热更

理解了ENV,热更部分可以先参考Lua 的代码加载和热更新方式

未完待续...

相关文章:

Lua的环境与热更

一、global_State,lua_State与G表 Lua支持多线程环境,使用 lua_State 结构来表示一个独立的 Lua 线程(或协程)。每个线程都需要一个独立的全局环境。而lua_State 中的l_G指针,指向一个global_State结构,这个就是我们常…...

HTML CSS JS基础考试题与答案

一、选择题&#xff08;2分/题&#xff09; 1&#xff0e;下面标签中&#xff0c;用来显示段落的标签是&#xff08; d &#xff09;。 A、<h1> B、<br /> C、<img /> D、<p> 2. 网页中的图片文件位于html文件的下一级文件夹img中&#xff0c;…...

若依解析(一)登录认证流程

JWTSpringSecurity 6.X 实现登录 JWT token只包含uuid ,token 解析uuid&#xff0c;然后某个常量加UUID 从Redis缓存查询用户信息 流程图如下 感谢若依&#xff0c;感谢开源&#xff0c;能有这么好系统供我学习。 设计数据库&#xff0c;部门表&#xff0c;用户表&#xff0c…...

Redis设计与实现第17章 -- 集群 总结1(节点 槽指派)

集群通过分片sharding来进行数据共享&#xff0c;并提供复制和故障转移功能。 17.1 节点 一个Redis集群通常由多个节点node组成&#xff0c;刚开始每个节点都是相互独立的&#xff0c;必须将各个独立的节点连接起来&#xff0c;才能构成一个包含多个节点的集群。通过CLUSTER …...

汽车控制软件下载移动管家手机控车一键启动app

移动管家手机控制汽车系统是一款实现车辆远程智能控制的应用程序‌。通过下载并安装特定的APP&#xff0c;用户可以轻松实现以下功能&#xff1a;‌远程启动与熄火‌&#xff1a;无论身处何地&#xff0c;只要有网络&#xff0c;即可远程启动或熄火车辆&#xff0c;提前预冷或预…...

推荐几个可以免费下载网站模板的资源站

推荐几个可以免费下载网站模板的资源站&#xff0c;上面有免费的wordpress模板和帝国CMS模板可以下载。 模板帝 Mobandi.com 模板帝是一个提供丰富网站模板资源的平台&#xff0c;旨在帮助用户快速构建和美化自己的网站。无论是个人博客、企业官网还是电子商务平台&#xff…...

H3C OSPF实验

实验拓扑 实验需求 按照图示配置 IP 地址按照图示分区域配置 OSPF &#xff0c;实现全网互通为了路由结构稳定&#xff0c;要求路由器使用环回口作为 Router-id&#xff0c;ABR 的环回口宣告进骨干区域 实验解法 一、配置IP地址 [R1]int l0 [R1-LoopBack0]ip add 1.1.1.1 32 […...

Vue框架开发一个简单的购物车(Vue.js)

让我们利用所学知识来开发一个简单的购物车 &#xff08;记得暴露属性和方法&#xff01;&#xff01;&#xff01;&#xff09; 首先来看一下最基本的一个html框架 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"&…...

Windows Terminal Solarized Dark 配色方案调整

起因 Widnows 10/11 下面自带的 Terminal 还是比较方便的&#xff0c;因为不需要安装额外的 Terminal 软件。 我喜欢 Solarized Dark 配色方案&#xff0c;虽然有人批评这个配色方案比较老&#xff0c;但我觉得它比较优雅&#xff0c;尤其对外这种眼神比较差的人&#xff0c;比…...

PyTorch张量运算与自动微分

PyTorch张量运算与自动微分 PyTorch由Facebook人工智能研究院于2017年推出&#xff0c;具有强大的GPU加速张量计算功能&#xff0c;并且能够自动进行微分计算&#xff0c;从而可以使用基于梯度的方法对模型参数进行优化&#xff0c;大部分研究人员、公司机构、数据比赛都使用P…...

【从零开始的LeetCode-算法】3264. K 次乘运算后的最终数组 I

给你一个整数数组 nums &#xff0c;一个整数 k 和一个整数 multiplier 。 你需要对 nums 执行 k 次操作&#xff0c;每次操作中&#xff1a; 找到 nums 中的 最小 值 x &#xff0c;如果存在多个最小值&#xff0c;选择最 前面 的一个。将 x 替换为 x * multiplier 。 请你…...

【Linux】gdb / cgdb 调试 + 进度条

&#x1f33b;个人主页&#xff1a;路飞雪吖~ &#x1f320;专栏&#xff1a;Linux 目录 一、Linux调试器-gdb &#x1f31f;开始使用 &#x1f320;小贴士&#xff1a; &#x1f31f;gdb指令 &#x1f320;小贴士&#xff1a; ✨watch 监视 ✨打条件断点 二、小程序----进…...

Jenkins Nginx Vue项目自动化部署

目录 一、环境准备 1.1 Jenkins搭建 1.2 NVM和Nodejs安装 1.3 Nginx安装 二、Jenkins配置 2.1 相关插件安装 2.2 全局工具安装 2.3 环境变量配置 2.4 邮箱配置&#xff08;构建后发送邮件&#xff09; 2.5 任务配置 三、Nginx配置 3.1 配置路由转发 四、部署项目 …...

视频汇聚平台Liveweb国标GB28181视频平台监控中心设计

在现代安防视频监控领域&#xff0c;Liveweb视频汇聚平台以其卓越的兼容性和灵活的拓展能力&#xff0c;为用户提供了一套全面的解决方案。该平台不仅能够实现视频的远程监控、录像、存储与回放等基础功能&#xff0c;还涵盖了视频转码、视频快照、告警、云台控制、语音对讲以及…...

文件比较和文件流

文件比较和文件流 一、文本比较工具 diff1.基本用法1.1输出格式 2.常用选项 二、文件流1.文件的打开模式2.文件流的分类ifstreamofstreamfstrem区别 3.文件流的函数1. 构造函数2. is_open 用于判断文件是否打开3. open4. getline5. close6. get()7. read8. write9. put10. gcou…...

【2024最新】基于Springboot+Vue的就业信息管理系统Lw+PPT

作者&#xff1a;计算机搬砖家 开发技术&#xff1a;SpringBoot、php、Python、小程序、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;Java精选实战项…...

PySide6 QSS(Qt Style Sheets) Reference: PySide6 QSS参考指南

Qt官网参考资料&#xff1a; QSS介绍&#xff1a; Styling the Widgets Application - Qt for Pythonhttps://doc.qt.io/qtforpython-6/tutorials/basictutorial/widgetstyling.html#tutorial-widgetstyling QSS 参考手册&#xff1a; Qt Style Sheets Reference | Qt Widge…...

【笔记】成为雍正

观古代历史&#xff0c;不过帝王一家一姓之家史 时间 1662年&#xff0c;田文镜出生。1672年&#xff0c;张廷玉出生。1674年&#xff0c;胤礽出生。1678年&#xff0c;胤禛出生。1679年&#xff0c;年羹尧出生。1680年&#xff0c;鄂尔泰出生。1700年&#xff0c;索额图被赐死…...

Codeforces Round 913 (Div. 3)

题目链接 B. YetnotherrokenKeoard 题意 输入 输出 思路 用两个栈分别维护小写字母下标和大写字母下标&#xff0c;用一个vis数组标记字母是否删除 示例代码 void solve() {string s;cin >> s;int n s.size();vector<bool> vis(n, false);stack<int>sk…...

斐波那契数

C语言实现斐波那契数列的多种方法_斐波那契数列c语言-CSDN博客 题目描述 斐波那契数列为&#xff1a;1,1,2,3,5,8,13.....&#xff0c;常规递推公式f(n)f(n-1)f(n-2); 输入描述 输入一个整数n(0<n<50),为多组数据。 输出描述 输出第n个斐波那契数 样例输入 1 2 4样例输出…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理

在城市的某个角落&#xff0c;一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延&#xff0c;滚滚浓烟弥漫开来&#xff0c;周围群众的生命财产安全受到严重威胁。就在这千钧一发之际&#xff0c;消防救援队伍迅速行动&#xff0c;而豪越科技消防一体化安全管控平台构建的消防“…...

【51单片机】4. 模块化编程与LCD1602Debug

1. 什么是模块化编程 传统编程会将所有函数放在main.c中&#xff0c;如果使用的模块多&#xff0c;一个文件内会有很多代码&#xff0c;不利于组织和管理 模块化编程则是将各个模块的代码放在不同的.c文件里&#xff0c;在.h文件里提供外部可调用函数声明&#xff0c;其他.c文…...

理想汽车5月交付40856辆,同比增长16.7%

6月1日&#xff0c;理想汽车官方宣布&#xff0c;5月交付新车40856辆&#xff0c;同比增长16.7%。截至2025年5月31日&#xff0c;理想汽车历史累计交付量为1301531辆。 官方表示&#xff0c;理想L系列智能焕新版在5月正式发布&#xff0c;全系产品力有显著的提升&#xff0c;每…...