Ejemplo n.º 1
0
static void persistfunction(PersistInfo *pi)
{
					/* perms reftbl ... func */
	Closure *cl = clvalue(getobject(pi->L, -1));
	lua_checkstack(pi->L, 2);
	if(cl->c.isC) {
		/* It's a C function. For now, we aren't going to allow
		 * persistence of C closures, even if the "C proto" is
		 * already in the permanents table. */
		lua_pushstring(pi->L, "Attempt to persist a C function");
		lua_error(pi->L);
	} else {
		/* It's a Lua closure. */
		{
			/* We don't really _NEED_ the number of upvals,
			 * but it'll simplify things a bit */
			pi->writer(pi->L, &cl->l.p->nups, sizeof(lu_byte), pi->ud);
		}
		/* Persist prototype */
		{
			pushproto(pi->L, cl->l.p);
					/* perms reftbl ... func proto */
			persist(pi);
			lua_pop(pi->L, 1);
					/* perms reftbl ... func */
		}
		/* Persist upvalue values (not the upvalue objects
		 * themselves) */
		{
			int i;
			for(i=0; i<cl->l.p->nups; i++) {
					/* perms reftbl ... func */
				pushupval(pi->L, cl->l.upvals[i]);
					/* perms reftbl ... func upval */
				persist(pi);
				lua_pop(pi->L, 1);
					/* perms reftbl ... func */
			}
					/* perms reftbl ... func */
		}
		/* Persist function environment */
		{
			lua_getfenv(pi->L, -1);
					/* perms reftbl ... func fenv */
			if(lua_equal(pi->L, -1, LUA_GLOBALSINDEX)) {
				/* Function has the default fenv */
					/* perms reftbl ... func _G */
				lua_pop(pi->L, 1);
					/* perms reftbl ... func */
				lua_pushnil(pi->L);
					/* perms reftbl ... func nil */
			}
					/* perms reftbl ... func fenv/nil */
			persist(pi);
			lua_pop(pi->L, 1);
					/* perms reftbl ... func */
		}
	}
}
Ejemplo n.º 2
0
static void persistproto(PersistInfo *pi)
{
					/* perms reftbl ... proto */
	Proto *p = toproto(pi->L, -1);
	lua_checkstack(pi->L, 2);

	/* Persist constant refs */
	{
		int i;
		pi->writer(pi->L, &p->sizek, sizeof(int), pi->ud);
		for(i=0; i<p->sizek; i++) {
			LIF(A,pushobject)(pi->L, &p->k[i]);
					/* perms reftbl ... proto const */
			persist(pi);
			lua_pop(pi->L, 1);
					/* perms reftbl ... proto */
		}
	}
					/* perms reftbl ... proto */

	/* serialize inner Proto refs */
	{
		int i;
		pi->writer(pi->L, &p->sizep, sizeof(int), pi->ud);
		for(i=0; i<p->sizep; i++)
		{
			pushproto(pi->L, p->p[i]);
					/* perms reftbl ... proto subproto */
			persist(pi);
			lua_pop(pi->L, 1);
					/* perms reftbl ... proto */
		}
	}
					/* perms reftbl ... proto */
	/* Serialize code */
	{
		pi->writer(pi->L, &p->sizecode, sizeof(int), pi->ud);
		pi->writer(pi->L, p->code, sizeof(Instruction) * p->sizecode, pi->ud);
	}
	/* Serialize misc values */
	{
		pi->writer(pi->L, &p->nups, sizeof(lu_byte), pi->ud);
		pi->writer(pi->L, &p->numparams, sizeof(lu_byte), pi->ud);
		pi->writer(pi->L, &p->is_vararg, sizeof(lu_byte), pi->ud);
		pi->writer(pi->L, &p->maxstacksize, sizeof(lu_byte), pi->ud);
	}
	/* We do not currently persist upvalue names, local variable names,
	 * variable lifetimes, line info, or source code. */
}
Ejemplo n.º 3
0
static void unpersistproto(int ref, UnpersistInfo *upi) {
	/* perms reftbl ... */
	Proto *p;
	int i;
	int sizep, sizek;

	/* We have to be careful. The GC expects a lot out of protos. In
	 * particular, we need to give the function a valid string for its
	 * source, and valid code, even before we actually read in the real
	 * code. */
	TString *source = luaS_newlstr(upi->L, "", 0);
	p = luaF_newproto(upi->L);
	p->source = source;
	p->sizecode=1;
	p->code = luaM_newvector(upi->L, 1, Instruction);
	p->code[0] = CREATE_ABC(OP_RETURN, 0, 1, 0);
	p->maxstacksize = 2;
	p->sizek = 0;
	p->sizep = 0;


	pushproto(upi->L, p);
	/* perms reftbl ... proto */
	/* We don't need to register early, since protos can never ever be
	 * involved in cyclic references */

	/* Read in constant references */
	{
		verify(luaZ_read(&upi->zio, &sizek, sizeof(int)) == 0);
		luaM_reallocvector(upi->L, p->k, 0, sizek, TObject);
		for(i=0; i<sizek; i++) {
			/* perms reftbl ... proto */
			unpersist(upi);
			/* perms reftbl ... proto k */
			setobj2s(&p->k[i], getobject(upi->L, -1));
			p->sizek++;
			lua_pop(upi->L, 1);
			/* perms reftbl ... proto */
		}
		/* perms reftbl ... proto */
	}
	/* Read in sub-proto references */
	{
		verify(luaZ_read(&upi->zio, &sizep, sizeof(int)) == 0);
		luaM_reallocvector(upi->L, p->p, 0, sizep, Proto*);
		for(i=0; i<sizep; i++) {
			/* perms reftbl ... proto */
			unpersist(upi);
			/* perms reftbl ... proto subproto */
			p->p[i] = toproto(upi->L, -1);
			p->sizep++;
			lua_pop(upi->L, 1);
			/* perms reftbl ... proto */
		}
		/* perms reftbl ... proto */
	}

	/* Read in code */
	{
		verify(luaZ_read(&upi->zio, &p->sizecode, sizeof(int)) == 0);
		luaM_reallocvector(upi->L, p->code, 1, p->sizecode, Instruction);
		verify(luaZ_read(&upi->zio, p->code,
		                 sizeof(Instruction) * p->sizecode) == 0);
	}

	/* Read in misc values */
	{
		verify(luaZ_read(&upi->zio, &p->nups, sizeof(lu_byte)) == 0);
		verify(luaZ_read(&upi->zio, &p->numparams, sizeof(lu_byte)) == 0);
		verify(luaZ_read(&upi->zio, &p->is_vararg, sizeof(lu_byte)) == 0);
		verify(luaZ_read(&upi->zio, &p->maxstacksize, sizeof(lu_byte)) == 0);
	}
}