Skip to content

Instantly share code, notes, and snippets.

@0branch
Created August 27, 2011 16:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0branch/1175541 to your computer and use it in GitHub Desktop.
Save 0branch/1175541 to your computer and use it in GitHub Desktop.
new metatable syntax for Lua: VM patch
diff --git a/src/Makefile b/src/Makefile
index e4a3cd6..9a29e1e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -8,7 +8,7 @@
PLAT= none
CC= gcc
-CFLAGS= -O2 -Wall $(MYCFLAGS)
+CFLAGS= -O2 -Wall $(MYCFLAGS) -DMT_PATCH
AR= ar rcu
RANLIB= ranlib
RM= rm -f
diff --git a/src/lbaselib.c b/src/lbaselib.c
index 2a4c079..73b9a97 100644
--- a/src/lbaselib.c
+++ b/src/lbaselib.c
@@ -642,6 +642,11 @@ static void base_open (lua_State *L) {
lua_setfield(L, -2, "__mode"); /* metatable(w).__mode = "kv" */
lua_pushcclosure(L, luaB_newproxy, 1);
lua_setglobal(L, "newproxy"); /* set global `newproxy' */
+ /* alternate metatable syntax */
+#ifdef MT_PATCH
+ lua_pushboolean(L, 1);
+ lua_setglobal(L, "_MT");
+#endif
}
diff --git a/src/lvm.c b/src/lvm.c
index ee3256a..273a682 100644
--- a/src/lvm.c
+++ b/src/lvm.c
@@ -112,6 +112,15 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
const TValue *res = luaH_get(h, key); /* do a primitive get */
+#ifdef MT_PATCH
+ if ( h->metatable && ttisstring(key) ) {
+ const char* key_str = getstr(tsvalue(key));
+ if ( strcmp(key_str, "__mt") == 0 ) {
+ sethvalue(L, val, h->metatable);
+ return;
+ }
+ }
+#endif
if (!ttisnil(res) || /* result is no nil? */
(tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
setobj2s(L, val, res);
@@ -138,6 +147,15 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
+#ifdef MT_PATCH
+ if ( ttisstring(key) ) {
+ const char* key_str = getstr(tsvalue(key));
+ if ( strcmp(key_str, "__mt") == 0 ) {
+ h->metatable = (Table*) thvalue(val);
+ return;
+ }
+ }
+#endif
if (!ttisnil(oldval) || /* result is no nil? */
(tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
setobj2t(L, oldval, val);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment