热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

lua1.1源码阅读总结

GC1.怎么回收的lua中所有已经分配的数据都会用一些指令的数据结构来记录,当需要回收时,先遍历当前栈内所有object,把ref标志位打上1,遍历符号表(这部分不能回收),反符号

GC

1. 怎么回收的lua 中所有已经分配的数据都会用一些指令的数据结构来记录,当需要回收时,先遍历当前栈内所有 object,把 ref 标志位打上 1,遍历符号表(这部分不能回收),反符号表中的所有对象的 ref 标志位也打上 1, 如果有其它不用回收的也同样操作。回收也比较简单,这里遍历所有内部数据结构,如果是 0 就直接释放, 如果是 1 就置 0(可能下次就回收了), 这样就结束了
2. 何时回收
这个 1.1 有个内部阀值,当新加 object 的数量到达阀值时,就会触发回收机制。

 


数据结构

  Hash

  

typedef struct Hash
{
char mark;
unsigned int nhash;
Node **list;
} Hash;
typedef struct node
{
Object ref;
Object val;
struct node *next;
} Node;
typedef union
{
Cfunction f;
real n;
char *s;
Byte *b;
struct Hash *a;
void *u;
} Value;
typedef struct Object
{
Type tag;
Value value;
} Object;

typedef struct
{
char *name;
Object object;
} Symbol;

  全局数据区

  

extern Symbol *lua_table; /* key - value 表*/
extern Word lua_ntable;
static Symbol tablebuffer[MAXSYMBOL] = {
{"type",{T_CFUNCTION,{lua_type}}},
...
};
/* list 和数组的结合使用,目地是用 list 和 array 的特性, 参考 lua_findsymbol
在 list 中查找,找到放到头(这样效率高点,下次再被用的概率大点), 没找到,就在头
节点上加一个
*/
Symbol *lua_table=tablebuffer;
Word lua_ntable=7;
static struct List o6={ tablebuffer+6, 0};
static struct List o5={ tablebuffer+5, &o6 };
static struct List o4={ tablebuffer+4, &o5 };
static struct List o3={ tablebuffer+3, &o4 };
static struct List o2={ tablebuffer+2, &o3 };
static struct List o1={ tablebuffer+1, &o2 };
static struct List o0={ tablebuffer+0, &o1 };
static struct List *searchlist=&o0;


extern char **lua_constant; /* 常量表 */
extern Word lua_nconstant;
static char tm[] = " mark";
static char *constantbuffer[MAXCONSTANT] = {tm+1, ti+1,
...
};

extern char **lua_string; /* 就是普通的字符指针数组 *、
extern Word lua_nstring;
static char *stringbuffer[MAXSTRING];
char **lua_string = stringbuffer;
Word lua_nstring=0;
extern Hash **lua_array;
extern Word lua_narray;
extern char *lua_file[]; /* 记录指针的数组 */
extern int lua_nfile;

  ps: lua_next 和 lua_nextval 可以看下,这个有点像迭代器的实现


虚拟指令

这个还是建议读下,主要就是对 stack 和 pc 的操作。

/*
** Execute the given opcode. Return 0 in success or 1 on error.
*/
int lua_execute (Byte *pc)
{
Object *oldbase = base;
base = top;
while (1)
{
OpCode opcode;
switch (opcode = (OpCode)*pc++)
{
case PUSHNIL: tag(top++) = T_NIL; break;

case PUSH0: tag(top) = T_NUMBER; nvalue(top++) = 0; break;
case PUSH1: tag(top) = T_NUMBER; nvalue(top++) = 1; break;
case PUSH2: tag(top) = T_NUMBER; nvalue(top++) = 2; break;
case PUSHBYTE: tag(top) = T_NUMBER; nvalue(top++) = *pc++; break;

case PUSHWORD:
{
CodeWord code;
get_word(code,pc);
tag(top) = T_NUMBER; nvalue(top++) = code.w;
}
break;

case PUSHFLOAT:
{
CodeFloat code;
get_float(code,pc);
tag(top) = T_NUMBER; nvalue(top++) = code.f;
}
break;
case PUSHSTRING:
{
CodeWord code;
get_word(code,pc);
tag(top) = T_STRING; svalue(top++) = lua_constant[code.w];
}
break;

case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2:
case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5:
case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8:
case PUSHLOCAL9: *top++ = *(base + (int)(opcode-PUSHLOCAL0)); break;

case PUSHLOCAL: *top++ = *(base + (*pc++)); break;

case PUSHGLOBAL:
{
CodeWord code;
get_word(code,pc);
*top++ = s_object(code.w);
}
break;

case PUSHINDEXED:
--top;
if (tag(top-1) != T_ARRAY)
{
lua_reportbug ("indexed expression not a table");
return 1;
}
{
Object *h = lua_hashdefine (avalue(top-1), top);
if (h == NULL) return 1;
*(top-1) = *h;
}
break;

case PUSHMARK: tag(top++) = T_MARK; break;

case PUSHOBJECT: *top = *(top-3); top++; break;

case STORELOCAL0: case STORELOCAL1: case STORELOCAL2:
case STORELOCAL3: case STORELOCAL4: case STORELOCAL5:
case STORELOCAL6: case STORELOCAL7: case STORELOCAL8:
case STORELOCAL9: *(base + (int)(opcode-STORELOCAL0)) = *(--top); break;

case STORELOCAL: *(base + (*pc++)) = *(--top); break;

case STOREGLOBAL:
{
CodeWord code;
get_word(code,pc);
s_object(code.w) = *(--top);
}
break;
case STOREINDEXED0:
if (tag(top-3) != T_ARRAY)
{
lua_reportbug ("indexed expression not a table");
return 1;
}
{
Object *h = lua_hashdefine (avalue(top-3), top-2);
if (h == NULL) return 1;
*h = *(top-1);
}
top -= 3;
break;

case STOREINDEXED:
{
int n = *pc++;
if (tag(top-3-n) != T_ARRAY)
{
lua_reportbug ("indexed expression not a table");
return 1;
}
{
Object *h = lua_hashdefine (avalue(top-3-n), top-2-n);
if (h == NULL) return 1;
*h = *(top-1);
}
top--;
}
break;

case STORELIST0:
case STORELIST:
{
int m, n;
Object *arr;
if (opcode == STORELIST0) m = 0;
else m = *(pc++) * FIELDS_PER_FLUSH;
n = *(pc++);
arr = top-n-1;
if (tag(arr) != T_ARRAY)
{
lua_reportbug ("internal error - table expected");
return 1;
}
while (n)
{
tag(top) = T_NUMBER; nvalue(top) = n+m;
*(lua_hashdefine (avalue(arr), top)) = *(top-1);
top--;
n--;
}
}
break;

case STORERECORD:
{
int n = *(pc++);
Object *arr = top-n-1;
if (tag(arr) != T_ARRAY)
{
lua_reportbug ("internal error - table expected");
return 1;
}
while (n)
{
CodeWord code;
get_word(code,pc);
tag(top) = T_STRING; svalue(top) = lua_constant[code.w];
*(lua_hashdefine (avalue(arr), top)) = *(top-1);
top--;
n--;
}
}
break;

case ADJUST:
{
Object *newtop = base + *(pc++);
while (top top = newtop; /* top could be bigger than newtop */
}
break;

case CREATEARRAY:
if (tag(top-1) == T_NIL)
nvalue(top-1) = 101;
else
{
if (tonumber(top-1)) return 1;
if (nvalue(top-1) <= 0) nvalue(top-1) = 101;
}
avalue(top-1) = lua_createarray(nvalue(top-1));
if (avalue(top-1) == NULL)
return 1;
tag(top-1) = T_ARRAY;
break;

case EQOP:
{
Object *l = top-2;
Object *r = top-1;
--top;
if (tag(l) != tag(r))
tag(top-1) = T_NIL;
else
{
switch (tag(l))
{
case T_NIL: tag(top-1) = T_NUMBER; break;
case T_NUMBER: tag(top-1) = (nvalue(l) == nvalue(r)) ? T_NUMBER : T_NIL; break;
case T_ARRAY: tag(top-1) = (avalue(l) == avalue(r)) ? T_NUMBER : T_NIL; break;
case T_FUNCTION: tag(top-1) = (bvalue(l) == bvalue(r)) ? T_NUMBER : T_NIL; break;
case T_CFUNCTION: tag(top-1) = (fvalue(l) == fvalue(r)) ? T_NUMBER : T_NIL; break;
case T_USERDATA: tag(top-1) = (uvalue(l) == uvalue(r)) ? T_NUMBER : T_NIL; break;
case T_STRING: tag(top-1) = (strcmp (svalue(l), svalue(r)) == 0) ? T_NUMBER : T_NIL; break;
case T_MARK: return 1;
}
}
nvalue(top-1) = 1;
}
break;

case LTOP:
{
Object *l = top-2;
Object *r = top-1;
--top;
if (tag(l) == T_NUMBER && tag(r) == T_NUMBER)
tag(top-1) = (nvalue(l) else
{
if (tostring(l) || tostring(r))
return 1;
tag(top-1) = (strcmp (svalue(l), svalue(r)) <0) ? T_NUMBER : T_NIL;
}
nvalue(top-1) = 1;
}
break;

case LEOP:
{
Object *l = top-2;
Object *r = top-1;
--top;
if (tag(l) == T_NUMBER && tag(r) == T_NUMBER)
tag(top-1) = (nvalue(l) <= nvalue(r)) ? T_NUMBER : T_NIL;
else
{
if (tostring(l) || tostring(r))
return 1;
tag(top-1) = (strcmp (svalue(l), svalue(r)) <= 0) ? T_NUMBER : T_NIL;
}
nvalue(top-1) = 1;
}
break;

case ADDOP:
{
Object *l = top-2;
Object *r = top-1;
if (tonumber(r) || tonumber(l))
return 1;
nvalue(l) += nvalue(r);
--top;
}
break;

case SUBOP:
{
Object *l = top-2;
Object *r = top-1;
if (tonumber(r) || tonumber(l))
return 1;
nvalue(l) -= nvalue(r);
--top;
}
break;

case MULTOP:
{
Object *l = top-2;
Object *r = top-1;
if (tonumber(r) || tonumber(l))
return 1;
nvalue(l) *= nvalue(r);
--top;
}
break;

case DIVOP:
{
Object *l = top-2;
Object *r = top-1;
if (tonumber(r) || tonumber(l))
return 1;
nvalue(l) /= nvalue(r);
--top;
}
break;

case CONCOP:
{
Object *l = top-2;
Object *r = top-1;
if (tostring(r) || tostring(l))
return 1;
svalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r)));
if (svalue(l) == NULL)
return 1;
--top;
}
break;

case MINUSOP:
if (tonumber(top-1))
return 1;
nvalue(top-1) = - nvalue(top-1);
break;

case NOTOP:
tag(top-1) = tag(top-1) == T_NIL ? T_NUMBER : T_NIL;
break;

case ONTJMP:
{
CodeWord code;
get_word(code,pc);
if (tag(top-1) != T_NIL) pc += code.w;
}
break;

case ONFJMP:
{
CodeWord code;
get_word(code,pc);
if (tag(top-1) == T_NIL) pc += code.w;
}
break;

case JMP:
{
CodeWord code;
get_word(code,pc);
pc += code.w;
}
break;

case UPJMP:
{
CodeWord code;
get_word(code,pc);
pc -= code.w;
}
break;

case IFFJMP:
{
CodeWord code;
get_word(code,pc);
top--;
if (tag(top) == T_NIL) pc += code.w;
}
break;
case IFFUPJMP:
{
CodeWord code;
get_word(code,pc);
top--;
if (tag(top) == T_NIL) pc -= code.w;
}
break;
case POP: --top; break;

case CALLFUNC:
{
Byte *newpc;
Object *b = top-1;
while (tag(b) != T_MARK) b--;
if (tag(b-1) == T_FUNCTION)
{
lua_debugline = 0; /* always reset debug flag */
newpc = bvalue(b-1);
bvalue(b-1) = pc; /* store return code */
nvalue(b) = (base-stack); /* store base value */
base = b+1;
pc = newpc;
if (MAXSTACK-(base-stack) {
lua_error ("stack overflow");
return 1;
}
}
else if (tag(b-1) == T_CFUNCTION)
{
int nparam;
lua_debugline = 0; /* always reset debug flag */
nvalue(b) = (base-stack); /* store base value */
base = b+1;
nparam = top-base; /* number of parameters */
(fvalue(b-1))(); /* call C function */

/* shift returned values */
{
int i;
int nretval = top - base - nparam;
top = base - 2;
base = stack + (int) nvalue(base-1);
for (i=0; i {
*top = *(top+nparam+2);
++top;
}
}
}
else
{
lua_reportbug ("call expression not a function");
return 1;
}
}
break;

case RETCODE:
{
int i;
int shift = *pc++;
int nretval = top - base - shift;
top = base - 2;
pc = bvalue(base-2);
base = stack + (int) nvalue(base-1);
for (i=0; i {
*top = *(top+shift+2);
++top;
}
}
break;

case HALT:
base = oldbase;
return 0; /* success */

case SETFUNCTION:
{
CodeWord file, func;
get_word(file,pc);
get_word(func,pc);
if (lua_pushfunction (file.w, func.w))
return 1;
}
break;

case SETLINE:
{
CodeWord code;
get_word(code,pc);
lua_debugline = code.w;
}
break;

case RESET:
lua_popfunction ();
break;

default:
lua_error ("internal error - opcode didn't match");
return 1;
}
}
}

  

 



推荐阅读
  • 深入理解Redis的数据结构与对象系统
    本文详细探讨了Redis中的数据结构和对象系统的实现,包括字符串、列表、集合、哈希表和有序集合等五种核心对象类型,以及它们所使用的底层数据结构。通过分析源码和相关文献,帮助读者更好地理解Redis的设计原理。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 深入解析Redis内存对象模型
    本文详细介绍了Redis内存对象模型的关键知识点,包括内存统计、内存分配、数据存储细节及优化策略。通过实际案例和专业分析,帮助读者全面理解Redis内存管理机制。 ... [详细]
  • 对象自省自省在计算机编程领域里,是指在运行时判断一个对象的类型和能力。dir能够返回一个列表,列举了一个对象所拥有的属性和方法。my_list[ ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • 本文详细介绍了 Apache Jena 库中的 Txn.executeWrite 方法,通过多个实际代码示例展示了其在不同场景下的应用,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • Scala 实现 UTF-8 编码属性文件读取与克隆
    本文介绍如何使用 Scala 以 UTF-8 编码方式读取属性文件,并实现属性文件的克隆功能。通过这种方式,可以确保配置文件在多线程环境下的一致性和高效性。 ... [详细]
  • 本文详细解析了Java中hashCode()和equals()方法的实现原理及其在哈希表结构中的应用,探讨了两者之间的关系及其实现时需要注意的问题。 ... [详细]
  • YB02 防水车载GPS追踪器
    YB02防水车载GPS追踪器由Yuebiz科技有限公司设计生产,适用于车辆防盗、车队管理和实时追踪等多种场合。 ... [详细]
  • Lua编程进阶:数组与迭代器详解
    本文深入探讨了Lua语言中的数组和迭代器,通过实例讲解了一维数组、多维数组的使用方法及迭代器的工作原理。 ... [详细]
author-avatar
最美的你
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有