1. 一些简单的例子

 a = "abc"
 print(#a)  // 3

当获取的是字符串的长度时直接获取字符串的len

    setnvalue(ra, cast_num(tsvalue(rb)->len));

我们需要了解字符串是怎么样的结构

typedef union TString
{
    struct
    {
        CommonHeader;
        lu_byte reserved;  // 设置这个是个保留字的标记位, 值会是gafqX_tokens的的第几个 + 1
        unsigned int hash; // 加快查找匹配
        size_t len;        // 不用\0结尾,所以需要长度
    } tsv;
} TString;

这里回忆一下字符串是怎么创建的

TString *gafqS_newlstr(gafq_State *L, const char *str, size_t l)
{
    GCObject *o;
    unsigned int h = cast(unsigned int, l);
    size_t step = (l >> 5) + 1;
    size_t l1;
    for (l1 = l; l1 >= step; l1 -= step) // 计算新字符串的哈希值
        h = h ^ ((h << 5) + (h >> 2) + cast(unsigned char, str[l1 - 1]));
    // lua把字符串放在strt中 取出哈希值相同的链表
    for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; o != NULL; o = o->gch.next)
    {
        TString *ts = rawgco2ts(o);
        if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0))
        {
            if (isdead(G(L), o))
                changewhite(o);
            return ts;
        }
    }
    return newlstr(L, str, l, h); // 不存在创建新的字符串
}


//如果在全局的strt中的hash没找到字符串,会创建个新的
static TString *newlstr(gafq_State *L, const char *str, size_t l, unsigned int h)
{
    TString *ts;
    stringtable *tb;
    if (l + 1 > (MAX_SIZET - sizeof(TString)) / sizeof(char))
        gafqM_toobig(L);
    ts = cast(TString *, gafqM_malloc(L, (l + 1) * sizeof(char) + sizeof(TString)));
    ts->tsv.len = l;
    ts->tsv.hash = h;
    ts->tsv.marked = gafqC_white(G(L));
    ts->tsv.tt = GAFQ_TSTRING;
    ts->tsv.reserved = 0;
    memcpy(ts + 1, str, l * sizeof(char));
    ((char *)(ts + 1))[l] = '\0';
    tb = &G(L)->strt;  // 打算把新创建的字符串放入strt中
    h = lmod(h, tb->size);
    ts->tsv.next = tb->hash[h];
    tb->hash[h] = obj2gco(ts);
    tb->nuse++;
    if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT / 2)
        gafqS_resize(L, tb->size * 2);
    return ts;
}


发表评论