// src/lvm.c
...
void get_type(const TValue *obj) {
printf("%d ", ttype(obj));
if (ttisnumber(obj)) {
int data = obj->value_.n;
printf("is number: %d", data);
} else if (ttisstring(obj)) {
printf("is string: ");
TString *ts;
ts = &(obj->value_.gc->ts);
// ts = lua_State->CallInfo->u.LuaCall.(stack-base-for-this-call).Value.GCObject.TString
// 从内存上看其实字符串的值直接放在了 TString 后面,这样还能省掉一个成员:(lstring.c 108)
// 因此,下方代码实现了读取并打印 ts pointer 后面的 read_length 位的字符
// ts 等于当前线程状态下 current function 的 callinfo
int i;
int s_length = 32;
for(i = 0; i < s_length; i++){
printf("%c ", ((char *)(ts-s_length))[i]);
};
for(i = 0; i < s_length; i++){
printf("%c ", ((char *)(ts+1))[i]);
};
} else if (ttisnil(obj)) {
printf("is nil");
} else if (ttisshrstring(obj)) {
printf("is shrstring");
} else if (ttislngstring(obj)) {
printf("is lngstring");
} else if (ttistable(obj)) {
printf("is table");
} else if (ttisfunction(obj)) {
printf("is function");
} else if (ttisclosure(obj)) {
printf("is closure");
} else if (ttisLclosure(obj)) {
printf("is Lclosure");
} else {
printf("type not found");
};
printf("\n");
}
void print_opcode_detail(int opcode, StkId base, TValue *k, CallInfo *ci, Instruction i) {
// printf("%d", opcode);
vmdispatch (opcode) {
vmcase(OP_LOADK,
// Register A (specified in instruction field A)
TValue *register_A = RA(i);
print_type(register_A);
// Kst(n): Element n in the constant list
TValue *element_n_of_constant_list = KBx(i);
print_type(element_n_of_constant_list);
// TValue x = *base;
// print_type(base);
printf("%p\n%p\n", register_A, element_n_of_constant_list);
printf(" => OP_LOADK /* A Bx R(A) := Kst(Bx) */");
)
vmcase(OP_GETTABUP,
// Register A (specified in instruction field A)
TValue *register_A = RA(i);
print_type(register_A);
// Register B or a constant index
// TValue *register_B = RB(i);
// print_type(register_B);
// Register C or a constant index
TValue *register_C_or_constant_index = RKC(i);
print_type(register_C_or_constant_index);
printf(" => OP_GETTABUP /* A B C R(A) := UpValue[B][RK(C)] */");
)
vmcase(OP_SETTABUP,
// Register A (specified in instruction field A)
TValue *register_A = RA(i);
print_type(register_A);
// Register B or a constant index
TValue *register_B_or_constant_index = RKB(i);
print_type(register_B_or_constant_index);
// Register C or a constant index
TValue *register_C_or_constant_index = RKC(i);
print_type(register_C_or_constant_index);
// TValue x = *base;
// print_type(base);
printf("%p\n%p\n%p\n", register_A, register_B_or_constant_index, register_C_or_constant_index);
printf(" => OP_SETTABUP /* A B C UpValue[A][RK(B)] := RK(C)*/");
)
vmcase(OP_CALL,
// printf(" => OP_CALL /* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */");
)
vmcase(OP_RETURN,
// printf(" => OP_RETURN /* A B return R(A), ... ,R(A+B-2) (see note) */");
)
vmcase(OP_CLOSURE,
// printf(" => OP_CLOSURE /* A Bx R(A) := closure(KPROTO[Bx])*/");
)
}
printf("\n");
}
void luaV_execute (lua_State *L) {
CallInfo *ci = L->ci;
LClosure *cl;
TValue *k;
StkId base;
newframe: /* reentry point when frame changes (call/return) */
lua_assert(ci == L->ci);
cl = clLvalue(ci->func);
k = cl->p->k;
base = ci->u.l.base;
/* main loop of interpreter */
for (;;) {
Instruction i = *(ci->u.l.savedpc++);
StkId ra;
int code = GET_OPCODE(i);
print_opcode_detail(code, base, k, ci, i);
...
}
}
...