lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi,

Despite the time I have spent on Lua I still do not understand how the
code generator works unfortunately. I have got by so far as most of
the new bytecodes I added were just variations of existing bytecodes.
Now that I am trying to implement the type assertion operator for the
first time I am having to invoke certain functions mentioned below -
and I feel unsure of what I am doing. I would hugely appreciate any
help.

My aim is to generate a bytecode instruction that asserts the type of
an expression. I am treating the operator has a unary operator. Unlike
the existing unary operators the difference is that in this case the
bytecode has only one operand A which identifies a register - and the
bytecode asserts the type of the value held in that register. As this
is a unary operator then it can be used within expressions.

So I am modelling my implementation based on codenot() in lcode.c.
Below is a trimmed version.

I guess that all I need here is 1) to assign a register to 'e' if not
assigned, 2) generate the bytecode for type assertion and 3) ensure
that everything else carries on as before. Below seems to work but I
do not quite understand the steps.

My questions are:
a) What does luaK_dischargevars() do?
b) What does discharge2anyreg() do? It seems to also call luaK_dischargevars().
c) I find that if I call freeexp() below it causes bad code generation
- presumably because the register gets freed?

static void codecast(FuncState *fs, UnOpr op, expdesc *e) {
  luaK_dischargevars(fs, e);
  switch (e->k) {
    case VRELOCABLE:
    case VNONRELOC: {
      discharge2anyreg(fs, e);
      /* freeexp(fs, e); */
      OpCode opcode;
      ravitype_t tt;
      if (op == OPR_TO_NUMBER && e->ravi_type != RAVI_TNUMFLT) {
        opcode = OP_RAVI_TOFLT;
        tt = RAVI_TNUMFLT;
      }
      else {
        /* nothing to do*/
        return;
      }
      luaK_codeABC(fs, opcode, e->u.info, 0, 0);
      e->ravi_type = tt;
      e->k = VNONRELOC;
      return;
    }
    default: break;
  }
  luaX_syntaxerror(fs->ls, "invalid type assertion");  /* cannot happen */
}

Thanks and Regards
Dibyendu