Lua源码分析 Gc篇(二)数据结构 副本
[TOC]
这是这个gc系列的第二篇,这一篇主要讲GC用到的数据结构,有助于理解gc的,所以放在前面
栈就是我们平时写代码接触最多的lua_State。在实现上是用一个数组实现的。每个成员类型是TValue,看下文详细介绍。这里不打算详细介绍栈的结构和内容,只会介绍和gc相关的一些内容,主要是帮助我们更好的理解lua的gc。
定义
下面是lua_State的定义,会看到栈的身影,top和base指针。
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 * ...
PIL.9Lua中的闭包
Lua中的函数是 第一类的值加上合适的词法域。那么,函数是第一类值意味着什么呢?这是说,在Lua中,一个函数,就是一个和 数字或字符串一样具有某些权限的值。一个程序可以把函数存储在变量中(全局或者局部都可以)和表中,把函数作为参数传递给其他函数,或者以函数作为值返回。
函数具有词法域又是什么意思呢?就是说函数可以访问他们包裹函数的变量。
这两个特性给了Lua巨大的弹性;具体点说,一个程序在运行一段不受信任的代码时(比如从网络上收到的代码)可以重新定义一个函数来增加功能或者擦除一个函数来创建一个安全的环境。更重要的是,这些特性运行我们从函数语言的世界应用很多强大的编程技术到Lua。即使你对函数式编程没有什么兴趣,但是看一下这些技术是非常有价值的,这会让你的程序更小更简单。
下面的例子说明了函数作为第一类值的情况:
a = {p = print} a.p("hello world") -- hello worldprint = math.sin -- 'print' now refers to the sine functiona.p(print(1)) ...
Lua之Table个人总结
在lua中Table是数组和集合的混合物。作为数组时,可以使用除了nil以外的值作为索引。
Table的构造利用下标来标明元素123456local table = {}table[1]='hello'table[5]='world'for i,v in pairs(table)do print(table[i])end
输出121 hello5 world
在Table内部通过索引来声明1234local table = { [1] = 'hello', [5] = 'world' }for i, v in pairs(table) do print(table[i])end
输出121 hello5 world
在Table内部不通过索引来声明1234local table = {'hello','world'}for k, v in pairs(table) do print(k,v)end
输出121 hello2 world
Note:
1,可以看到通过 ...
Lua学习笔记一
PS:由于公司项目中用到Lua,所以准备学习一下,这里做下学习笔记。
Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
基本语法交互式编程lua -i 进入交互式编程
脚本式编程新建一个hello.lua文件,将lua代码写在hello.lua中
print("Hello world")
执行:
lua hello.lua
结果:
Hello rorld
也可以将代码改为如下形式:
12#!/usr/local/bin/luaprint("Hello world")
执行:
./hello.lua
结果和上面一样。
这种模式称为脚本式编程。
注释单行注释:
--
多行注释:
1234 多行注释 多行注释--]]
标识符以字母或者下划线_开头,后面加上0个或多个字母,下划线,数字。(标识符区分大小写)
关键字
and
break
do
else
elseif
end
false
for
function
if
in
local
nil
n ...
Lua学习笔记(五)
错误处理
assert
error
pcall
xpcall
debug
调试
垃圾回收
垃圾回收函数
错误处理平时写代码的时候出现错误其实是一件十分平常的事情,自然,如何处理错误也是需要联系的方法。
一般在Lua中可以使用assert和error来处理错误。
assert简单实例:
123456local function add(a,b) assert(type(a)=="number","a不是数字") assert(type(b)=="number","b不是数字") return a+bendadd(10)
输出结果:
在这个过程中,assert先检查第一个参数,如果没问题什么也不做,如果有问题的话,就把第二个参数作为错误信息抛出来。
error语法:
1error (message [, level])
error的功能主要就是终止在执行的函数,同时返回message的内容作为错误信息(error永远不会返回),一般情况就是,error附加一些错误位置的信息到message的头部 ...
Redis Lua脚本中学教程(下)
在中学教程的上半部分我们介绍了Redis Lua相关的命令,没有看过或者忘记的同学可以步行前往直接使用机票Redis Lua脚本中学教程(上)。今天我们来简单学习一下Lua的语法。
在介绍Lua语法之前,先来介绍一下Lua的身世。Lua是由简称为PUC-Rio的团队设计、开发和维护的。Lua在葡萄牙语中是月亮的意思,所以它不是简写,而是一个名词。所以只能写成Lua,而不能写成LUA或者其他什么的。接下来我们正式入门Lua。
变量变量名可以是由字母、数字和下划线组成的字符串,但不能以数字开头。另外需要注意的是,需要尽量避免使用下划线加一个或多个大写字母格式的变量名,因为这是Lua的保留字,除了这种格式以外,还有一些普通格式的保留字:
and
break
do
else
elseif
end
false
for
function
goto
if
in
local
nil
not
or
repeat
return
then
true
until
while
Lua是大小写敏感的,and是保留字,但And和AND不是。
全局变量前面我们提到过Redis不支 ...
Lua
Lua是一个简洁,轻量,可扩展的脚本语言。其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。
Lua源码结构
虚拟机核心功能lapi.c lctype.c ldebug.c ldo.c lfunc.c lgc.c lmem.c lobject.c lopcodes.c lstate.c lstring.c ltable.c ltm.c lvm.c lzio.c
源码解析及预编译字节码lcode.c ldump.c llex.c lparser.c lunddump.c
内嵌库lauxlib.c lbaselib.c lbitlib.c lcorolib.c ldblib.c linit.c liolib.c lmathlib.c loadlib.c loslib.c lstrlib.c ltablib.c
可执行文件lua.c(解析器) luac.c(编译器)
Building lua on windows在virtual studio中创建以下3个项目
链接库:虚拟机核心功能,源码解析及预编译字节码,内嵌库
解析:解析器,依赖链接库
编译:编译器,依 ...
PIL.33Lua的线程和状态机
Lua并不支持真正的多线程,也就是说,抢先的线程间共享内存。缺乏这个支持有两个原因。一是ISO C不提供,所以没有可移植的方式来实现。第二个原因就是我们不认为多线程对Lua是一件好事。
多线程被开发来针对底层的编程。像信号量和监视器这样的同步算法在操作系统的上下文中被提出。找出并修正与多线程相关的bug是非常困难的,某几个这样的bug还会导致安全问题。而且,在某些非常挑剔的情况下同步会导致巨大的性能下降,如内存分配。
多线程的问题是由于对内存的抢占使用而生,所以我们可以使用非抢占式的线程或者不共享内存来避免这些问题。Lua两者都支持。Lua线程(经常被叫做协程)是合作性的,因此会避免未知的线程切换所带来的问题。Lua状态机不共享内存,所以在Lua为并行提供了一个好的基础。接下来我们就会介绍
多线程Lua中,线程的本制就是一个协程, coroutine。我们可以把一个协程看做一个线程,加上一个好的接口;或者我们可以把线程就作一个底层的API。
从C API的观点来看,你会发觉把线程看成一个 栈 会非常有用————从实现的观点来看,Lua线程就是一个栈。每个 栈 保留了一个线程所有挂起的调 ...
lua字符串学习
基础字符串函数
函数
含义
string.lower(s)
字符串转换成小写
string.upper(s)
字符串转换成大写
string.len(s)
字符串长度
string.rep(s,2)
将字符串 s 重复 2 次
string.sub(s, j, j)
截取字符串
模式匹配string.find 函数string.find 函数用于在给定的目标字符串当中搜索一个模式。例如:
123s = "hello world"i, j = string.find(s, "hello")print(i, j)
find 函数会返回匹配到的起始所以和结尾索引。如果没匹配到任何就返回 nil。
string.match 函数string.match 返回的是目标字符串中与模式相匹配的那部分子串。
1print(string.match("hello world", "hello")) ---> hello
string.gsub 函数string.gsub 函数有三个参数,目标字符串、 ...
Lua
前段时间在腾讯课堂上看到一个视频,是关于一个将C#项目转换成lua项目的一篇介绍。他们描述的方案是反编译C#输出的Dll文件,反编译得出的数据会作C#翻译lua的源数据。一时起了敬畏之心,借助这个机会恰好梳理一下自己的lua知识。
我是在c的基础之上进行lua学习的,期间发现有很多lua的特性是与C语言不相同的,个人认为如果不注意这些区别很容易在未来的工作中出现难以排查的bug,程序开发还是需要一定的严谨性。
缘起
正值待业充电期,在腾讯课堂上看到一篇高效热更新,Lua翻译工具详解,它采用的方案是反编译C#的dll文件,根据反编译的内容再将其翻译成Lua语言,继而实现项目的代码更新部分。为了能够熟知这种方案的可行性以及其效率和稳定性,决定先从lua这门语言着手研究。
关于lua的开发环境的配置
我使用的是LuaStudio,很便捷的一个IDE,安装完毕之后就可以直接使用。
lua官方网站也有免费提供在线解释器
当然如果想自己体验搭建解释器的话,可以参考从零开始的Lua宅[1]:编译Lua解释器这篇博文。
lua中声明的对象不具有C语言中引用类型的那种数据传递的特性。
t ...