婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識(shí)庫 > lua中賦值類型代碼詳解

lua中賦值類型代碼詳解

熱門標(biāo)簽:電話機(jī)器人每天搜索多少次 海口智能語音電銷機(jī)器人好用嗎 免費(fèi)門店地圖標(biāo)注注冊入駐 衡水外呼線路解決 外呼系統(tǒng)一天耗費(fèi)多少流量 艾比利外呼系統(tǒng) 昆明電話外呼系統(tǒng)好么 陜西便宜電銷機(jī)器人軟件 杞縣地圖標(biāo)注app

我們來看看lua vm在解析下面源碼并生成bytecode時(shí)的整個(gè)過程:

 foo = "bar"
 local a, b = "a", "b"
 foo = a

首先我們先使用ChunkySpy這個(gè)工具來看看vm最終會(huì)具體生成什么樣的vm instructions

在這里,開頭為[數(shù)字]的行是vm真正生成的字節(jié)碼,我們看到一共生成了六行字節(jié)碼。首先loadk將常量表中下標(biāo)為1的常量即"bar"賦給寄存器0;然后setglobal將寄存器0的內(nèi)容賦給全局變量表中下標(biāo)為0的全局變量即foo;loadk再將"a"和"b"分別賦值給了寄存器0、1,在這里寄存器0和1分別表示當(dāng)前函數(shù)的local變量即變量a和b;最后setglobal將變量a的值賦給了全局變量foo;最后一個(gè)return01是vm在每一個(gè)chunk最后都會(huì)生成了,并沒有什么用。現(xiàn)在應(yīng)該比較清除的了解了lua vm生成的字節(jié)碼的含義了,接下來我們看看vm是怎樣且為什么生成這些個(gè)字節(jié)碼的。

當(dāng)我們用luaL_dofile函數(shù)執(zhí)行這個(gè)lua腳本源碼時(shí)會(huì)有兩個(gè)階段,第一個(gè)是將腳本加載進(jìn)內(nèi)存,分詞解析并生成字節(jié)碼并將其整個(gè)包裹為main chunk放于lua stack棧頂,第二是調(diào)用lua_pcall執(zhí)行這個(gè)chunk,這里我們只會(huì)分析第一個(gè)過程。

前面幾篇文章說了,當(dāng)dofile時(shí)會(huì)跑到一個(gè)叫做luaY_parser的函數(shù)中,

Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
 struct LexState lexstate;
 struct FuncState funcstate;
 -- ... ...
 funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
 luaX_next(lexstate); /* read first token */
 chunk(lexstate);
 -- ... ...
 return funcstate.f;
}

函數(shù)luaY_parser前面兩行定義了LexState和FuncState結(jié)構(gòu)體變量,其中LexState不僅用于保存當(dāng)前的詞法分析狀態(tài)信息,而且也保存了整個(gè)編譯系統(tǒng)的全局狀態(tài),F(xiàn)uncState結(jié)構(gòu)體來保存當(dāng)前函數(shù)編譯的狀態(tài)數(shù)據(jù)。在lua源碼中都會(huì)有一個(gè)全局的函數(shù)執(zhí)行體,即為main func,在開始解析的時(shí)候當(dāng)前的函數(shù)必然是main func函數(shù),此時(shí)第三行的funcstate表示了這個(gè)函數(shù)的狀態(tài),由于lua規(guī)定這個(gè)函數(shù)必然會(huì)接收不定參數(shù)因此第五行將is_vararg標(biāo)識(shí)設(shè)為VARARG_ISVARARG。接著第六行l(wèi)uaX_next解析文件流分離出第一個(gè)token,將其保存在lexstate的t成員中,此時(shí)t為“foo”全局變量。接著調(diào)用了chunk函數(shù),這里開始了遞歸下降解析的全部過程:

static void chunk (LexState *ls) {
 /* chunk -> { stat [`;'] } */
 int islast = 0;
 enterlevel(ls);
 while (!islast  !block_follow(ls->t.token)) {
  islast = statement(ls);//遞歸下降點(diǎn)
  testnext(ls, ';');
  lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg 
        ls->fs->freereg >= ls->fs->nactvar);
  ls->fs->freereg = ls->fs->nactvar; /* free registers */
 }
 leavelevel(ls);
}

lua是有作用域?qū)哟胃拍畹模虼水?dāng)進(jìn)入一個(gè)層次時(shí)會(huì)調(diào)用enterlevel函數(shù),離開當(dāng)前層次則會(huì)調(diào)用leavelevel函數(shù)。首先進(jìn)入while循環(huán),當(dāng)前token為“foo”,這既不是終結(jié)標(biāo)志也不是一個(gè)block開始的詞素,因此會(huì)進(jìn)入statement函數(shù),statement函數(shù)主體是一個(gè)長長的switch...case...代碼結(jié)構(gòu),根據(jù)第一個(gè)token進(jìn)入不同的調(diào)用解析分支。在我們這個(gè)例子中會(huì)進(jìn)入default分支:

static int statement (LexState *ls) {
 -- ... ...
 switch (ls->t.token) {
  case TK_IF: { /* stat -> ifstat */
   ifstat(ls, line);
   return 0;
  }
  case TK_WHILE: { /* stat -> whilestat */
   whilestat(ls, line);
   return 0;
  }
  -- ... ...
  default: {
   exprstat(ls);
   return 0; /* to avoid warnings */
  }
 }
}

進(jìn)入exprstate函數(shù):

static void exprstat (LexState *ls) {
 /* stat -> func | assignment */
 FuncState *fs = ls->fs;
 struct LHS_assign v;
 primaryexp(ls, v.v);
 if (v.v.k == VCALL) /* stat -> func */
  SETARG_C(getcode(fs, v.v), 1); /* call statement uses no results */
 else { /* stat -> assignment */
  v.prev = NULL;
  assignment(ls, v, 1);
 }
}

第四行的LHS_assign結(jié)構(gòu)體是為了處理多變量賦值的情況的,例如a,b,c = ...。在LHS_assign中成員v類型為expdesc描述了等號(hào)左邊的變量,詳情可見上篇文章里對expdesc的介紹。接下來進(jìn)入primaryexp,來獲取并填充“foo”變量的expdesc信息,這會(huì)接著進(jìn)入prefixexp函數(shù)中

 static void prefixexp (LexState *ls, expdesc *v) {
  /* prefixexp -> NAME | '(' expr ')' */
  switch (ls->t.token) {
   case '(': {
    int line = ls->linenumber;
    luaX_next(ls);
    expr(ls, v);
    check_match(ls, ')', '(', line);
    luaK_dischargevars(ls->fs, v);
    return;
   }
   case TK_NAME: {
    singlevar(ls, v);
    return;
   }
   default: {
    luaX_syntaxerror(ls, "unexpected symbol");
    return;
   }
  }
 }

由于當(dāng)前token是“foo”,因此進(jìn)入TK_NAME分支,調(diào)用singlevar。

static void singlevar (LexState *ls, expdesc *var) {
 TString *varname = str_checkname(ls);
 FuncState *fs = ls->fs;
 if (singlevaraux(fs, varname, var, 1) == VGLOBAL)
  var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */
}
static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
 if (fs == NULL) { /* no more levels? */
  init_exp(var, VGLOBAL, NO_REG); /* default is global variable */
  return VGLOBAL;
 }
 else {
  int v = searchvar(fs, n); /* look up at current level */
  if (v >= 0) {
   init_exp(var, VLOCAL, v);
   if (!base)
    markupval(fs, v); /* local will be used as an upval */
   return VLOCAL;
  }
  else { /* not found at current level; try upper one */
   if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL)
    return VGLOBAL;
   var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */
   var->k = VUPVAL; /* upvalue in this level */
   return VUPVAL;
  }
 }

在singlevaraux函數(shù)中會(huì)判斷變量是local、upvalue還是global的。如果fs為null了則說明變量為全局的,否則進(jìn)入searchvar在當(dāng)前的函數(shù)局部變量數(shù)組中查找,否則根據(jù)fs的prev成員取得其父函數(shù)的FuncState并傳入singlevaraux中遞歸查找,如果前面的都沒滿足則變量為upvlaue。此例中進(jìn)入第21行中,由于fs已經(jīng)指向了main func因此其prev為null,“foo”判定為global并返回到exprstate函數(shù)中。在取得了“foo”的信息后,因?yàn)椤癴oo”不是函數(shù)調(diào)用,因此接著進(jìn)入assignment函數(shù)中

primaryexp(ls, v.v);
 if (v.v.k == VCALL) /* stat -> func */
  SETARG_C(getcode(fs, v.v), 1); /* call statement uses no results */
 else { /* stat -> assignment */
  v.prev = NULL;
  assignment(ls, v, 1);
 }

在assignment函數(shù)中首先判斷下一個(gè)token是否為“,",此例中不是則說明是單變量的賦值,接著check下一個(gè)token為”=“,成立,接著調(diào)用explist1判斷等號(hào)右邊有幾個(gè)值,此例為1個(gè),然后會(huì)判斷左邊的變量數(shù)是否等于右邊的值數(shù),不等于則進(jìn)入adjust_assign函數(shù)進(jìn)行調(diào)整,此例是相等的因此依次進(jìn)入luaK_setoneret和luaK_storevar函數(shù)。在luaK_storevar中首先進(jìn)入int e = luaK_exp2anyreg(fs, ex);函數(shù)luaK_exp2anyreg的K代表了此函數(shù)是字節(jié)碼相關(guān)的函數(shù),ex為值”bar“,這個(gè)函數(shù)又調(diào)用了discharge2reg,根據(jù)ex的類型來生成不同的字節(jié)碼:

static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
 luaK_dischargevars(fs, e);
 switch (e->k) {
  case VNIL: {
   luaK_nil(fs, reg, 1);
   break;
  }
  case VFALSE: case VTRUE: {
   luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
   break;
  }
  case VK: {
   luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info);
   break;
  }
//... ...
}

由于”bar“是常量因此調(diào)用luaK_codeABx函數(shù)生成loadk字節(jié)碼。reg為保存載入的常量值的寄存器號(hào),e->u.s.info根據(jù)不同類型值代表不同含義,根據(jù)注釋我們知道此時(shí)info為常量數(shù)組的下標(biāo)。

typedef enum {
 //... ...
 VK,    /* info = index of constant in `k' */
 VKNUM,  /* nval = numerical value */
 VLOCAL,  /* info = local register */
 VGLOBAL,  /* info = index of table; aux = index of global name in `k' */
 //... ...
} expkind;

生成了loadk后返回到上面的函數(shù)中接著進(jìn)入luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);其中e為luaK_exp2anyreg的返回值表示常量保存在的寄存器標(biāo)號(hào),info根據(jù)注釋當(dāng)為global類型時(shí)表示global table的相應(yīng)下標(biāo),因此luaK_codeABx函數(shù)將生成setglobal字節(jié)碼,將剛剛用loadk將常量加載到寄存器中的值保存到global table相應(yīng)的位置上。因此foo = "bar"語句就完整的生成了相應(yīng)的字節(jié)碼了。

接下來將生成local a,b = "a","b"語句的字節(jié)碼了。過程大致相同,不同的是a,b是local變量且這個(gè)賦值語句是多變量賦值語句,因此前面的函數(shù)會(huì)用LHS_assign鏈表將a,b變量連接起來。如圖所示:

以上所述就是本文都全部內(nèi)容了,希望大家能夠喜歡。

您可能感興趣的文章:
  • Lua基礎(chǔ)教程之賦值語句、表達(dá)式、流程控制、函數(shù)學(xué)習(xí)筆記
  • Lua中的基本數(shù)據(jù)類型詳細(xì)介紹
  • Lua變量類型簡明總結(jié)
  • Lua數(shù)據(jù)類型介紹
  • Lua教程(三):值與類型介紹

標(biāo)簽:臨滄 昌都 海口 西寧 宿遷 南京 泰安 營口

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《lua中賦值類型代碼詳解》,本文關(guān)鍵詞  lua,中,賦值,類型,代碼,詳解,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《lua中賦值類型代碼詳解》相關(guān)的同類信息!
  • 本頁收集關(guān)于lua中賦值類型代碼詳解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    久久精品国产一区二区三 | 日韩三级视频在线观看| 国产日韩欧美一区二区三区乱码| 欧美日韩一区二区电影| 国产欧美一区二区精品性| 成人免费在线播放视频| 欧美一区二区黄| 美洲天堂一区二卡三卡四卡视频 | 日韩国产在线观看| 色琪琪一区二区三区亚洲区| 久久精品国产**网站演员| 日韩精品一区二区三区视频播放| 亚洲女同女同女同女同女同69| 91麻豆精品久久久久蜜臀| 另类欧美日韩国产在线| 天天影视网天天综合色在线播放| 欧美大片一区二区三区| 成人性生交大片免费看视频在线| 狠狠色狠狠色综合系列| 国产精品不卡在线| 国产精品亲子伦对白| 在线观看精品一区| 日本欧美在线观看| 国产精品三级电影| 欧美图片一区二区三区| 日韩精品福利网| 丝袜美腿亚洲色图| 欧美国产视频在线| 国产午夜亚洲精品午夜鲁丝片| 99re成人精品视频| 欧美在线色视频| 欧美高清激情brazzers| 日韩午夜在线影院| 国产情人综合久久777777| 成人免费看视频| 91精品免费观看| 激情欧美一区二区三区在线观看| 久久机这里只有精品| 极品少妇xxxx精品少妇偷拍 | 成人app下载| 国产精品一区一区三区| 国产精品久久久久久久久久免费看 | 国产一区视频在线看| 国产在线精品一区在线观看麻豆| 国产在线视频一区二区三区| 不卡av免费在线观看| 91美女在线看| 91精品福利在线一区二区三区| 欧美videos大乳护士334| 中文成人av在线| 亚洲国产欧美另类丝袜| 国产一区二区调教| 播五月开心婷婷综合| 欧美日韩一区二区不卡| 亚洲色图20p| 欧美图片一区二区三区| 日韩精品一区二区三区视频| 日本一不卡视频| 26uuu亚洲综合色| 人禽交欧美网站| 国产在线播精品第三| 综合久久给合久久狠狠狠97色| 欧美一级日韩一级| 日韩电影在线一区二区三区| 欧美日韩国产一区二区三区地区| 欧美大片国产精品| 欧美精品日韩精品| 99久久国产免费看| 久久国产综合精品| 天堂精品中文字幕在线| 国产精品一卡二| 蜜桃传媒麻豆第一区在线观看| 成人av资源在线| 国产盗摄一区二区| 欧美精品视频www在线观看| 中文在线资源观看网站视频免费不卡| 亚洲国产色一区| 亚洲成在人线免费| 国产成人福利片| 成人av在线网| 在线不卡免费欧美| 久久婷婷一区二区三区| 激情另类小说区图片区视频区| 在线观看91视频| 欧美三级在线播放| 亚洲欧美偷拍三级| 一区二区三区.www| 色哟哟精品一区| 欧美在线一区二区| 亚洲欧美影音先锋| 亚洲高清免费视频| 一本久道中文字幕精品亚洲嫩| 欧美日韩一区二区三区在线看| 亚洲精选免费视频| 免费在线视频一区| 在线成人免费观看| 三级久久三级久久| 在线播放欧美女士性生活| 一区二区三区四区乱视频| 99精品视频在线观看免费| 中文字幕欧美激情一区| 国产欧美日韩另类视频免费观看| 一区二区三区中文在线| 国产精品天天摸av网| 午夜精品久久久久久久| 一区二区三区成人在线视频| 欧美三区在线观看| 国产高清不卡二三区| 国产精品区一区二区三| 日韩电影在线免费观看| 精品久久国产老人久久综合| 中文字幕在线不卡| 在线中文字幕不卡| 久久精品网站免费观看| 波多野结衣在线一区| 欧美精品日韩一区| 亚洲免费在线视频| 国产剧情一区二区| 欧美日韩中文另类| 中文在线一区二区| 五月天网站亚洲| 亚洲二区在线观看| 欧美成人bangbros| 国产一区二区在线看| 欧美日韩不卡一区二区| 91成人免费在线| 日韩福利电影在线观看| 色香蕉久久蜜桃| 久久91精品久久久久久秒播| 99re这里都是精品| 欧美精品丝袜中出| 亚洲男同性恋视频| 日韩欧美精品在线视频| 亚洲高清在线精品| 2017欧美狠狠色| 水野朝阳av一区二区三区| 久久亚区不卡日本| 国产毛片一区二区| 综合色天天鬼久久鬼色| heyzo一本久久综合| 国产精品自拍一区| 久久婷婷国产综合精品青草| 欧美xxxxx裸体时装秀| 免费观看在线色综合| 亚洲6080在线| 久久伊人中文字幕| 国产精品对白交换视频| 99re热视频这里只精品| 91视频观看免费| 日韩一区二区电影网| www.久久精品| 欧美日本免费一区二区三区| 成人三级在线视频| 天天色天天爱天天射综合| 亚洲国产视频一区| 亚洲高清视频中文字幕| 欧美xxxxxxxx| 成人aa视频在线观看| 蜜桃精品视频在线观看| 亚洲黄色片在线观看| 国产色产综合产在线视频| 日韩欧美国产一区二区在线播放| 亚洲国产wwwccc36天堂| 欧美激情一区在线| 日韩欧美一区二区三区在线| 欧美午夜视频网站| 成人黄色网址在线观看| 国产最新精品精品你懂的| 丝瓜av网站精品一区二区| 亚洲精品国产一区二区三区四区在线 | 中文字幕av资源一区| 日韩三级精品电影久久久 | 日本亚洲一区二区| 国产精品久久久久国产精品日日| 精品久久五月天| 91精品国产一区二区| 精品婷婷伊人一区三区三| 一本大道久久a久久综合| 成人动漫av在线| 国产一区二区美女| 日韩你懂的电影在线观看| 亚洲免费在线观看视频| 亚洲欧洲精品一区二区三区| 国产资源在线一区| 蜜桃传媒麻豆第一区在线观看| 久久精品一区二区| 国产亚洲制服色| 成人午夜av在线| 国内欧美视频一区二区| 欧美午夜精品久久久久久超碰| 色婷婷综合在线| av成人老司机| 蜜臀av性久久久久蜜臀aⅴ四虎| 亚洲国产视频直播| 日本一区二区三区四区| 久久久五月婷婷| 欧美精品久久久久久久久老牛影院 | 亚洲一区二区三区爽爽爽爽爽| 欧美不卡视频一区| 国产视频视频一区|