Fixed #, switched over to __instance_positions, deleted :new().
This commit is contained in:
parent
cd479f05fd
commit
0ef2794f2a
109
limmutable.c
109
limmutable.c
@ -173,9 +173,11 @@ static int Lcreate_instance(lua_State *L)
|
|||||||
|
|
||||||
static int Llen(lua_State *L)
|
static int Llen(lua_State *L)
|
||||||
{
|
{
|
||||||
lua_pushvalue(L, 1);
|
lua_getmetatable(L, 1);
|
||||||
luaL_getmetatable(L, MYTYPE);
|
// Stack: [mt]
|
||||||
lua_getfield(L, -1, "fields");
|
lua_getfield(L, -1, "__fields");
|
||||||
|
// Stack: [mt, fields]
|
||||||
|
lua_len(L, -1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,31 +185,28 @@ static int Lindex(lua_State *L)
|
|||||||
{
|
{
|
||||||
lua_getmetatable(L, 1);
|
lua_getmetatable(L, 1);
|
||||||
// Stack: [mt]
|
// Stack: [mt]
|
||||||
lua_getfield(L, -1, "__fields");
|
lua_getfield(L, -1, "__field_positions");
|
||||||
// Stack: [mt, fields]
|
// Stack: [mt, field_positions]
|
||||||
|
lua_pushvalue(L, 2);
|
||||||
lua_pushnil(L);
|
// Stack: [mt, field_positions, k]
|
||||||
while (lua_next(L, -2) != 0) {
|
|
||||||
// Stack: [mt, fields, i, field]
|
|
||||||
if (lua_rawequal(L, -1, 2)) {
|
|
||||||
lua_pop(L, 1);
|
|
||||||
// All the slowness is concentrated here
|
|
||||||
// Stack: [mt, fields, i]
|
|
||||||
lua_getfield(L, -3, "__instances");
|
|
||||||
// Stack: [mt, fields, i, buckets]
|
|
||||||
lua_rawgeti(L, -1, *((lua_Integer*)lua_touserdata(L, 1)));
|
|
||||||
// Stack: [mt, fields, i, buckets, bucket]
|
|
||||||
lua_pushvalue(L, 1);
|
|
||||||
// Stack: [mt, fields, i, buckets, bucket, inst_udata]
|
|
||||||
lua_rawget(L, -2);
|
lua_rawget(L, -2);
|
||||||
// Stack: [mt, fields, i, buckets, bucket, inst_table]
|
// Stack: [mt, field_positions, i]
|
||||||
lua_rawgeti(L, -1, lua_tonumber(L, -4));
|
if (! lua_isnil(L, -1)) {
|
||||||
// Stack: [mt, fields, i, buckets, bucket, inst_table, result]
|
// Stack: [mt, field_positions, i]
|
||||||
|
lua_getfield(L, -3, "__instances");
|
||||||
|
// Stack: [mt, field_positions, i, buckets]
|
||||||
|
lua_rawgeti(L, -1, *((lua_Integer*)lua_touserdata(L, 1)));
|
||||||
|
// Stack: [mt, field_positions, i, buckets, bucket]
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
// Stack: [mt, field_positions, i, buckets, bucket, inst_udata]
|
||||||
|
lua_rawget(L, -2);
|
||||||
|
// Stack: [mt, field_positions, i, buckets, bucket, inst_table]
|
||||||
|
lua_rawgeti(L, -1, lua_tointeger(L, -4));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
// Fall back to class:
|
||||||
}
|
// Stack: [mt, field_positions, i]
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 2);
|
||||||
// Stack: [mt]
|
// Stack: [mt]
|
||||||
lua_pushvalue(L, 2);
|
lua_pushvalue(L, 2);
|
||||||
// Stack: [mt, key]
|
// Stack: [mt, key]
|
||||||
@ -292,9 +291,11 @@ static int Lnexti(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Stack: [mt, buckets, bucket, inst_table, fields, i2, next_fieldname]
|
// Stack: [mt, buckets, bucket, inst_table, fields, i2, next_fieldname]
|
||||||
lua_rawgeti(L, -4, lua_tonumber(L, -2));
|
lua_pop(L, 1);
|
||||||
// Stack: [mt, buckets, bucket, inst_table, fields, i2, next_fieldname, value]
|
// Stack: [mt, buckets, bucket, inst_table, fields, i2]
|
||||||
return 3;
|
lua_rawgeti(L, -3, lua_tonumber(L, -1));
|
||||||
|
// Stack: [mt, buckets, bucket, inst_table, fields, i2, value]
|
||||||
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Lipairs(lua_State *L)
|
static int Lipairs(lua_State *L)
|
||||||
@ -308,12 +309,48 @@ static int Lipairs(lua_State *L)
|
|||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int Lnext(lua_State *L)
|
||||||
|
{
|
||||||
|
lua_getmetatable(L, 1);
|
||||||
|
// Stack: [mt]
|
||||||
|
lua_getfield(L, -1, "__instances");
|
||||||
|
// Stack: [mt, buckets]
|
||||||
|
lua_rawgeti(L, -1, *((lua_Integer*)lua_touserdata(L, 1)));
|
||||||
|
// Stack: [mt, buckets, bucket]
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
// Stack: [mt, buckets, bucket, inst_udata]
|
||||||
|
lua_rawget(L, -2);
|
||||||
|
// Stack: [mt, buckets, bucket, inst_table]
|
||||||
|
lua_getfield(L, -4, "__field_positions");
|
||||||
|
// Stack: [mt, buckets, bucket, inst_table, fields]
|
||||||
|
lua_pushvalue(L, 2);
|
||||||
|
// Stack: [mt, buckets, bucket, inst_table, fields, k]
|
||||||
|
if (lua_next(L, -2) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// Stack: [mt, buckets, bucket, inst_table, fields, k2, next_i]
|
||||||
|
lua_rawgeti(L, -4, lua_tonumber(L, -1));
|
||||||
|
// Stack: [mt, buckets, bucket, inst_table, fields, k2, next_i, value]
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int Lpairs(lua_State *L)
|
||||||
|
{
|
||||||
|
lua_pushcfunction(L, Lnext);
|
||||||
|
// Stack: [Lnexti]
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
// Stack: [Lnexti, inst_udata]
|
||||||
|
lua_pushnil(L);
|
||||||
|
// Stack: [Lnexti, inst_udata, nil]
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
static const luaL_Reg R[] =
|
static const luaL_Reg R[] =
|
||||||
{
|
{
|
||||||
{ "__len", Llen},
|
{ "__len", Llen},
|
||||||
{ "__index", Lindex},
|
{ "__index", Lindex},
|
||||||
{ "__ipairs", Lipairs},
|
{ "__ipairs", Lipairs},
|
||||||
{ "new", Lcreate_instance},
|
{ "__pairs", Lpairs},
|
||||||
{ NULL, NULL}
|
{ NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -356,6 +393,20 @@ static int Lmake_class(lua_State *L)
|
|||||||
lua_setfield(L, -2, "__fields");
|
lua_setfield(L, -2, "__fields");
|
||||||
// Stack: [CLS]
|
// Stack: [CLS]
|
||||||
|
|
||||||
|
size_t n = lua_objlen(L, 1);
|
||||||
|
lua_createtable(L, 0, n);
|
||||||
|
// Stack: [CLS, __field_positions]
|
||||||
|
lua_pushnil(L);
|
||||||
|
while (lua_next(L, 1) != 0) {
|
||||||
|
// Stack: [CLS, __field_positions, i, fieldname]
|
||||||
|
lua_pushvalue(L, -2);
|
||||||
|
// Stack: [CLS, __field_positions, i, fieldname, i]
|
||||||
|
lua_settable(L, -4);
|
||||||
|
// Stack: [CLS, __field_positions, i]
|
||||||
|
}
|
||||||
|
lua_setfield(L, -2, "__field_positions");
|
||||||
|
// Stack: [CLS]
|
||||||
|
|
||||||
// If methods were passed in, copy them over
|
// If methods were passed in, copy them over
|
||||||
if (n_args > 1) {
|
if (n_args > 1) {
|
||||||
// Stack: [
|
// Stack: [
|
||||||
|
4
test.lua
4
test.lua
@ -62,6 +62,10 @@ test("Instantiating class", function()
|
|||||||
v = assert(Vec(1,3))
|
v = assert(Vec(1,3))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
test("Testing # operator", function()
|
||||||
|
assert(#v == 2)
|
||||||
|
end)
|
||||||
|
|
||||||
test("Testing method", function()
|
test("Testing method", function()
|
||||||
assert(v:len2() == 10)
|
assert(v:len2() == 10)
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user