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

隨筆-341  評論-2670  文章-0  trackbacks-0
    說到底Kernel FP是一個腳本引擎,所以是需要API的。接下來的代碼用來加載一些Kernel FP代碼文件,并執行main函數。

    首先,我們讀入的文件是一個目錄,目錄記錄了一個Kernel FP程序所需要的所有代碼文件:Project.txt
1 Startup.txt
2 SysUtils.txt
3 List.txt

    讀入文件之后將文件按行分割:
1     VUnicodeString TestDataPath=VFileName(GetConsole()->GetAppPath()).MakeAbsolute(L"..\\TestData\\").GetStrW();
2     VUnicodeString TestOutput;
3     VL_UniStrings CodeFiles;
4     {
5         VL_FileStream Stream(TestDataPath+L"Project.txt",VL_FileStream::vfomRead);
6         VUnicodeString Project=ReadText(&Stream);
7         CodeFiles.SetText(Project);
8     }

    現在CodeFiles已經有3個文件的文件名了,現在需要聲明一些Kernel FP對象,然后加載這些文件。文件在語法分析的時候出錯,程序需要打印出錯誤信息:
 1     VL_KfpSymbol Symbol;
 2     Symbol.AddUnit(CreateConsoleUnit());
 3     VBool ErrorOccurred=false;
 4     for(VInt i=0;i<CodeFiles.GetCount();i++)
 5     {
 6         VL_FileStream Stream(TestDataPath+CodeFiles[i],VL_FileStream::vfomRead);
 7         VUnicodeString TestCode=ReadText(&Stream);
 8 
 9         VL_KfpError::List Errors;
10         Symbol.AddUnit(TestCode,Errors);
11         if(Errors.GetCount())
12         {
13             TestOutput+=L"文件\""+VUnicodeString(CodeFiles[i])+L"\"含有語法錯誤:\r\n";
14             TestOutput+=ToString(Errors);
15             ErrorOccurred=true;
16         }
17     }

    收集了所有代碼文件之后,需要先進行一次編譯,在內部生成運行時所需要的assembly。當然,API不允許外部訪問內部信息:
 1     if(!ErrorOccurred)
 2     {
 3         VL_KfpError::List Errors;
 4         Symbol.PreCompile(Errors);
 5         if(Errors.GetCount())
 6         {
 7             TestOutput+=L"生成符號表時發生錯誤\r\n";
 8             TestOutput+=ToString(Errors);
 9             ErrorOccurred=true;
10         }
11     }

    如果到這一步仍然沒有問題的話,我們可以創建VL_KfpMachine了。這個Machine提供了訪問程序公布的一些函數和對象。
1     if(!ErrorOccurred)
2     {
3         VL_KfpMachine::Ptr Machine=Symbol.CreateMachine();
4         RunProgram(Machine);
5     }
6     else
7     {
8         GetConsole()->Write(TestOutput);
9     }

    中間有一步出錯的話,控制臺窗口上會顯示所有錯誤信息。在上面我們發現有一個ToString函數將一個錯誤列表轉換成字符串:
 1 VUnicodeString ToString(VL_KfpError::List& Errors)
 2 {
 3     VUnicodeString Result=L"";
 4     for(VInt i=0;i<Errors.GetCount();i++)
 5     {
 6         Result+=L"錯誤["+VUnicodeString(i+1)+L"]\t模塊:"+Errors[i]->Module+L"\t行號:"+VUnicodeString(Errors[i]->Token.LineInFile+1)+L"\r\n";
 7         Result+=L"信息:"+Errors[i]->Message+L"\r\n";
 8     }
 9     return Result;
10 }

    接下來是RunProgram函數了。這個函數獲得startup.main,我們假設main函數是放在startup命名空間下面的。當然,如果不確定命名空間的話,我們可以通過其他豐富的查詢手段來獲得我們需要的函數:
 1 void RunProgram(VL_KfpMachine::Ptr Machine)
 2 {
 3     ConsolePlugin Plugin;
 4     Machine->AddPlugin(&Plugin,false);
 5 
 6     VInt Index=0;
 7     VInt ID=Machine->GetFunctionFirstIdByName(L"startup.main");
 8     if(ID==-1)
 9     {
10         break;
11     }
12     else
13     {
14         VL_KfpValue MainFunction=Machine->CreateFunction(ID);
15         if(MainFunction.IsInvokable())
16         {
17             MainFunction=Machine->CreateEvaluableIO(MainFunction);
18         }
19         GetConsole()->Write(L"返回值:"+MainFunction.GetDebugString()+L"\r\n");
20     }
21 }

    這里面有兩個問題。控制臺程序是要有read和write的API的。所以我們這里提供了兩個接口。首先,剛才在編譯Kernel FP之前有一句代碼添加read和write的符號:
1     VL_KfpSymbol Symbol;
2     Symbol.AddUnit(CreateConsoleUnit());

    CreateConsoleUnit代碼如下:
 1 KfpUnit CreateConsoleUnit()
 2 {
 3     KfpUnit Unit(L"console");
 4     Unit.AddImport(L"system");
 5     //func read :: IO string alias "KfpType::read"
 6     Unit.AddFuncAlias(KfpDecl(L"read"),
 7         KfpType(L"IO")<<KfpType(L"string"),
 8         L"console::read"
 9         );
10     //func write :: string -> IO void alias "KfpType::write"
11     Unit.AddFuncAlias(KfpDecl(L"write"),
12         KfpType(L"string")>>(KfpType(L"IO")<<KfpType(L"void")),
13         L"console::write"
14         );
15     //func writeln :: string -> IO void alias "KfpType::writeln"
16     Unit.AddFuncAlias(KfpDecl(L"writeln"),
17         KfpType(L"string")>>(KfpType(L"IO")<<KfpType(L"void")),
18         L"console::writeln"
19         );
20     return Unit;
21 }

    有了這些符號還是不夠的。程序運行的過程中,調用了這些函數的話,仍然需要我們處理。所以我們還得實現一個插件來執行這三個函數:
 1 class ConsolePlugin : public VL_KfpPlugin
 2 {
 3 protected:
 4     VInt        FuncRead;
 5     VInt        FuncWrite;
 6     VInt        FuncWriteLine;
 7 public:
 8     ConsolePlugin()
 9     {
10         FuncRead=-1;
11         FuncWrite=-1;
12         FuncWriteLine=-1;
13     }
14 
15     void DestroyUserValue(VL_Base* Object)
16     {
17     }
18 
19     void ConnectMachine()
20     {
21         FuncRead        =RegisterExternalFunction(L"console::read",        1);
22         FuncWrite        =RegisterExternalFunction(L"console::write",    2);
23         FuncWriteLine    =RegisterExternalFunction(L"console::writeln",    2);
24     }
25 
26     VUnicodeString GetName()
27     {
28         return L"Vczh KernelFP Demo Console Plugin";
29     }
30 
31     VLE_KfpPluginResult Invoke(VInt ExternalID , InParams& In , OutParams& Out)
32     {
33         if(ExternalID==FuncWrite || ExternalID==FuncWriteLine)
34         {
35             if(In.Parameters.GetCount()==2)
36             {
37                 VUnicodeString String;
38                 if(In.Parameters[0].GetString(String))
39                 {
40                     if(ExternalID==FuncWrite)
41                     {
42                         GetConsole()->Write(String);
43                     }
44                     else
45                     {
46                         GetConsole()->Write(String+L"\r\n");
47                     }
48                     Out.Result=GetMachine()->CreateIOSuccess(GetMachine()->CreateVoid());
49                     return vkprSuccess;
50                 }
51                 else if(In.Parameters[0].GetErrorMessage(Out.ErrorMessage))
52                 {
53                     return vkprFail;
54                 }
55             }
56             Out.ErrorMessage=
57                 (ExternalID==FuncWrite?
58                 L"write函數的參數必須是一個string和一個IOEnv。":
59                 L"writeln函數的參數必須是一個string和一個IOEnv。"
60                 );
61             return vkprFail;
62         }
63         if(ExternalID==FuncRead)
64         {
65             if(In.Parameters.GetCount()==1)
66             {
67                 VUnicodeString String;
68                 GetConsole()->Read(String);
69                 Out.Result=GetMachine()->CreateIOSuccess(GetMachine()->CreateString(String));
70                 return vkprSuccess;
71             }
72             else
73             {
74                 Out.ErrorMessage=L"read函數的參數必須是一個IOEnv。";
75                 return vkprFail;
76             }
77         }
78         return vkprPass;
79     }
80 };

    插件在ConnectMachine的時候,注冊函數名和參數個數,然后返回一個ID供Invoke使用。跟IO有關的函數都是IO類型的。譬如read是IO string,而write是string->IO void。IO類型的函數都多了一個參數用于其他用途,所以read、write和writeln的參數個數才會是1、2和2。

    Kernel FP API還提供了一些輔助函數用于創建或訪問IO對象。實際上只要插件的行為與插件所聲明的函數類型一致的話,基本上是不會有問題的。程序到這里就結束了,讓我們看一看system(自動加載)模塊與console(CreateConsoleUnit)模塊生成的代碼:

    首先是system模塊:
  1 module system
  2 
  3 type void
  4 
  5 type int
  6 
  7 type float
  8 
  9 type char
 10 
 11 data bool = (false | true)
 12 
 13 data list T = (empty | (list T (list T)))
 14 
 15 data maybe Ts Tf = ((success Ts) | (fail Tf))
 16 
 17 type string = (list char)
 18 
 19 data pair T1 T2 = (pair T1 T2)
 20 
 21 data IOError = (ioemessage string)
 22 
 23 type IOEnv
 24 
 25 type IO T = (IOEnv -> (maybe (pair T IOEnv) IOError))
 26 
 27 func iadd :: (int -> (int -> int)) alias "kernelfp::iadd"
 28 
 29 func isub :: (int -> (int -> int)) alias "kernelfp::isub"
 30 
 31 func imul :: (int -> (int -> int)) alias "kernelfp::imul"
 32 
 33 func idiv :: (int -> (int -> int)) alias "kernelfp::idiv"
 34 
 35 func imod :: (int -> (int -> int)) alias "kernelfp::imod"
 36 
 37 func igt :: (int -> (int -> bool)) alias "kernelfp::igt"
 38 
 39 func ilt :: (int -> (int -> bool)) alias "kernelfp::ilt"
 40 
 41 func iequ :: (int -> (int -> bool)) alias "kernelfp::iequ"
 42 
 43 func iegt :: (int -> (int -> bool)) alias "kernelfp::iegt"
 44 
 45 func ielt :: (int -> (int -> bool)) alias "kernelfp::ielt"
 46 
 47 func ineq :: (int -> (int -> bool)) alias "kernelfp::ineq"
 48 
 49 func fadd :: (float -> (float -> float)) alias "kernelfp::fadd"
 50 
 51 func fsub :: (float -> (float -> float)) alias "kernelfp::fsub"
 52 
 53 func fmul :: (float -> (float -> float)) alias "kernelfp::fmul"
 54 
 55 func fdiv :: (float -> (float -> float)) alias "kernelfp::fdiv"
 56 
 57 func fmod :: (float -> (float -> float)) alias "kernelfp::fmod"
 58 
 59 func fgt :: (float -> (float -> bool)) alias "kernelfp::fgt"
 60 
 61 func flt :: (float -> (float -> bool)) alias "kernelfp::flt"
 62 
 63 func fequ :: (float -> (float -> bool)) alias "kernelfp::fequ"
 64 
 65 func fegt :: (float -> (float -> bool)) alias "kernelfp::fegt"
 66 
 67 func felt :: (float -> (float -> bool)) alias "kernelfp::felt"
 68 
 69 func fneq :: (float -> (float -> bool)) alias "kernelfp::fneq"
 70 
 71 func isnan :: (float -> bool) alias "kernelfp::isnan"
 72 
 73 func isinf :: (float -> bool) alias "kernelfp::isinf"
 74 
 75 func chr :: (int -> char) alias "kernelfp::chr"
 76 
 77 func ord :: (char -> int) alias "kernelfp::ord"
 78 
 79 func cgt :: (char -> (char -> bool)) alias "kernelfp::cgt"
 80 
 81 func clt :: (char -> (char -> bool)) alias "kernelfp::clt"
 82 
 83 func cequ :: (char -> (char -> bool)) alias "kernelfp::cequ"
 84 
 85 func cegt :: (char -> (char -> bool)) alias "kernelfp::cegt"
 86 
 87 func celt :: (char -> (char -> bool)) alias "kernelfp::celt"
 88 
 89 func cneq :: (char -> (char -> bool)) alias "kernelfp::cneq"
 90 
 91 func ceil :: (float -> float) alias "kernelfp::ceil"
 92 
 93 func floor :: (float -> float) alias "kernelfp::floor"
 94 
 95 func trunc :: (float -> float) alias "kernelfp::trunc"
 96 
 97 func itof :: (int -> float) alias "kernelfp::itof"
 98 
 99 func ftoi :: (float -> int) alias "kernelfp::ftoi"
100 
101 func abs :: (float -> float) alias "kernelfp::abs"
102 
103 func exp :: (float -> float) alias "kernelfp::exp"
104 
105 func ln :: (float -> float) alias "kernelfp::ln"
106 
107 func lg :: (float -> float) alias "kernelfp::lg"
108 
109 func sqr :: (float -> float) alias "kernelfp::sqr"
110 
111 func pow :: (float -> (float -> float)) alias "kernelfp::pow"
112 
113 func sin :: (float -> float) alias "kernelfp::sin"
114 
115 func cos :: (float -> float) alias "kernelfp::cos"
116 
117 func tan :: (float -> float) alias "kernelfp::tan"
118 
119 func asin :: (float -> float) alias "kernelfp::asin"
120 
121 func acos :: (float -> float) alias "kernelfp::acos"
122 
123 func atan :: (float -> float) alias "kernelfp::atan"
124 
125 func atan2 :: (float -> (float -> float)) alias "kernelfp::atan2"
126 
127 func itoa :: (int -> string) alias "kernelfp::itoa"
128 
129 func ftoa :: (float -> string) alias "kernelfp::ftoa"
130 
131 func atoi :: (string -> (maybe int string)) alias "kernelfp::atoi"
132 
133 func atof :: (string -> (maybe float string)) alias "kernelfp::atof"
134 
135 func iovoid :: (IO void) alias "kernelfp::iovoid"
136 
137 func (>>>) T1 T2 :: ((IO T1) -> ((IO T2) -> (IO T2))) alias "kernelfp::(>>>)"
138 
139 func (>>=) T1 T2 :: ((IO T1) -> ((T1 -> (IO T2)) -> (IO T2))) alias "kernelfp::(>>=)"
140 

    然后是console模塊:
1 module console
2 import system
3 
4 func read :: (IO string) alias "console::read"
5 
6 func write :: (string -> (IO void)) alias "console::write"
7 
8 func writeln :: (string -> (IO void)) alias "console::writeln"
9 

    一個將Kernel FP代碼當成命令行程序執行的宿主程序已經完成了。現在讓我們看看完整的代碼:
  1 #include "..\..\..\..\VL++\Library\Platform\VL_Console.h"
  2 #include "..\..\..\..\VL++\Library\Script\KernelFP\VL_KFPScript.h"
  3 #include "..\..\..\..\VL++\Library\Data\VL_Stream.h"
  4 #include "..\..\..\..\VL++\Library\Data\VL_System.h"
  5 #include "..\..\..\..\VL++\Library\Data\VL_Uniop.h"
  6 
  7 using namespace vl;
  8 using namespace vl::platform;
  9 using namespace vl::kernalfp;
 10 using namespace vl::stream;
 11 using namespace vl::system;
 12 using namespace vl::uniop;
 13 
 14 VUnicodeString ToString(VL_KfpError::List& Errors)
 15 {
 16     VUnicodeString Result=L"";
 17     for(VInt i=0;i<Errors.GetCount();i++)
 18     {
 19         Result+=L"錯誤["+VUnicodeString(i+1)+L"]\t模塊:"+Errors[i]->Module+L"\t行號:"+VUnicodeString(Errors[i]->Token.LineInFile+1)+L"\r\n";
 20         Result+=L"信息:"+Errors[i]->Message+L"\r\n";
 21     }
 22     return Result;
 23 }
 24 
 25 KfpUnit CreateConsoleUnit()
 26 {
 27     KfpUnit Unit(L"console");
 28     Unit.AddImport(L"system");
 29     //func read :: IO string alias "KfpType::read"
 30     Unit.AddFuncAlias(KfpDecl(L"read"),
 31         KfpType(L"IO")<<KfpType(L"string"),
 32         L"console::read"
 33         );
 34     //func write :: string -> IO void alias "KfpType::write"
 35     Unit.AddFuncAlias(KfpDecl(L"write"),
 36         KfpType(L"string")>>(KfpType(L"IO")<<KfpType(L"void")),
 37         L"console::write"
 38         );
 39     //func writeln :: string -> IO void alias "KfpType::writeln"
 40     Unit.AddFuncAlias(KfpDecl(L"writeln"),
 41         KfpType(L"string")>>(KfpType(L"IO")<<KfpType(L"void")),
 42         L"console::writeln"
 43         );
 44     return Unit;
 45 }
 46 
 47 class ConsolePlugin : public VL_KfpPlugin
 48 {
 49 protected:
 50     VInt        FuncRead;
 51     VInt        FuncWrite;
 52     VInt        FuncWriteLine;
 53 public:
 54     ConsolePlugin()
 55     {
 56         FuncRead=-1;
 57         FuncWrite=-1;
 58         FuncWriteLine=-1;
 59     }
 60 
 61     void DestroyUserValue(VL_Base* Object)
 62     {
 63     }
 64 
 65     void ConnectMachine()
 66     {
 67         FuncRead        =RegisterExternalFunction(L"console::read",        1);
 68         FuncWrite        =RegisterExternalFunction(L"console::write",    2);
 69         FuncWriteLine    =RegisterExternalFunction(L"console::writeln",    2);
 70     }
 71 
 72     VUnicodeString GetName()
 73     {
 74         return L"Vczh KernelFP Demo Console Plugin";
 75     }
 76 
 77     VLE_KfpPluginResult Invoke(VInt ExternalID , InParams& In , OutParams& Out)
 78     {
 79         if(ExternalID==FuncWrite || ExternalID==FuncWriteLine)
 80         {
 81             if(In.Parameters.GetCount()==2)
 82             {
 83                 VUnicodeString String;
 84                 if(In.Parameters[0].GetString(String))
 85                 {
 86                     if(ExternalID==FuncWrite)
 87                     {
 88                         GetConsole()->Write(String);
 89                     }
 90                     else
 91                     {
 92                         GetConsole()->Write(String+L"\r\n");
 93                     }
 94                     Out.Result=GetMachine()->CreateIOSuccess(GetMachine()->CreateVoid());
 95                     return vkprSuccess;
 96                 }
 97                 else if(In.Parameters[0].GetErrorMessage(Out.ErrorMessage))
 98                 {
 99                     return vkprFail;
100                 }
101             }
102             Out.ErrorMessage=
103                 (ExternalID==FuncWrite?
104                 L"write函數的參數必須是一個string和一個IOEnv。":
105                 L"writeln函數的參數必須是一個string和一個IOEnv。"
106                 );
107             return vkprFail;
108         }
109         if(ExternalID==FuncRead)
110         {
111             if(In.Parameters.GetCount()==1)
112             {
113                 VUnicodeString String;
114                 GetConsole()->Read(String);
115                 Out.Result=GetMachine()->CreateIOSuccess(GetMachine()->CreateString(String));
116                 return vkprSuccess;
117             }
118             else
119             {
120                 Out.ErrorMessage=L"read函數的參數必須是一個IOEnv。";
121                 return vkprFail;
122             }
123         }
124         return vkprPass;
125     }
126 };
127 
128 void RunProgram(VL_KfpMachine::Ptr Machine)
129 {
130     ConsolePlugin Plugin;
131     Machine->AddPlugin(&Plugin,false);
132 
133     VInt Index=0;
134     VInt ID=Machine->GetFunctionFirstIdByName(L"startup.main");
135     if(ID==-1)
136     {
137         break;
138     }
139     else
140     {
141         VL_KfpValue MainFunction=Machine->CreateFunction(ID);
142         if(MainFunction.IsInvokable())
143         {
144             MainFunction=Machine->CreateEvaluableIO(MainFunction);
145         }
146         GetConsole()->Write(L"返回值:"+MainFunction.GetDebugString()+L"\r\n");
147     }
148 }
149 
150 void vlmain()
151 {
152     GetConsole()->SetTitle(L"Vczh Kernal FP");
153     GetConsole()->SetPauseOnExit(true);
154     GetConsole()->SetTestMemoryLeaks(true);
155 
156     VUnicodeString TestDataPath=VFileName(GetConsole()->GetAppPath()).MakeAbsolute(L"..\\TestData\\").GetStrW();
157     VUnicodeString TestOutput;
158     VL_UniStrings CodeFiles;
159     {
160         VL_FileStream Stream(TestDataPath+L"Project.txt",VL_FileStream::vfomRead);
161         VUnicodeString Project=ReadText(&Stream);
162         CodeFiles.SetText(Project);
163     }
164 
165     VL_KfpSymbol Symbol;
166     Symbol.AddUnit(CreateConsoleUnit());
167     VBool ErrorOccurred=false;
168     for(VInt i=0;i<CodeFiles.GetCount();i++)
169     {
170         VL_FileStream Stream(TestDataPath+CodeFiles[i],VL_FileStream::vfomRead);
171         VUnicodeString TestCode=ReadText(&Stream);
172 
173         VL_KfpError::List Errors;
174         Symbol.AddUnit(TestCode,Errors);
175         if(Errors.GetCount())
176         {
177             TestOutput+=L"文件\""+VUnicodeString(CodeFiles[i])+L"\"含有語法錯誤:\r\n";
178             TestOutput+=ToString(Errors);
179             ErrorOccurred=true;
180         }
181     }
182     if(!ErrorOccurred)
183     {
184         VL_KfpError::List Errors;
185         Symbol.PreCompile(Errors);
186         if(Errors.GetCount())
187         {
188             TestOutput+=L"生成符號表時發生錯誤\r\n";
189             TestOutput+=ToString(Errors);
190             ErrorOccurred=true;
191         }
192     }
193     if(!ErrorOccurred)
194     {
195         VL_KfpMachine::Ptr Machine=Symbol.CreateMachine();
196         RunProgram(Machine);
197     }
198     else
199     {
200         GetConsole()->Write(TestOutput);
201     }
202 }
posted on 2008-12-17 19:15 陳梓瀚(vczh) 閱讀(1649) 評論(1)  編輯 收藏 引用 所屬分類: 腳本技術

評論:
# re: 使用Kernel FP API實現一個運行Kernel FP代碼的控制臺程序 2008-12-18 06:29 | dell筆記本
收藏,謝謝  回復  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久久久久欧美| 欧美一区二区成人6969| 国产精品theporn88| 久久久人成影片一区二区三区观看 | 国产精品女同互慰在线看| 欧美亚洲不卡| 国产精品久久精品日日| 国产美女精品视频免费观看| 国产免费亚洲高清| 在线观看日韩av电影| 亚洲欧洲另类| 亚洲一区尤物| 久久免费高清视频| 亚洲人成在线播放| 亚洲国产老妈| 国产精品99久久久久久www| 午夜精品一区二区三区在线视 | 欧美华人在线视频| 国产精品私房写真福利视频| 国产亚洲激情在线| 亚洲国产一区在线观看| 亚洲日本免费| 国产在线国偷精品产拍免费yy| 在线观看91精品国产麻豆| 亚洲精品国产精品国自产观看浪潮 | 亚洲一区二区三区精品动漫| 久久久91精品国产一区二区精品| 欧美xart系列在线观看| 国产精品毛片a∨一区二区三区|国| 国产一区二区欧美日韩| 在线视频日韩| 欧美激情黄色片| 午夜一级在线看亚洲| 欧美久久久久久久久| 一区国产精品| 欧美在线视频观看免费网站| 亚洲人成人77777线观看| 久久久天天操| 国语自产精品视频在线看一大j8 | 99精品国产热久久91蜜凸| 久久人人爽人人| 国产日韩一级二级三级| 在线视频亚洲欧美| 91久久国产精品91久久性色| 欧美一区二区在线免费观看| 国产精品久久久久久久久借妻| 亚洲第一在线视频| 麻豆乱码国产一区二区三区| 午夜日韩在线| 国产精品私拍pans大尺度在线| 99国产一区| 亚洲大胆美女视频| 免费不卡视频| 91久久精品久久国产性色也91| 久久综合给合久久狠狠狠97色69| 中国av一区| 国产精品三上| 久久国产精品99久久久久久老狼| 亚洲免费视频网站| 国产视频一区二区在线观看 | 亚洲激情国产| 欧美成年人网站| 亚洲激情综合| 亚洲国产精品一区| 欧美精品在线观看| 一区二区三区色| 一本色道久久综合狠狠躁篇怎么玩 | 亚洲人成在线影院| 欧美激情一区二区三区蜜桃视频| 久久人91精品久久久久久不卡 | 国内外成人在线视频| 久久亚洲色图| 美女图片一区二区| 99精品国产在热久久婷婷| 亚洲国产成人av在线| 欧美成人亚洲| 在线一区观看| 亚洲专区在线| 一区二区三区在线看| 亚洲第一视频| 欧美日韩一区二区三区视频| 亚洲欧美日韩专区| 欧美怡红院视频一区二区三区| 国产在线一区二区三区四区 | 国产原创一区二区| 麻豆成人91精品二区三区| 噜噜噜躁狠狠躁狠狠精品视频| 亚洲精品美女91| 一区二区三区国产精华| 国产午夜亚洲精品不卡| 亚洲成色精品| 国产精品三级视频| 欧美成人免费在线视频| 欧美日韩精品在线播放| 久久久精品国产99久久精品芒果| 久久偷窥视频| 亚洲欧美另类国产| 老司机精品久久| 亚洲午夜精品久久久久久浪潮| 欧美一级视频精品观看| 91久久精品一区| 亚洲伊人久久综合| 亚洲国产精品毛片| 亚洲欧美一区二区原创| 亚洲精品视频在线播放| 欧美专区在线观看| 亚洲视频大全| 欧美1级日本1级| 久久久7777| 欧美三级在线视频| 欧美成人在线网站| 国产一区二区三区在线观看免费| 亚洲经典三级| 精品成人乱色一区二区| 亚洲一区二区三区国产| 亚洲美女av黄| 久久久xxx| 久久成人国产| 国产精品美女主播| 亚洲精品久久视频| 91久久黄色| 久久久www免费人成黑人精品| 欧美高清不卡| 伊人春色精品| 在线视频精品一区| 一区二区91| 欧美aa在线视频| 另类亚洲自拍| 国产一区二区三区网站| 亚洲欧美日韩精品久久| 亚洲夜间福利| 欧美午夜三级| 亚洲欧洲精品一区二区| 亚洲国产精品嫩草影院| 老司机免费视频一区二区| 久久久人成影片一区二区三区观看| 国产精品视频yy9299一区| 99国产精品99久久久久久| 亚洲美女啪啪| 欧美精品一区二区三区高清aⅴ| 亚洲国产精品毛片| 日韩视频精品在线| 欧美日本乱大交xxxxx| 亚洲区在线播放| 一区二区三区视频在线播放| 欧美日韩色一区| 亚洲一区二区免费视频| 午夜精品亚洲| 国产在线成人| 蜜桃久久av一区| 日韩亚洲一区二区| 亚洲一级网站| 国产欧美日韩综合一区在线播放 | 久久亚洲图片| 激情欧美日韩一区| 麻豆久久久9性大片| 欧美成人在线免费观看| 亚洲日韩成人| 国产精品劲爆视频| 性感少妇一区| 欧美sm重口味系列视频在线观看| 亚洲人成人一区二区在线观看| 欧美福利视频一区| 夜夜爽99久久国产综合精品女不卡 | 亚洲欧美日韩综合aⅴ视频| 国产一区二区三区久久| 久久精品久久99精品久久| 欧美韩日一区| 香蕉久久国产| 亚洲国产精品久久久久婷婷老年| 欧美视频一区二区在线观看 | 欧美三级中文字幕在线观看| 亚洲欧美视频在线观看| 欧美黄色成人网| 亚洲欧美在线另类| 在线不卡亚洲| 国产精品蜜臀在线观看| 鲁大师影院一区二区三区| 99国产精品99久久久久久粉嫩| 久久国产精彩视频| 日韩视频一区二区三区| 国产一级揄自揄精品视频| 欧美人交a欧美精品| 午夜国产一区| 亚洲经典在线看| 久久伊人亚洲| 一本到高清视频免费精品| 亚洲国产三级| 国产精品激情电影| 蜜桃av噜噜一区二区三区| 亚洲欧美日韩国产综合| 亚洲美女视频| 欧美国产激情二区三区| 久久久久久国产精品一区| 中文在线一区| 99视频超级精品| 亚洲国产综合在线看不卡| 国产亚洲一区二区三区在线观看| 欧美精品一区二区三区四区| 美女黄毛**国产精品啪啪|