{"id":498,"date":"2021-12-11T14:45:38","date_gmt":"2021-12-11T06:45:38","guid":{"rendered":"https:\/\/www.ccagml.com\/?p=498"},"modified":"2021-12-11T14:45:38","modified_gmt":"2021-12-11T06:45:38","slug":"lua%e4%bb%8emain%e5%bc%80%e5%a7%8b2%e4%b9%8btable%e6%93%8d%e4%bd%9c%e8%a7%a3%e6%9e%90token%e7%9a%84%e6%89%a7%e8%a1%8c%e6%b5%81%e7%a8%8b","status":"publish","type":"post","link":"https:\/\/www.ccagml.com\/?p=498","title":{"rendered":"lua\u4ecemain\u5f00\u59cb2\u4e4btable\u64cd\u4f5c\u89e3\u6790token\u7684\u6267\u884c\u6d41\u7a0b"},"content":{"rendered":"<h2>\u4e0a\u4e00\u6587\u89e3\u6790\u4e86token,\u672c\u7ae0\u6211\u4eec\u6765\u770b\u6267\u884c<\/h2>\n<h2>1. \u4e00\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50<\/h2>\n<pre><code class=\"line-numbers\">local a = {1,2,3}\na[6] = 1\na[\"aaa\"]= 1\n\n<\/code><\/pre>\n<h1>2.\u89e3\u6790\u51fa\u7684token\u662f\u4ec0\u4e48<\/h1>\n<pre><code class=\"line-numbers\">\/\/ \u6211\u4eec\u7684\u4f8b\u5b50\nlocal a = {1,2,3}\na[6] = 1\na[\"aaa\"]= 1\n\n268(TK_LOCAL) -&gt; 285(TK_NAME) -&gt; 61('=') -&gt; 123('{') -&gt; 284(TK_NUMBER) -&gt; 44(',') -&gt; 284(TK_NUMBER) -&gt; 44(',') -&gt; 284(TK_NUMBER) -&gt; 125('}')\n285(TK_NAME) -&gt; 91('[') -&gt; 284(TK_NUMBER) -&gt; 93(']') -&gt; 61('=') -&gt; 284(TK_NUMBER)\n285(TK_NAME) -&gt; 91('[') -&gt; 286(TK_STRING) -&gt; 93(']') -&gt; 61('=') -&gt; 284(TK_NUMBER)\n\n<\/code><\/pre>\n<h1>3.\u6267\u884c\u7684\u5f00\u59cb<\/h1>\n<pre><code class=\"line-numbers\">static int handle_script(gafq_State *L, char **argv, int n)\n{\n    ...\n    status = docall(L, narg, 0); \/\/ \u8fd9\u8fb9\u6267\u884c\u4e86\u6587\u4ef6\u597d\u50cf\n    ...\n}\n\n<\/code><\/pre>\n<h1>4.\u6267\u884c<\/h1>\n<pre><code class=\"line-numbers\">void gafqD_call(gafq_State *L, StkId func, int nResults)\n{\n    \/\/\u597d\u50cf\u5982\u679c\u662fc\u65b9\u6cd5gafqD_precall\u8fd9\u91cc\u4f1a\u6267\u884c, gafq\u65b9\u6cd5\u5c31gafqV_execute\u6267\u884c\n    if (gafqD_precall(L, func, nResults) == PCRGAFQ)\/\/ \u5224\u65ad\u662fgafq\u7684\u51fd\u6570\u8fd8\u662fc\u7684\u51fd\u6570\n        gafqV_execute(L, 1); \n}\n\n<\/code><\/pre>\n<h1>5.gafqV_execute<\/h1>\n<pre><code class=\"line-numbers\">gvm.c\n\nvoid gafqV_execute(gafq_State *L, int nexeccalls)\n{\n    ...\n    for (;;)\n    {\n        \/\/\u53d6\u51fa\u5f53\u524d\u6307\u4ee4 i = 25165834  \/\/ 00011000000 00000000000 001010 \/\/ 001010\u662f\u5341\u8fdb\u523610,\u8fd9\u4e2a\u64cd\u4f5c\u662f\u521b\u5efa\u4e00\u4e2a\u65b0\u7684table\n        const Instruction i = *pc++;\n        ...\n        ra = RA(i); \/\/ 0x635420\n        switch (GET_OPCODE(i))\n        {\n        case OP_NEWTABLE:\n        {\n            int b = GETARG_B(i);\n            int c = GETARG_C(i);\n            sethvalue(L, ra, gafqH_new(L, gafqO_fb2int(b), gafqO_fb2int(c)));\n            Protect(gafqC_checkGC(L));\n            continue;\n        }\n        }\n    }\n}\n\n\n<\/code><\/pre>\n<h1>6.gafqV_execute \u6211\u4eec\u6240\u6709\u7684\u6307\u4ee4i<\/h1>\n<pre><code class=\"line-numbers\">gvm.c\n\nconst Instruction i = *pc++;\ni = 25165834    OP_NEWTABLE\ni = 65          OP_LOADK\ni = 16513       OP_LOADK\ni = 32961       OP_LOADK\ni = 25182242    OP_SETLIST\ni = 2176843785  OP_SETTABLE\ni = 2185232393  OP_SETTABLE\ni = 8388638     OP_RETURN\n\n<\/code><\/pre>\n<h1>7. \u521d\u59cb\u5316table<\/h1>\n<pre><code class=\"line-numbers\">gtable.c\n\n\/\/ \u521d\u59cb\u5316table\nTable *gafqH_new(gafq_State *L, int narray, int nhash)\n{\n    Table *t = gafqM_new(L, Table);\n    gafqC_link(L, obj2gco(t), GAFQ_TTABLE);\n    t-&gt;metatable = NULL;\n    t-&gt;flags = cast_byte(~0);\n    \/* temporary values (kept only if some malloc fails) *\/\n    t-&gt;array = NULL;\n    t-&gt;sizearray = 0;\n    t-&gt;lsizenode = 0;\n    t-&gt;node = cast(Node *, dummynode);\n    setarrayvector(L, t, narray); \/\/ \u521d\u59cb\u5316\u6570\u7ec4\u90e8\u5206\n    setnodevector(L, t, nhash);   \/\/ \u521d\u59cb\u5316\u54c8\u5e0c\u90e8\u5206\n    return t;\n}\n\n\/\/ \u521d\u59cb\u5316\u6570\u7ec4\u90e8\u5206, \u6211\u4eec\u7684\u4f8b\u5b50local a = {1,2,3}\u8fd9\u91cc\u6570\u7ec4\u90e8\u5206size\u662f3\nstatic void setarrayvector(gafq_State *L, Table *t, int size)\n{\n    int i;\n    gafqM_reallocvector(L, t-&gt;array, t-&gt;sizearray, size, TValue);\n    for (i = t-&gt;sizearray; i &lt; size; i++)\n        setnilvalue(&amp;t-&gt;array[i]);\n    t-&gt;sizearray = size;\n}\n\n\/\/\u6211\u4eec\u7684\u4f8b\u5b50local a = {1,2,3}\u8fd9\u91cc\u7684size\u662f0\nstatic void setnodevector(gafq_State *L, Table *t, int size)\n{\n    int lsize;\n    if (size == 0)\n    {                                      \/* no elements to hash part? *\/\n        t-&gt;node = cast(Node *, dummynode); \/* use common `dummynode' *\/\n        lsize = 0;\n    }\n    else   \n    {   \/\/ \u65b0\u5efa\u8868\u6709hash\u7684\u65f6\u5019\u7684\u6570\u636e\n        ...\n    }\n    t-&gt;lsizenode = cast_byte(lsize);\n    t-&gt;lastfree = gnode(t, size); \/* all positions are free *\/\n}\n\n\n<\/code><\/pre>\n<h1>8.\u770bOP_SETLIST\u64cd\u4f5c,\u5bf9\u5e94\u6211\u4eec\u7684local a = {1,2,3}<\/h1>\n<pre><code class=\"line-numbers\">case OP_SETLIST:\n        {\n            int n = GETARG_B(i);\n            int c = GETARG_C(i);\n            int last;\n            Table *h;\n            if (n == 0)\n            {\n                n = cast_int(L-&gt;top - ra) - 1;\n                L-&gt;top = L-&gt;ci-&gt;top;\n            }\n            if (c == 0)\n                c = cast_int(*pc++);\n            runtime_check(L, ttistable(ra));\n            h = hvalue(ra); \/\/ ra\u653e\u7684\u662f\u6211\u4eec\u7684table\n            last = ((c - 1) * LFIELDS_PER_FLUSH) + n;\n            if (last &gt; h-&gt;sizearray) \/\/ \u5224\u65ad\u6570\u7ec4\u90e8\u5206\u7684\u7a7a\u95f4\u591f\u4e0d\u591f\n                gafqH_resizearray(L, h, last); \/\/ \u91cd\u65b0\u5f04\u4e00\u4e0b\u6570\u7ec4\u90e8\u5206\u7684\u7a7a\u95f4\n            for (; n &gt; 0; n--)\n            {\n                TValue *val = ra + n;\n                setobj2t(L, gafqH_setnum(L, h, last--), val);\n                gafqC_barriert(L, h, val);\n            }\n            continue;\n        }\n\/\/ \u6269\u5927\u6570\u7ec4\u90e8\u5206\u7684\u7a7a\u95f4\nvoid gafqH_resizearray(gafq_State *L, Table *t, int nasize)\n{\n    int nsize = (t-&gt;node == dummynode) ? 0 : sizenode(t);\n    resize(L, t, nasize, nsize);\n}\n\n\/\/ \u91cd\u65b0\u8ba1\u7b97\u6211\u4eec\u7684table\u7684\u5927\u5c0f\nstatic void resize(gafq_State *L, Table *t, int nasize, int nhsize)\n{\n    int i;\n    int oldasize = t-&gt;sizearray;\n    int oldhsize = t-&gt;lsizenode;\n    Node *nold = t-&gt;node;  \u539f\u672c\u7684\u54c8\u5e0c\u8868\u90e8\u5206\n    if (nasize &gt; oldasize) \/\/ \u5224\u65ad\u6570\u7ec4\u90e8\u5206\u9700\u8981\u589e\u52a0?\n        setarrayvector(L, t, nasize);\n    setnodevector(L, t, nhsize); \/\/ \u589e\u52a0\u54c8\u5e0c\u90e8\u5206\u7684\u7a7a\u95f4\n    if (nasize &lt; oldasize)\n    { \/* array part must shrink? *\/\n        t-&gt;sizearray = nasize;\n        \/* re-insert elements from vanishing slice *\/\n        for (i = nasize; i &lt; oldasize; i++)\n        {\n            if (!ttisnil(&amp;t-&gt;array[i]))\n                setobjt2t(L, gafqH_setnum(L, t, i + 1), &amp;t-&gt;array[i]);\n        }\n        \/* shrink array *\/\n        gafqM_reallocvector(L, t-&gt;array, oldasize, nasize, TValue);\n    }\n    \/* re-insert elements from hash part *\/\n    for (i = twoto(oldhsize) - 1; i &gt;= 0; i--)\n    {\n        Node *old = nold + i;\n        if (!ttisnil(gval(old)))\n            setobjt2t(L, gafqH_set(L, t, key2tval(old)), gval(old));\n    }\n    if (nold != dummynode)\n        gafqM_freearray(L, nold, twoto(oldhsize), Node); \/* free old array *\/\n}\n\n\n\nTValue *gafqH_setnum(gafq_State *L, Table *t, int key)\n{\n    const TValue *p = gafqH_getnum(t, key);\n    if (p != gafqO_nilobject)\n        return cast(TValue *, p);\n    else\n    {\n        TValue k;\n        setnvalue(&amp;k, cast_num(key));\n        return newkey(L, t, &amp;k);\n    }\n}\n\/\/ \u67e5\u627e\u7684\u6570\u5b57\nconst TValue *gafqH_getnum(Table *t, int key)\n{\n    \/\/ \u5982\u679c\u67e5\u627e\u7684\u7d22\u5f15\u5728array\u91cc\u9762,\u90a3\u4e48\u662f\u5728\u6570\u7ec4\u91cc\u9762,\u5426\u5219\u662f\u5728\u54c8\u5e0c\u8868\u91cc\u9762\n    if (cast(unsigned int, key - 1) &lt; cast(unsigned int, t-&gt;sizearray))\n        return &amp;t-&gt;array[key - 1];\n    else\n    {\n        gafq_Number nk = cast_num(key);\n        Node *n = hashnum(t, nk);\n        do\n        { \/* check whether `key' is somewhere in the chain *\/\n            if (ttisnumber(gkey(n)) &amp;&amp; gafqi_numeq(nvalue(gkey(n)), nk))\n                return gval(n); \/* that's it *\/\n            else\n                n = gnext(n);\n        } while (n);\n        return gafqO_nilobject;\n    }\n}\n\n\n<\/code><\/pre>\n<h1>9.\u770bOP_SETTABLE\u64cd\u4f5c<\/h1>\n<pre><code class=\"line-numbers\">void gafqV_execute(gafq_State *L, int nexeccalls)\n{\n    for (;;)\n    {\n        \/\/\u53d6\u51fa\u5f53\u524d\u6307\u4ee4\n        const Instruction i = *pc++;\n        ...\n        switch (GET_OPCODE(i)){\n        ...\n\n        case OP_SETTABLE:\n        {\n            \/\/\u4f46\u64cd\u4f5c\u7684\u8868\u4e0d\u5728 upvalue \u4e2d\uff0c\u800c\u5728\u5bc4\u5b58\u5668\u91cc\u3002\u5b83\u4eec\u5728\u5b9e\u73b0\u4e0a\u7684\u533a\u522b\u4ec5\u5728\u4e8e\uff0c\u524d\u8005b\u662f\u5bf9 upvalue \u7684\u7d22\u5f15\uff0c\u800c\u540e\u8005\u5219\u8868\u793a\u5bc4\u5b58\u5668\u53f7\u3002\n            Protect(gafqV_settable(L, ra, RKB(i), RKC(i)));\n            continue;\n        }\n        }\n    }\n}\n\n\n\/\/\u5bf9\u8868\u7ed3\u6784\u5199\u64cd\u4f5c\u7684\u5c01\u88c5\uff0c\u540c\u6837\u4f1a\u5f15\u53d1\u5143\u65b9\u6cd5\nvoid gafqV_settable(gafq_State *L, const TValue *t, TValue *key, StkId val)\n{\n    int loop;\n    TValue temp;\n    for (loop = 0; loop &lt; MAXTAGLOOP; loop++) \/\/ \u907f\u514d\u5143\u8868\u6b7b\u5faa\u73af\n    {\n        const TValue *tm;\n        if (ttistable(t))\n        {   \/\/ \u6211\u4eec\u8fd9\u91cc\u662f\u4e2atable\n            Table *h = hvalue(t);\n            TValue *oldval = gafqH_set(L, h, key);\n            if (!ttisnil(oldval) || (tm = fasttm(L, h-&gt;metatable, TM_NEWINDEX)) == NULL)\n            {   \/\/\u6ca1\u6709\u5143\u65b9\u6cd5\u8d70\u8fd9\u91cc\n                setobj2t(L, oldval, val);\n                h-&gt;flags = 0;\n                gafqC_barriert(L, h, val); \/\/ \u5904\u7406\u5783\u573e\u56de\u6536\n                return;\n            }\n            \/* else will try the tag method *\/\n        }\n        if (ttisfunction(tm))\n        {\n            \/\/ \u6709\u5143\u65b9\u6cd5\u8d70\u8fd9\u91cc\n            callTM(L, tm, t, key, val);\n            return;\n        }\n        ...\n        setobj(L, &amp;temp, tm);\n        t = &amp;temp;\n    }\n    gafqG_runerror(L, \"loop in settable\");\n}\n\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u4e0a\u4e00\u6587\u89e3\u6790\u4e86token,\u672c\u7ae0\u6211\u4eec\u6765\u770b\u6267\u884c 1. \u4e00\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50 local a = {1,2,3} a[6] <a href=\"https:\/\/www.ccagml.com\/?p=498\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">lua\u4ecemain\u5f00\u59cb2\u4e4btable\u64cd\u4f5c\u89e3\u6790token\u7684\u6267\u884c\u6d41\u7a0b<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[32],"tags":[],"_links":{"self":[{"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/posts\/498"}],"collection":[{"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=498"}],"version-history":[{"count":1,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/posts\/498\/revisions"}],"predecessor-version":[{"id":499,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=\/wp\/v2\/posts\/498\/revisions\/499"}],"wp:attachment":[{"href":"https:\/\/www.ccagml.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=498"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=498"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ccagml.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=498"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}