精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

詳解關于Lua源碼分析學習教程

移動開發 iOS
關于Lua源碼分析學習教程是本文要介紹的內容,主要來了解LUA中源碼的使用方法。Lua首先將源程序編譯成為字節碼,然后交由虛擬機解釋執行.對于每一個函數,Lua的編譯器將創建一個原型.

關于Lua源碼分析學習教程是本文要介紹的內容,主要來了解LUA源碼的使用方法。Lua首先將源程序編譯成為字節碼,然后交由虛擬機解釋執行。對于每一個函數,Lua的編譯器將創建一個原型(prototype),它由一組指令及其使用到的常量組成[1]。最初的Lua虛擬機是基于棧的。到1993年,Lua5.0版本,采用了基于寄存器的虛擬機,使得Lua的解釋效率得到提升。

體系結構與指令系統

與虛擬機和指令相關的文件主要有兩個: lopcodes.c 和 lvm.c。從名稱可以看出來,這兩個文件分別用于描述操作碼(指令)和虛擬機。

首先來看指令:

Lua共有38條指令,在下面兩處地方分別描述了這些指令的名稱和模式, 如下:

  1. lopcodes.c:16  
  2. const char *const luaP_opnames[NUM_OPCODES+1] = {  
  3. "MOVE",  
  4. "LOADK",  
  5. "LOADBOOL",  
  6. "LOADNIL",  
  7. "GETUPVAL",  
  8. "GETGLOBAL",  
  9. "GETTABLE",  
  10. "SETGLOBAL",  
  11. "SETUPVAL",  
  12. "SETTABLE",  
  13. "NEWTABLE",  
  14. "SELF",  
  15. "ADD",  
  16. "SUB",  
  17. "MUL",  
  18. "DIV",  
  19. "MOD",  
  20. "POW",  
  21. "UNM",  
  22. "NOT",  
  23. "LEN",  
  24. "CONCAT",  
  25. "JMP",  
  26. "EQ",  
  27. "LT",  
  28. "LE",  
  29. "TEST",  
  30. "TESTSET",  
  31. "CALL",  
  32. "TAILCALL",  
  33. "RETURN",  
  34. "FORLOOP",  
  35. "FORPREP",  
  36. "TFORLOOP",  
  37. "SETLIST",  
  38. "CLOSE",  
  39. "CLOSURE",  
  40. "VARARG",  
  41. NULL  
  42. };  
  43.  
  44. #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))  
  45.  
  46. const lu_byte luaP_opmodes[NUM_OPCODES] = {  
  47. /*       T A    B       C     mode           opcode    */  
  48. opmode(0, 1, OpArgR, OpArgN, iABC)         /* OP_MOVE */  
  49. ,opmode(0, 1, OpArgK, OpArgN, iABx)        /* OP_LOADK */  
  50. ,opmode(0, 1, OpArgU, OpArgU, iABC)        /* OP_LOADBOOL */  
  51. ,opmode(0, 1, OpArgR, OpArgN, iABC)        /* OP_LOADNIL */  
  52. ,opmode(0, 1, OpArgU, OpArgN, iABC)        /* OP_GETUPVAL */  
  53. ,opmode(0, 1, OpArgK, OpArgN, iABx)        /* OP_GETGLOBAL */  
  54. ,opmode(0, 1, OpArgR, OpArgK, iABC)        /* OP_GETTABLE */  
  55. ,opmode(0, 0, OpArgK, OpArgN, iABx)        /* OP_SETGLOBAL */  
  56. ,opmode(0, 0, OpArgU, OpArgN, iABC)        /* OP_SETUPVAL */  
  57. ,opmode(0, 0, OpArgK, OpArgK, iABC)        /* OP_SETTABLE */  
  58. ,opmode(0, 1, OpArgU, OpArgU, iABC)        /* OP_NEWTABLE */  
  59. ,opmode(0, 1, OpArgR, OpArgK, iABC)        /* OP_SELF */  
  60. ,opmode(0, 1, OpArgK, OpArgK, iABC)        /* OP_ADD */  
  61. ,opmode(0, 1, OpArgK, OpArgK, iABC)        /* OP_SUB */  
  62. ,opmode(0, 1, OpArgK, OpArgK, iABC)        /* OP_MUL */  
  63. ,opmode(0, 1, OpArgK, OpArgK, iABC)        /* OP_DIV */  
  64. ,opmode(0, 1, OpArgK, OpArgK, iABC)        /* OP_MOD */  
  65. ,opmode(0, 1, OpArgK, OpArgK, iABC)        /* OP_POW */  
  66. ,opmode(0, 1, OpArgR, OpArgN, iABC)        /* OP_UNM */  
  67. ,opmode(0, 1, OpArgR, OpArgN, iABC)        /* OP_NOT */  
  68. ,opmode(0, 1, OpArgR, OpArgN, iABC)        /* OP_LEN */  
  69. ,opmode(0, 1, OpArgR, OpArgR, iABC)        /* OP_CONCAT */  
  70. ,opmode(0, 0, OpArgR, OpArgN, iAsBx)        /* OP_JMP */  
  71. ,opmode(1, 0, OpArgK, OpArgK, iABC)        /* OP_EQ */  
  72. ,opmode(1, 0, OpArgK, OpArgK, iABC)        /* OP_LT */  
  73. ,opmode(1, 0, OpArgK, OpArgK, iABC)        /* OP_LE */  
  74. ,opmode(1, 1, OpArgR, OpArgU, iABC)        /* OP_TEST */  
  75. ,opmode(1, 1, OpArgR, OpArgU, iABC)        /* OP_TESTSET */  
  76. ,opmode(0, 1, OpArgU, OpArgU, iABC)        /* OP_CALL */  
  77. ,opmode(0, 1, OpArgU, OpArgU, iABC)        /* OP_TAILCALL */  
  78. ,opmode(0, 0, OpArgU, OpArgN, iABC)        /* OP_RETURN */  
  79. ,opmode(0, 1, OpArgR, OpArgN, iAsBx)        /* OP_FORLOOP */  
  80. ,opmode(0, 1, OpArgR, OpArgN, iAsBx)        /* OP_FORPREP */  
  81. ,opmode(1, 0, OpArgN, OpArgU, iABC)        /* OP_TFORLOOP */  
  82. ,opmode(0, 0, OpArgU, OpArgU, iABC)        /* OP_SETLIST */  
  83. ,opmode(0, 0, OpArgN, OpArgN, iABC)        /* OP_CLOSE */  
  84. ,opmode(0, 1, OpArgU, OpArgN, iABx)        /* OP_CLOSURE */  
  85. ,opmode(0, 1, OpArgU, OpArgN, iABC)        /* OP_VARARG */  
  86. }; 

前面一個數組容易理解,表示了每條指令的名稱。后面一個數組表示的是指令的模式。奇怪的符號讓人有些費解。在看模式之前, 首先來看Lua指令的格式,如圖:

詳解關于Lua源碼分析學習教程

如上圖, Lua的指令可以分成三種形式. 即在上面的模式數組中也可以看到的iABC, iABx 和 iAsBx. 對于三種形式的指令來說, 前兩部分都是一樣的, 分別是6位的操作碼和8位A操作數; 區別在于, 后面部是分割成為兩個長度為9位的操作符(B, C),一個無符號的18位操作符Bx還是有符號的18位操作符sBx. 這些定義的代碼如下:

  1. lopcodes.c : 34  
  2. /*  
  3. ** size and position of opcode arguments.  
  4. */  
  5. #define SIZE_C        9  
  6. #define SIZE_B        9  
  7. #define SIZE_Bx        (SIZE_C + SIZE_B)  
  8. #define SIZE_A        8  
  9.  
  10. #define SIZE_OP        6  
  11.  
  12. #define POS_OP        0  
  13. #define POS_A        (POS_OP + SIZE_OP)  
  14. #define POS_C        (POS_A + SIZE_A)  
  15. #define POS_B        (POS_C + SIZE_C)  
  16. #define POS_Bx        POS_C 

再來看指令的操作模式, Lua使用一個字節來表示指令的操作模式. 具體的含義如下:

1、使用最高位來表示是否是一條測試指令. 之所以將這一類型的指令特別地標識出來, 是因為Lua的指令長度是32位,對于分支指令來說, 要想在這32位中既表示兩個操作數來做比較, 同時還要表示一個跳轉的地址, 是很困難的. 因此將這種指令分成兩條, 第一條是測試指令, 緊接著一條無條件跳轉. 如果判斷條件成立則將PC(Program Counter, 指示下一條要執行的指令)加一, 跳過下一條無條件跳轉指令, 繼續執行; 否則跳轉.

2、第二位用于表示A操作數是否被設置

3、接下來的二位用于表示操作數B的格式,OpArgN表示操作數未被使用, OpArgU表示操作數被使用(立即數?), OpArgR表示表示操作數是寄存器或者跳轉的偏移量, OpArgK表示操作數是寄存器或者常量.

最后, 給出Lua虛擬機的體系結構圖(根據源代碼分析得出):

詳解關于Lua源碼分析學習教程

首先, 我們注意到, Lua的解釋器還是一個以棧為中心的結構. 在lua_State這個結構中,有許多個字段用于描述這個結構.stack用于指向絕對棧底, 而base指向了當前正在執行的函數的第一個參數, 而top指向棧頂的第一個空元素.

我們可以看到,這個體系結構中并沒有獨立出來的寄存器. 從以下代碼來看:

  1. lvm.c:343  
  2. #define RA(i)    (base+GETARG_A(i))  
  3. /* to be used after possible stack reallocation */  
  4. #define RB(i)    check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))  
  5. #define RC(i)    check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))  
  6. #define RKB(i)    check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \  
  7.     ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))  
  8. #define RKC(i)    check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \  
  9.     ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))  
  10. #define KBx(i)    check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) 

當指令操作數的類型是寄存器時,它的內容是以base為基址在棧上的索引值.如圖所示.寄存器實際是base之上棧元素的別名;當指令操作數的類型的常數時, 它首先判斷B操作數的最位是否為零.如果是零,則按照和寄存器的處理方法一樣做,如果不是零,則在常數表中找相應的值.

我們知道Lua中函數的執行過程是這樣的. 首先將函數壓棧,然后依次將參數壓棧,形成圖中所示的棧的內容. 因此R[0]到R[n]也分別表示了Arg[1]到Arg[N+1].在第一個參數之下,就是當前正在執行的函數,對于Lua的函數(相對C函數)來說,它是指向類型為 Prototype的TValue, 在Prototype中字段code指向了一個數組用來表示組成這個函數的所有指令,字段k指向一個數組來表示這個函數使用到的所有常量.最后,Lua在解釋執行過程中有專門的變量pc來指向下一條要執行的指令.

指令解釋器

有了前面對指令格式和體系結構的介紹,現在我們可以進入正題, 來看看Lua的指令是如何執行的了.主函數如下:

  1. lvm.c:373  
  2. void luaV_execute (lua_State *L, int nexeccalls) {  
  3. LClosure *cl;  
  4. StkId base;  
  5. TValue *k;  
  6. const Instruction *pc;  
  7. reentry: /* entry point */  
  8. lua_assert(isLua(L->ci));  
  9. pc = L->savedpc;  
  10. cl = &clvalue(L->ci->func)->l;  
  11. base = L->base;  
  12. k = cl->p->k; 

這是最開始的初始化過程.其中, pc被初始化成為了L->savedpc,base被初始化成為了L->base, 即程序從L->savedpc開始執行 (在下一篇專題中,將會介紹到 L->savedpc在函數調用的預處理過程中指向了當前函數的code),而L->base指向棧中當前函數的下一個位置.cl表示當前正在執行閉包(當前可以理解成為函數),k指向當前閉包的常量表.

接下來(注意,為了專注主要邏輯, 我將其中用于Debugger支持,斷言等代碼省略了):

  1. /* main loop of interpreter */  
  2. for (;;) {  
  3.     const Instruction i = *pc++;  
  4.     StkId ra;  
  5.     /* 省略Debugger支持和Coroutine支持*/  
  6.     /* warning!! several calls may realloc the stack and invalidate `ra' */  
  7.     ra = RA(i);  
  8.     /* 省略斷言 */  
  9.     switch (GET_OPCODE(i)) { 

進入到解釋器的主循環,處理很簡單,取得當前指令,pc遞增,初始化ra,然后根據指令的操作碼進行選擇. 接下來的代碼是什么樣的, 估計大家都能想到,一大串的case來指示每條指令的執行.具體的實現可以參考源碼, 在這里不對每一條指令展開, 只是對其中有主要的幾類指令進行說明:

傳值類的指令,與MOVE為代表:

  1. lvm.c:403  
  2.       case OP_MOVE: {  
  3.         setobjs2s(L, ra, RB(i));  
  4.         continue;  
  5.       }  
  6. lopcodes:154  
  7. OP_MOVE,/*    A B    R(A) :R(B)                    */  
  8. lobject.h:161  
  9. #define setobj(L,obj1,obj2) \  
  10. { const TValue *o2=(obj2); TValue *o1=(obj1); \  
  11.     o1->value = o2->value; o1->tt=o2->tt; \  
  12.     checkliveness(G(L),o1); }  
  13.  
  14. /*  
  15. ** different types of sets, according to destination  
  16. */  
  17. /* from stack to (same) stack */  
  18. #define setobjs2s    setobj 

從注釋來看, 這條指令是將操作數A,B都做為寄存器,然后將B的值給A. 而實現也是簡單明了,只使用了一句. 宏展開以后, 可以看到, R[A],R[B]的類型是TValue, 只是將這兩域的值傳過來即可. 對于可回收對象來說,真實值不會保存在棧上,所以只是改了指針,而對于非可回收對象來說,則是直接將值從R[B]賦到R[A].

數值運算類指令,與ADD為代表:

  1. lvm.c:470  
  2.       case OP_ADD: {  
  3.         arith_op(luai_numadd, TM_ADD);  
  4.         continue;  
  5.       }  
  6. lvm.c:360  
  7. #define arith_op(op,tm) { \  
  8.         TValue *rb = RKB(i); \  
  9.         TValue *rc = RKC(i); \  
  10.         if (ttisnumber(rb) && ttisnumber(rc)) { \  
  11.           lua_Number nb = nvalue(rb), nc = nvalue(rc); \  
  12.           setnvalue(ra, op(nb, nc)); \  
  13.         } \  
  14.         else \  
  15.           Protect(Arith(L, ra, rb, rc, tm)); \  
  16.       }  
  17. lopcodes.c:171  
  18. OP_ADD,/*    A B C    R(A) :RK(B) + RK(C)                */ 

如果兩個操作數都是數值的話,關鍵的一行是:

  1. setnvalue(ra,op(nb,nc)); 

即兩個操作數相加以后,把值賦給R[A].值得注意的是,操作數B,C都是RK, 即可能是寄存器也可能是常量,這最決于最B和C的最高位是否為1,如果是1,則是常量,反之則是寄存器.具體可以參考宏ISK的實現.

如果兩個操作數不是數值,即調用了Arith函數,它嘗試將兩個操作轉換成數值進行計算,如果無法轉換,則使用元表機制.該函數的實現如下:

  1. lvm.c:313  
  2. static void Arith (lua_State *L, StkId ra, const TValue *rb,  
  3.                    const TValue *rc, TMS op) {  
  4. TValue tempb, tempc;  
  5. const TValue *b, *c;  
  6. if ((b = luaV_tonumber(rb, &tempb)) != NULL &&  
  7.       (c = luaV_tonumber(rc, &tempc)) != NULL) {  
  8.     lua_Number nb = nvalue(b), nc = nvalue(c);  
  9.     switch (op) {  
  10.       case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;  
  11.       case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;  
  12.       case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;  
  13.       case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;  
  14.       case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;  
  15.       case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;  
  16.       case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;  
  17.       default: lua_assert(0); break;  
  18.     }  
  19. }  
  20. else if (!call_binTM(L, rb, rc, ra, op))  
  21.     luaG_aritherror(L, rb, rc);  

在上面call_binTM用于調用到元表中的元方法,因為在Lua以前的版本中元方法也被叫做tag method, 所以函數最后是以TM結尾的.

  1. lvm:163  
  2. static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,  
  3.                        StkId res, TMS event) {  
  4. const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */  
  5. if (ttisnil(tm))  
  6.     tm = luaT_gettmbyobj(L, p2, event); /* try second operand */  
  7. if (!ttisfunction(tm)) return 0;  
  8. callTMres(L, res, tm, p1, p2);  
  9. return 1;  

在 這個函數中,試著從二個操作數中找到其中一個操作數的元方法(第一個操作數優先), 這里event表示具體哪一個元方法,找到了之后,再使用函數callTMres()去調用相應的元方法. callTMres()的實現很簡單,只是將元方法,第一,第二操作數先后壓棧,再調用并取因返回值.具體如下:

  1. lvm.c:82  
  2. static void callTMres (lua_State *L, StkId res, const TValue *f,  
  3.                         const TValue *p1, const TValue *p2) {  
  4. ptrdiff_t result = savestack(L, res);  
  5. setobj2s(L, L->top, f); /* push function */  
  6. setobj2s(L, L->top+1, p1); /* 1st argument */  
  7. setobj2s(L, L->top+2, p2); /* 2nd argument */  
  8. luaD_checkstack(L, 3);  
  9. L->top += 3;  
  10. luaD_call(L, L->top - 3, 1);  
  11. res = restorestack(L, result);  
  12. L->top--;  
  13. setobjs2s(L, res, L->top);  

邏輯運算類指令,與EQ為代表:

  1. lvm.c:541  
  2.       case OP_EQ: {  
  3.         TValue *rb = RKB(i);  
  4.         TValue *rc = RKC(i);  
  5.         Protect(  
  6.           if (equalobj(L, rb, rc) == GETARG_A(i))  
  7.             dojump(L, pc, GETARG_sBx(*pc));  
  8.         )  
  9.         pc++;  
  10.         continue;  
  11.       }  
  12. lopcodes.c:185  
  13. OP_EQ,/*    A B C    if ((RK(B) == RK(C)) ~= A) then pc++        */ 

在這條指令實現的過程中,equalobj與之前的算術運算類似,讀者可以自行分析.關鍵看它是如果實現中跳轉的,如果RK[B]==RK[C]并且A為1 的情況下(即條件為真),則會使用pc取出下一條指令,調用dojump進行跳轉,否則pc++,掛空緊接著的無條件跳轉指令. dojump的實現如下:

  1. lvm.c:354  
  2. #define dojump(L,pc,i)    {(pc) += (i); luai_threadyield(L);} 

luai_threadyield只是順序地調用lua_unlock和lua_lock,這里為釋放一次鎖,使得別的線程可以得到調度.

函數調用類指令,與CALL為代表:

  1. lvm.c:582  
  2.       case OP_CALL: {  
  3.         int b = GETARG_B(i);  
  4.         int nresults = GETARG_C(i) - 1;  
  5.         if (b != 0) L->top = ra+b; /* else previous instruction set top */  
  6.         L->savedpc = pc;  
  7.         switch (luaD_precall(L, ra, nresults)) {  
  8.           case PCRLUA: {  
  9.             nexeccalls++;  
  10.             goto reentry; /* restart luaV_execute over new Lua function */  
  11.           }  
  12.           case PCRC: {  
  13.             /* it was a C function (`precall' called it); adjust results */  
  14.             if (nresults >= 0) L->top = L->ci->top;  
  15.             base = L->base;  
  16.             continue;  
  17.           }  
  18.           default: {  
  19.             return; /* yield */  
  20.           }  
  21.         }  
  22.       }  
  23. lopcodes.c:192  
  24.  
  25. OP_CALL,/*    A B C    R(A), ... ,R(A+C-2) :R(A)(R(A+1), ... ,R(A+B-1)) */ 

這一條指令將在下一個介紹Lua函數調用規范的專題中詳細介紹. 在這里只是簡單地說明CALL指令的R[A]表示的是即將要調用的函數,而B和C則分別表示參數個數加1,和返回值個數加1. 之所以這里需要加1,其原因是:B和C使用零來表示變長的參數和變長的返回值,而實際參數個數就向后推了一個.

指令的介紹就先到此為止了, 其它的指令的實現也比較類似.仔細閱讀源碼就可很容易地分析出它的意義來. 下一篇將是一個專題, 詳細地介紹Lua中函數的調用是如何實現的.

小結:詳解關于Lua源碼分析學習教程的內容介紹完了,希望通過本文的學習能對你有所幫助!

責任編輯:zhaolei 來源: 互聯網
相關推薦

2011-08-24 15:42:38

LUA源代碼

2011-08-25 16:20:33

Lua腳本變量

2011-08-23 17:06:03

2011-08-23 15:34:56

Lua模式 匹配

2011-08-24 14:14:13

LUA環境 配置

2011-08-24 11:03:33

LUA環境 安裝

2011-08-23 16:37:05

Lua數學庫

2011-08-24 15:34:44

MinGWLua環境配置

2011-09-02 13:51:00

PhoneGap框架HTML5

2011-08-24 17:09:35

LUA閉包函數

2011-08-24 11:08:09

Lua

2011-08-25 10:07:24

Lua 5.0函數編譯器

2011-08-31 10:20:26

MTK驅動開發

2011-08-24 13:27:07

Lua 游戲C接口腳本

2011-08-24 16:59:59

LuaModule

2011-08-23 16:48:41

Lua 5.1API 函數

2011-08-23 13:54:10

LUA全局變量

2011-08-24 14:33:14

LUA開發環境Decoda

2011-08-25 14:03:32

UbuntuLUA安裝

2011-08-25 17:25:55

LUADelphi
點贊
收藏

51CTO技術棧公眾號

欧美日韩福利视频| 欧美亚洲综合网| 精品在线不卡| 天天爽夜夜爽夜夜爽精品| 久久夜色电影| 欧美在线观看一区二区| 伊人久久在线观看| 日本xxxxxwwwww| 日韩av网站免费在线| 久久久极品av| 麻豆av免费看| 中文字幕乱码在线播放| 亚洲欧美综合色| 国产综合动作在线观看| 亚洲一区二区三区高清视频| 欧美日韩亚洲三区| 国产一区二区三区中文| 成人在线免费观看av| 日本高清视频在线观看| 成人动漫在线一区| 91精品久久久久久久久久久久久 | 国产欧美日韩麻豆91| 999在线观看免费大全电视剧| 台湾佬中文在线| 欧美特黄一区| 久久久久99精品久久久久| 天天插天天射天天干| 国产精品乱码一区二区| 一本色道久久综合亚洲精品高清 | 精品自拍一区| 不卡在线视频中文字幕| 国产日产欧美精品| 欧美a视频在线观看| 欧美精品导航| 久久夜色撩人精品| 成人小视频免费看| 国产主播性色av福利精品一区| 欧美美女一区二区在线观看| 青青草视频在线免费播放| 午夜小视频福利在线观看| 国产精品私人影院| 神马一区二区影院| 黄色片视频在线观看| eeuss国产一区二区三区| 亚洲综合在线小说| 99国产精品99| 狠狠色丁香久久婷婷综| 成人午夜一级二级三级| 中文字幕欧美在线观看| 欧美aaaaa成人免费观看视频| 欧美中文在线观看| av资源免费观看| 欧美国产日本| 欧美另类第一页| 人妻少妇精品一区二区三区| 偷偷www综合久久久久久久| 中文字幕视频一区二区在线有码| 亚洲精品午夜视频| 欧美视频免费| 日韩在线免费观看视频| 国产美女网站视频| 99视频精品视频高清免费| 亚洲色图狂野欧美| 国产一区二区三区四区五区六区 | 精品视频在线导航| 国精产品一区一区三区免费视频| 亚洲资源网你懂的| 亚洲欧美另类中文字幕| 国产又大又粗又爽的毛片| heyzo久久| 日韩亚洲一区二区| 午夜精品福利在线视频| 狠狠色丁香久久综合频道| 欧美激情区在线播放| 日韩黄色在线视频| 日本伊人午夜精品| 国产日韩欧美成人| 国内精品久久久久久久久久| 欧美日韩精品| 久久久久久久国产精品视频| 国产无遮挡又黄又爽在线观看| 亚洲激情专区| 国产精品久久久久久久久借妻| 一本色道久久综合亚洲| 国产精品1024| 免费看污久久久| 欧美日韩xx| 一区二区三区免费在线观看| 亚洲 高清 成人 动漫| 免费在线播放电影| 色av一区二区| 黄色片免费网址| 久久亚洲黄色| 久久人人爽人人爽爽久久| 久久久国产成人| 性感少妇一区| 91亚洲午夜在线| 外国精品视频在线观看 | 国内不卡的二区三区中文字幕| 91aaaa| 6—12呦国产精品| 国产精品乡下勾搭老头1| 精品一区二区三区自拍图片区| 在线观看黄av| 无码av免费一区二区三区试看 | 在线精品播放av| jizz18女人高潮| 精品动漫3d一区二区三区免费版| 国产精品白嫩初高中害羞小美女| 91亚洲欧美激情| 91丨国产丨九色丨pron| 六月婷婷激情网| 国产v综合v| 精品国产一区二区三区忘忧草 | 天堂在线视频免费| 亚洲少妇30p| 成年人在线观看视频免费| 91精品国产自产在线丝袜啪| 亚洲视频一区二区在线| 欧美 日韩 国产在线| 69xxx在线| 欧美午夜在线观看| 三级黄色片网站| 日韩系列在线| 午夜精品蜜臀一区二区三区免费| 波多野结衣啪啪| jlzzjlzz亚洲日本少妇| 91网站在线观看免费| av小说天堂网| 国产精品麻豆一区二区| 欧美黄色免费影院| 国偷自产av一区二区三区| 欧美大码xxxx| 国产精品爽爽久久久久久| 国产婷婷一区二区| 日韩亚洲欧美精品| 天堂а√在线8种子蜜桃视频| 亚洲日本成人在线观看| 欧美三级理论片| 九九久久成人| 97超视频免费观看| 女人18毛片一区二区三区| 亚洲免费色视频| 91精品999| 亚洲国产日韩欧美在线| 91国产一区在线| 涩涩视频免费看| 久久福利毛片| 欧美激情一二三区| 国产美女在线一区| 伊人久久亚洲| 欧美激情视频一区二区| 国产jzjzjz丝袜老师水多| 亚洲视频一二三| av在线免费观看不卡| 91精品天堂福利在线观看| 91久久久久久久久久| 在线中文免费视频| 欧美成人vps| 五月天婷婷综合网| 91美女精品福利| 爱情岛论坛成人| 欧美电影免费播放| 亚洲一区二区三区毛片 | 国a精品视频大全| 性xxxxbbbb| 在线一区二区三区四区五区 | 国产精品高潮呻吟视频| eeuss影院www在线播放| 欧美精品乱人伦久久久久久| 欧美黑人性猛交xxx| 成人高清av在线| 国产熟女高潮视频| 成人亚洲一区| 亚洲综合一区二区不卡| 蜜桃麻豆av在线| 亚洲最新av在线网站| 91在线观看喷潮| 亚洲国产精品久久人人爱| 成人网站免费观看| 蜜桃久久久久久久| 国产精品一线二线三线| 亚洲宅男一区| 96pao国产成视频永久免费| 1234区中文字幕在线观看| 亚洲午夜未满十八勿入免费观看全集 | 国产精品日韩专区| 亚洲一区二区三区高清视频| 亚洲乱码国产乱码精品精可以看| 中文字幕无码人妻少妇免费| 日韩极品在线观看| 粉嫩av一区二区三区天美传媒| 日本一道高清一区二区三区| 国产精品你懂得| 成人在线高清免费| 最近2019中文免费高清视频观看www99 | 一本一生久久a久久精品综合蜜| 日韩欧美一级| 国产精品久久久久久久久粉嫩av| 欧美日韩经典丝袜| 中文字幕精品一区二区精品| 亚洲精品国偷拍自产在线观看蜜桃| 一本色道久久综合亚洲精品按摩| 天天色影综合网| 久久久久久综合| av av在线| 韩国精品免费视频| caopor在线视频| 韩国在线一区| 中文字幕久精品免| 免费黄色成人| 国产精品美女久久久久av福利| 国产69精品久久| 欧美孕妇与黑人孕交| 天堂亚洲精品| 精品国产一区二区三区久久狼黑人| 手机看片福利永久| 欧美一级黄色录像| 日日噜噜夜夜狠狠久久波多野| av成人老司机| 成人做爰69片免费| 国内成人免费视频| 天天干天天爽天天射| 先锋影音久久| 免费在线观看视频a| 一区二区三区在线电影| 亚洲人成网站在线观看播放| 妖精一区二区三区精品视频| 国产精品永久入口久久久| 国产精品视频一区视频二区| 国产精品你懂得| 91福利精品在线观看| 国产91精品网站| 黑人巨大精品欧美一区二区桃花岛| 久久久久久久网站| 欧美人与动牲性行为| 欧美xxxx综合视频| av网址在线播放| 欧美成人中文字幕| a视频在线免费看| 久久国产精品99国产精| 含羞草www国产在线视频| 在线电影欧美日韩一区二区私密| 免费在线视频你懂得| 亚洲欧美另类国产| 国产免费a∨片在线观看不卡| 亚洲欧美精品伊人久久| 欧美成熟毛茸茸| 亚洲欧洲xxxx| 国产福利电影在线| 神马国产精品影院av| 一广人看www在线观看免费视频| 中文字幕久久精品| 九七久久人人| 欧美激情图片区| 国产传媒在线观看| 欧美又大又硬又粗bbbbb| 日韩在线短视频| 国产欧美一区二区三区四区 | 国产成人精品福利一区二区三区| 亚洲精品在线播放| 国产综合 伊人色| 久久av免费| 亚洲免费视频一区| 中文字幕免费一区二区三区| 免费人成在线观看视频播放| 亚洲激情网址| 日日碰狠狠丁香久燥| 久久久久国产精品一区二区| 亚洲男人天堂色| 国产一区二区精品在线观看| 岛国av免费观看| 久久婷婷国产综合精品青草| 欧美亚洲色综久久精品国产| 亚洲色图丝袜美腿| 欧美成人aaaaⅴ片在线看| 色综合天天综合网天天狠天天| 亚洲 小说区 图片区| 欧美一区二区三区成人| 日韩一级免费毛片| 中文字幕亚洲精品| 色婷婷在线播放| 日本久久久久久| 久久69av| 久久久久无码国产精品一区| 日产午夜精品一线二线三线| 成人国产在线看| 久久激情久久| 一级日本黄色片| 国产色爱av资源综合区| 天天操天天操天天操天天操天天操| 午夜精品福利一区二区三区蜜桃| 青青国产在线视频| 欧美精品一区二区精品网| 国产区视频在线播放| 欧美激情一二三| 91福利精品在线观看| 精品国产综合| 亚洲精品国产首次亮相| 日韩av资源在线| 国产福利一区在线| 99久久99久久精品免费看小说.| 一区二区三区日韩欧美精品| 国产一卡二卡三卡| 亚洲丁香婷深爱综合| 免费黄色在线| 国产精品99蜜臀久久不卡二区| 豆花视频一区二区| 五月天男人天堂| 日韩成人dvd| 欧美 变态 另类 人妖| 亚洲人被黑人高潮完整版| 亚洲精品久久久久久久蜜桃| 欧美精品一区二区在线播放 | 国产99久久精品一区二区300| 黄色录像特级片| 免费观看在线色综合| av在线网站观看| 亚洲综合色在线| 国产婷婷一区二区三区久久| 国产亚洲激情视频在线| 天堂av中文在线观看| 91精品天堂| 91国语精品自产拍| 天堂在线中文在线| 亚洲国产精品成人综合| 欧产日产国产69| 亚洲精品久久久久久久久久久| 色在线视频网| 91久久精品一区二区别| 亚洲精彩视频| 亚洲免费在线播放视频| 国产精品久久看| 一区二区视频网| 中文字幕亚洲一区二区三区五十路 | 五月婷婷六月色| 国精产品一区一区三区有限在线| 麻豆国产精品| 在线观看污视频| 国产一区二区福利视频| 卡通动漫亚洲综合| 欧美一区二区三区在线电影| 欧美精品日韩少妇| 成人黄色影片在线| 亚洲人成免费网站| 色姑娘综合天天| 伊人夜夜躁av伊人久久| 精品国产18久久久久久| 欧美高清视频在线观看| 久久久久九九精品影院| 日韩一级免费看| 成人丝袜高跟foot| 日韩欧美中文字幕一区二区| 亚洲国产三级网| 亚洲男人av| 日韩福利在线| 久久国产精品99精品国产| 欧美特黄一级片| 日韩一区二区三区三四区视频在线观看| 爆操欧美美女| 国产精品久久久久久久久久直播| 激情久久久久久久| 一区二区三区少妇| 色老综合老女人久久久| 欧美一区二区三区| 97超级碰碰| 国产视频久久| 人妻视频一区二区| 欧美久久久久中文字幕| 欧美日韩色网| 欧美日韩国产一二| 久久 天天综合| 久久精品性爱视频| 亚洲老头老太hd| 亚洲欧洲二区| 亚洲中文字幕无码av永久| 国产亚洲精品中文字幕| 国产日韩精品suv| 91精品国产91久久久久| 欧美肉体xxxx裸体137大胆| 精品综合久久久久| 五月婷婷激情综合| 国产精品二线| 99久久精品免费看国产一区二区三区| 99精品国产一区二区青青牛奶| mm131丰满少妇人体欣赏图| 91精品综合久久久久久| 黄色在线观看www| 影音先锋在线亚洲| 99视频精品全部免费在线| 中文字幕在线观看免费| 欧美黑人又粗大| 日韩欧美三级| 日本三级日本三级日本三级极| 在线亚洲+欧美+日本专区| 人人澡人人添人人爽一区二区| 欧美激情www| 岛国一区二区三区| 一级全黄裸体免费视频| 91av视频在线免费观看|