Skip to content

Instantly share code, notes, and snippets.

@cloudwu
Created March 25, 2020 10:32
Show Gist options
  • Save cloudwu/a094583029f15bb74fa6df194159d008 to your computer and use it in GitHub Desktop.
Save cloudwu/a094583029f15bb74fa6df194159d008 to your computer and use it in GitHub Desktop.
Change seed for lua 5.3
/*
Only for lua 5.3
You can use lua_changeseed(L, seed) to change a seed for a lua VM.
lua_State *L = luaL_newstate();
lua_changeseed(L, myseed);
*/
#include "lstate.h"
#include "lobject.h"
#include "lstring.h"
#if !defined(LUAI_HASHLIMIT)
#define LUAI_HASHLIMIT 5
#endif
static unsigned int luaS_hash_ (const char *str, size_t l, unsigned int seed) {
unsigned int h = seed ^ cast(unsigned int, l);
size_t step = (l >> LUAI_HASHLIMIT) + 1;
for (; l >= step; l -= step)
h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1]));
return h;
}
static void
changelists(GCObject *p, unsigned int seed) {
while (p != NULL) {
TString *ts;
switch (p->tt) {
case LUA_TSHRSTR:
ts = gco2ts(p);
ts->hash = luaS_hash_(getstr(ts), ts->shrlen, seed);
break;
case LUA_TLNGSTR:
ts = gco2ts(p);
ts->extra = 0;
break;
}
p = p->next;
}
}
static void
rearrange(stringtable *tb, unsigned int seed) {
int i;
int size = tb->size;
for (i=0;i<size;i++) {
TString *ts = tb->hash[i];
tb->hash[i] = NULL;
while (ts != NULL) {
int nidx = lmod(ts->hash, size);
TString *next = ts->u.hnext;
ts->u.hnext = tb->hash[nidx];
tb->hash[nidx] = ts;
ts = next;
}
}
}
void
lua_changeseed(lua_State *L, unsigned int seed) {
global_State *g = G(L);
g->seed = seed;
changelists(g->allgc, seed);
changelists(g->fixedgc, seed);
rearrange(&g->strt, seed);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment