Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- src/lapi.c | 35 +++++++++++++++++++++++++++++++++++
- src/lbaselib.c | 30 ++++++++++++++++++++++++++++++
- src/ldo.c | 4 ++++
- src/lgc.c | 18 ++++++++++++++++++
- src/lobject.h | 25 +++++++++++++++++++++++++
- src/lstate.h | 6 ++++++
- src/ltm.c | 40 ++++++++++++++++++++++++++++++++++++++++
- src/lua.h | 11 +++++++++++
- src/luaconf.h | 1 +
- src/lvm.c | 24 ++++++++++++++++++++++++
- 10 files changed, 194 insertions(+)
- diff --git src/lapi.c src/lapi.c
- index 02b7fab..3f7b3b0 100644
- --- src/lapi.c
- +++ src/lapi.c
- @@ -436,6 +436,9 @@ LUA_API const void *lua_topointer (lua_State *L, int idx) {
- case LUA_TTHREAD: return thvalue(o);
- case LUA_TUSERDATA: return getudatamem(uvalue(o));
- case LUA_TLIGHTUSERDATA: return pvalue(o);
- +#if defined(LUA_PROXY_ENABLED)
- + case LUA_TPROXY: return pxvalue(o);
- +#endif
- default: return NULL;
- }
- }
- @@ -707,6 +710,11 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
- case LUA_TUSERDATA:
- mt = uvalue(obj)->metatable;
- break;
- +#if defined(LUA_PROXY_ENABLED)
- + case LUA_TPROXY:
- + mt = pxvalue(obj)->metatable;
- + break;
- +#endif
- default:
- mt = G(L)->mt[ttnov(obj)];
- break;
- @@ -872,6 +880,16 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
- }
- break;
- }
- +#if defined(LUA_PROXY_ENABLED)
- + case LUA_TPROXY: {
- + pxvalue(obj)->metatable = mt;
- + if (mt) {
- + luaC_objbarrier(L, gcvalue(obj), mt);
- + luaC_checkfinalizer(L, gcvalue(obj), mt);
- + }
- + break;
- + }
- +#endif
- default: {
- G(L)->mt[ttnov(obj)] = mt;
- break;
- @@ -1297,3 +1315,20 @@ LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1,
- }
- +#if defined(LUA_PROXY_ENABLED)
- +/* Envelops a value at the given index and pushes the proxy unto the stack */
- +LUA_API void lua_envelop (lua_State *L, int idx) {
- + GCObject *o;
- + Proxy *px;
- + lua_lock(L);
- + o = luaC_newobj(L, LUA_TPROXY, sizeof(Proxy));
- + px = gco2px(o);
- + px->value = *index2addr(L, idx); /* set enveloped value */
- + px->metatable = NULL; /* no initial metatable */
- + setpxvalue(L, L->top, px);
- + api_incr_top(L);
- + lua_unlock(L);
- +}
- +#endif
- +
- +
- diff --git src/lbaselib.c src/lbaselib.c
- index 6460e4f..7c50ed4 100644
- --- src/lbaselib.c
- +++ src/lbaselib.c
- @@ -123,10 +123,20 @@ static int luaB_getmetatable (lua_State *L) {
- static int luaB_setmetatable (lua_State *L) {
- +#if !defined(LUA_PROXY_ENABLED)
- int t = lua_type(L, 2);
- luaL_checktype(L, 1, LUA_TTABLE);
- luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
- "nil or table expected");
- +#else
- + int t1, t2;
- + t1 = lua_type(L, 1);
- + luaL_argcheck(L, t1 == LUA_TTABLE || t1 == LUA_TPROXY, 1,
- + "table or proxy expected");
- + t2 = lua_type(L, 2);
- + luaL_argcheck(L, t2 == LUA_TNIL || t2 == LUA_TTABLE, 2,
- + "nil or table expected");
- +#endif
- if (luaL_getmetafield(L, 1, "__metatable") != LUA_TNIL)
- return luaL_error(L, "cannot change a protected metatable");
- lua_settop(L, 2);
- @@ -450,10 +460,30 @@ static int luaB_tostring (lua_State *L) {
- }
- +#if defined(LUA_PROXY_ENABLED)
- +/* proxy = envelop(value, metatable) */
- +static int luaB_envelop (lua_State *L) {
- + luaL_checkany(L, 1);
- + if (!lua_isnoneornil(L, 2)) { /* have metatable? */
- + luaL_checktype(L, 2, LUA_TTABLE);
- + lua_envelop(L, 1);
- + lua_pushvalue(L, 2);
- + lua_setmetatable(L, -2);
- + }
- + else /* no metatable */
- + lua_envelop(L, 1);
- + return 1;
- +}
- +#endif
- +
- +
- static const luaL_Reg base_funcs[] = {
- {"assert", luaB_assert},
- {"collectgarbage", luaB_collectgarbage},
- {"dofile", luaB_dofile},
- +#if defined(LUA_PROXY_ENABLED)
- + {"envelop", luaB_envelop},
- +#endif
- {"error", luaB_error},
- {"getmetatable", luaB_getmetatable},
- {"ipairs", luaB_ipairs},
- diff --git src/ldo.c src/ldo.c
- index 316e45c..c8b0db4 100644
- --- src/ldo.c
- +++ src/ldo.c
- @@ -317,6 +317,10 @@ static void tryfuncTM (lua_State *L, StkId func) {
- StkId p;
- if (!ttisfunction(tm))
- luaG_typeerror(L, func, "call");
- +#if defined(LUA_PROXY_ENABLED)
- + if (ttisproxy(func))
- + setobj2s(L, func, &pxvalue(func)->value);
- +#endif
- /* Open a hole inside the stack at 'func' */
- for (p = L->top; p > func; p--)
- setobjs2s(L, p, p-1);
- diff --git src/lgc.c src/lgc.c
- index db4df82..2a68eba 100644
- --- src/lgc.c
- +++ src/lgc.c
- @@ -278,6 +278,18 @@ static void reallymarkobject (global_State *g, GCObject *o) {
- linkgclist(gco2p(o), g->gray);
- break;
- }
- +#if defined(LUA_PROXY_ENABLED)
- + case LUA_TPROXY: {
- + Proxy *px = gco2px(o);
- + if (iscollectable(&px->value)) { /* mark value if required */
- + markobject(g, gcvalue(&px->value));
- + }
- + markobjectN(g, px->metatable); /* mark any metatable */
- + gray2black(o);
- + g->GCmemtrav += sizeof(Proxy);
- + break;
- + }
- +#endif
- default: lua_assert(0); break;
- }
- }
- @@ -716,6 +728,12 @@ static void freeobj (lua_State *L, GCObject *o) {
- luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen));
- break;
- }
- +#if defined(LUA_PROXY_ENABLED)
- + case LUA_TPROXY: {
- + luaM_freemem(L, o, sizeof(Proxy));
- + break;
- + }
- +#endif
- default: lua_assert(0);
- }
- }
- diff --git src/lobject.h src/lobject.h
- index 2408861..52e4ae7 100644
- --- src/lobject.h
- +++ src/lobject.h
- @@ -156,6 +156,9 @@ typedef struct lua_TValue {
- #define ttislcf(o) checktag((o), LUA_TLCF)
- #define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA))
- #define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))
- +#if defined(LUA_PROXY_ENABLED)
- +#define ttisproxy(o) checktag((o), ctb(LUA_TPROXY))
- +#endif
- #define ttisdeadkey(o) checktag((o), LUA_TDEADKEY)
- @@ -175,6 +178,9 @@ typedef struct lua_TValue {
- #define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc))
- #define bvalue(o) check_exp(ttisboolean(o), val_(o).b)
- #define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc))
- +#if defined(LUA_PROXY_ENABLED)
- +#define pxvalue(o) check_exp(ttisproxy(o), gco2px(val_(o).gc))
- +#endif
- /* a dead value may get the 'gc' field, but cannot access its contents */
- #define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))
- @@ -237,6 +243,13 @@ typedef struct lua_TValue {
- val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TTHREAD)); \
- checkliveness(L,io); }
- +#if defined(LUA_PROXY_ENABLED)
- +#define setpxvalue(L,obj,x) \
- + { TValue *io = (obj); Proxy *x_ = (x); \
- + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TPROXY)); \
- + checkliveness(L,io); }
- +#endif
- +
- #define setclLvalue(L,obj,x) \
- { TValue *io = (obj); LClosure *x_ = (x); \
- val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_TLCL)); \
- @@ -519,6 +532,18 @@ typedef struct Table {
- #define sizenode(t) (twoto((t)->lsizenode))
- +#if defined(LUA_PROXY_ENABLED)
- +/*
- +** Proxies
- +*/
- +typedef struct Proxy {
- + CommonHeader;
- + TValue value;
- + Table *metatable;
- +} Proxy;
- +#endif
- +
- +
- /*
- ** (address of) a fixed nil value
- */
- diff --git src/lstate.h src/lstate.h
- index 56b3741..2f59bc6 100644
- --- src/lstate.h
- +++ src/lstate.h
- @@ -216,6 +216,9 @@ union GCUnion {
- struct Table h;
- struct Proto p;
- struct lua_State th; /* thread */
- +#if defined(LUA_PROXY_ENABLED)
- + struct Proxy px;
- +#endif
- };
- @@ -232,6 +235,9 @@ union GCUnion {
- #define gco2t(o) check_exp((o)->tt == LUA_TTABLE, &((cast_u(o))->h))
- #define gco2p(o) check_exp((o)->tt == LUA_TPROTO, &((cast_u(o))->p))
- #define gco2th(o) check_exp((o)->tt == LUA_TTHREAD, &((cast_u(o))->th))
- +#if defined(LUA_PROXY_ENABLED)
- +#define gco2px(o) check_exp((o)->tt == LUA_TPROXY, &((cast_u(o))->px))
- +#endif
- /* macro to convert a Lua object into a GCObject */
- diff --git src/ltm.c src/ltm.c
- index 0e7c713..92d8779 100644
- --- src/ltm.c
- +++ src/ltm.c
- @@ -29,7 +29,11 @@ static const char udatatypename[] = "userdata";
- LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = {
- "no value",
- "nil", "boolean", udatatypename, "number",
- +#if !defined(LUA_PROXY_ENABLED)
- "string", "table", "function", udatatypename, "thread",
- +#else
- + "string", "table", "function", udatatypename, "thread", "proxy",
- +#endif
- "proto" /* this last case is used for tests only */
- };
- @@ -76,6 +80,11 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
- case LUA_TUSERDATA:
- mt = uvalue(o)->metatable;
- break;
- +#if defined(LUA_PROXY_ENABLED)
- + case LUA_TPROXY:
- + mt = pxvalue(o)->metatable;
- + break;
- +#endif
- default:
- mt = G(L)->mt[ttnov(o)];
- }
- @@ -89,12 +98,22 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
- */
- const char *luaT_objtypename (lua_State *L, const TValue *o) {
- Table *mt;
- +#if !defined(LUA_PROXY_ENABLED)
- if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) ||
- (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) {
- const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name"));
- if (ttisstring(name)) /* is '__name' a string? */
- return getstr(tsvalue(name)); /* use it as type name */
- }
- +#else
- + if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) ||
- + (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL) ||
- + (ttisproxy(o) && (mt = pxvalue(o)->metatable) != NULL)) {
- + const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name"));
- + if (ttisstring(name)) /* is '__name' a string? */
- + return getstr(tsvalue(name)); /* use it as type name */
- + }
- +#endif
- return ttypename(ttnov(o)); /* else use standard type name */
- }
- @@ -123,12 +142,33 @@ void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
- int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
- StkId res, TMS event) {
- +#if !defined(LUA_PROXY_ENABLED)
- const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
- if (ttisnil(tm))
- tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
- if (ttisnil(tm)) return 0;
- luaT_callTM(L, tm, p1, p2, res, 1);
- return 1;
- +#else
- + const TValue *lhs = p1;
- + const TValue *rhs = p2;
- + const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
- + if (!ttisnil(tm)) {
- + if (ttisproxy(p1)) {
- + lhs = &pxvalue(p1)->value;
- + if (luaV_equalobj(L, p1, p2)) /* special case */
- + rhs = lhs;
- + }
- + }
- + else {
- + tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
- + if (ttisnil(tm)) return 0;
- + if (ttisproxy(p2))
- + rhs = &pxvalue(p2)->value;
- + }
- + luaT_callTM(L, tm, lhs, rhs, res, 1);
- + return 1;
- +#endif
- }
- diff --git src/lua.h src/lua.h
- index c236e36..4f1feff 100644
- --- src/lua.h
- +++ src/lua.h
- @@ -70,8 +70,15 @@ typedef struct lua_State lua_State;
- #define LUA_TFUNCTION 6
- #define LUA_TUSERDATA 7
- #define LUA_TTHREAD 8
- +#if defined(LUA_PROXY_ENABLED)
- +#define LUA_TPROXY 9
- +#endif
- +#if! defined(LUA_PROXY_ENABLED)
- #define LUA_NUMTAGS 9
- +#else
- +#define LUA_NUMTAGS 10
- +#endif
- @@ -328,6 +335,10 @@ LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s);
- LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
- LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
- +#if defined(LUA_PROXY_ENABLED)
- +LUA_API void (lua_envelop) (lua_State *L, int idx);
- +#endif
- +
- /*
- diff --git src/luaconf.h src/luaconf.h
- index 9eeeea6..8c1bb65 100644
- --- src/luaconf.h
- +++ src/luaconf.h
- @@ -781,6 +781,7 @@
- ** Local configuration. You can use this space to add your redefinitions
- ** without modifying the main part of the file.
- */
- +#define LUA_PROXY_ENABLED
- diff --git src/lvm.c src/lvm.c
- index cc43d87..a618983 100644
- --- src/lvm.c
- +++ src/lvm.c
- @@ -179,7 +179,12 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
- /* else will try the metamethod */
- }
- if (ttisfunction(tm)) { /* is metamethod a function? */
- +#if !defined(LUA_PROXY_ENABLED)
- luaT_callTM(L, tm, t, key, val, 1); /* call it */
- +#else
- + luaT_callTM(L, tm, ttisproxy(t) ? &pxvalue(t)->value : t,
- + key, val, 1); /* call it */
- +#endif
- return;
- }
- t = tm; /* else try to access 'tm[key]' */
- @@ -226,7 +231,12 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
- }
- /* try the metamethod */
- if (ttisfunction(tm)) {
- +#if !defined(LUA_PROXY_ENABLED)
- luaT_callTM(L, tm, t, key, val, 0);
- +#else
- + luaT_callTM(L, tm, ttisproxy(t) ? &pxvalue(t)->value : t,
- + key, val, 0);
- +#endif
- return;
- }
- t = tm; /* else repeat assignment over 'tm' */
- @@ -440,6 +450,16 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
- tm = fasttm(L, hvalue(t2)->metatable, TM_EQ);
- break; /* will try TM */
- }
- +#if defined(LUA_PROXY_ENABLED)
- + case LUA_TPROXY: {
- + if (pxvalue(t1) == pxvalue(t2)) return 1;
- + else if (L == NULL) return 0;
- + tm = fasttm(L, pxvalue(t1)->metatable, TM_EQ);
- + if (tm == NULL)
- + tm = fasttm(L, pxvalue(t2)->metatable, TM_EQ);
- + break; /* will try TM */
- + }
- +#endif
- default:
- return gcvalue(t1) == gcvalue(t2);
- }
- @@ -536,6 +556,10 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
- tm = luaT_gettmbyobj(L, rb, TM_LEN);
- if (ttisnil(tm)) /* no metamethod? */
- luaG_typeerror(L, rb, "get length of");
- +#if defined(LUA_PROXY_ENABLED)
- + if (ttisproxy(rb))
- + rb = &pxvalue(rb)->value;
- +#endif
- break;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement