Exemplo n.º 1
0
void
op_for(void)
{
    Var		idx, list;
    
    idx = pop();
    list = pop();
    
    if( list.type == MAP)
    {
	list.v.list = map_keys( list.v.map );
	list.type = LIST;
    }
    if( list.type == STR)
    {
	list.v.list = string_list( list.v.str );
	list.type = LIST;
    }
    if (list.type != LIST) {
	var_free(list);
	raise(E_FOR);
    } else if (idx.v.num >= list.v.list->len) {	/* loop is complete */
	var_free(list);
	frame.pc = frame.m->code[frame.pc + 1];	/* skip to end */
    } else {
	var_assign_local(frame.stack, frame.m->code[frame.pc],
		var_dup(list.v.list->el[idx.v.num]));
	idx.v.num++;
	push(list);		/* push list */
	push(idx);		/* push new index */
	pushpc(frame.pc - 1);	/* push address of FOR statement */
	frame.pc += 2;		/* go to first instruction in loop */
    }
}
Exemplo n.º 2
0
void
op_continue(void)
{
    Var		newpc;
    int		break_lvl = frame.m->code[frame.pc++];

    while (break_lvl--) {
	do {
	    newpc = pop();
	    var_free(newpc);
	} while (newpc.type != PC || newpc.v.num < 0);
    }
    if (frame.m->code[newpc.v.num] == DOWHILE) {
	pushpc(newpc.v.num);
	frame.pc = frame.m->code[newpc.v.num + 2];
    } else {
	frame.pc = newpc.v.num;		/* all the others push their own PC */
    }
}
Exemplo n.º 3
0
void
op_forrng(void)
{
    Var		v, upper;

    upper = pop();
    v = pop();
    if (v.type != NUM || upper.type != NUM) {
	var_free(upper);  var_free(v);
	raise(E_TYPE);
    } else if (v.v.num > upper.v.num) {
	frame.pc = frame.m->code[frame.pc + 1];
    } else {
	var_assign_local(frame.stack, frame.m->code[frame.pc], v);
	v.v.num++;
	push(v);
	push(upper);
	pushpc(frame.pc - 1);
	frame.pc += 2;
    }
}
Exemplo n.º 4
0
void
op_do(void)
{
    pushpc(frame.m->code[frame.pc++]);
}
Exemplo n.º 5
0
void
op_argstart(void)
{
    pushpc(-ARGSTART);
}
Exemplo n.º 6
0
void
op_pushpc(void)
{
    pushpc(frame.pc - 1);
}
Exemplo n.º 7
0
static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) {
  int stack[MAXSTACK];  /* stores last instruction that changed a stack entry */
  const Instruction *code = pt->code;
  int top = pt->numparams;
  int pc = 0;
  if (pt->is_vararg)  /* varargs? */
    top++;  /* `arg' */
  while (pc < lastpc) {
    const Instruction i = code[pc++];
    LUA_ASSERT(0 <= top && top <= pt->maxstacksize, "wrong stack");
    switch (GET_OPCODE(i)) {
      case OP_RETURN: {
        LUA_ASSERT(top >= GETARG_U(i), "wrong stack");
        top = GETARG_U(i);
        break;
      }
      case OP_TAILCALL: {
        LUA_ASSERT(top >= GETARG_A(i), "wrong stack");
        top = GETARG_B(i);
        break;
      }
      case OP_CALL: {
        int nresults = GETARG_B(i);
        if (nresults == MULT_RET) nresults = 1;
        LUA_ASSERT(top >= GETARG_A(i), "wrong stack");
        top = pushpc(stack, pc, GETARG_A(i), nresults);
        break;
      }
      case OP_PUSHNIL: {
        top = pushpc(stack, pc, top, GETARG_U(i));
        break;
      }
      case OP_POP: {
        top -= GETARG_U(i);
        break;
      }
      case OP_SETTABLE:
      case OP_SETLIST: {
        top -= GETARG_B(i);
        break;
      }
      case OP_SETMAP: {
        top -= 2*GETARG_U(i);
        break;
      }
      case OP_CONCAT: {
        top -= GETARG_U(i);
        stack[top++] = pc-1;
        break;
      }
      case OP_CLOSURE: {
        top -= GETARG_B(i);
        stack[top++] = pc-1;
        break;
      }
      case OP_JMPONT:
      case OP_JMPONF: {
        int newpc = pc + GETARG_S(i);
        /* jump is forward and do not skip `lastpc'? */
        if (pc < newpc && newpc <= lastpc) {
          stack[top-1] = pc-1;  /* value comes from `and'/`or' */
          pc = newpc;  /* do the jump */
        }
        else
          top--;  /* do not jump; pop value */
        break;
      }
      default: {
        OpCode op = GET_OPCODE(i);
        LUA_ASSERT(luaK_opproperties[op].push != VD,
                   "invalid opcode for default");
        top -= luaK_opproperties[op].pop;
        LUA_ASSERT(top >= 0, "wrong stack");
        top = pushpc(stack, pc, top, luaK_opproperties[op].push);
      }
    }
  }
  return code[stack[stackpos]];
}