diff --git a/src/cobj.c b/src/cobj.c index 0998b18..6263d8c 100644 --- a/src/cobj.c +++ b/src/cobj.c @@ -211,6 +211,7 @@ CObjString *cosmoO_takeString(CState *state, char *str, size_t sz) { CObjString *cosmoO_allocateString(CState *state, const char *str, size_t sz, uint32_t hash) { CObjString *strObj = (CObjString*)cosmoO_allocateBase(state, sizeof(CObjString), COBJ_STRING); + strObj->isIString = false; strObj->str = (char*)str; strObj->length = sz; strObj->hash = hash; @@ -254,7 +255,10 @@ void cosmoO_setObject(CState *state, CObjObject *object, CValue key, CValue val) return; } - object->istringFlags = 0; // reset cache + // if the key is an IString, we need to reset the cache + if (IS_STRING(key) && ((CObjString*)cosmoV_readObj(key))->isIString) + object->istringFlags = 0; // reset cache + if (IS_NIL(val)) { // if we're setting an index to nil, we can safely mark that as a tombstone cosmoT_remove(state, &object->tbl, key); } else { diff --git a/src/cobj.h b/src/cobj.h index a4bfce4..6ab7c7f 100644 --- a/src/cobj.h +++ b/src/cobj.h @@ -37,6 +37,7 @@ typedef struct CObj { typedef struct CObjString { CommonHeader; // "is a" CObj + bool isIString; int length; char *str; uint32_t hash; // for hashtable lookup diff --git a/src/cstate.c b/src/cstate.c index e68d793..c700a2a 100644 --- a/src/cstate.c +++ b/src/cstate.c @@ -49,6 +49,10 @@ CState *cosmoV_newState() { state->iStrings[ISTRING_GETTER] = cosmoO_copyString(state, "__getter", 8); state->iStrings[ISTRING_SETTER] = cosmoO_copyString(state, "__setter", 8); + // set the IString flags + for (int i = 0; i < ISTRING_MAX; i++) + state->iStrings[i]->isIString = true; + return state; } diff --git a/src/cstate.h b/src/cstate.h index d38acde..9799f4e 100644 --- a/src/cstate.h +++ b/src/cstate.h @@ -14,7 +14,6 @@ typedef struct CCallFrame { typedef enum IStringEnum { ISTRING_INIT, // __init - ISTRING_EQUAL, // __equal ISTRING_INDEX, // __index ISTRING_NEWINDEX, // __newindex ISTRING_GETTER, // __getter