Lua5.4源码分析:一. 简述lua变量类型可变特性的实现。
概述
lua是由C语言编写,运行在虚拟机上的弱类型解释型语言。
- lua变量为什么可以任意改变类型?
切豆腐理论
对于硬盘上保存的数据来说,其本身不具备“意义”,其含义取决于我们如何解释这一段数据
- 首地址 + 长度 确定内存上的一段数据。
- 编码/解码 赋予这段数据意义。
TValue
typedef union Value {
struct GCObject *gc; /* collectable objects */
void *p; /* light userdata */
lua_CFunction f; /* light C functions */
lua_Integer i; /* integer numbers */
lua_Number n; /* float numbers */
} Value;
#define TValuefields Value value_; lu_byte tt_
typedef struct TValue {
TValuefields;
} TValue;
- 使用union特性。
- tt_ 类型(长度)(C语言)。
- value_ 首地址。
setfltvalue
#define val_(o) ((o)->value_)
#define settt_(o,t) ((o)->tt_=(t))
#define LUA_TNUMBER 3
#define LUA_VNUMFLT makevariant(LUA_TNUMBER, 1) /* float numbers */
#define setfltvalue(obj,x) \
{ TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_VNUMFLT); }
浮点类型编码:
- val_ 值,n是上述的value_。
- settt_ 类型。
tonumber
#define rawtt(o) ((o)->tt_)
#define checktag(o,t) (rawtt(o) == (t))
#define ttisfloat(o) checktag((o), LUA_VNUMFLT)
#define check_exp(c,e) (e)
#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n)
#define tonumber(o,n) \
(ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n))
浮点类型解码:
- ttisfloat 类型测试。
- fltvalue 解码赋给n。
- luaV_tonumber_ 尝试类型转换。
- 注意三元运算符和逗号运算符的语义。