Lua処理系コード読み(4) Instruction

llimits.h

/*
** type for virtual-machine instructions
** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
*/
typedef lu_int32 Instruction;

Lua VM命令の型。4バイト(=32ビット)。

lopcodes.hに

/*===========================================================================
  We assume that instructions are unsigned numbers.
  All instructions have an opcode in the first 6 bits.
  Instructions can have the following fields:
  `A' : 8 bits
  `B' : 9 bits
  `C' : 9 bits
  `Bx' : 18 bits (`B' and `C' together)
  `sBx' : signed Bx

  A signed argument is represented in excess K; that is, the number
  value is the unsigned value minus K. K is exactly the maximum value
  for that argument (so that -max is represented by 0, and +max is
  represented by 2*max), which is half the maximum for the corresponding
  unsigned argument.
===========================================================================*/

とあるように、オペコードとオペランドからなる4バイトのVM命令。LuaANSI-Cで書かれてるのでマクロで切り分けてるんだけど、ビットフィールドで表現するなら以下の様な構造。

enum OpCode {
  OP_MOVE,
  OP_LOADK,
  // ...
};
struct I_ABC {
  enum OpCode opcode : 6;
  unsigned a : 8;
  unsigned b : 9;
  unsigned c : 9;
};
struct I_ABx {
  enum OpCode opcode : 6;
  unsigned a : 8;
  unsigned bx : 18;
};
struct I_AsBx {
  enum OpCode opcode : 6;
  unsigned a : 8;
  int sbx : 18;
};
typedef union {
  int dummy;
  struct I_ABC abc;
  struct I_ABx abx;
  struct I_AsBx asbx;
} Instruction;

test