Fixed #, switched over to __instance_positions, deleted :new().

This commit is contained in:
Bruce Hill 2018-02-09 18:01:01 -08:00
parent cd479f05fd
commit 0ef2794f2a
2 changed files with 86 additions and 31 deletions

View File

@ -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: [

View File

@ -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)