青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

李錦俊(mybios)的blog

游戲開發 C++ Cocos2d-x OpenGL DirectX 數學 計算機圖形學 SQL Server

  C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
  86 Posts :: 0 Stories :: 370 Comments :: 0 Trackbacks

公告

QQ:30743734
EMain:mybios@qq.com

常用鏈接

留言簿(16)

我參與的團隊

最新隨筆

搜索

  •  

積分與排名

  • 積分 - 373331
  • 排名 - 67

最新評論

閱讀排行榜

評論排行榜

使用 Lua 編寫可嵌入式腳本

Lua 提供了高級抽象,卻又沒失去與硬件的關聯

未顯示需要 JavaScript 的文檔選項



級別: 初級

Martin Streicher (martin.streicher@linux-mag.com), 首席編輯, Linux Magazine

2006 年 6 月 12 日

雖然編譯性編程語言和腳本語言各自具有自己獨特的優點,但是如果我們使用這兩種類型的語言來編寫大型的應用程序會是什么樣子呢?Lua 是一種嵌入式腳本語言,它非常小,速度很快,功能卻非常強大。在創建其他配置文件或資源格式(以及與之對應的解析器)之前,請嘗試一下 Lua。

盡管諸如 Perl、Python、PHP 和 Ruby 之類的解釋性編程語言日益被 Web 應用程序廣泛地采納 —— 它們已經長期用來實現自動化系統管理任務 —— 但是諸如 C、C++ 之類的編譯性編程語言依然是必需的。編譯性編程語言的性能是腳本語言所無法企及的(只有手工調優的匯編程序的性能才能超過它),有些軟件 —— 包括操作系統和設備驅動程序 —— 只能使用編譯代碼來高效地實現。實際上,當軟件和硬件需要進行無縫地連接操作時,程序員本能地就會選擇 C 編譯器:C 非?;A,距離 “原始金屬材料非常近” —— 即可以操作硬件的很多特性 —— 并且 C 的表現力非常強大,可以提供高級編程結構,例如結構、循環、命名變量和作用域。

然而,腳本語言也有自己獨特的優點。例如,當某種語言的解釋器被成功移植到一種平臺上以后,使用這種語言編寫的大量腳本就可以不加任何修改在這種新平臺上運行 —— 它們沒有諸如系統特定的函數庫之類的依賴限制。(我們可以考慮一下 Microsoft? Windows? 操作系統上的許多 DLL 文件和 UNIX? 及 Linux? 上的很多 libcs)。另外,腳本語言通常都還會提供高級編程構造和便利的操作,程序員可以使用這些功能來提高生產效率和靈活性。另外,使用解釋語言來編程的程序員工作的速度更快,因為這不需要編譯和鏈接的步驟。C 及其類似語言中的 “編碼、編譯、鏈接、運行” 周期縮減成了更為緊湊的 “編寫腳本、運行”。

Lua 新特性

與其他腳本語言一樣,Lua 也有自己的一些特性:

  • Lua 類型。在 Lua 中,值可以有類型,但是變量的類型都是動態決定的。nil、布爾型、數字字符串 類型的工作方式與我們期望的一樣。
    • Nil 是值為 nil 的一種特殊類型,用來表示沒有值。
    • 布爾型的值可以是 truefalse 常量。(Nil 也可以表示 false,任何非 nil 的值都表示 true。)
    • Lua 中所有的數字都是雙精度的(不過我們可以非常簡便地編寫一些代碼來實現其他數字類型)。
    • 字符串是定長字符數組。(因此,要在一個字符串后面附加上字符,必須對其進行拷貝。)
  • 表、函數線程 類型都是引用。每個都可以賦值給一個變量,作為參數傳遞,或作為返回值從函數中返回。例如,下面是一個存儲函數的例子:

    -- example of an anonymous function
    -- returned as a value
    -- see http://www.tecgraf.puc-rio.br/~lhf/ftp/doc/hopl.pdf
    function add(x)
      return function (y) return (x + y) end
    end
    f = add(2)
    print(type(f), f(10))
    function  12
    

  • Lua 線程。線程是通過調用內嵌函數 coroutine.create(f) 創建的一個協同例程 (co-routine),其中 f 是一個 Lua 函數。線程不會在創建時啟動;相反,它是在創建之后使用 coroutine.resume(t) 啟動的,其中 t 就是一個線程。每個協同例程都必須使用 coroutine.yield() 偶爾獲得其他協同例程的處理器。
  • 賦值語句。Lua 允許使用多種賦值語句,可以先對表達式進行求值,然后再進行賦值。例如,下面的語句:

    i = 3
    a = {1, 3, 5, 7, 9}
    i, a[i], a[i+1], b = i+1, a[i+1], a[i]
    print (i, a[3], a[4], b, I)
    

    會生成 4 7 5 nil nil。如果變量列表的個數大于值列表的個數,那么多出的變量都被賦值為 nil;因此,b 就是 nil。如果值的個數多于變量的個數,那么多出的值部分就會簡單地丟棄。在 Lua 中,變量名是大小寫敏感的,這可以解釋為什么 I 的值是 nil。
  • 塊(Chunk)。 可以是任何 Lua 語句序列。塊可以保存到文件中,或者保存到 Lua 程序中的字符串中。每個塊都是作為一個匿名函數體來執行的。因此,塊可以定義局部變量和返回值。
  • 更酷的東西。Lua 具有一個標記-清理垃圾收集器。在 Lua 5.1 中,垃圾收集器是以增量方式工作的。Lua 具有完整的詞法閉包(這與 Scheme 類似,而與 Python 不同)。Lua 具有可靠的尾部調用語義(同樣,這也與 Scheme 類似,而與 Python 不同)。

Programming in Lua 和 Lua-users wiki (鏈接請參見后面的 參考資料 部分)中可以找到更多 Lua 代碼的例子。

在所有的工程任務中,要在編譯性語言和解釋性語言之間作出選擇,就意味著要在這種環境中對每種語言的優缺點、權重和折中進行評測,并接受所帶來的風險。





回頁首


在兩個世界之間最好地進行混合

如果您希望充分利用這兩個世界的優點,應該怎樣辦呢,是選擇最好的性能還是選擇高級強大的抽象?更進一步說,如果我們希望對處理器密集且依賴于系統的算法和函數以及與系統無關且很容易根據需要而進行修改的單獨邏輯進行優化,那又當如何呢?

對高性能代碼和高級編程的需要進行平衡是 Lua(一種可嵌入式腳本語言)要解決的問題。在需要時我們可以使用編譯后的代碼來實現底層的功能,然后調用 Lua 腳本來操作復雜的數據。由于 Lua 腳本是與編譯代碼獨立的,因此我們可以單獨修改這些腳本。使用 Lua,開發周期就非常類似于 “編碼、編譯、運行、編寫腳本、編寫腳本、編寫腳本 ...”。

例如,Lua Web 站點 “使用” 頁面(請參見 參考資料)列出了主流市場上的幾個計算機游戲,包括 World of Warcraft 和(家用版的)Defender,它們集成 Lua 來實現很多東西,從用戶界面到敵人的人工智能都可以。Lua 的其他應用程序包括流行的 Linux 軟件更新工具 apt-rpm 的擴展機制,還有 “Crazy Ivan” Robocup 2000 冠軍聯賽的控制邏輯。這個頁面上的很多推薦感言都對 Lua 的小巧與杰出性能贊不絕口。





回頁首


開始使用 Lua

Lua 5.0.2 版本是撰寫本文時的最新版本,不過最近剛剛發布了 5.1 版本。您可以從 lua.org 上下載 Lua 的源代碼,在 Lua-users wiki(鏈接請參見 參考資料)上可以找到預先編譯好的二進制文件。完整的 Lua 5.0.2 核心文件中包括了標準庫和 Lua 編譯器,不過只有 200KB 大小。

如果您使用的是 Debian Linux,那么可以以超級用戶的身份運行下面的命令來快速安裝 Lua 5.0:

# apt-get install lua50

本文中給出的例子都是在 Debian Linux Sarge 上運行的,使用的是 Lua 5.0.2 和 2.4.27-2-686 版本的 Linux 內核。

在系統上安裝好 Lua 之后,我們可以首先來試用一下單獨的 Lua 解釋器。(所有的 Lua 應用程序必須要嵌入到宿主應用程序中。解釋器只是一種特殊類型的宿主,對于開發和調試工作來說非常有用。)創建一個名為 factorial.lua 的文件,然后輸入下面的代碼:

-- defines a factorial function
function fact (n)
  if n == 0 then
    return 1
  else
    return n * fact(n-1)
  end
end

print("enter a number:")
a = io.read("*number")
print(fact(a))

factorial.lua 中的代碼 —— 更確切地說是任何 Lua 語句序列 —— 都稱為一個,這在上面的 Lua 特性 中已經進行了介紹。要執行剛才創建的代碼塊,請運行命令 lua factorial.lua

$ lua factorial.lua
enter a number:
10
3628800

或者像在其他解釋性語言中一樣,我們可以在代碼頂部添加一行 “標識符”(#!),使這個腳本變成可執行的,然后像單獨命令一樣來運行這個文件:

$ (echo '#! /usr/bin/lua'; cat factorial.lua) > factorial 
$ chmod u+x factorial
$ ./factorial
enter a number:
4
24





回頁首


Lua 語言

Lua 具有現代腳本語言中的很多便利:作用域,控制結構,迭代器,以及一組用來處理字符串、產生及收集數據和執行數學計算操作的標準庫。在 Lua 5.0 Reference Manual 中有對 Lua 語言的完整介紹(請參見 參考資料)。

在 Lua 中,只有 具有類型,而變量的類型是動態決定的。Lua 中的基本類型(值)有 8 種: nil,布爾型,數字,字符串,函數,線程,表 以及 用戶數據。前 6 種類型基本上是自描述的(例外情況請參見上面的 Lua 特性 一節);最后兩個需要一點解釋。

Lua 表

在 Lua 中,表是用來保存所有數據的結構。實際上,表是 Lua 中惟一的 數據結構。我們可以將表作為數組、字典(也稱為散列聯合數組)、樹、記錄,等等。

與其他編程語言不同,Lua 表的概念不需要是異構的:表可以包含任何類型的組合,也可以包含類數組元素和類字典元素的混合體。另外,任何 Lua 值 —— 包括函數或其他表 —— 都可以用作字典元素的鍵值。

要對表進行瀏覽,請啟動 Lua 解釋器,并輸入清單 1 中的黑體顯示的代碼。


清單 1. 體驗 Lua 表
$ lua
> -- create an empty table and add some elements
> t1 = {}
> t1[1] = "moustache"
> t1[2] = 3
> t1["brothers"] = true

> -- more commonly, create the table and define elements
> all at once
> t2 = {[1] = "groucho", [3] = "chico", [5] = "harpo"}
> t3 = {[t1[1]] = t2[1], accent = t2[3], horn = t2[5]}
> t4 = {}
> t4[t3] = "the marx brothers"
> t5 = {characters = t2, marks = t3}
> t6 = {["a night at the opera"] = "classic"}

> -- make a reference and a string
> i = t3
> s = "a night at the opera"

> -- indices can be any Lua value
> print(t1[1], t4[t3], t6[s])
moustache   the marx brothers classic

> -- the phrase table.string is the same as table["string"]
> print(t3.horn, t3["horn"])
harpo   harpo

> -- indices can also be "multi-dimensional"
> print (t5["marks"]["horn"], t5.marks.horn)
harpo   harpo

> -- i points to the same table as t3
> = t4[i]
the marx brothers

> -- non-existent indices return nil values
> print(t1[2], t2[2], t5.films)
nil     nil     nil

>  -- even a function can be a key 
> t = {}
> function t.add(i,j)
>> return(i+j)
>> end
> print(t.add(1,2))
3
> print(t['add'](1,2))
3
>  -- and another variation of a function as a key 
> t = {}
> function v(x)
>> print(x)
>> end
> t[v] = "The Big Store"
> for key,value in t do key(value) end
The Big Store

正如我們可能期望的一樣,Lua 還提供了很多迭代器函數來對表進行處理。全局變量 table 提供了這些函數(是的,Lua 包就是表)。有些函數,例如 table.foreachi(),會期望一個從 1(數字 1)開始的連續整數范圍:

> table.foreachi(t1, print)
1 moustache
2 3

另外一些函數,例如 table.foreach(),會對整個表進行迭代:

> table.foreach(t2,print)
1       groucho
3       chico
5       harpo
> table.foreach(t1,print)
1       moustache
2       3
brothers        true

盡管有些迭代器對整數索引進行了優化,但是所有迭代器都只簡單地處理 (key, value) 對。

現在我們可以創建一個表 t,其元素是 {2, 4, 6, language="Lua", version="5", 8, 10, 12, web="www.lua.org"},然后運行 table.foreach(t, print) table.foreachi(t, print)。

用戶數據

由于 Lua 是為了嵌入到使用另外一種語言(例如 C 或 C++)編寫的宿主應用程序中,并與宿主應用程序協同工作,因此數據可以在 C 環境和 Lua 之間進行共享。正如 Lua 5.0 Reference Manual 所說,userdata 類型允許我們在 Lua 變量中保存任意的 C 數據。我們可以認為 userdata 就是一個字節數組 —— 字節可以表示指針、結構或宿主應用程序中的文件。

用戶數據的內容源自于 C,因此在 Lua 中不能對其進行修改。當然,由于用戶數據源自于 C,因此在 Lua 中也沒有對用戶數據預定義操作。不過我們可以使用另外一種 Lua 機制來創建對 userdata 進行處理的操作,這種機制稱為 元表(metatable)。

元表

由于表和用戶數據都非常靈活,因此 Lua 允許我們重載這兩種類型的數據的操作(不能重載其他 6 種類型)。元表 是一個(普通的)Lua 表,它將標準操作映射成我們提供的函數。元表的鍵值稱為事件;值(換而言之就是函數)稱為元方法。

函數 setmetatable()getmetatable() 分別對對象的元表進行修改和查詢。每個表和 userdada 對象都可以具有自己的元表。

例如,添加操作對應的事件是 __add。我們可以推斷這段代碼所做的事情么?

-- Overload the add operation
-- to do string concatenation
--
mt = {}

function String(string)
  return setmetatable({value = string or ''}, mt)
end

-- The first operand is a String table
-- The second operand is a string
-- .. is the Lua concatenate operator
--
function mt.__add(a, b)
  return String(a.value..b)
end

s = String('Hello')
print((s + ' There ' + ' World!').value )

這段代碼會產生下面的文本:

Hello There World!

函數 String() 接收一個字符串 string,將其封裝到一個表({value = s or ''})中,并將元表 mt 賦值給這個表。函數 mt.__add() 是一個元方法,它將字符串 b 添加到在 a.value 中找到的字符串后面 b 次。這行代碼 print((s + ' There ' + ' World!').value ) 調用這個元方法兩次。

__index 是另外一個事件。__index 的元方法每當表中不存在鍵值時就會被調用。下面是一個例子,它記住 (memoize) 函數的值:

-- code courtesy of Rici Lake, rici@ricilake.net
function Memoize(func, t)
  return setmetatable(
     t or {},
    {__index =
      function(t, k)
        local v = func(k);
        t[k] = v;
        return v;
        end
    }
  )
end

COLORS = {"red", "blue", "green", "yellow", "black"}
color = Memoize(
  function(node)
    return COLORS[math.random(1, table.getn(COLORS))]
    end
)

將這段代碼放到 Lua 解釋器中,然后輸入 print(color[1], color[2], color[1])。您將會看到類似于 blue black blue 的內容。

這段代碼接收一個鍵值 node,查找 node 指定的顏色。如果這種顏色不存在,代碼就會給 node 賦一個新的隨機選擇的顏色。否則,就返回賦給 node 的顏色。在前一種情況中,__index 元方法被執行一次以分配一個顏色。后一種情況比較簡單,所執行的是快速散列查找。

Lua 語言提供了很多其他功能強大的特性,所有這些特性都有很好的文檔進行介紹。在碰到問題或希望與專家進行交談時,請連接 Lua Users Chat Room IRC Channel(請參見 參考資料)獲得非常熱心的支持。





回頁首


嵌入和擴展

除了語法簡單并且具有功能強大的表結構之外,Lua 的強大功能使其可以與宿主語言混合使用。由于 Lua 與宿主語言的關系非常密切,因此 Lua 腳本可以對宿主語言的功能進行擴充。但是這種融合是雙贏的:宿主語言同時也可以對 Lua 進行擴充。舉例來說,C 函數可以調用 Lua 函數,反之亦然。

Lua 與宿主語言之間的這種共生關系的核心是宿主語言是一個虛擬堆棧。虛擬堆棧與實際堆棧類似,是一種后進先出(LIFO)的數據結構,可以用來臨時存儲函數參數和函數結果。要從 Lua 中調用宿主語言的函數(反之亦然),調用者會將一些值壓入堆棧中,并調用目標函數;被調用的函數會彈出這些參數(當然要對類型和每個參數的值進行驗證),對數據進行處理,然后將結果放入堆棧中。當控制返回給調用程序時,調用程序就可以從堆棧中提取出返回值。

實際上在 Lua 中使用的所有的 C 應用程序編程接口(API)都是通過堆棧來進行操作的。堆棧可以保存 Lua 的值,不過值的類型必須是調用程序和被調用者都知道的,特別是向堆棧中壓入的值和從堆棧中彈出的值更是如此(例如 lua_pushnil()lua_pushnumber()

清單 2 給出了一個簡單的 C 程序(節選自 參考資料Programming in Lua 一書的第 24 章),它實現了一個很小但卻功能完善的 Lua 解釋器。


清單 2. 一個簡單的 Lua 解釋器
 1 #include <stdio.h>
 2 #include <lua.h>
 3 #include <lauxlib.h>
 4 #include <lualib.h>
 5
 6 int main (void) {
 7   char buff[256];
 8   int error;
 9   lua_State *L = lua_open();   /* opens Lua */
10   luaopen_base(L);             /* opens the basic library */
11   luaopen_table(L);            /* opens the table library */
12   luaopen_io(L);               /* opens the I/O library */
13   luaopen_string(L);           /* opens the string lib. */
14   luaopen_math(L);             /* opens the math lib. */
15
16   while (fgets(buff, sizeof(buff), stdin) != NULL) {
17     error = luaL_loadbuffer(L, buff, strlen(buff), "line") ||
18             lua_pcall(L, 0, 0, 0);
19     if (error) {
20       fprintf(stderr, "%s", lua_tostring(L, -1));
21       lua_pop(L, 1);  /* pop error message from the stack */
22     }
23   }
24
25   lua_close(L);
26   return 0;
27 }

第 2 行到第 4 行包括了 Lua 的標準函數,幾個在所有 Lua 庫中都會使用的方便函數以及用來打開庫的函數。第 9 行創建了一個 Lua 狀態。所有的狀態最初都是空的;我們可以使用 luaopen_...() 將函數庫添加到狀態中,如第 10 行到第 14 行所示。

第 17 行和 luaL_loadbuffer() 會從 stdin 中以塊的形式接收輸入,并對其進行編譯,然后將其放入虛擬堆棧中。第 18 行從堆棧中彈出數據并執行之。如果在執行時出現了錯誤,就向堆棧中壓入一個 Lua 字符串。第 20 行訪問棧頂(棧頂的索引為 -1)作為 Lua 字符串,打印消息,然后從堆棧中刪除該值。

使用 C API,我們的應用程序也可以進入 Lua 狀態來提取信息。下面的代碼片段從 Lua 狀態中提取兩個全局變量:

..
if (luaL_loadfile(L, filename) || lua_pcall(L, 0, 0, 0))
  error(L, "cannot run configuration file: %s", lua_tostring(L, -1));

lua_getglobal(L, "width");
lua_getglobal(L, "height");
..
width = (int) lua_tonumber(L, -2);
height = (int) lua_tonumber(L, -1);
..

請再次注意傳輸是通過堆棧進行的。從 C 中調用任何 Lua 函數與這段代碼類似:使用 lua_getglobal() 來獲得函數,將參數壓入堆棧,調用 lua_pcall(),然后處理結果。如果 Lua 函數返回 n 個值,那么第一個值的位置在堆棧的 -n 處,最后一個值在堆棧中的位置是 -1。

反之,在 Lua 中調用 C 函數也與之類似。如果您的操作系統支持動態加載,那么 Lua 可以根據需要來動態加載并調用函數。(在必須使用靜態加載的操作系統中,可以對 Lua 引擎進行擴充,此時調用 C 函數時需要重新編譯 Lua。)





回頁首


結束語

Lua 是一種學習起來容易得難以置信的語言,但是它簡單的語法卻掩飾不了其強大的功能:這種語言支持對象(這與 Perl 類似),元表使表類型具有相當程度的可伸展性,C API 允許我們在腳本和宿主語言之間進行更好的集成和擴充。Lua 可以在 C、C++、C#、Java? 和 Python 語言中使用。

在創建另外一個配置文件或資源格式(以及相應的處理程序)之前,請嘗試一下 Lua。Lua 語言及其社區非常健壯,具有創新精神,隨時準備好提供幫助。





回頁首


參考資料

學習

獲得產品和技術
  • 下載 Lua 5.0.2Lua 5.1 源代碼,從頭開始編譯 Lua。

  • Lua-users wiki 上,瀏覽很多預先構建的、可安裝的 Lua 二進制文件。

  • LuaForge 上可以找到大量的代碼庫,包括很多語言綁定和專門的計算庫。

  • 訂購免費的 SEK for Linux ,這有兩張 DVD,包括最新的 IBM for Linux 試用軟件,包括 DB2?、Lotus?、Rational?、Tivoli? 和 WebSphere?。

  • 在您的下一個開發項目中采用 IBM 試用軟件,這可以從 developerWorks 直接下載。


討論






關于作者

Martin Streicher 是 Linux Magazine 的首席編輯。他在普渡大學獲得了計算機碩士學位,自 1982 年以來,就一直在使用 Pascal、C、Perl、Java 以及(最近使用的)Ruby 編程語言編寫類 Unix 系統。

posted on 2006-11-18 09:39 李錦俊(mybios) 閱讀(1257) 評論(0)  編輯 收藏 引用 所屬分類: LUA
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            99日韩精品| 国产精品久久久久久久久久免费| 亚洲电影免费观看高清完整版在线观看 | 久久免费一区| 亚洲欧美一区二区三区在线| 亚洲欧美另类在线| 亚洲永久免费| 久久影视精品| 欧美午夜精品理论片a级按摩 | 亚洲视频一二区| 午夜精品一区二区在线观看| 久久久久久久一区二区| 欧美激情精品| 国产午夜精品美女视频明星a级| 黄色精品一区| 国产精品99久久不卡二区| 久久se精品一区精品二区| 欧美成人午夜免费视在线看片| 亚洲另类黄色| 久久精品国产亚洲一区二区| 欧美日韩国产不卡| 国产一区二区三区的电影 | 日韩亚洲视频| 久久不射中文字幕| 亚洲人成在线播放| 久久久精品免费视频| 国产精品videosex极品| 亚洲第一精品夜夜躁人人躁| 亚洲欧美日韩中文播放| 亚洲国产美女| 久久久97精品| 国产女主播在线一区二区| 亚洲另类春色国产| 美女视频一区免费观看| 亚洲影院在线观看| 欧美日韩在线精品一区二区三区| 狠狠色丁香久久婷婷综合丁香 | 另类天堂视频在线观看| 在线视频你懂得一区| 欧美成人综合一区| 亚洲电影免费观看高清完整版在线观看 | 亚洲中字黄色| 日韩一级成人av| 牛牛影视久久网| 在线看片欧美| 久久久中精品2020中文| 香蕉久久久久久久av网站 | 一区二区av在线| 欧美h视频在线| 亚洲综合三区| 国产精品伦一区| 一区二区免费在线视频| 亚洲国产1区| 老司机凹凸av亚洲导航| 精品91在线| 久久亚洲综合| 欧美中文字幕精品| 国内精品国语自产拍在线观看| 午夜在线成人av| 亚洲女爱视频在线| 国产午夜精品一区二区三区欧美 | 亚洲国产精品999| 老司机精品视频网站| 亚洲欧美亚洲| 国产一区二区观看| 美脚丝袜一区二区三区在线观看| 久久国产福利| 91久久香蕉国产日韩欧美9色| 欧美激情视频免费观看| 欧美成人午夜| 中文av一区特黄| 亚洲性xxxx| 韩日欧美一区| 亚洲第一区在线| 欧美午夜精品久久久久久人妖 | 美女视频网站黄色亚洲| 免费亚洲电影在线| 夜夜夜久久久| 亚洲欧美伊人| 亚洲高清资源综合久久精品| 91久久精品一区二区别| 欧美午夜理伦三级在线观看| 欧美午夜视频一区二区| 亚洲欧美视频在线| 久久精品成人| 一区二区欧美日韩视频| 性娇小13――14欧美| 亚洲欧洲日产国产综合网| 一区二区三区www| 一区在线影院| 在线亚洲欧美专区二区| 激情成人亚洲| 一区二区三区四区五区在线| 极品尤物久久久av免费看| 亚洲精品国产无天堂网2021| 国产欧美韩国高清| 亚洲国内高清视频| 国产一本一道久久香蕉| 亚洲精品中文字幕女同| 欧美激情1区2区3区| 亚洲综合精品四区| 欧美亚洲日本国产| 亚洲美女福利视频网站| 欧美一站二站| 亚洲一区二区三区免费视频| 久久在线免费观看| 欧美专区福利在线| 欧美日韩高清不卡| 免费亚洲网站| 国产婷婷成人久久av免费高清| 亚洲日本中文字幕区| 在线观看日韩一区| 午夜伦欧美伦电影理论片| 一区二区三区四区五区精品| 久久综合九色综合欧美狠狠| 久久精品青青大伊人av| 欧美日韩一区二区三区四区在线观看| 久久免费国产精品1| 国产伦精品一区二区三区视频孕妇| 亚洲激情成人| 亚洲国产一区二区三区青草影视| 欧美一区二区三区在线视频| 午夜国产精品影院在线观看| 欧美日韩日本国产亚洲在线| 亚洲黄色影院| 亚洲精品视频一区| 欧美成人a∨高清免费观看| 久久亚洲欧美| 国语自产精品视频在线看一大j8 | 狠狠入ady亚洲精品| 亚洲欧美日韩精品在线| 亚洲欧美日韩国产成人| 欧美日韩在线视频一区二区| 亚洲日韩视频| 一区二区三区高清视频在线观看| 欧美成人精品一区| 亚洲欧洲综合| 一区二区三区视频免费在线观看| 欧美精品videossex性护士| 亚洲精品国产欧美| 国产精品99久久久久久宅男| 欧美日韩不卡一区| 一区二区高清在线观看| 亚洲欧美日韩国产一区二区| 国产精品亚洲网站| 欧美一区二区三区在线观看视频| 久久精品亚洲| 在线观看日韩一区| 欧美美女bb生活片| 亚洲午夜精品久久久久久app| 欧美一区91| 在线看无码的免费网站| 欧美好骚综合网| 亚洲视频在线观看三级| 久久久久久久久久久一区 | 国产精品理论片| 欧美一区二区三区的| 免费在线欧美视频| 一区二区动漫| 国产区精品视频| 麻豆精品精华液| 亚洲卡通欧美制服中文| 欧美伊人久久大香线蕉综合69| 国产精品专区一| 亚洲黄色在线视频| 欧美日韩精品一区二区天天拍小说| 一本大道久久a久久综合婷婷| 性xx色xx综合久久久xx| 在线不卡中文字幕播放| 欧美日韩精品一本二本三本| 亚洲欧美日韩中文视频| 亚洲激情成人网| 久久精品一区蜜桃臀影院 | 女仆av观看一区| 亚洲一区二区免费| 欧美大片第1页| 亚洲综合大片69999| 在线成人h网| 国产精品久久激情| 免费观看成人www动漫视频| 亚洲淫性视频| 亚洲高清久久久| 久久久精品国产免费观看同学| 日韩一级黄色片| 在线不卡中文字幕| 国产三区二区一区久久| 欧美日韩精品免费观看视频完整 | 国产精品免费视频xxxx| 美女91精品| 午夜免费在线观看精品视频| 亚洲精品永久免费精品| 免费视频一区| 久久久综合网| 午夜性色一区二区三区免费视频| 91久久国产综合久久蜜月精品| 国产亚洲精品bv在线观看| 国产精品久久一区主播| 欧美视频亚洲视频| 欧美三级在线视频| 欧美另类99xxxxx|