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

wordpress连接服务器wordpress网站seo设置

wordpress连接服务器,wordpress网站seo设置,网站开发时间进度表 开发费用,六安网站建设电话前言 在 lua vm 中#xff0c;upvalue 是一个重要的数据结构。upvalue 以一种高效的方式实现了词法作用域#xff0c;使得函数能成为 lua 中的第一类值#xff0c;也因其高效的设计#xff0c;导致在实现上有点复杂。 函数 (proto) upvalue 构成了闭包#xff08;closu…前言 在 lua vm 中upvalue 是一个重要的数据结构。upvalue 以一种高效的方式实现了词法作用域使得函数能成为 lua 中的第一类值也因其高效的设计导致在实现上有点复杂。 函数 (proto) upvalue 构成了闭包closure在 lua 中调用一个函数实际上是调用一个闭包。upvalue 就相当于函数的上下文。 这种带 “上下文” 的函数也导致了热更新的麻烦可以说是麻烦透顶了。没法简单的通过替换新的函数代码来更新一个旧闭包因为旧闭包上可能带着几个 upvalue这几个 upvalue 的值可能已经发生改变或者也被其他的函数引用着。 图1函数与upvalue 所以要更新一个旧闭包得把旧闭包上的所有 upvalue 都找出来绑定到新函数上形成一个新闭包再用这个新闭包替换旧闭包。 本文主要讲 upvalue 在 lua vm 中的实现下篇文章再讲如何解决带有 upvalue 的闭包的热更新问题。 下文分析基于 lua5.4.6。 1. upvalue 1.1 upvalue 实现上要解决的问题 upvalue 就是外部函数的局部变量比如下面的函数定义中var1 就是 inner 的一个 upvalue。 local function getf(delta)local var1 100local function inner()return var1deltaendreturn inner endlocal f1 getf(10)upvalue 复杂的地方在于在离开了 upvalue 的作用域之后还要能够访问得到。比如上面调用了 local f1 getf(10) var1 是在 getf 的栈上分配的getf 返回后栈空间被抹掉但 inner 还要能访问 var1所以要想办法把它捕捉下来。 1.2 upvalue 的实现 下面先讲 lua 闭包的 upvalue最后再讲 c 闭包的因为复杂性几乎都在 lua 闭包这里面了。 1.2.1 upvalue 相关的结构体 与 upvalue 相关的结构体有 1、UpVal可以说是 upvalue 的本体了很巧妙的结构运行时用到的变量。 typedef struct UpVal {CommonHeader;union {TValue *p; /* points to stack or to its own value */ptrdiff_t offset; /* used while the stack is being reallocated */} v;union {struct { /* (when open) */struct UpVal *next; /* linked list */struct UpVal **previous;} open;TValue value; /* the value (when closed) */} u; } UpVal;2、Upvaldesc这个是编译时产生的信息Proto 结构体就包含 Upvaldesc* 类型的数组upvalues用于描述当前函数用到的 upvalue 信息。 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 functions list) */lu_byte kind; /* kind of corresponding variable */ } Upvaldesc;typedef struct Proto {...Upvaldesc *upvalues; /* upvalue information */... } Proto; 3、lua_State 中的 openupval 字段它是 UpVal* 类型的链表它相当于一个 cache保存当前栈上还存活着的被引用到的 upvalue。 struct lua_State {...UpVal *openupval; /* list of open upvalues in this stack */... };4、LClosure 中的 upvals 数组。 typedef struct LClosure {ClosureHeader;struct Proto *p;UpVal *upvals[1]; /* list of upvalues */ } LClosure;1.2.2 upvalue 的访问 upvalue 是间接访问的LClosure 结构体的 upvals 字段是 UpVal* 类型的数组。访问的时候先通过 upvals 获得到 UpVal 指针再通过 UpVal 里面的 v.p 去访问具体的变量伪码如下 UpVal* UpValPtr closure-upvals[upidx]; TValue* p UpValPtr-v.p;需要这样间接访问主要是因为 UpVal 本身会随着函数调用的返回发生状态的变化从 open 改为 close这时它的值也从栈上被拷贝到了 “自己身上”所以指针v.p是变化的不能写死。 至于为什么会发生 open 到 close 的变化后面会讲。 1.2.3 upvalue 的创建 upvalue 是在编译的时候计算好一个 Proto 需要什么 upvalue相关信息存放在 Proto 的 upvalues 数组 Upvaldesc *upvalues; /* upvalue information */中的。 举个例子对于这样一个脚本内部的函数 f1、f2 既引用了 getf 之外的变量 var1也引用了 getf 之内的变量 var2、var3并且在 local f1, f2 getf() 调用完成后f1 还要能访问到 var1、var2f2 还要能访问到 var1、var3。 local var1 1local function getf()local var2 2local var3 3local function f1()return var1 var2endlocal function f2()return var1 var3endreturn f1, f2 endlocal retf1, retf2 getf() 编译结果是 图2upvalue 编译信息 从编译结果可以看到每个 Proto 都会生成 UpvalueDesc 数组用于描述这个函数proto会用到的 upvalue。 index 表示在 LClosure 的 upvals 数组中是第几个。 name 表示变量名。 instack 表示这个 upvalue 是否刚好是上一层函数的局部变量比如 var2 是 f1 的上一层的所以 instack 为 true而 var1 是上两层的所以为 false。 idx 表示 instack 为 false 的情况下可以在上一层函数的 upvals 数组的第几个找到这个 upvalue。 kind 表示 upvalue 类型一般都是 VDKREG即普通类型。 补充说明kind 是 lua5.4 才整出来的lua5.3 及之前都只有 VDKREG。5.4 新增了 RDKCONSTRDKTOCLOSERDKCTC。 RDKCONST 是对应到 const指定变量为常量。 RDKTOCLOSE 是对应到 close指定变量为 to be closed 的类似于 RAII 特性超出作用域后执行 __close 元函数。 RDKCTC 我也闹不清楚。 从例子上可以看到f1 引用了上一层函数 getf 的局部变量 var2所以它的 instack 值是 true而引用了上两层的局部变量 var1则它的 instack 是 false。 instack 主要就是在创建 Closure 的时候帮助初始化 Closure 的 upvals 数组对于 instack 为 true 的 upvalue直接搜索上一层函数的栈空间即可对于 instack 为 false 的 upvalue就不能这样了为什么呢因为上两层的有可能已经不在栈上了。能想象得到吗举个例子 local function l1()local var1 1local function l2()local var2 2local function l3()return var1var23endreturn l3endreturn l2 endlocal ret_l2 l1()local ret_l3 ret_l2()调用 l1 的时候得到了 l2这时候 l1 已经返回了它的栈已经回收了这时候再调用 l2在创建 l3 这个闭包的时候是不可能再找到 l1 的栈去搜索 var1 这个变量的。 所以要解决这个问题就需要让 l2 在创建的时候先帮忙把 var1 捕捉下来保存到自己的 upvals 数组中等 l3 创建的时候就可以从 l2 的 upvals 数组中找到了。 这正是 pushclosure 干的活 static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,StkId ra) {int nup p-sizeupvalues;Upvaldesc *uv p-upvalues;int i;LClosure *ncl luaF_newLclosure(L, nup);ncl-p p;setclLvalue2s(L, ra, ncl); /* anchor new closure in stack */for (i 0; i nup; i) { /* fill in its upvalues */if (uv[i].instack) /* upvalue refers to local variable? */ncl-upvals[i] luaF_findupval(L, base uv[i].idx);else /* get upvalue from enclosing function */ncl-upvals[i] encup[uv[i].idx];luaC_objbarrier(L, ncl, ncl-upvals[i]);} }函数实现可以看到instack 为 true 时调用 luaF_findupval 去上一层函数的栈上搜索instack 为 false 时上一层函数已经帮忙捕捉好了直接从它的 upvals 数组即这里的 encup 变量中索引。 这里 uv[i].idx 就是上面 upvaldesc 的 idx 列即当 instack 为 false 时它对应于上一层函数的 upvals 数组的第几项。 1.2.4 upvalue 的变化从 open 到 close 分两个阶段讲getf 调用时以及 getf 调用后。 1、getf 调用时var2、var3 这两个变量作为 f1, f2 的 upvalue它们还处在 getf 的栈上这时候它们会被放在 lua_State 的 openupval 链表中。 2、getf 调用后它的栈要被收回的这时候 lua vm 会调用 luaF_close 来关闭 getf 栈上被引用的 upvalue最终是 luaF_closeupval 这个函数执行 void luaF_closeupval (lua_State *L, StkId level) {UpVal *uv;StkId upl; /* stack index pointed by uv */while ((uv L-openupval) ! NULL (upl uplevel(uv)) level) {TValue *slot uv-u.value; /* new position for value */lua_assert(uplevel(uv) L-top.p);luaF_unlinkupval(uv); /* remove upvalue from openupval list */setobj(L, slot, uv-v.p); /* move value to upvalue slot */uv-v.p slot; /* now current value lives here */if (!iswhite(uv)) { /* neither white nor dead? */nw2black(uv); /* closed upvalues cannot be gray */luaC_barrier(L, uv, slot);}} }要理解这个函数就要知道 StkId level 这个参数的意义它在这里是 getf 的 base 指针即它的栈底。同个 lua_State 的函数调用链上的所有函数共用一个栈按顺序各占一段栈空间栈是一个数组所以后调用的函数的变量在栈上的索引是更大的表现上就是指针值更大。而 openupval 链表里面 Upval 里的 p 就是指向这指针所以遍历 openupval 的时候遇到 p 比 base 大的就表明这个是 getf 栈上的变量要把它 close 掉。 close 的操作就是把 upval 从 openupval 链表移掉同时把 upval 的 p 指向的值拷贝到它自身上。 图3upvalue close 时的拷贝 1.2.5 C 闭包中的 upvalue C 闭包CClosure也是有 upvalue 的是在 lua_pushcclosure 时设置的但用的是值拷贝所以多个 C 闭包不能共享 upvalue。如果要在多个 C 闭包只能是各自的upvalue 指向同一个 table 这样的变量。 CClosure 的 upvalue 直接用的是 TValue 类型的数组不是指针在创建的时候用的值拷贝。 typedef struct CClosure {ClosureHeader;lua_CFunction f;TValue upvalue[1]; /* list of upvalues */ } CClosure;2. 参考
http://www.w-s-a.com/news/720408/

相关文章:

  • 网站建设公司哪家好 皆来磐石网络网站建设"淘宝网" 在颜色选取和搭配方面有哪些值得学习的地方.
  • 网站如何做移动规则适配北京住房与城乡建设部网站
  • 课堂阵地建设网站wordpress运行机制
  • 网站建设的需求方案企业网站建设费用明细
  • 创口贴网站模板京创影视app
  • 团购网站建设目的网站有很多304状态码
  • 运用阿里云怎么做网站外资企业可以在中国境内做网站吗
  • 云南住房和城乡建设局网站西安做官网的公司
  • 企业网站图片上传网站建设和应用的情况
  • 网站不显示内容吗聊城网架公司
  • 南昌网站建设企业网站托管外包怎么做
  • 做非洲外贸的网站网站可以用PS设计吗
  • PHP搭建IDC网站青岛福瀛建设集团网站
  • 安徽网站优化多少钱软件界面设计的基本原则
  • 网站建设动态页面修改删除dnf卖飞机的网站怎么做的
  • 万网是做什么的seo综合
  • 网站关键词分隔符php网站开发平台下载
  • 郑州那家做网站便宜商业计划书免费word版
  • 秦时明月的个人网站怎么做网站开发公司需要招聘哪些人
  • 广告网站建设制作设计服务商安卓app软件定制
  • 公司网站设计与实现中国职业培训在线官方网站
  • 网站服务器空间租用郑州官网网站推广优化
  • 郑州网站建设外包业务wordpress站酷首页
  • 机关门户网站 建设 方案个人怎么申请注册商标
  • 梧州网站建设有哪些九江网站建设优化
  • APP网站建设开发企业发展英文seo招聘
  • 临海市住房和城乡建设规划局网站高校图书馆网站的建设方案
  • 建立门户网站张店易宝网站建设
  • wordpress中英文站点厦门seo顾问屈兴东
  • 邯郸网站建设项目重庆网站备案系统