Exemplo n.º 1
0
LUA_API const void *lua_topointer (lua_State *L, int idx) {
    StkId o = index2addr(L, idx);
    switch (ttype(o)) {
    case LUA_TTABLE:
        return hvalue(o);
    case LUA_TLCL:
        return clLvalue(o);
    case LUA_TCCL:
        return clCvalue(o);
    case LUA_TLCF:
        return cast(void *, cast(size_t, fvalue(o)));
    case LUA_TTHREAD:
        return thvalue(o);
    case LUA_TUSERDATA:
    case LUA_TLIGHTUSERDATA:
        return lua_touserdata(L, idx);
    default:
        return NULL;
    }
}
Exemplo n.º 2
0
static void rehash (lua_State *L, Hash *t) {
  int oldsize = t->size;
  Node *nold = t->node;
  int nelems = numuse(t);
  int i;
  LUA_ASSERT(nelems<=oldsize, "wrong count");
  if (nelems >= oldsize-oldsize/4)  /* using more than 3/4? */
    setnodevector(L, t, (lint32)oldsize*2);
  else if (nelems <= oldsize/4 &&  /* less than 1/4? */
           oldsize > MINPOWER2)
    setnodevector(L, t, oldsize/2);
  else
    setnodevector(L, t, oldsize);
  for (i=0; i<oldsize; i++) {
    Node *old = nold+i;
    if (ttype(&old->val) != LUA_TNIL)
      *luaH_set(L, t, &old->key) = old->val;
  }
  luaM_free(L, nold);  /* free old array */
}
Exemplo n.º 3
0
int luaT_efectivetag (TObject *o)
{
  int t;
  switch (t = ttype(o)) {
    case LUA_T_ARRAY:
      return o->value.a->htag;
    case LUA_T_USERDATA: {
      int tag = o->value.ts->u.d.tag;
      return (tag >= 0) ? LUA_T_USERDATA : tag;
    }
    case LUA_T_CLOSURE:
      return o->value.cl->consts[0].ttype;
#ifdef DEBUG
    case LUA_T_PMARK: case LUA_T_CMARK:
    case LUA_T_CLMARK: case LUA_T_LINE:
      LUA_INTERNALERROR("invalid type");
#endif
    default:
      return t;
  }
}
Exemplo n.º 4
0
static long int hashindex (TObject *ref)
{
  long int h;
  switch (ttype(ref)) {
    case LUA_T_NUMBER:
      h = (long int)nvalue(ref); break;
    case LUA_T_STRING: case LUA_T_USERDATA:
      h = tsvalue(ref)->hash; break;
    case LUA_T_FUNCTION:
      h = (IntPoint)ref->value.tf; break;
    case LUA_T_CFUNCTION:
      h = (IntPoint)fvalue(ref); break;
    case LUA_T_ARRAY:
      h = (IntPoint)avalue(ref); break;
    default:
      lua_error ("unexpected type to index table");
      h = 0;  /* UNREACHEABLE */
  }
  if (h < 0) h = -h;
  return h;
}
Exemplo n.º 5
0
static int32 markobject(TObject *o) {
	switch (ttype(o)) {
	case LUA_T_STRING:
		strmark(tsvalue(o));
		break;
	case LUA_T_ARRAY:
		hashmark(avalue(o));
		break;
	case LUA_T_CLOSURE:
	case LUA_T_CLMARK:
		closuremark(o->value.cl);
		break;
	case LUA_T_PROTO:
	case LUA_T_PMARK:
		protomark(o->value.tf);
		break;
	default:
		break;  // numbers, cprotos, etc
	}
	return 0;
}
Exemplo n.º 6
0
static void markobject (GCState *st, TObject *o) {
  switch (ttype(o)) {
    case LUA_TUSERDATA:  case LUA_TSTRING:
      strmark(tsvalue(o));
      break;
    case LUA_TMARK:
      markclosure(st, infovalue(o)->func);
      break;
    case LUA_TFUNCTION:
      markclosure(st, clvalue(o));
      break;
    case LUA_TTABLE: {
      if (!ismarked(hvalue(o))) {
        hvalue(o)->mark = st->tmark;  /* chain it in list of marked */
        st->tmark = hvalue(o);
      }
      break;
    }
    default: break;  /* numbers, etc */
  }
}
Exemplo n.º 7
0
LUA_API int lua_ref (lua_State *L,  int lock) {
  int ref;
  if (ttype(L->top-1) == LUA_TNIL)
    ref = LUA_REFNIL;
  else {
    if (L->refFree != NONEXT) {  /* is there a free place? */
      ref = L->refFree;
      L->refFree = L->refArray[ref].st;
    }
    else {  /* no more free places */
      luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref,
                      "reference table overflow", MAX_INT);
      L->nblocks += sizeof(struct Ref);
      ref = L->refSize++;
    }
    L->refArray[ref].o = *(L->top-1);
    L->refArray[ref].st = lock ? LOCK : HOLD;
  }
  L->top--;
  return ref;
}
Exemplo n.º 8
0
static void PrintConstant(const Proto* f, int i)
{
	const TValue* o=&f->k[i];
	switch (ttypenv(o))
	{
	case LUA_TNIL:
	printf("nil");
	break;
	case LUA_TBOOLEAN:
	printf(bvalue(o) ? "true" : "false");
	break;
	case LUA_TNUMBER:
	printf(LUA_NUMBER_FMT,nvalue(o));
	break;
	case LUA_TSTRING:
	PrintString(rawtsvalue(o));
	break;
	default:                /* cannot happen */
	printf("? type=%d",ttype(o));
	break;
	}
}
Exemplo n.º 9
0
void stop_script() {
	lua_Object paramObj = lua_getparam(1);
	lua_Type type = ttype(Address(paramObj));
	LState *state;

	if (paramObj == LUA_NOOBJECT || (type != LUA_T_CPROTO && type != LUA_T_PROTO && type != LUA_T_TASK))
		lua_error("Bad argument to stop_script");

	if (type == LUA_T_TASK) {
		uint32 task = (uint32)nvalue(Address(paramObj));
		for (state = lua_rootState->next; state != NULL; state = state->next) {
			if (state->id == task)
				break;
		}
		if (state) {
			if (state != lua_state) {
				lua_statedeinit(state);
				luaM_free(state);
			}
		}
	} else if (type == LUA_T_PROTO || type == LUA_T_CPROTO) {
		for (state = lua_rootState->next; state != NULL;) {
			bool match;
			if (type == LUA_T_PROTO) {
				match = (state->taskFunc.ttype == type && tfvalue(&state->taskFunc) == tfvalue(Address(paramObj)));
			} else {
				match = (state->taskFunc.ttype == type && fvalue(&state->taskFunc) == fvalue(Address(paramObj)));
			}
			if (match && state != lua_state) {
				LState *tmp = state->next;
				lua_statedeinit(state);
				luaM_free(state);
				state = tmp;
			} else {
				state = state->next;
			}
		}
	}
}
Exemplo n.º 10
0
int32 luaC_ref (TObject *o, int32 lock)
{
  int32 ref;
  if (ttype(o) == LUA_T_NIL)
    ref = -1;   /* special ref for nil */
  else {
    for (ref=0; ref<L->refSize; ref++)
      if (L->refArray[ref].status == FREE)
        goto found;
    /* no more empty spaces */ {
      int32 oldSize = L->refSize;
      L->refSize = luaM_growvector(&L->refArray, L->refSize, struct ref,
                                   refEM, MAX_INT);
      for (ref=oldSize; ref<L->refSize; ref++)
        L->refArray[ref].status = FREE;
      ref = oldSize;
    } found:
    L->refArray[ref].o = *o;
    L->refArray[ref].status = lock ? LOCK : HOLD;
  }
  return ref;
}
Exemplo n.º 11
0
static int traversetable (global_State *g, Table *h) {
  int i;
  int weakkey = 0;
  int weakvalue = 0;
  const TValue *mode;
  if (h->metatable)
    markobject(g, h->metatable);
  mode = gfasttm(g, h->metatable, TM_MODE);
  if (mode && ttisstring(mode)) {  /* is there a weak mode? */
    weakkey = (strchr(svalue(mode), 'k') != NULL);
    weakvalue = (strchr(svalue(mode), 'v') != NULL);
    if (weakkey || weakvalue) {  /* is really weak? */
      h->marked &= ~(KEYWEAK | VALUEWEAK);  /* clear bits */
      h->marked |= cast_byte((weakkey << KEYWEAKBIT) |
                             (weakvalue << VALUEWEAKBIT));
      h->gclist = g->weak;  /* must be cleared after GC, ... */
      g->weak = obj2gco(h);  /* ... so put in the appropriate list */
    }
  }
  if (weakkey && weakvalue) return 1;
  if (!weakvalue) {
    i = h->sizearray;
    while (i--)
      markvalue(g, &h->array[i]);
  }
  i = sizenode(h);
  while (i--) {
    Node *n = gnode(h, i);
    lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n)));
    if (ttisnil(gval(n)))
      removeentry(n);  /* remove empty entries */
    else {
      lua_assert(!ttisnil(gkey(n)));
      if (!weakkey) markvalue(g, gkey(n));
      if (!weakvalue) markvalue(g, gval(n));
    }
  }
  return weakkey || weakvalue;
}
Exemplo n.º 12
0
static void luaB_foreachvar (void) {
  GCnode *g;
  TObject f;  /* see comment in 'foreachi' */
  f = *luaA_Address(luaL_functionarg(1));
  luaD_checkstack(4);  /* for extra var name, f, var name, and globalval */
  for (g = L->rootglobal.next; g; g = g->next) {
    TaggedString *s = (TaggedString *)g;
    if (s->u.s.globalval.ttype != LUA_T_NIL) {
      pushtagstring(s);  /* keep (extra) s on stack to avoid GC */
      *(L->stack.top++) = f;
      pushtagstring(s);
      *(L->stack.top++) = s->u.s.globalval;
      luaD_calln(2, 1);
      if (ttype(L->stack.top-1) != LUA_T_NIL) {
        L->stack.top--;
        *(L->stack.top-1) = *L->stack.top;  /* remove extra s */
        return;
      }
      L->stack.top-=2;  /* remove result and extra s */
    }
  }
}
Exemplo n.º 13
0
LUA_API int lua_setmetatable (lua_State *L, int objindex) {
  TObject *obj, *mt;
  int res = 1;
  lua_lock(L);
  api_checknelems(L, 1);
  obj = luaA_index(L, objindex);
  mt = (!ttisnil(L->top - 1)) ? L->top - 1 : defaultmeta(L);
  api_check(L, ttistable(mt));
  switch (ttype(obj)) {
    case LUA_TTABLE: {
#if LUA_REFCOUNT
      __AddRefDirect(hvalue(mt));
      __ReleaseDirect(L, hvalue(obj)->metatable);
#endif LUA_REFCOUNT
	  hvalue(obj)->metatable = hvalue(mt);  /* write barrier */
      break;
    }
    case LUA_TUSERDATA: {
#if LUA_REFCOUNT
      __AddRefDirect(hvalue(mt));
	  __ReleaseDirect(L, &uvalue(obj)->uv.metatable);
#endif LUA_REFCOUNT
      uvalue(obj)->uv.metatable = hvalue(mt);  /* write barrier */
      break;
    }
    default: {
      res = 0;  /* cannot set */
      break;
    }
  }
#if LUA_REFCOUNT
  setnilvalue(--L->top);
#else !LUA_REFCOUNT
  L->top--;
#endif LUA_REFCOUNT
  lua_unlock(L);
  return res;
}
Exemplo n.º 14
0
int32 luaT_efectivetag(TObject *o) {
	int32 t;
	switch (t = ttype(o)) {
	case LUA_T_ARRAY:
		return o->value.a->htag;
	case LUA_T_USERDATA:
		{
			int32 tag = o->value.ud.tag;
			return (tag >= 0) ? LUA_T_USERDATA : tag;
		}
	case LUA_T_CLOSURE:
		return o->value.cl->consts[0].ttype;
#ifdef LUA_DEBUG
	case LUA_T_PMARK:
	case LUA_T_CMARK:
	case LUA_T_CLMARK:
	case LUA_T_LINE:
		lua_error("internal error");
#endif
	default:
		return t;
	}
}
Exemplo n.º 15
0
static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
  Closure *cl = NULL;
  switch (ttype(func)) {
    case LUA_TFUNCTION:
      cl = clvalue(func);
      break;
    case LUA_TMARK:
      cl = infovalue(func)->func;
      break;
    default:
      lua_error(L, "value for `lua_getinfo' is not a function");
  }
  if (cl->isC) {
    ar->source = "=C";
    ar->linedefined = -1;
    ar->what = "C";
  }
  else
    infoLproto(ar, cl->f.l);
  luaO_chunkid(ar->short_src, ar->source, sizeof(ar->short_src));
  if (ar->linedefined == 0)
    ar->what = "main";
}
Exemplo n.º 16
0
void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
  const TValue *tm;
  switch (ttype(rb)) {
    case LUA_TTABLE: {
      Table *h = hvalue(rb);
      tm = fasttm(L, h->metatable, TM_LEN);
      if (tm) break;  /* metamethod? break switch to call it */
      setnvalue(ra, cast_num(luaH_getn(h)));  /* else primitive len */
      return;
    }
    case LUA_TSTRING: {
      setnvalue(ra, cast_num(tsvalue(rb)->len));
      return;
    }
    default: {  /* try metamethod */
      tm = luaT_gettmbyobj(L, rb, TM_LEN);
      if (ttisnil(tm))  /* no metamethod? */
        luaG_typeerror(L, rb, "get length of");
      break;
    }
  }
  callTMres(L, ra, tm, rb, luaO_nilobject);
}
Exemplo n.º 17
0
/*
** returns the index of a `key' for table traversals. First goes all
** elements in the array part, then elements in the hash part. The
** beginning of a traversal is signalled by -1.
*/
static int findindex (lv_State *L, Table *t, StkId key) {
    int i;
    if (ttisnil(key)) return -1;  /* first iteration */
    i = arrayindex(key);
    if (0 < i && i <= t->sizearray)  /* is `key' inside array part? */
        return i-1;  /* yes; that's the index (corrected to C) */
    else {
        Node *n = mainposition(t, key);
        do {  /* check whether `key' is somewhere in the chain */
            /* key may be dead already, but it is ok to use it in `next' */
            if (lvO_rawequalObj(key2tval(n), key) ||
                    (ttype(gkey(n)) == LV_TDEADKEY && iscollectable(key) &&
                     gcvalue(gkey(n)) == gcvalue(key))) {
                i = cast_int(n - gnode(t, 0));  /* key index in hash table */
                /* hash elements are numbered after array ones */
                return i + t->sizearray;
            }
            else n = gnext(n);
        } while (n);
        lvG_runerror(L, "invalid key to " LV_QL("next"));  /* key not found */
        return 0;  /* to avoid warnings */
    }
}
Exemplo n.º 18
0
/*
 * equality of ktap values. ks == NULL means raw equality
 */
int kp_equalobjv(ktap_state *ks, const ktap_value *t1, const ktap_value *t2)
{
	switch (ttype(t1)) {
	case KTAP_TNIL:
		return 1;
	case KTAP_TNUMBER:
		return nvalue(t1) == nvalue(t2);
	case KTAP_TBOOLEAN:
		return bvalue(t1) == bvalue(t2);  /* true must be 1 !! */
	case KTAP_TLIGHTUSERDATA:
		return pvalue(t1) == pvalue(t2);
	case KTAP_TLCF:
		return fvalue(t1) == fvalue(t2);
	case KTAP_TSHRSTR:
		return eqshrstr(rawtsvalue(t1), rawtsvalue(t2));
	case KTAP_TLNGSTR:
		return kp_tstring_eqlngstr(rawtsvalue(t1), rawtsvalue(t2));
	case KTAP_TUSERDATA:
		if (uvalue(t1) == uvalue(t2))
			return 1;
		else if (ks == NULL)
			return 0;
	case KTAP_TTABLE:
		if (hvalue(t1) == hvalue(t2))
			return 1;
		else if (ks == NULL)
			return 0;
#ifdef __KERNEL__
	case KTAP_TBTRACE:
		return kp_btrace_equal(btvalue(t1), btvalue(t2));
#endif
	default:
		return gcvalue(t1) == gcvalue(t2);
	}

	return 0;
}
Exemplo n.º 19
0
/*
** Call a function (C or Lua). The parameters must be on the stack,
** between [top-nArgs,top). The function to be called is right below the
** arguments.
** When returns, the results are on the stack, between [top-nArgs-1,top).
** The number of results is nResults, unless nResults=MULT_RET.
*/
void luaD_calln (int nArgs, int nResults) {
  struct Stack *S = &L->stack;  /* to optimize */
  StkId base = (S->top-S->stack)-nArgs;
  TObject *func = S->stack+base-1;
  StkId firstResult;
  int i;
  switch (ttype(func)) {
    case LUA_T_CPROTO:
      ttype(func) = LUA_T_CMARK;
      firstResult = callC(fvalue(func), base);
      break;
    case LUA_T_PROTO:
      ttype(func) = LUA_T_PMARK;
      firstResult = luaV_execute(NULL, tfvalue(func), base);
      break;
    case LUA_T_CLOSURE: {
      Closure *c = clvalue(func);
      TObject *proto = &(c->consts[0]);
      ttype(func) = LUA_T_CLMARK;
      firstResult = (ttype(proto) == LUA_T_CPROTO) ?
                       callCclosure(c, fvalue(proto), base) :
                       luaV_execute(c, tfvalue(proto), base);
      break;
    }
    default: { /* func is not a function */
      /* Check the tag method for invalid functions */
      TObject *im = luaT_getimbyObj(func, IM_FUNCTION);
      if (ttype(im) == LUA_T_NIL)
        lua_error("call expression not a function");
      luaD_callTM(im, (S->top-S->stack)-(base-1), nResults);
      return;
    }
  }
  /* adjust the number of results */
  if (nResults == MULT_RET)
    nResults = (S->top-S->stack)-firstResult;
  else
    luaD_adjusttop(firstResult+nResults);
  /* move results to base-1 (to erase parameters and function) */
  base--;
  for (i=0; i<nResults; i++)
    *(S->stack+base+i) = *(S->stack+firstResult+i);
  S->top -= firstResult-base;
}
Exemplo n.º 20
0
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(luaV_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 (luaV_lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
            dojump(L, pc, GETARG_sBx(*pc));
        )
        pc++;
        continue;
      }
Exemplo n.º 21
0
Arquivo: lvm.c Projeto: uvbs/wx2Server
/*
** Executes the given Lua function. Parameters are between [base,top).
** Returns n such that the the results are between [n,top).
*/
StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
  const Proto *const tf = cl->f.l;
  StkId top;  /* keep top local, for performance */
  const Instruction *pc = tf->code;
  TString **const kstr = tf->kstr;
  const lua_Hook linehook = L->linehook;
  infovalue(base-1)->pc = &pc;
  luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK);
  if (tf->is_vararg)  /* varargs? */
    adjust_varargs(L, base, tf->numparams);
  else
    luaD_adjusttop(L, base, tf->numparams);
  top = L->top;
  /* main loop of interpreter */
  for (;;) {
    const Instruction i = *pc++;
    if (linehook)
      traceexec(L, base, top, linehook);
    switch (GET_OPCODE(i)) {
      case OP_END: {
        L->top = top;
        return top;
      }
      case OP_RETURN: {
        L->top = top;
        return base+GETARG_U(i);
      }
      case OP_CALL: {
        int nres = GETARG_B(i);
        if (nres == MULT_RET) nres = LUA_MULTRET;
        L->top = top;
        luaD_call(L, base+GETARG_A(i), nres);
        top = L->top;
        break;
      }
      case OP_TAILCALL: {
        L->top = top;
        luaD_call(L, base+GETARG_A(i), LUA_MULTRET);
        return base+GETARG_B(i);
      }
      case OP_PUSHNIL: {
        int n = GETARG_U(i);
        LUA_ASSERT(n>0, "invalid argument");
        do {
          ttype(top++) = LUA_TNIL;
        } while (--n > 0);
        break;
      }
      case OP_POP: {
        top -= GETARG_U(i);
        break;
      }
      case OP_PUSHINT: {
        ttype(top) = LUA_TNUMBER;
        nvalue(top) = (Number)GETARG_S(i);
        top++;
        break;
      }
      case OP_PUSHSTRING: {
        ttype(top) = LUA_TSTRING;
        tsvalue(top) = kstr[GETARG_U(i)];
        top++;
        break;
      }
      case OP_PUSHNUM: {
        ttype(top) = LUA_TNUMBER;
        nvalue(top) = tf->knum[GETARG_U(i)];
        top++;
        break;
      }
      case OP_PUSHNEGNUM: {
        ttype(top) = LUA_TNUMBER;
        nvalue(top) = -tf->knum[GETARG_U(i)];
        top++;
        break;
      }
      case OP_PUSHUPVALUE: {
        *top++ = cl->upvalue[GETARG_U(i)];
        break;
      }
      case OP_GETLOCAL: {
        *top++ = *(base+GETARG_U(i));
        break;
      }
      case OP_GETGLOBAL: {
        L->top = top;
        *top = *luaV_getglobal(L, kstr[GETARG_U(i)]);
        top++;
        break;
      }
      case OP_GETTABLE: {
        L->top = top;
        top--;
        *(top-1) = *luaV_gettable(L, top-1);
        break;
      }
      case OP_GETDOTTED: {
        ttype(top) = LUA_TSTRING;
        tsvalue(top) = kstr[GETARG_U(i)];
        L->top = top+1;
        *(top-1) = *luaV_gettable(L, top-1);
        break;
      }
      case OP_GETINDEXED: {
        *top = *(base+GETARG_U(i));
        L->top = top+1;
        *(top-1) = *luaV_gettable(L, top-1);
        break;
      }
      case OP_PUSHSELF: {
        TObject receiver;
        receiver = *(top-1);
        ttype(top) = LUA_TSTRING;
        tsvalue(top++) = kstr[GETARG_U(i)];
        L->top = top;
        *(top-2) = *luaV_gettable(L, top-2);
        *(top-1) = receiver;
        break;
      }
      case OP_CREATETABLE: {
        L->top = top;
        luaC_checkGC(L);
        hvalue(top) = luaH_new(L, GETARG_U(i));
        ttype(top) = LUA_TTABLE;
        top++;
        break;
      }
      case OP_SETLOCAL: {
        *(base+GETARG_U(i)) = *(--top);
        break;
      }
      case OP_SETGLOBAL: {
        L->top = top;
        luaV_setglobal(L, kstr[GETARG_U(i)]);
        top--;
        break;
      }
      case OP_SETTABLE: {
        StkId t = top-GETARG_A(i);
        L->top = top;
        luaV_settable(L, t, t+1);
        top -= GETARG_B(i);  /* pop values */
        break;
      }
      case OP_SETLIST: {
        int aux = GETARG_A(i) * LFIELDS_PER_FLUSH;
        int n = GETARG_B(i);
        Hash *arr = hvalue(top-n-1);
        L->top = top-n;  /* final value of `top' (in case of errors) */
        for (; n; n--)
          *luaH_setint(L, arr, n+aux) = *(--top);
        break;
      }
      case OP_SETMAP: {
        int n = GETARG_U(i);
        StkId finaltop = top-2*n;
        Hash *arr = hvalue(finaltop-1);
        L->top = finaltop;  /* final value of `top' (in case of errors) */
        for (; n; n--) {
          top-=2;
          *luaH_set(L, arr, top) = *(top+1);
        }
        break;
      }
      case OP_ADD: {
        if (tonumber(top-2) || tonumber(top-1))
          call_arith(L, top, TM_ADD);
        else
          nvalue(top-2) += nvalue(top-1);
        top--;
        break;
      }
      case OP_ADDI: {
        if (tonumber(top-1)) {
          ttype(top) = LUA_TNUMBER;
          nvalue(top) = (Number)GETARG_S(i);
          call_arith(L, top+1, TM_ADD);
        }
        else
          nvalue(top-1) += (Number)GETARG_S(i);
        break;
      }
      case OP_SUB: {
        if (tonumber(top-2) || tonumber(top-1))
          call_arith(L, top, TM_SUB);
        else
          nvalue(top-2) -= nvalue(top-1);
        top--;
        break;
      }
      case OP_MULT: {
        if (tonumber(top-2) || tonumber(top-1))
          call_arith(L, top, TM_MUL);
        else
          nvalue(top-2) *= nvalue(top-1);
        top--;
        break;
      }
      case OP_DIV: {
        if (tonumber(top-2) || tonumber(top-1))
          call_arith(L, top, TM_DIV);
        else
          nvalue(top-2) /= nvalue(top-1);
        top--;
        break;
      }
      case OP_POW: {
        if (!call_binTM(L, top, TM_POW))
          lua_error(L, "undefined operation");
        top--;
        break;
      }
      case OP_CONCAT: {
        int n = GETARG_U(i);
        luaV_strconc(L, n, top);
        top -= n-1;
        L->top = top;
        luaC_checkGC(L);
        break;
      }
      case OP_MINUS: {
        if (tonumber(top-1)) {
          ttype(top) = LUA_TNIL;
          call_arith(L, top+1, TM_UNM);
        }
        else
          nvalue(top-1) = -nvalue(top-1);
        break;
      }
      case OP_NOT: {
        ttype(top-1) =
           (ttype(top-1) == LUA_TNIL) ? LUA_TNUMBER : LUA_TNIL;
        nvalue(top-1) = 1;
        break;
      }
      case OP_JMPNE: {
        top -= 2;
        if (!luaO_equalObj(top, top+1)) dojump(pc, i);
        break;
      }
      case OP_JMPEQ: {
        top -= 2;
        if (luaO_equalObj(top, top+1)) dojump(pc, i);
        break;
      }
      case OP_JMPLT: {
        top -= 2;
        if (luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i);
        break;
      }
      case OP_JMPLE: {  /* a <= b  ===  !(b<a) */
        top -= 2;
        if (!luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i);
        break;
      }
      case OP_JMPGT: {  /* a > b  ===  (b<a) */
        top -= 2;
        if (luaV_lessthan(L, top+1, top, top+2)) dojump(pc, i);
        break;
      }
      case OP_JMPGE: {  /* a >= b  ===  !(a<b) */
        top -= 2;
        if (!luaV_lessthan(L, top, top+1, top+2)) dojump(pc, i);
        break;
      }
      case OP_JMPT: {
        if (ttype(--top) != LUA_TNIL) dojump(pc, i);
        break;
      }
      case OP_JMPF: {
        if (ttype(--top) == LUA_TNIL) dojump(pc, i);
        break;
      }
      case OP_JMPONT: {
        if (ttype(top-1) == LUA_TNIL) top--;
        else dojump(pc, i);
        break;
      }
      case OP_JMPONF: {
        if (ttype(top-1) != LUA_TNIL) top--;
        else dojump(pc, i);
        break;
      }
      case OP_JMP: {
        dojump(pc, i);
        break;
      }
      case OP_PUSHNILJMP: {
        ttype(top++) = LUA_TNIL;
        pc++;
        break;
      }
      case OP_FORPREP: {
        if (tonumber(top-1))
          lua_error(L, "`for' step must be a number");
        if (tonumber(top-2))
          lua_error(L, "`for' limit must be a number");
        if (tonumber(top-3))
          lua_error(L, "`for' initial value must be a number");
        if (nvalue(top-1) > 0 ?
            nvalue(top-3) > nvalue(top-2) :
            nvalue(top-3) < nvalue(top-2)) {  /* `empty' loop? */
          top -= 3;  /* remove control variables */
          dojump(pc, i);  /* jump to loop end */
        }
        break;
      }
      case OP_FORLOOP: {
        LUA_ASSERT(ttype(top-1) == LUA_TNUMBER, "invalid step");
        LUA_ASSERT(ttype(top-2) == LUA_TNUMBER, "invalid limit");
        if (ttype(top-3) != LUA_TNUMBER)
          lua_error(L, "`for' index must be a number");
        nvalue(top-3) += nvalue(top-1);  /* increment index */
        if (nvalue(top-1) > 0 ?
            nvalue(top-3) > nvalue(top-2) :
            nvalue(top-3) < nvalue(top-2))
          top -= 3;  /* end loop: remove control variables */
        else
          dojump(pc, i);  /* repeat loop */
        break;
      }
      case OP_LFORPREP: {
        Node *node;
        if (ttype(top-1) != LUA_TTABLE)
          lua_error(L, "`for' table must be a table");
        node = luaH_next(L, hvalue(top-1), &luaO_nilobject);
        if (node == NULL) {  /* `empty' loop? */
          top--;  /* remove table */
          dojump(pc, i);  /* jump to loop end */
        }
        else {
          top += 2;  /* index,value */
          *(top-2) = *key(node);
          *(top-1) = *val(node);
        }
        break;
      }
      case OP_LFORLOOP: {
        Node *node;
        LUA_ASSERT(ttype(top-3) == LUA_TTABLE, "invalid table");
        node = luaH_next(L, hvalue(top-3), top-2);
        if (node == NULL)  /* end loop? */
          top -= 3;  /* remove table, key, and value */
        else {
          *(top-2) = *key(node);
          *(top-1) = *val(node);
          dojump(pc, i);  /* repeat loop */
        }
        break;
      }
      case OP_CLOSURE: {
        L->top = top;
        luaV_Lclosure(L, tf->kproto[GETARG_A(i)], GETARG_B(i));
        top = L->top;
        luaC_checkGC(L);
        break;
      }
    }
  }
}
Exemplo n.º 22
0
LUA_API void lua_setglobals (lua_State *L) {
  StkId newtable = --L->top;
  LUA_ASSERT(ttype(newtable) == LUA_TTABLE, "table expected");
  L->gt = hvalue(newtable);
}
Exemplo n.º 23
0
void Decompiler::decompileRange(Byte *start, Byte *end) {
  // First, scan for IFFUPJMP, which is used for repeat/until, so
  // we can recognize the start of such loops.  We only keep the
  // last value to match each address, which represents the outermost
  // repeat/until loop starting at that point.
  std::map<Byte *, Byte *> rev_iffupjmp_map;

  for (Byte *scan = start; end == NULL || scan < end;
       scan += get_instr_len(*scan)) {
    if (*scan == IFFUPJMP)
      rev_iffupjmp_map[scan + 2 - scan[1]] = scan;
    else if (*scan == IFFUPJMPW)
      rev_iffupjmp_map[scan + 3 - (scan[1] | (scan[2] << 8))] = scan;
    else if (*scan == ENDCODE)
      break;
  }

  while (end == NULL || start < end) {
    int locs_here = local_var_defs->count(start);
    if (locs_here > 0) {
      // There were local variable slots just pushed onto the stack
      // Print them out (in the second pass)

      // First, if there are multiple defined, it must be from
      // local x, y, z = f() or local a, b.  So just ignore the extra
      // entries.
      for (int i = 1; i < locs_here; i++) {
	delete stk->top(); stk->pop();
      }
      Expression *def = stk->top(); stk->pop();

      // Print the local variable names, and at the same time push
      // fake values onto the stack
      *os << indent_str << "local ";
      for (int i = 0; i < locs_here; i++) {
	std::string locname = localname(tf, tf->code[1] + stk->size());
	*os << locname;
	if (i + 1 < locs_here)
	  *os << ", ";
	stk->push(new VarExpr(start, "<" + locname + " stack slot>"));
      }

      // Print the definition, unless it's nil
      VarExpr *v = dynamic_cast<VarExpr *>(def);
      if (v == NULL || v->name != "nil")
	*os << " = " << *def;
      *os << std::endl;
	  delete def;

      local_var_defs->erase(start);
    }

    if (rev_iffupjmp_map.find(start) != rev_iffupjmp_map.end()) {
      // aha, do a repeat/until loop
      *os << indent_str << "repeat\n";
      Decompiler indented_dc = *this;
      indented_dc.indent_str += std::string(4, ' ');
      indented_dc.break_pos = rev_iffupjmp_map[start];
      indented_dc.break_pos += get_instr_len(*indented_dc.break_pos);
      indented_dc.decompileRange(start, rev_iffupjmp_map[start]);

      Expression *e = stk->top(); stk->pop();
      *os << indent_str << "until " << *e << std::endl;
      delete e;

      start = indented_dc.break_pos;
      continue;
    }

    Byte opc = *start++;
    int aux;

    switch (opc) {
    case ENDCODE:
      return;

    case PUSHNIL:
      aux = *start++;
      goto pushnil;

    case PUSHNIL0:
      aux = 0;
    pushnil:
      for (int i = 0; i <= aux; i++)
	stk->push(new VarExpr(start, "nil")); // Cheat a little :)
      break;

    case PUSHNUMBER:
      aux = *start++;
      goto pushnumber;

    case PUSHNUMBER0:
    case PUSHNUMBER1:
    case PUSHNUMBER2:
      aux = opc - PUSHNUMBER0;
      goto pushnumber;

    case PUSHNUMBERW:
      aux = start[0] | (start[1] << 8);
      start += 2;
    pushnumber:
      stk->push(new NumberExpr(start, aux));
      break;

    case PUSHCONSTANT:
      aux = *start++;
      goto pushconst;

    case PUSHCONSTANT0:
    case PUSHCONSTANT1:
    case PUSHCONSTANT2:
    case PUSHCONSTANT3:
    case PUSHCONSTANT4:
    case PUSHCONSTANT5:
    case PUSHCONSTANT6:
    case PUSHCONSTANT7:
      aux = opc - PUSHCONSTANT0;
      goto pushconst;

    case PUSHCONSTANTW:
      aux = start[0] | (start[1] << 8);
      start += 2;
    pushconst:
      switch (ttype(tf->consts + aux)) {
      case LUA_T_STRING:
	stk->push(new StringExpr(start, tsvalue(tf->consts + aux)));
	break;
      case LUA_T_NUMBER:
	stk->push(new NumberExpr(start, nvalue(tf->consts + aux)));
	break;
      case LUA_T_PROTO:
	stk->push(new FuncExpr(start, tfvalue(tf->consts + aux), indent_str));
	break;
      default:
	*os << indent_str << "error: invalid constant type "
	    << int(ttype(tf->consts + aux)) << std::endl;
      }
      break;

    case PUSHUPVALUE:
      aux = *start++;
      goto pushupvalue;

    case PUSHUPVALUE0:
    case PUSHUPVALUE1:
      aux = opc - PUSHUPVALUE0;
    pushupvalue:
      {
	if (aux >= num_upvals) {
	  *os << indent_str << "error: invalid upvalue #"
	      << aux << std::endl;
	}

	std::ostringstream s;
	s << "%" << *upvals[aux];
	stk->push(new VarExpr(start, s.str()));
      }
      break;

    case PUSHLOCAL:
      aux = *start++;
      goto pushlocal;

    case PUSHLOCAL0:
    case PUSHLOCAL1:
    case PUSHLOCAL2:
    case PUSHLOCAL3:
    case PUSHLOCAL4:
    case PUSHLOCAL5:
    case PUSHLOCAL6:
    case PUSHLOCAL7:
      aux = opc - PUSHLOCAL0;
    pushlocal:
      stk->push(new VarExpr(start, localname(tf, aux)));
      break;

    case GETGLOBAL:
      aux = *start++;
      goto getglobal;

    case GETGLOBAL0:
    case GETGLOBAL1:
    case GETGLOBAL2:
    case GETGLOBAL3:
    case GETGLOBAL4:
    case GETGLOBAL5:
    case GETGLOBAL6:
    case GETGLOBAL7:
      aux = opc - GETGLOBAL0;
      goto getglobal;

    case GETGLOBALW:
      aux = start[0] | (start[1] << 8);
      start += 2;
    getglobal:
      stk->push(new VarExpr(start, svalue(tf->consts + aux)));
      break;

    case GETTABLE:
      {
	Expression *index = stk->top(); stk->pop();
	Expression *table = stk->top(); stk->pop();

	stk->push(new BracketsIndexExpr(start, table, index));
      }
      break;

    case GETDOTTED:
      aux = *start++;
      goto getdotted;

    case GETDOTTED0:
    case GETDOTTED1:
    case GETDOTTED2:
    case GETDOTTED3:
    case GETDOTTED4:
    case GETDOTTED5:
    case GETDOTTED6:
    case GETDOTTED7:
      aux = opc - GETDOTTED0;
      goto getdotted;

    case GETDOTTEDW:
      aux = start[0] | (start[1] << 8);
      start += 2;
    getdotted:
      {
	Expression *tbl = stk->top(); stk->pop();
	stk->push(new DotIndexExpr(start, tbl, new StringExpr
				(start, tsvalue(tf->consts + aux))));
      }
      break;

    case PUSHSELF:
      aux = *start++;
      goto pushself;

    case PUSHSELF0:
    case PUSHSELF1:
    case PUSHSELF2:
    case PUSHSELF3:
    case PUSHSELF4:
    case PUSHSELF5:
    case PUSHSELF6:
    case PUSHSELF7:
      aux = opc - PUSHSELF0;
      goto pushself;

    case PUSHSELFW:
      aux = start[0] | (start[1] << 8);
      start += 2;
    pushself:
      {
	Expression *tbl = stk->top(); stk->pop();
	stk->push(new SelfExpr(start, tbl, new StringExpr
			       (start, tsvalue(tf->consts + aux))));
	stk->push(new VarExpr(start, "<self>"));
	// Fake value, FuncCallExpr will handle it
      }
      break;

    case CREATEARRAY:
      start++;
      goto createarray;

    case CREATEARRAY0:
    case CREATEARRAY1:
      goto createarray;

    case CREATEARRAYW:
      start += 2;
    createarray:
      stk->push(new ArrayExpr(start));
      break;

    case SETLOCAL:
    case SETLOCAL0:
    case SETLOCAL1:
    case SETLOCAL2:
    case SETLOCAL3:
    case SETLOCAL4:
    case SETLOCAL5:
    case SETLOCAL6:
    case SETLOCAL7:
    case SETGLOBAL:
    case SETGLOBAL0:
    case SETGLOBAL1:
    case SETGLOBAL2:
    case SETGLOBAL3:
    case SETGLOBAL4:
    case SETGLOBAL5:
    case SETGLOBAL6:
    case SETGLOBAL7:
    case SETGLOBALW:
    case SETTABLE0:
    case SETTABLE:
      start--;
      do_multi_assign(start);
      break;

    case SETLIST:
      start++;			// assume offset is correct
      goto setlist;

    case SETLISTW:
      start += 2;

    case SETLIST0:
    setlist:
      aux = *start++;
      {
	ArrayExpr::mapping_list new_mappings;
	for (int i = 0; i < aux; i++) {
	  Expression *val = stk->top(); stk->pop();
	  new_mappings.push_front(std::make_pair((Expression *) NULL, val));
	}
	ArrayExpr *a = dynamic_cast<ArrayExpr *>(stk->top());
	if (a == NULL) {
	  *os << indent_str
	      << "error: attempt to setlist a non-array object\n";
	}
	// Append the new list
	a->mappings.splice(a->mappings.end(), new_mappings);
	a->pos = start;
      }
      break;

    case SETMAP:
      aux = *start++;
      goto setmap;

    case SETMAP0:
      aux = 0;
    setmap:
      {
	ArrayExpr::mapping_list new_mappings;
	for (int i = 0; i <= aux; i++) {
	  Expression *val = stk->top(); stk->pop();
	  Expression *key = stk->top(); stk->pop();
	  new_mappings.push_front(std::make_pair(key, val));
	}
	ArrayExpr *a = dynamic_cast<ArrayExpr *>(stk->top());
	if (a == NULL) {
	  *os << indent_str
	      << "error: attempt to setmap a non-array object\n";
	}
	// Append the new list
	a->mappings.splice(a->mappings.end(), new_mappings);
	a->pos = start;
      }
      break;

    case EQOP:
      do_binary_op(start, 1, false, " == ");
      break;

    case NEQOP:
      do_binary_op(start, 1, false, " ~= ");
      break;

    case LTOP:
      do_binary_op(start, 1, false, " < ");
      break;

    case LEOP:
      do_binary_op(start, 1, false, " <= ");
      break;

    case GTOP:
      do_binary_op(start, 1, false, " > ");
      break;

    case GEOP:
      do_binary_op(start, 1, false, " >= ");
      break;

    case ADDOP:
      do_binary_op(start, 3, false, " + ");
      break;

    case SUBOP:
      do_binary_op(start, 3, false, " - ");
      break;

    case MULTOP:
      do_binary_op(start, 4, false, " * ");
      break;

    case DIVOP:
      do_binary_op(start, 4, false, " / ");
      break;

    case POWOP:
      do_binary_op(start, 6, true, " ^ ");
      break;

    case CONCOP:
      do_binary_op(start, 2, false, " .. ");
      break;

    case MINUSOP:
      do_unary_op(start, 5, "-");
      break;

    case NOTOP:
      do_unary_op(start, 5, "not ");
      break;

    case ONTJMP:
      aux = *start++;
      goto ontjmp;

    case ONTJMPW:
      aux = start[0] | (start[1] << 8);
      start += 2;
    ontjmp:
      // push_expr_1 ontjmp(label) push_expr_2 label:  -> expr_1 || expr_2
      decompileRange(start, start + aux);
      do_binary_op(start + aux, 0, false, " or ");
      start = start + aux;
      break;

    case ONFJMP:
      aux = *start++;
      goto onfjmp;

    case ONFJMPW:
      aux = start[0] | (start[1] << 8);
      start += 2;
    onfjmp:
      // push_expr_1 onfjmp(label) push_expr_2 label:  -> expr_2 && expr_2
      decompileRange(start, start + aux);
      do_binary_op(start + aux, 0, false, " and ");
      start = start + aux;
      break;

    case JMP:
      aux = *start++;
      goto jmp;

    case JMPW:
      aux = start[0] | (start[1] << 8);
      start += 2;
    jmp:
      {
	Byte *dest = start + aux;
	if (dest == break_pos) {
	  *os << indent_str << "break\n";
	  break;
	}

	// otherwise, must be the start of a while statement
	Byte *while_cond_end;
	for (while_cond_end = dest; end == NULL || while_cond_end < end;
	     while_cond_end += get_instr_len(*while_cond_end))
	  if (*while_cond_end == IFTUPJMP || *while_cond_end == IFTUPJMPW)
	    break;
	if (end != NULL && while_cond_end >= end) {
	  *os << indent_str
	      << "error: JMP not in break, while, if/else\n";
	}

	// push the while condition onto the stack
	decompileRange(dest, while_cond_end);

	*os << indent_str << "while " << *stk->top()
	    << " do\n";
	delete stk->top();
	stk->pop();

	// decompile the while body
	Decompiler indented_dc = *this;
	indented_dc.indent_str += std::string(4, ' ');
	indented_dc.break_pos = while_cond_end + get_instr_len(*while_cond_end);
	indented_dc.decompileRange(start, dest);

	*os << indent_str << "end\n";
	start = indented_dc.break_pos;
      }
      break;

    case IFFJMP:
      aux = *start++;
      goto iffjmp;

    case IFFJMPW:
      aux = start[0] | (start[1] << 8);
      start += 2;
    iffjmp:
      {
	// Output an if/end, if/else/end, if/elseif/else/end, ... statement
	Byte *if_part_end = start + aux;
	Decompiler indented_dc = *this;
	indented_dc.indent_str += std::string(4, ' ');

	*os << indent_str << "if " << *stk->top();
	delete stk->top();
	stk->pop();
	*os << " then\n";

	bool has_else;
	Byte *else_part_end;
	get_else_part(start, if_part_end, has_else, else_part_end);

	// Output the if part
      output_if:
	indented_dc.decompileRange(start, if_part_end);
	start = start + aux;

	if (has_else) {
	  // Check whether the entire else part is a single
	  // if or if/else statement
	  Byte *instr_scan = start;
	  while (is_expr_opc(*instr_scan) &&
		 (end == NULL || instr_scan < else_part_end))
	    instr_scan += get_instr_len(*instr_scan);
	  if ((end == NULL || instr_scan < else_part_end) &&
	      (*instr_scan == IFFJMP || *instr_scan == IFFJMPW)) {
	    // OK, first line will be if, check if it will go all
	    // the way through
	    Byte *new_start, *new_if_part_end, *new_else_part_end;
	    bool new_has_else;
	    if (*instr_scan == IFFJMP) {
	      aux = instr_scan[1];
	      new_start = instr_scan + 2;
	    }
	    else {
	      aux = instr_scan[1] | (instr_scan[2] << 8);
	      new_start = instr_scan + 3;
	    }
	    new_if_part_end = new_start + aux;
	    get_else_part(new_start, new_if_part_end, new_has_else,
			  new_else_part_end);
	    if (new_if_part_end == else_part_end ||
		(new_has_else && new_else_part_end == else_part_end)) {
	      // Yes, output an elseif
	      decompileRange(start, instr_scan); // push condition
	      *os << indent_str << "elseif " << *stk->top() << " then\n";
	      delete stk->top();
	      stk->pop();

	      start = new_start;
	      if_part_end = new_if_part_end;
	      has_else = new_has_else;
	      else_part_end = new_else_part_end;
	      goto output_if;
	    }
	  }
	  *os << indent_str << "else\n";
	  indented_dc.decompileRange(start, else_part_end);
	  start = else_part_end;
	}
	*os << indent_str << "end\n";
      }
      break;

    case CLOSURE:
      aux = *start++;
      goto closure;

    case CLOSURE0:
    case CLOSURE1:
      aux = opc - CLOSURE0;
    closure:
      {
	FuncExpr *f = dynamic_cast<FuncExpr *>(stk->top());
	if (f == NULL) {
	  *os << indent_str
	      << "error: closure requires a function\n";
	}
	stk->pop();
	f->num_upvals = aux;
	f->upvals = new Expression*[aux];
	for (int i = aux - 1; i >= 0; i--) {
	  f->upvals[i] = stk->top(); stk->pop();
	}
	stk->push(f);
      }
      break;

    case CALLFUNC:
      aux = *start++;
      goto callfunc;

    case CALLFUNC0:
    case CALLFUNC1:
      aux = opc - CALLFUNC0;
    callfunc:
      {
	int num_args = *start++;
	FuncCallExpr *e = new FuncCallExpr(start);
	e->num_args = num_args;
	e->args = new Expression*[num_args];
	for (int i = num_args - 1; i >= 0; i--) {
	  e->args[i] = stk->top();
	  stk->pop();
	}
	e->func = stk->top();
	stk->pop();
	if (aux == 0) {
	  *os << indent_str << *e << std::endl;
	  delete e;
	}
	else if (aux == 1 || aux == 255) // 255 for return f()
	  stk->push(e);
	else {
	  stk->push(e);
	  for (int i = 1; i < aux; i++)
	    stk->push(new VarExpr(start, "<extra result>"));
	}
      }
      break;

    case RETCODE:
      {
	int num_rets = stk->size() + tf->code[1] - *start++;
	ExprStack rets;

	for (int i = 0; i < num_rets; i++) {
	  rets.push(stk->top());
	  stk->pop();
	}
	*os << indent_str << "return";
	for (int i = 0; i < num_rets; i++) {
	  *os << " " << *rets.top();
	  delete rets.top();
	  rets.pop();
	  if (i + 1 < num_rets)
	    *os << ",";
	}
	*os << std::endl;
      }
      break;

    case SETLINE:
      aux = *start++;
      goto setline;

    case SETLINEW:
      aux = start[0] | (start[1] << 8);
      start += 2;
    setline:
      break;			// ignore line info

    case POP:
      aux = *start++;
      goto pop;

    case POP0:
    case POP1:
      aux = opc - POP0;
    pop:
      for (int i = 0; i <= aux; i++) {
	local_var_defs->insert(stk->top()->pos);
	delete stk->top(); stk->pop();
      }
      break;

    //Nop
    default:
      break;
    }
  }
}
Exemplo n.º 24
0
static void luaI_type() {
	lua_Object o = luaL_nonnullarg(1);
	lua_pushstring(luaO_typenames[-ttype(luaA_Address(o))]);
	lua_pushnumber(lua_tag(o));
}
Exemplo n.º 25
0
TObject *luaH_setint (lua_State *L, Hash *t, int key) {
  TObject index;
  ttype(&index) = LUA_TNUMBER;
  nvalue(&index) = key;
  return luaH_set(L, t, &index);
}
Exemplo n.º 26
0
	loop2(TypBin, ptBin, nCorrTyp, nPtBins)
	{

		float pt1 = PtRes::PtBinLow(  ptBin);
		float pt2 = PtRes::PtBinHigh( ptBin);

		gStyle->SetOptStat(0);

		double nEntries = RelDiffPt[TypBin][ptBin]->Integral();
		RelDiffPt[TypBin][ptBin]->Scale(1./nEntries);

		RelDiffPt_Func[TypBin][ptBin]->SetParameter(1, 0.0);
		RelDiffPt_Func[TypBin][ptBin]->SetParameter(2, 0.1);
		RelDiffPt[TypBin][ptBin]->Fit( RelDiffPt_Func[TypBin][ptBin] );

		TCanvas canv ("canv",";lel;",1024,768);

		canv.SetLeftMargin  ( RelDiffPt_leftmargin   );
		canv.SetRightMargin ( RelDiffPt_rightmargin  );
		canv.SetTopMargin   ( RelDiffPt_topmargin    );
		canv.SetBottomMargin( RelDiffPt_bottommargin );

		RelDiffPt[TypBin][ptBin]->SetTitle("");
		//RelDiffPt[TypBin][ptBin]->GetXaxis()->CenterTitle(1);
		RelDiffPt[TypBin][ptBin]->GetXaxis()->SetTitleSize( RelDiffPt_xlabelsize );
		RelDiffPt[TypBin][ptBin]->GetXaxis()->SetTitle( "x = #frac{p_{T}^{reco}-p_{T}^{gen}}{p_{T}^{gen}}" );
		RelDiffPt[TypBin][ptBin]->GetYaxis()->SetTitleSize( RelDiffPt_ylabelsize );
		RelDiffPt[TypBin][ptBin]->GetYaxis()->SetTitle( "occurance" );
		RelDiffPt[TypBin][ptBin]->SetTitleOffset( RelDiffPt_xlabeloffset ,"X");
		RelDiffPt[TypBin][ptBin]->SetTitleOffset( RelDiffPt_ylabeloffset ,"Y");
		RelDiffPt[TypBin][ptBin]->GetYaxis()->CenterTitle(1);

		double amp   = abs(RelDiffPt_Func[TypBin][ptBin]->GetParameter(0));
		double x0    = abs(RelDiffPt_Func[TypBin][ptBin]->GetParameter(1));
		double sigma = abs(RelDiffPt_Func[TypBin][ptBin]->GetParameter(2));

		double amp_Err   = abs(RelDiffPt_Func[TypBin][ptBin]->GetParError(0));
		double x0_Err    = abs(RelDiffPt_Func[TypBin][ptBin]->GetParError(1));
		double sigma_Err = abs(RelDiffPt_Func[TypBin][ptBin]->GetParError(2));

		RelDiffPtSigma[TypBin][ptBin] = sigma; 
		RelDiffPtMean [TypBin][ptBin] = x0;

		(*PtResolutionParams[TypBin][ptBin])[0] = sigma;
		(*PtResolutionParams[TypBin][ptBin])[1] = x0;

		TLatex tres( RelDiffPt_tres_upperleftposx, RelDiffPt_tres_upperleftposy , Form("#splitline{#splitline{amp = %.3f #pm %.3f}{x_{0} = %.3f #pm %.3f}}{#sigma = %.3f #pm %.3f}", amp, amp_Err, x0, x0_Err, sigma, sigma_Err) ); 
		tres.SetTextSize( RelDiffPt_figuretextsize );
		tres.SetNDC(kTRUE);

		TLatex ttype( RelDiffPt_ttype_upperleftposx, RelDiffPt_ttype_upperleftposy , Form("#splitline{%s}{p_{T} = [%.2f - %.2f] GeV/c}", particletype(TypBin).c_str(), pt1, pt2 ) ); 
		ttype.SetTextSize( RelDiffPt_figuretextsize );
		ttype.SetNDC(kTRUE);


		RelDiffPt[TypBin][ptBin]->Draw("");
		tres.Draw();
		ttype.Draw();

		std::string dir   = Form("./figures/");
		std::string filePDF = Form("PtRelDiff_%d_pt_%.2f-%.2f.pdf", TypBin, pt1, pt2);
		std::string filePNG = Form("PtRelDiff_%d_pt_%.2f-%.2f.png", TypBin, pt1, pt2);

		std::string figurePNG = dir+filePNG;
		std::string figurePDF = dir+filePDF;

		canv.SaveAs( figurePNG.c_str() );
		canv.SaveAs( figurePDF.c_str() );

		canv.Clear();

	}
Exemplo n.º 27
0
static UpVal *toupval(lua_State *L, int stackpos)
{
	lua_assert(ttype(getobject(L, stackpos)) == LUA_TUPVAL);
	return gco2uv(getobject(L, stackpos)->value.gc);
}
Exemplo n.º 28
0
LUA_API int lua_type (lua_State *L, int idx) {
  StkId o = luaA_indexAcceptable(L, idx);
  return (o == NULL) ? LUA_TNONE : ttype(o);
}
Exemplo n.º 29
0
void current_script() {
	ttype(lua_state->stack.top) = LUA_T_TASK;
	nvalue(lua_state->stack.top) = (float)lua_state->id;
	incr_top;
}
Exemplo n.º 30
0
static void init_entry (int tag)
{
  int i;
  for (i=0; i<IM_N; i++)
    ttype(luaT_getim(tag, i)) = LUA_T_NIL;
}