Commit 13c1e1f2 authored by meir's avatar meir Committed by Oran Agra
Browse files

Added support for Lua readonly tables.

The new feature can be turned off and on using the new `lua_enablereadonlytable` Lua API.

(cherry picked from commit 92b5098b87e2d0880a530899119524bf1dfbc332)
parent 34505d26
...@@ -674,6 +674,8 @@ LUA_API void lua_rawset (lua_State *L, int idx) { ...@@ -674,6 +674,8 @@ LUA_API void lua_rawset (lua_State *L, int idx) {
api_checknelems(L, 2); api_checknelems(L, 2);
t = index2adr(L, idx); t = index2adr(L, idx);
api_check(L, ttistable(t)); api_check(L, ttistable(t));
if (hvalue(t)->readonly)
luaG_runerror(L, "Attempt to modify a readonly table");
setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
luaC_barriert(L, hvalue(t), L->top-1); luaC_barriert(L, hvalue(t), L->top-1);
L->top -= 2; L->top -= 2;
...@@ -687,6 +689,8 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) { ...@@ -687,6 +689,8 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
api_checknelems(L, 1); api_checknelems(L, 1);
o = index2adr(L, idx); o = index2adr(L, idx);
api_check(L, ttistable(o)); api_check(L, ttistable(o));
if (hvalue(o)->readonly)
luaG_runerror(L, "Attempt to modify a readonly table");
setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1); setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
luaC_barriert(L, hvalue(o), L->top-1); luaC_barriert(L, hvalue(o), L->top-1);
L->top--; L->top--;
...@@ -709,6 +713,8 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { ...@@ -709,6 +713,8 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
} }
switch (ttype(obj)) { switch (ttype(obj)) {
case LUA_TTABLE: { case LUA_TTABLE: {
if (hvalue(obj)->readonly)
luaG_runerror(L, "Attempt to modify a readonly table");
hvalue(obj)->metatable = mt; hvalue(obj)->metatable = mt;
if (mt) if (mt)
luaC_objbarriert(L, hvalue(obj), mt); luaC_objbarriert(L, hvalue(obj), mt);
...@@ -1085,3 +1091,11 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { ...@@ -1085,3 +1091,11 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
return name; return name;
} }
LUA_API void lua_enablereadonlytable (lua_State *L, int objindex, int enabled) {
const TValue* o = index2adr(L, objindex);
api_check(L, ttistable(o));
Table* t = hvalue(o);
api_check(L, t != hvalue(registry(L)));
t->readonly = enabled;
}
...@@ -80,7 +80,6 @@ LUA_API int lua_gethookcount (lua_State *L) { ...@@ -80,7 +80,6 @@ LUA_API int lua_gethookcount (lua_State *L) {
return L->basehookcount; return L->basehookcount;
} }
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
int status; int status;
CallInfo *ci; CallInfo *ci;
......
...@@ -338,6 +338,7 @@ typedef struct Node { ...@@ -338,6 +338,7 @@ typedef struct Node {
typedef struct Table { typedef struct Table {
CommonHeader; CommonHeader;
lu_byte flags; /* 1<<p means tagmethod(p) is not present */ lu_byte flags; /* 1<<p means tagmethod(p) is not present */
int readonly;
lu_byte lsizenode; /* log2 of size of `node' array */ lu_byte lsizenode; /* log2 of size of `node' array */
struct Table *metatable; struct Table *metatable;
TValue *array; /* array part */ TValue *array; /* array part */
......
...@@ -364,6 +364,7 @@ Table *luaH_new (lua_State *L, int narray, int nhash) { ...@@ -364,6 +364,7 @@ Table *luaH_new (lua_State *L, int narray, int nhash) {
t->array = NULL; t->array = NULL;
t->sizearray = 0; t->sizearray = 0;
t->lsizenode = 0; t->lsizenode = 0;
t->readonly = 0;
t->node = cast(Node *, dummynode); t->node = cast(Node *, dummynode);
setarrayvector(L, t, narray); setarrayvector(L, t, narray);
setnodevector(L, t, nhash); setnodevector(L, t, nhash);
......
...@@ -358,6 +358,8 @@ struct lua_Debug { ...@@ -358,6 +358,8 @@ struct lua_Debug {
int i_ci; /* active function */ int i_ci; /* active function */
}; };
LUA_API void lua_enablereadonlytable (lua_State *L, int index, int enabled);
/* }====================================================================== */ /* }====================================================================== */
......
...@@ -138,6 +138,8 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { ...@@ -138,6 +138,8 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
const TValue *tm; const TValue *tm;
if (ttistable(t)) { /* `t' is a table? */ if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t); Table *h = hvalue(t);
if (h->readonly)
luaG_runerror(L, "Attempt to modify a readonly table");
TValue *oldval = luaH_set(L, h, key); /* do a primitive set */ TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
if (!ttisnil(oldval) || /* result is no nil? */ if (!ttisnil(oldval) || /* result is no nil? */
(tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment