Example #1
0
static int boolK (FuncState *fs, int b) {
  TValue o;
  setbvalue(&o, b);
  return addk(fs, &o, &o);
}
Example #2
0
LUA_API void lua_pushboolean (lua_State *L, int b) {
  lua_lock(L);
  setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
  api_incr_top(L);
  lua_unlock(L);
}
Example #3
0
static int ICACHE_FLASH_ATTR boolK (FuncState *fs, int b) {
  TValue o;
  setbvalue(&o, b);
  return addk(fs, &o, &o);
}
Example #4
0
File: lvm.c Project: wflk/psykoosi
void luaV_execute (lua_State *L, int nexeccalls) {
  LClosure *cl;
  StkId base;
  TValue *k;
  const Instruction *pc;
 reentry:  /* entry point */
  lua_assert(isLua(L->ci));
  pc = L->savedpc;
  cl = &clvalue(L->ci->func)->l;
  base = L->base;
  k = cl->p->k;
  /* main loop of interpreter */
  for (;;) {
    const Instruction i = *pc++;
    StkId ra;
    if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
        (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
      traceexec(L, pc);
      if (L->status == LUA_YIELD) {  /* did hook yield? */
        L->savedpc = pc - 1;
        return;
      }
      base = L->base;
    }
    /* warning!! several calls may realloc the stack and invalidate `ra' */
    ra = RA(i);
    lua_assert(base == L->base && L->base == L->ci->base);
    lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
    lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
    switch (GET_OPCODE(i)) {
      case OP_MOVE: {
        setobjs2s(L, ra, RB(i));
        continue;
      }
      case OP_LOADK: {
        setobj2s(L, ra, KBx(i));
        continue;
      }
      case OP_LOADBOOL: {
        setbvalue(ra, GETARG_B(i));
        if (GETARG_C(i)) pc++;  /* skip next instruction (if C) */
        continue;
      }
      case OP_LOADNIL: {
        TValue *rb = RB(i);
        do {
          setnilvalue(rb--);
        } while (rb >= ra);
        continue;
      }
      case OP_GETUPVAL: {
        int b = GETARG_B(i);
        setobj2s(L, ra, cl->upvals[b]->v);
        continue;
      }
      case OP_GETGLOBAL: {
        TValue g;
        TValue *rb = KBx(i);
        sethvalue(L, &g, cl->env);
        lua_assert(ttisstring(rb));
        Protect(luaV_gettable(L, &g, rb, ra));
        continue;
      }
      case OP_GETTABLE: {
        Protect(luaV_gettable(L, RB(i), RKC(i), ra));
        continue;
      }
      case OP_SETGLOBAL: {
        TValue g;
        sethvalue(L, &g, cl->env);
        lua_assert(ttisstring(KBx(i)));
        Protect(luaV_settable(L, &g, KBx(i), ra));
        continue;
      }
      case OP_SETUPVAL: {
        UpVal *uv = cl->upvals[GETARG_B(i)];
        setobj(L, uv->v, ra);
        luaC_barrier(L, uv, ra);
        continue;
      }
      case OP_SETTABLE: {
        Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
        continue;
      }
      case OP_NEWTABLE: {
        int b = GETARG_B(i);
        int c = GETARG_C(i);
        sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
        Protect(luaC_checkGC(L));
        continue;
      }
      case OP_SELF: {
        StkId rb = RB(i);
        setobjs2s(L, ra+1, rb);
        Protect(luaV_gettable(L, rb, RKC(i), ra));
        continue;
      }
      case OP_ADD: {
        arith_op(luai_numadd, TM_ADD);
        continue;
      }
      case OP_SUB: {
        arith_op(luai_numsub, TM_SUB);
        continue;
      }
      case OP_MUL: {
        arith_op(luai_nummul, TM_MUL);
        continue;
      }
      case OP_DIV: {
        arith_op(luai_numdiv, TM_DIV);
        continue;
      }
      case OP_MOD: {
        arith_op(luai_nummod, TM_MOD);
        continue;
      }
      case OP_POW: {
        arith_op(luai_numpow, TM_POW);
        continue;
      }
      case OP_UNM: {
        TValue *rb = RB(i);
        if (ttisnumber(rb)) {
          lua_Number nb = nvalue(rb);
          setnvalue(ra, luai_numunm(nb));
        }
        else {
          Protect(Arith(L, ra, rb, rb, TM_UNM));
        }
        continue;
      }
      case OP_NOT: {
        int res = l_isfalse(RB(i));  /* next assignment may change this value */
        setbvalue(ra, res);
        continue;
      }
      case OP_LEN: {
        const TValue *rb = RB(i);
        switch (ttype(rb)) {
          case LUA_TTABLE: {
            setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
            break;
          }
          case LUA_TSTRING: {
            setnvalue(ra, cast_num(tsvalue(rb)->len));
            break;
          }
          default: {  /* try metamethod */
            Protect(
              if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
                luaG_typeerror(L, rb, "get length of");
            )
          }
        }
        continue;
      }
      case OP_CONCAT: {
        int b = GETARG_B(i);
        int c = GETARG_C(i);
        Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
        setobjs2s(L, RA(i), base+b);
        continue;
      }
      case OP_JMP: {
        dojump(L, pc, GETARG_sBx(i));
        continue;
      }
      case OP_EQ: {
        TValue *rb = RKB(i);
        TValue *rc = RKC(i);
        Protect(
          if (equalobj(L, rb, rc) == GETARG_A(i))
            dojump(L, pc, GETARG_sBx(*pc));
        )
        pc++;
        continue;
      }
      case OP_LT: {
        Protect(
          if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
            dojump(L, pc, GETARG_sBx(*pc));
        )
        pc++;
        continue;
      }
      case OP_LE: {
        Protect(
          if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
            dojump(L, pc, GETARG_sBx(*pc));
        )
        pc++;
        continue;
      }
Example #5
0
Proto *load_jit_proto(lua_State *L, jit_proto *p) {
	Proto *f = luaF_newproto(L);
	unsigned int i;

	/* proto source */
	f->source = luaS_new(L, p->name);
	/* jit_func */
	f->jit_func = p->jit_func;
	/* linedefined */
	f->linedefined = p->linedefined;
	/* lastlinedefined */
	f->lastlinedefined = p->lastlinedefined;
	/* nups */
	f->nups = p->nups;
	/* numparams */
	f->numparams = p->numparams;
	/* is_vararg */
	f->is_vararg = p->is_vararg;
	/* maxstacksize */
	f->maxstacksize = p->maxstacksize;
	/* sizek */
	f->sizek = p->sizek;
	/* k */
	f->k=luaM_newvector(L,p->sizek,TValue);
	for(i = 0; i < p->sizek; i++) {
		TValue *o=&f->k[i];
		switch(p->k[i].type) {
			case TYPE_STRING:
				setsvalue2n(L,o, luaS_newlstr(L, p->k[i].val.str, p->k[i].length));
				break;
			case TYPE_BOOLEAN:
				setbvalue(o, p->k[i].val.b != 0);
				break;
			case TYPE_NUMBER:
				setnvalue(o, p->k[i].val.num);
				break;
			case TYPE_NIL:
			default:
				setnilvalue(o);
				break;
		}
	}
	/* sizep */
	f->sizep = p->sizep;
	/* p */
	f->p=luaM_newvector(L,(size_t)p->sizep,Proto*);
	for(i = 0; i < p->sizep; i++) {
		f->p[i] = load_jit_proto(L, &(p->p[i]));
	}
	/* sizecode */
	f->sizecode = p->sizecode;
	/* code */
	f->code=luaM_newvector(L,(size_t)p->sizecode,Instruction);
	for(i = 0; i < p->sizecode; i++) {
		f->code[i] = p->code[i];
	}
	/* sizelineinfo */
	f->sizelineinfo = p->sizelineinfo;
	/* lineinfo */
	f->lineinfo=luaM_newvector(L,(size_t)p->sizelineinfo,int);
	for(i = 0; i < p->sizelineinfo; i++) {
		f->lineinfo[i] = p->lineinfo[i];
	}
	/* sizelocvars */
	f->sizelocvars = p->sizelocvars;
	/* locvars */
	f->locvars=luaM_newvector(L,p->sizelocvars,LocVar);
	for(i = 0; i < p->sizelocvars; i++) {
		jit_LocVar *locvar = &(p->locvars[i]);
		f->locvars[i].varname = luaS_new(L, locvar->varname);
		f->locvars[i].startpc = locvar->startpc;
		f->locvars[i].endpc = locvar->endpc;
	}
	/* sizeupvalues */
	f->sizeupvalues = p->sizeupvalues;
	/* upvalues */
	f->upvalues=luaM_newvector(L,(size_t)p->sizeupvalues,TString*);
	for(i = 0; i < p->sizeupvalues; i++) {
		f->upvalues[i] = luaS_new(L, p->upvalues[i]);
	}
	return f;
}
Example #6
0
void SexeLoadConstants(LoadState* S, Proto* f, sexe_stack_t *stack)
{
  char *lit;
  char **lits;
  char *s_ptr;
  int tot;
  int idx;
  int i;

  lit = NULL;
  lits = NULL;
  if (stack->type == SESTACK_LITERAL) {
    /* literals */
    lit = (char *)calloc(stack->size + 1, sizeof(char));
    LoadBlock(S, lit, stack->size);

    tot = 0;
    for (i = 0; i < stack->size; i++) {
      if (lit[i] == '\0')
        tot++;
    }
    VERBOSE("[CONSTANT] loaded x%d literal strings <%d bytes>\n", tot, sizeof(stack) + stack->size);

    lits = (char **)calloc(tot + 1, sizeof(char *));

    idx = 0;
    s_ptr = lit;
    for (i = 0; i < stack->size; i++) {
      if (lit[i] == '\0') {
        lits[idx] = s_ptr;
        VERBOSE("[CONSTANT] lits[%d] = '%s'\n", idx, lits[idx]);

        idx++;
        s_ptr = &lit[i+1];
      }
    }
  }

  /* constants */
  memset(stack, 0, sizeof(sexe_stack_t));
  LoadBlock(S, stack, sizeof(sexe_stack_t));
  VERBOSE("[CONSTANT] loading x%d constants\n", stack->size);
  f->k=luaM_newvector(S->L, stack->size, TValue);
  f->sizek = stack->size;
  for (i=0; i < stack->size; i++) setnilvalue(&f->k[i]);
  for (i=0; i < stack->size; i++) {
    TValue* o=&f->k[i];
    sexe_const_t con;

    memset(&con, 0, sizeof(con));
    LoadBlock(S, &con, sizeof(con));


    switch (con.con_type)
    {
      case LUA_TNIL:
        setnilvalue(o);
        break;
      case LUA_TBOOLEAN:
        setbvalue(o, (unsigned char)con.con_val);
        break;
      case LUA_TNUMBER:
        setnvalue(o, (lua_Number)con.con_val);
        break;
      case LUA_TSTRING:
        if (lits && con.con_val < tot) {
          char *raw = lits[con.con_val];
          size_t str_len = strlen(raw); 
          char *s = luaZ_openspace(S->L, S->b, str_len);
          memcpy(s, raw, str_len);
          setsvalue2n(S->, o, luaS_newlstr(S->L, s, str_len));
        }
        //setsvalue2n(S->L, o, lits[con.con_val]);
        break;
    }
  }
Example #7
0
File: vm.c Project: joelagnel/ktap
static void ktap_execute(ktap_state *ks)
{
	int exec_count = 0;
	ktap_callinfo *ci;
	ktap_lclosure *cl;
	ktap_value *k;
	unsigned int instr, opcode;
	StkId base; /* stack pointer */
	StkId ra; /* register pointer */
	int res, nresults; /* temp varible */

	ci = ks->ci;

 newframe:
	cl = CLVALUE(ci->func);
	k = cl->p->k;
	base = ci->u.l.base;

 mainloop:
	/* main loop of interpreter */

	/* dead loop detaction */
	if (exec_count++ == 10000) {
		if (G(ks)->mainthread != ks) {
			kp_error(ks, "non-mainthread executing too much, "
				     "please try to enlarge execution limit\n");
			return;
		}

		cond_resched();
		if (signal_pending(current)) {
			flush_signals(current);
			return;
		}
		exec_count = 0;
	}

	instr = *(ci->u.l.savedpc++);
	opcode = GET_OPCODE(instr);

	/* ra is target register */
	ra = RA(instr);

	switch (opcode) {
	case OP_MOVE:
		setobj(ra, base + GETARG_B(instr));
		break;
	case OP_LOADK:
		setobj(ra, k + GETARG_Bx(instr));
		break;
	case OP_LOADKX:
		setobj(ra, k + GETARG_Ax(*ci->u.l.savedpc++));
		break;
	case OP_LOADBOOL:
		setbvalue(ra, GETARG_B(instr));
		if (GETARG_C(instr))
			ci->u.l.savedpc++;
		break;
	case OP_LOADNIL: {
		int b = GETARG_B(instr);
		do {
			setnilvalue(ra++);
		} while (b--);
		break;
		}
	case OP_GETUPVAL: {
		int b = GETARG_B(instr);
		setobj(ra, cl->upvals[b]->v);
		break;
		}
	case OP_GETTABUP: {
		int b = GETARG_B(instr);
		gettable(ks, cl->upvals[b]->v, RKC(instr), ra);
		base = ci->u.l.base;
		break;
		}
	case OP_GETTABLE:
		gettable(ks, RB(instr), RKC(instr), ra);
		base = ci->u.l.base;
		break;
	case OP_SETTABUP: {
		int a = GETARG_A(instr);
		settable(ks, cl->upvals[a]->v, RKB(instr), RKC(instr));
		base = ci->u.l.base;
		break;
		}
	case OP_SETUPVAL: {
		ktap_upval *uv = cl->upvals[GETARG_B(instr)];
		setobj(uv->v, ra);
		break;
		}
	case OP_SETTABLE:
		settable(ks, ra, RKB(instr), RKC(instr));
		base = ci->u.l.base;
		break;
	case OP_NEWTABLE: {
		int b = GETARG_B(instr);
		int c = GETARG_C(instr);
		ktap_table *t = kp_table_new(ks);
		sethvalue(ra, t);
		if (b != 0 || c != 0)
			kp_table_resize(ks, t, fb2int(b), fb2int(c));
		break;
		}
	case OP_SELF: {
		StkId rb = RB(instr);
		setobj(ra+1, rb);
		gettable(ks, rb, RKC(instr), ra);
		base = ci->u.l.base;
		break;
		}
	case OP_ADD:
		arith_op(ks, NUMADD);
		break;
	case OP_SUB:
		arith_op(ks, NUMSUB);
		break;
	case OP_MUL:
		arith_op(ks, NUMMUL);
		break;
	case OP_DIV:
		/* divide 0 checking */
		if (!nvalue(RKC(instr))) {
			kp_error(ks, "divide 0 arith operation\n");
			return;
		}
		arith_op(ks, NUMDIV);
		break;
	case OP_MOD:
		/* divide 0 checking */
		if (!nvalue(RKC(instr))) {
			kp_error(ks, "mod 0 arith operation\n");
			return;
		}
		arith_op(ks, NUMMOD);
		break;
	case OP_POW:
		kp_error(ks, "ktap don't support pow arith in kernel\n");
		return;
	case OP_UNM: {
		ktap_value *rb = RB(instr);
		if (ttisnumber(rb)) {
			ktap_number nb = nvalue(rb);
			setnvalue(ra, NUMUNM(nb));
		}
		break;
		}
	case OP_NOT:
		res = isfalse(RB(instr));
		setbvalue(ra, res);
		break;
	case OP_LEN: {
		int len = kp_objlen(ks, RB(instr));
		if (len < 0)
			return;
		setnvalue(ra, len);
		break;
		}
	case OP_CONCAT: {
		int b = GETARG_B(instr);
		int c = GETARG_C(instr);
		ktap_concat(ks, b, c);
		break;
		}
	case OP_JMP:
		dojump(ci, instr, 0);
		break;
	case OP_EQ: {
		ktap_value *rb = RKB(instr);
		ktap_value *rc = RKC(instr);
		if ((int)equalobj(ks, rb, rc) != GETARG_A(instr))
			ci->u.l.savedpc++;
		else
			donextjump(ci);

		base = ci->u.l.base;
		break;
		}
	case OP_LT:
		if (lessthan(ks, RKB(instr), RKC(instr)) != GETARG_A(instr))
			ci->u.l.savedpc++;
		else
			donextjump(ci);
		base = ci->u.l.base;
		break;
	case OP_LE:
		if (lessequal(ks, RKB(instr), RKC(instr)) != GETARG_A(instr))
			ci->u.l.savedpc++;
		else
			donextjump(ci);
		base = ci->u.l.base;
		break;
	case OP_TEST:
		if (GETARG_C(instr) ? isfalse(ra) : !isfalse(ra))
			ci->u.l.savedpc++;
		else
			donextjump(ci);
		break;
	case OP_TESTSET: {
		ktap_value *rb = RB(instr);
		if (GETARG_C(instr) ? isfalse(rb) : !isfalse(rb))
			ci->u.l.savedpc++;
		else {
			setobj(ra, rb);
			donextjump(ci);
		}
		break;
		}
	case OP_CALL: {
		int b = GETARG_B(instr);
		int ret;

		nresults = GETARG_C(instr) - 1;

		if (b != 0)
			ks->top = ra + b;

		ret = precall(ks, ra, nresults);
		if (ret) { /* C function */
			if (nresults >= 0)
				ks->top = ci->top;
			base = ci->u.l.base;
			break;
		} else { /* ktap function */
			ci = ks->ci;
			/* this flag is used for return time, see OP_RETURN */
			ci->callstatus |= CIST_REENTRY;
			goto newframe;
		}
		break;
		}
	case OP_TAILCALL: {
		int b = GETARG_B(instr);

		if (b != 0)
			ks->top = ra+b;
		if (precall(ks, ra, -1))  /* C function? */
			base = ci->u.l.base;
		else {
			int aux;

			/* 
			 * tail call: put called frame (n) in place of
			 * caller one (o)
			 */
			ktap_callinfo *nci = ks->ci;  /* called frame */
			ktap_callinfo *oci = nci->prev;  /* caller frame */
			StkId nfunc = nci->func;  /* called function */
			StkId ofunc = oci->func;  /* caller function */
			/* last stack slot filled by 'precall' */
			StkId lim = nci->u.l.base +
				    CLVALUE(nfunc)->p->numparams;

			/* close all upvalues from previous call */
			if (cl->p->sizep > 0)
				function_close(ks, oci->u.l.base);

			/* move new frame into old one */
			for (aux = 0; nfunc + aux < lim; aux++)
				setobj(ofunc + aux, nfunc + aux);
			/* correct base */
			oci->u.l.base = ofunc + (nci->u.l.base - nfunc);
			/* correct top */
			oci->top = ks->top = ofunc + (ks->top - nfunc);
			oci->u.l.savedpc = nci->u.l.savedpc;
			/* remove new frame */
			ci = ks->ci = oci;
			/* restart ktap_execute over new ktap function */
			goto newframe;
		}
		break;
		}
	case OP_RETURN: {
		int b = GETARG_B(instr);
		if (b != 0)
			ks->top = ra+b-1;
		if (cl->p->sizep > 0)
			function_close(ks, base);
		b = poscall(ks, ra);

		/* if it's called from external invocation, just return */
		if (!(ci->callstatus & CIST_REENTRY))
			return;

		ci = ks->ci;
		if (b)
			ks->top = ci->top;
		goto newframe;
		}
	case OP_FORLOOP: {
		ktap_number step = nvalue(ra+2);
		/* increment index */
		ktap_number idx = NUMADD(nvalue(ra), step);
		ktap_number limit = nvalue(ra+1);
		if (NUMLT(0, step) ? NUMLE(idx, limit) : NUMLE(limit, idx)) {
			ci->u.l.savedpc += GETARG_sBx(instr);  /* jump back */
			setnvalue(ra, idx);  /* update internal index... */
			setnvalue(ra+3, idx);  /* ...and external index */
		}
		break;
		}
	case OP_FORPREP: {
		const ktap_value *init = ra;
		const ktap_value *plimit = ra + 1;
		const ktap_value *pstep = ra + 2;

		if (!ktap_tonumber(init, ra)) {
			kp_error(ks, KTAP_QL("for")
				 " initial value must be a number\n");
			return;
		} else if (!ktap_tonumber(plimit, ra + 1)) {
			kp_error(ks, KTAP_QL("for")
				 " limit must be a number\n");
			return;
		} else if (!ktap_tonumber(pstep, ra + 2)) {
			kp_error(ks, KTAP_QL("for") " step must be a number\n");
			return;
		}

		setnvalue(ra, NUMSUB(nvalue(ra), nvalue(pstep)));
		ci->u.l.savedpc += GETARG_sBx(instr);
		break;
		}
	case OP_TFORCALL: {
		StkId cb = ra + 3;  /* call base */
		setobj(cb + 2, ra + 2);
		setobj(cb + 1, ra + 1);
		setobj(cb, ra);
		ks->top = cb + 3;  /* func. + 2 args (state and index) */
		kp_call(ks, cb, GETARG_C(instr));
		base = ci->u.l.base;
		ks->top = ci->top;
		instr = *(ci->u.l.savedpc++);  /* go to next instruction */
		ra = RA(instr);
		}
		/*go through */
	case OP_TFORLOOP:
		if (!ttisnil(ra + 1)) {  /* continue loop? */
			setobj(ra, ra + 1);  /* save control variable */
			ci->u.l.savedpc += GETARG_sBx(instr);  /* jump back */
		}
		break;
	case OP_SETLIST: {
		int n = GETARG_B(instr);
		int c = GETARG_C(instr);
		int last;
		ktap_table *h;

		if (n == 0)
			n = (int)(ks->top - ra) - 1;
		if (c == 0)
			c = GETARG_Ax(*ci->u.l.savedpc++);

		h = hvalue(ra);
		last = ((c - 1) * LFIELDS_PER_FLUSH) + n;
		if (last > h->sizearray)  /* needs more space? */
			kp_table_resizearray(ks, h, last);

		for (; n > 0; n--) {
			ktap_value *val = ra+n;
			kp_table_setint(ks, h, last--, val);
		}
		/* correct top (in case of previous open call) */
		ks->top = ci->top;
		break;
		}
	case OP_CLOSURE: {
		/* need to use closure cache? (multithread contention issue)*/
		ktap_proto *p = cl->p->p[GETARG_Bx(instr)];
		pushclosure(ks, p, cl->upvals, base, ra);
		break;
		}
	case OP_VARARG: {
		int b = GETARG_B(instr) - 1;
		int j;
		int n = (int)(base - ci->func) - cl->p->numparams - 1;
		if (b < 0) {  /* B == 0? */
			b = n;  /* get all var. arguments */
			checkstack(ks, n);
			/* previous call may change the stack */
			ra = RA(instr);
			ks->top = ra + n;
		}
		for (j = 0; j < b; j++) {
			if (j < n) {
				setobj(ra + j, base - n + j);
			} else
				setnilvalue(ra + j);
		}
		break;
		}
	case OP_EXTRAARG:
		return;

	case OP_EVENT: {
		struct ktap_event *e = ks->current_event;

		if (unlikely(!e)) {
			kp_error(ks, "invalid event context\n");
			return;
		}
		setevalue(ra, e);
		break;
		}

	case OP_EVENTNAME: {
		struct ktap_event *e = ks->current_event;

		if (unlikely(!e)) {
			kp_error(ks, "invalid event context\n");
			return;
		}
		setsvalue(ra, kp_tstring_new(ks, e->call->name));
		break;
		}
	case OP_EVENTARG:
		if (unlikely(!ks->current_event)) {
			kp_error(ks, "invalid event context\n");
			return;
		}

		kp_event_getarg(ks, ra, GETARG_B(instr));		
		break;
	case OP_LOAD_GLOBAL: {
		ktap_value *cfunc = cfunction_cache_get(ks, GETARG_C(instr));
		setobj(ra, cfunc);
		}
		break;

	case OP_EXIT:
		return;
	}

	goto mainloop;
}
Example #8
0
File: lcode.cpp Project: swizl/lua
/*static*/ int FuncState::boolK (/*FuncState *fs,*/ int b) {
	TValue o;
	setbvalue(&o, b);
	return addk(&o, &o);
}
Example #9
0
File: Lapi.c Project: mniip/LUA
LUA_API void LUA_pushboolean (LUA_State *L, int b) {
  LUA_lock(L);
  setbvalue(L->top, (b != 0));  /* ensure that true is 1 */
  api_incr_top(L);
  LUA_unlock(L);
}
Example #10
0
StkId luaV_execute (lua_State *L) {
  LClosure *cl;
  TObject *k;
  const Instruction *pc;
 callentry:  /* entry point when calling new functions */
  L->ci->u.l.pc = &pc;
  if (L->hookmask & LUA_MASKCALL)
    luaD_callhook(L, LUA_HOOKCALL, -1);
 retentry:  /* entry point when returning to old functions */
  lua_assert(L->ci->state == CI_SAVEDPC ||
             L->ci->state == (CI_SAVEDPC | CI_CALLING));
  L->ci->state = CI_HASFRAME;  /* activate frame */
  pc = L->ci->u.l.savedpc;
  cl = &clvalue(L->base - 1)->l;
  k = cl->p->k;
  /* main loop of interpreter */
  for (;;) {
    const Instruction i = *pc++;
    StkId base, ra;
    if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
        (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
      traceexec(L);
      if (L->ci->state & CI_YIELD) {  /* did hook yield? */
        L->ci->u.l.savedpc = pc - 1;
        L->ci->state = CI_YIELD | CI_SAVEDPC;
        return NULL;
      }
    }
    /* warning!! several calls may realloc the stack and invalidate `ra' */
    base = L->base;
    ra = RA(i);
    lua_assert(L->ci->state & CI_HASFRAME);
    lua_assert(base == L->ci->base);
    lua_assert(L->top <= L->stack + L->stacksize && L->top >= base);
    lua_assert(L->top == L->ci->top ||
         GET_OPCODE(i) == OP_CALL ||   GET_OPCODE(i) == OP_TAILCALL ||
         GET_OPCODE(i) == OP_RETURN || GET_OPCODE(i) == OP_SETLISTO);
    switch (GET_OPCODE(i)) {
      case OP_MOVE: {
        setobjs2s(ra, RB(i));
        break;
      }
      case OP_LOADK: {
        setobj2s(ra, KBx(i));
        break;
      }
      case OP_LOADBOOL: {
        setbvalue(ra, GETARG_B(i));
        if (GETARG_C(i)) pc++;  /* skip next instruction (if C) */
        break;
      }
      case OP_LOADNIL: {
        TObject *rb = RB(i);
        do {
          setnilvalue(rb--);
        } while (rb >= ra);
        break;
      }
      case OP_GETUPVAL: {
        int b = GETARG_B(i);
        setobj2s(ra, cl->upvals[b]->v);
        break;
      }
      case OP_GETGLOBAL: {
        TObject *rb = KBx(i);
        const TObject *v;
        lua_assert(ttisstring(rb) && ttistable(&cl->g));
        v = luaH_getstr(hvalue(&cl->g), tsvalue(rb));
        if (!ttisnil(v)) { setobj2s(ra, v); }
        else
          setobj2s(XRA(i), luaV_index(L, &cl->g, rb, 0));
        break;
      }
      case OP_GETTABLE: {
        StkId rb = RB(i);
        TObject *rc = RKC(i);
        if (ttistable(rb)) {
          const TObject *v = luaH_get(hvalue(rb), rc);
          if (!ttisnil(v)) { setobj2s(ra, v); }
          else
            setobj2s(XRA(i), luaV_index(L, rb, rc, 0));
        }
        else
          setobj2s(XRA(i), luaV_getnotable(L, rb, rc, 0));
        break;
      }
      case OP_SETGLOBAL: {
        lua_assert(ttisstring(KBx(i)) && ttistable(&cl->g));
        luaV_settable(L, &cl->g, KBx(i), ra);
        break;
      }
      case OP_SETUPVAL: {
        int b = GETARG_B(i);
        setobj(cl->upvals[b]->v, ra);  /* write barrier */
        break;
      }
      case OP_SETTABLE: {
        luaV_settable(L, ra, RKB(i), RKC(i));
        break;
      }
      case OP_NEWTABLE: {
        int b = GETARG_B(i);
        b = fb2int(b);
        sethvalue(ra, luaH_new(L, b, GETARG_C(i)));
        luaC_checkGC(L);
        break;
      }
      case OP_SELF: {
        StkId rb = RB(i);
        TObject *rc = RKC(i);
        runtime_check(L, ttisstring(rc));
        setobjs2s(ra+1, rb);
        if (ttistable(rb)) {
          const TObject *v = luaH_getstr(hvalue(rb), tsvalue(rc));
          if (!ttisnil(v)) { setobj2s(ra, v); }
          else
            setobj2s(XRA(i), luaV_index(L, rb, rc, 0));
        }
        else
          setobj2s(XRA(i), luaV_getnotable(L, rb, rc, 0));
        break;
      }
      case OP_ADD: {
        TObject *rb = RKB(i);
        TObject *rc = RKC(i);
        if (ttisnumber(rb) && ttisnumber(rc)) {
          setnvalue(ra, nvalue(rb) + nvalue(rc));
        }
        else
          Arith(L, ra, rb, rc, TM_ADD);
        break;
      }
      case OP_SUB: {
        TObject *rb = RKB(i);
        TObject *rc = RKC(i);
        if (ttisnumber(rb) && ttisnumber(rc)) {
          setnvalue(ra, nvalue(rb) - nvalue(rc));
        }
        else
          Arith(L, ra, rb, rc, TM_SUB);
        break;
      }
      case OP_MUL: {
        TObject *rb = RKB(i);
        TObject *rc = RKC(i);
        if (ttisnumber(rb) && ttisnumber(rc)) {
          setnvalue(ra, nvalue(rb) * nvalue(rc));
        }
        else
          Arith(L, ra, rb, rc, TM_MUL);
        break;
      }
      case OP_DIV: {
        TObject *rb = RKB(i);
        TObject *rc = RKC(i);
        if (ttisnumber(rb) && ttisnumber(rc)) {
          setnvalue(ra, nvalue(rb) / nvalue(rc));
        }
        else
          Arith(L, ra, rb, rc, TM_DIV);
        break;
      }
      case OP_POW: {
        Arith(L, ra, RKB(i), RKC(i), TM_POW);
        break;
      }
      case OP_UNM: {
        const TObject *rb = RB(i);
        TObject temp;
        if (tonumber(rb, &temp)) {
          setnvalue(ra, -nvalue(rb));
        }
        else {
          setnilvalue(&temp);
          if (!call_binTM(L, RB(i), &temp, ra, TM_UNM))
            luaG_aritherror(L, RB(i), &temp);
        }
        break;
      }
      case OP_NOT: {
        int res = l_isfalse(RB(i));  /* next assignment may change this value */
        setbvalue(ra, res);
        break;
      }
      case OP_CONCAT: {
        int b = GETARG_B(i);
        int c = GETARG_C(i);
        luaV_concat(L, c-b+1, c);  /* may change `base' (and `ra') */
        base = L->base;
        setobjs2s(RA(i), base+b);
        luaC_checkGC(L);
        break;
      }
      case OP_JMP: {
        dojump(pc, GETARG_sBx(i));
        break;
      }
      case OP_EQ: {
        if (equalobj(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
        else dojump(pc, GETARG_sBx(*pc) + 1);
        break;
      }
      case OP_LT: {
        if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
        else dojump(pc, GETARG_sBx(*pc) + 1);
        break;
      }
      case OP_LE: {
        if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) pc++;
        else dojump(pc, GETARG_sBx(*pc) + 1);
        break;
      }
      case OP_TEST: {
        TObject *rb = RB(i);
        if (l_isfalse(rb) == GETARG_C(i)) pc++;
        else {
          setobjs2s(ra, rb);
          dojump(pc, GETARG_sBx(*pc) + 1);
        }
        break;
      }
      case OP_CALL:
      case OP_TAILCALL: {
        StkId firstResult;
        int b = GETARG_B(i);
        int nresults;
        if (b != 0) L->top = ra+b;  /* else previous instruction set top */
        nresults = GETARG_C(i) - 1;
        firstResult = luaD_precall(L, ra);
        if (firstResult) {
          if (firstResult > L->top) {  /* yield? */
            lua_assert(L->ci->state == (CI_C | CI_YIELD));
            (L->ci - 1)->u.l.savedpc = pc;
            (L->ci - 1)->state = CI_SAVEDPC;
            return NULL;
          }
          /* it was a C function (`precall' called it); adjust results */
          luaD_poscall(L, nresults, firstResult);
          if (nresults >= 0) L->top = L->ci->top;
        }
        else {  /* it is a Lua function */
          if (GET_OPCODE(i) == OP_CALL) {  /* regular call? */
            (L->ci-1)->u.l.savedpc = pc;  /* save `pc' to return later */
            (L->ci-1)->state = (CI_SAVEDPC | CI_CALLING);
          }
          else {  /* tail call: put new frame in place of previous one */
            int aux;
            base = (L->ci - 1)->base;  /* `luaD_precall' may change the stack */
            ra = RA(i);
            if (L->openupval) luaF_close(L, base);
            for (aux = 0; ra+aux < L->top; aux++)  /* move frame down */
              setobjs2s(base+aux-1, ra+aux);
            (L->ci - 1)->top = L->top = base+aux;  /* correct top */
            lua_assert(L->ci->state & CI_SAVEDPC);
            (L->ci - 1)->u.l.savedpc = L->ci->u.l.savedpc;
            (L->ci - 1)->u.l.tailcalls++;  /* one more call lost */
            (L->ci - 1)->state = CI_SAVEDPC;
            L->ci--;  /* remove new frame */
            L->base = L->ci->base;
          }
          goto callentry;
        }
        break;
      }
      case OP_RETURN: {
        CallInfo *ci = L->ci - 1;  /* previous function frame */
        int b = GETARG_B(i);
        if (b != 0) L->top = ra+b-1;
        lua_assert(L->ci->state & CI_HASFRAME);
        if (L->openupval) luaF_close(L, base);
        L->ci->state = CI_SAVEDPC;  /* deactivate current function */
        L->ci->u.l.savedpc = pc;
        /* previous function was running `here'? */
        if (!(ci->state & CI_CALLING)) {
          lua_assert((ci->state & CI_C) || ci->u.l.pc != &pc);
          return ra;  /* no: return */
        }
        else {  /* yes: continue its execution */
          int nresults;
          lua_assert(ci->u.l.pc == &pc &&
                     ttisfunction(ci->base - 1) &&
                     (ci->state & CI_SAVEDPC));
          lua_assert(GET_OPCODE(*(ci->u.l.savedpc - 1)) == OP_CALL);
          nresults = GETARG_C(*(ci->u.l.savedpc - 1)) - 1;
          luaD_poscall(L, nresults, ra);
          if (nresults >= 0) L->top = L->ci->top;
          goto retentry;
        }
      }
      case OP_FORLOOP: {
        lua_Number step, idx, limit;
        const TObject *plimit = ra+1;
        const TObject *pstep = ra+2;
        if (!ttisnumber(ra))
          luaG_runerror(L, "`for' initial value must be a number");
        if (!tonumber(plimit, ra+1))
          luaG_runerror(L, "`for' limit must be a number");
        if (!tonumber(pstep, ra+2))
          luaG_runerror(L, "`for' step must be a number");
        step = nvalue(pstep);
        idx = nvalue(ra) + step;  /* increment index */
        limit = nvalue(plimit);
        if (step > 0 ? idx <= limit : idx >= limit) {
          dojump(pc, GETARG_sBx(i));  /* jump back */
          chgnvalue(ra, idx);  /* update index */
        }
        break;
      }
      case OP_TFORLOOP: {
        int nvar = GETARG_C(i) + 1;
        StkId cb = ra + nvar + 2;  /* call base */
        setobjs2s(cb, ra);
        setobjs2s(cb+1, ra+1);
        setobjs2s(cb+2, ra+2);
        L->top = cb+3;  /* func. + 2 args (state and index) */
        luaD_call(L, cb, nvar);
        L->top = L->ci->top;
        ra = XRA(i) + 2;  /* final position of first result */
        cb = ra + nvar;
        do {  /* move results to proper positions */
          nvar--;
          setobjs2s(ra+nvar, cb+nvar);
        } while (nvar > 0);
        if (ttisnil(ra))  /* break loop? */
          pc++;  /* skip jump (break loop) */
        else
          dojump(pc, GETARG_sBx(*pc) + 1);  /* jump back */
        break;
      }
      case OP_TFORPREP: {  /* for compatibility only */
        if (ttistable(ra)) {
          setobjs2s(ra+1, ra);
          setobj2s(ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next")));
        }
        dojump(pc, GETARG_sBx(i));
        break;
      }
      case OP_SETLIST:
      case OP_SETLISTO: {
        int bc;
        int n;
        Table *h;
        runtime_check(L, ttistable(ra));
        h = hvalue(ra);
        bc = GETARG_Bx(i);
        if (GET_OPCODE(i) == OP_SETLIST)
          n = (bc&(LFIELDS_PER_FLUSH-1)) + 1;
        else {
          n = L->top - ra - 1;
          L->top = L->ci->top;
        }
        bc &= ~(LFIELDS_PER_FLUSH-1);  /* bc = bc - bc%FPF */
        for (; n > 0; n--)
          setobj2t(luaH_setnum(L, h, bc+n), ra+n);  /* write barrier */
        break;
      }
      case OP_CLOSE: {
        luaF_close(L, ra);
        break;
      }
      case OP_CLOSURE: {
        Proto *p;
        Closure *ncl;
        int nup, j;
        p = cl->p->p[GETARG_Bx(i)];
        nup = p->nups;
        ncl = luaF_newLclosure(L, nup, &cl->g);
        ncl->l.p = p;
        for (j=0; j<nup; j++, pc++) {
          if (GET_OPCODE(*pc) == OP_GETUPVAL)
            ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
          else {
            lua_assert(GET_OPCODE(*pc) == OP_MOVE);
            ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
          }
        }
        setclvalue(ra, ncl);
        luaC_checkGC(L);
        break;
      }
    }
  }
}
Example #11
0
static int boolK(ktap_funcstate *fs, int b)
{
	ktap_value o;
	setbvalue(&o, b);
	return addk(fs, &o, &o);
}