Lua 소스 코드 읽 기 (7) 명령 - > Lua 명령 실행 과정
지난 절 Lua 스 택 의 기반 이 있 습 니 다. 이 절 은 Lua 명령 집행 과정 에서 관련 된 관건 적 인 데이터 구조, 절차 와 해당 하 는 함 수 를 설명 합 니 다.
분석 Lua 코드 를 저장 한 후에 관련 된 opcode 를 생 성 합 니 다. Proto 구조 체 에 저 장 된 것 입 니 다. 하나의 Lua 파일 은 전체 Proto 구조 체 를 가지 고 있 습 니 다. 만약 에 내부 에 정의 함수 가 있다 면 모든 함수 에 해당 하 는 Proto 구조 체 가 있 습 니 다. 여기 에는 명령 집행 과 관련 된 몇 명의 구성원 만 열거 되 어 있 습 니 다.
Tvalue * k: 상수 의 배열 을 저장 합 니 다. Instruction * code: 명령 을 저장 하 는 배열 입 니 다. struct Proto * * p: 이 Proto 에서 정의 하 는 함수 와 관련 된 Proto 데이터 입 니 다. Proto 구조 체 는 Lua 파일 을 분석 한 결과 물이 기 때문에 분석 단계 에서 중간 에 사 용 된 임시 데 이 터 를 저장 하고 그 안에 데 이 터 를 기록 해 야 합 니 다. 분석 이 끝 난 후에 이 분석 과정 에서 임시로 사 용 된 데 이 터 는 더 이상 사용 하지 않 습 니 다. 이 구조 체 는 Func State 입 니 다. 여기 서 명령 과 관련 된 구성원 만 열거 합 니 다.
Proto * f: 연 결 된 Proto 구조 체. int pc: 현재 pc 인덱스, CPU 가 명령 을 실행 할 때의 카운터 와 유사 합 니 다. 이 변 수 는 현재 Proto 의 code 배열 에 얼마나 많은 데 이 터 를 기 록 했 는 지 저장 하 는 데 사 용 됩 니 다. int freereg: 현재 사용 가능 한 레지스터 인덱스 입 니 다. 이상 의 준비 가 되 어 있 습 니 다. Proto 에 명령 을 언제 기록 하 는 지 보 겠 습 니 다. Lua 코드 에서 서로 다른 명령 형식 에 몇 가지 함 수 를 제공 하 였 습 니 다. luaKcodeABx/luaK_codeABC 등, 이 함수 들 은 결국 함수 luaK 를 호출 합 니 다.code:
(lcode.c)
797 static int luaK_code (FuncState *fs, Instruction i, int line) {
798 Proto *f = fs->f;
803 f->code[fs->pc] = i;
808 return fs->pc++;
809 }
앞에서 분석 한 바 와 같이 luaKcode 는 Proto 구조 체 의 code 배열 에 명령 을 기록 하고 code 배열 의 다음 쓰기 가능 한 위 치 를 되 돌려 줍 니 다. 이것 은 FuncState 의 pc 구성원 으로 저 장 됩 니 다.
다음은 Lua 가상 컴퓨터 가 모든 명령 을 진정 으로 수행 하 는 함수 luaV 를 살 펴 보 겠 습 니 다.execute:
(lvm.c)
343 #define RA(i) (base+GETARG_A(i))
344 /* to be used after possible stack reallocation */
345 #define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
346 #define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
347 #define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
348 ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
349 #define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
350 ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
351 #define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
373 void luaV_execute (lua_State *L, int nexeccalls) {
374 LClosure *cl;
375 StkId base;
376 TValue *k;
377 const Instruction *pc;
378 reentry: /* entry point */
380 pc = L->savedpc;
381 cl = &clvalue(L->ci->func)->l;
382 base = L->base;
383 k = cl->p->k;
384 /* main loop of interpreter */
385 for (;;) {
386 const Instruction i = *pc++;
387 StkId ra;
398 ra = RA(i);
402 switch (GET_OPCODE(i)) {
760 }
761 }
762 }
우선 함수 luaVexecute 에서 변수 pc 는 luaState 의 savedpc, 앞 에 나 타 났 던 luaD 입 니 다.precall 함수 에서 값 을 부여 하 는 것 은 함수 스 택 의 관련 변수 에 만 관심 을 가 질 뿐 이 줄 코드 를 열거 합 니 다.
(ldo.c)
264 int luaD_precall (lua_State *L, StkId func, int nresults) {
293 L->savedpc = p->code; /* starting point */
그 다음 에 이 함수 의 주 체 는 큰 순환 이다. pc 포인터 가 가리 키 는 명령 을 순서대로 꺼 내 서 해석 하고 집행 하 는 것 이다. 그리고 RA / RB / RC 등 몇 개의 매크로 를 주의해 야 한다. 그 데 이 터 는 모두 base, 즉 함수 스 택 의 시작 주소 로 얻 은 것 이다. 따라서 지난 함수 스 택 의 내용 과 이 절의 내용 을 결합 하면 명확 한 결론 을 얻 을 수 있다.
, , , . Lua , , base/top .
명령 에 상대 적 인 오프셋 을 저장 하지만 하나의 값 을 저장 해 야 합 니 다. 현재 함수 스 택 에 얼마나 많은 값 이 할당 되 었 는 지 알 고 있 습 니 다. 이 데 이 터 를 저장 하 는 변 수 는 바로 Func State 구조 체 의 freereg 입 니 다.
그래서 그림 3.1 에서 가장 오른쪽 은 R [0]... R [n] 의 의 미 를 나타 낸다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.