[루아2.4] hash mem opcode

1 분 소요

hash.h

기능을 추가하거나 삭제한 변경은 없습니다.

[2.2]
typedef struct Hash
{
 struct Hash   *next;
 char           mark;
 Word          nhash;
 Word           nuse;
 Node          *node;
} Hash;

[2.4]
typedef struct Hash
{
 struct Hash   *next;
 Node          *node;
 int           nhash;
 int            nuse;
 char           mark;
} Hash;

이렇게 Word 타입을 int로 바꿨습니다.

hash.c

헤더 파일과 마찬가지로 hash.c 파일도 동작에 영향을 주는 변경은 없습니다. 가장 많은 변경은 Word를 모두 int로 바꾼 코드들입니다. 그리고 hash.c에서도 재정의해서 쓰던 문자열 비교 매크로를 삭제했네요. 제 속이 다 시원합니다.

mem.c

역시 동작에 영향을 주는 변경은 없고 코드를 조금 더 명확히 하고 잠재적 버그를 막는 수준의 변경입니다.

[2.2]
void luaI_free (void *block)
{
  *((int *)block) = -1;  /* to catch errors */
  free(block);
}

[2.4]
void luaI_free (void *block)
{
  if (block)
  {
    *((int *)block) = -1;  /* to catch errors */
    free(block);
  }
}

동작은 같은데, free()를 하기 전에 block 포인터가 null인지 확인해서 잠재적 버그를 방지하는 코드를 추가했습니다.

opcode.c

[2.2]
static void growstack (void)
{
 if (stack == &initial_stack)
   lua_initstack();
 else
 {
  StkId t = top-stack;
  Long maxstack = stackLimit - stack;
  maxstack *= 2;
  stack = growvector(stack, maxstack, Object);
  stackLimit = stack+maxstack;
  top = stack + t;
  if (maxstack >= MAX_WORD/2)
    lua_error("stack size overflow");
 }
}

[2.4]
static void growstack (void)
{
 if (stack == &initial_stack)
   lua_initstack();
 else
 {
  static int limit = STACK_LIMIT;
  StkId t = top-stack;
  Long stacksize = stackLimit - stack;
  stacksize = growvector(&stack, stacksize, Object, stackEM, limit+100);
  stackLimit = stack+stacksize;
  top = stack + t;
  if (stacksize >= limit)
  {
    limit = stacksize;
    lua_error(stackEM);
  }
 }
}

같은 동작을 하는 코드입니다. STACK_LIMIT을 써서 (MAX_WORD/2) 처럼 의미를 알 수 없는 값보다 명확히 코드에 의미를 부여했습니다. 그래서 전체적으로 코드를 읽기가 수월하군요.

static void getglobal (Word n)
{
  *top = lua_table[n].object;
  incr_top;
  if (tag(top-1) == LUA_T_NIL)
  { /* must call getglobal fallback */
    tag(top-1) = LUA_T_STRING;
    tsvalue(top-1) = lua_table[n].varname;
    callFB(FB_GETGLOBAL);
  }
}

lua_Object lua_getlocal (lua_Function func, int local_number, char **name)
{
  Object *f = luaI_Address(func);
  *name = luaI_getlocalname(f->value.tf, local_number, lua_currentline(func));
  if (*name)
  {
    /* if "*name", there must be a LUA_T_LINE */
    /* therefore, f+2 points to function base */
    return Ref((f+2)+(local_number-1));
  }
  else
    return LUA_NOOBJECT;
}

루아 2.2 코드까지는 로컬 변수와 글로벌 변수를 테이블에서 구분하는 코드가 인덱스가 음수고 양수로 구분하는 식으로 다소 이해하기 힘들었습니다. 루아 2.4에서는 명시적으로 글로벌 변수를 관리하는 테이블과 로컬 변수를 관리하는 테이블을 분리해서 처리합니다. 여러모로 코드 퀄리티가 좋아진 것이 느껴집니다.

댓글남기기