《lua源码赏析》笔记 -2

来源:互联网 发布:大数据时代的缺点 编辑:程序博客网 时间:2024/04/29 09:28
 数据结构
 string :
短字符串  长字符串 
LUA_TSHRSTR      LUA_TLNGSTR
这个小类型区放在了 类型字节的 高四位,外部的API并不能看见 所以我们看到的只有LUA_STRING一种类型。
区分长短字符串的界限 由定义在 luaconf.h中的 宏 LUAI_MAXSHORTLEN来决定  默认设置为40个字节。这个宏不能设置少于十个字节。
字符串一旦被创建了  便不可以被改写。LUA的 值对象若是 字符串类型,那就以引用的形式存在。属于需要被垃圾收集的对象。
一个字符串如果没有任何一个地方引用他 就会被回收。
字符串类型被定义在lobject.h中。
typedef union TSring{
L_Umaxalign dummy;  / ensures maximum alignment for string /
struct{
 CommonHeader;--用于GC
 lu_byte extra;--用来记录辅助信息。
 unsigned int hash;    --记录字符串的hash 可以用来加速字符串的匹配和查找。
 size_t len; --lua不是用/0来记录接未的 所以要一个len域来记录字符串的长度。
}tsv;
}TSring;
字符串的数据内容没有被分配出一个独立的内存来保存,而是直接追加到了STstring的后面,用getstr这个宏就能够直接拿出来。
#define getstr(ts) cast(const char *,(ts)+1)


所有的短字符串都被存放在了全局表(global_State)的str域中。strt是 string table的 简写,他是一个哈希表。
就是短字符串都放在 了一个全局的哈希表中。


lstate.h:stringtable
typedef stuct stringtable{
   GCObject **hash;
   lu_int32 nuse;
   int size;
}stringtable;


相同的短字符串在同一个 lua_state中只存在 唯一一份 ,被称为字符串的内部化。
长字符串则独立 存放,从外部压入一个长字符串的时候,先简单复制一遍字符串,并不立即计算他的哈希值,而是标记一下extra域。知道需要对字符串做键匹配的时候,才惰性计算hash值,加快之后的键比较过程。


Hash Dos 
在lua 5.2.0之前,字符串是部分长短一律内部化后放在字符串表中的。
对于长字符串,为了加快内部化的过程,计算长字符串哈希值是跳跃进行的。
在lua 5.2.0发布后不久,有人在邮件列表中踢出,lua的这个设计可能给了别人攻击Hash Dos的机会。
就为了解决问题吧,就把长字符串给独立了出来,大量文本处理中的输入字符串不再通过哈希表内部化进入全局字符串表中了。与此同时使用了一个随机种子用于哈希值的计算。
这样攻击者就不容易轻易地构造出拥有和原来哈希值相同的不同字符串了。


字符串比较
比较两个字符串是否相同,西安区别长短字符串。
长字符穿比较线比较长度 长度比较完了 之后逐字节比较 
短字符串经过了内部化, 直接比较对象地址就行。

所有的短字符串都被内部化放在了全局的字符串表中。
原创粉丝点击