Javascript是一個腳本程式語言,而 Google 寫了一個JS engine ,可以分析javascript的程式碼並實作出來,這是一個用C語言寫出來的程式,就跟PHP類似,我們也可以對node.js寫extension,不過在學如何製作extension時,我們就得先學學 Google V8 Engine。
what is Context
你可以把 context 當成一個 Instance,裡面有包含原始的 object , properties 等,簡單的說, context 預設就像是 Javasceipt 的 window , 當 JS 直接對外部變數修改,而沒有宣告 local variable ,這時 context 的內容就會被更改,每個 Context 都要有一個 context scope ,就是為了 Garbage 管理 ,在之後的 v8 engine 語法中,常會見到 scope 這個名稱,幾乎所有的 v8 engine object ,都必需存放在scope中。
- //initial context
- Persistent<Context> context;
- context = Context::New();
V8 Handle
Handle是各種物件的reference,有自動的 GC (Garbage Collector) 處理,在 Google V8 Engine中,幾乎所有的變數都會宣告在 Handle裡,統一由Handle來管理。
- Handle 又分兩種類型, Local 與 Persistent ,這兩個其實也不難, Local Handle 的生命週期是由 HandleScope來控制,當變數不再被使用的時候,就會自動被GC給處理掉,Persistent Handle則是由工程師可自已控制,當不需要使用時,要手動 delete memory allocate 。
- void run(){
- HandleScope handle_scope;
- Persistent<String> PerName(String::New("Persistent var"));
- Local<String> LocalName(String::New("local var"));
- namePer.Dispose();//手動清除 memory
- //function 結束後, LocalName 因 handle_scope destruct 而跟著自動被清除
- }
V8 HandleScope
HandleScope 就是代表著 Handle 存在的區域,也可以說是 Handle的家,你必需先建立 HandleScope ,接著才能建立 Handle,不然 Handle可是會找不到家的喔。
HandleScope 會自動管理 Handle的生命週期,當HandleScope結束掉,家裡所有的 Handle 也會被清空。
- 同時宣告兩個以上的 HandleScope , 後面的HandleScope取代第一個HandleScope的所有功能,等於 Handle 有了兩個家,這時只要有一個 HandleScope存在, Handle就不會被清除。
V8 基本變數使用
V8 支援將多種變數轉成字串,這裡實際測試了變數型態有 Number,Integer, Boolean。
- 將變數以 UTF-8字串編碼輸出,String::Utf8Value utf_str(text);
- 將變數以 BIG5 字串編碼輸出,String::AsciiValue big_str(text);
- Integer為32位元,最大整數值 = 2147483647,最小整數值 = -2147483648
- #include <iostream>
- #include <v8-debug.h>
- #include <v8.h>
- using namespace std;
- using namespace v8;
- //void NeanderArray::set(int index, i::Object* value)
- int main(int argc, char* argv[]){
- HandleScope handle_scope;
- Persistent<Context> context = Context::New();
- Context::Scope context_scope(context);
- Handle<Number> Num= Number::New(100.5); //double
- Handle<Integer> inte= Integer::New(10); //32位元
- Handle<Integer> inte2= Integer::New(-10);
- Handle<Integer> int_max= Integer::New(2147483647);
- Handle<Integer> int_min= Integer::New(-2147483648);
- Handle<String> str= String::New("just string");
- Handle<Boolean> boolean= Boolean::New(1);
- Handle<Boolean> boolean2= Boolean::New(0);
- Handle<Boolean> boolean3= Boolean::New(2);
- Handle<Boolean> boolean4= Boolean::New(3);
- //String::AsciiValue b(inte); //ascii big5
- cout <<"Num = " << *String::Utf8Value(Num) << endl;
- cout <<"inte = " << *String::Utf8Value(inte) << endl;
- cout <<"inte2 = " << *String::Utf8Value(inte2) << endl;
- cout <<"int_max = " << *String::Utf8Value(int_max) << endl;
- cout <<"int_min = " << *String::Utf8Value(int_min) << endl;
- cout <<"str = " << *String::Utf8Value(str) << endl;
- cout <<"boolean = " << *String::Utf8Value(boolean) << endl;
- cout <<"boolean2 = " << *String::Utf8Value(boolean2) << endl;
- cout <<"boolean3 = " << *String::Utf8Value(boolean3) << endl;
- cout <<"boolean4 = " << *String::Utf8Value(boolean4) << endl;
- context.Dispose();
- return 0;
- }
- [puritys]V8$ ./exe/basic.o
- Num = 100.5
- inte = 10
- inte2 = -10
- int_max = 2147483647
- int_min = -2147483648
- str = just string
- boolean = true
- boolean2 = false
- boolean3 = true
- boolean4 = true
V8 Array
V8 的 Array 就像 JS , PHP 一樣,想塞什麼值就塞什麼值,在 Array 中塞 Array 也沒問題啦。
- #include <iostream>
- #include <v8-debug.h>
- #include <v8.h>
- using namespace std;
- using namespace v8;
- //void NeanderArray::set(int index, i::Object* value)
- int main(int argc, char* argv[]){
- HandleScope handle_scope;
- Persistent<Context> context = Context::New();
- Context::Scope context_scope(context);
- Handle<Array> array= Array::New(4);
- array->Set(0, Integer::New(1));
- array->Set(1, String::New("string test"));
- array->Set(2, String::New("中文"));
- Handle<Array> array2= Array::New(2);
- array2->Set(0, Integer::New(2));
- array2->Set(1, Integer::New(2));
- //將array2 塞到 array1
- array->Set(3, array2);
- cout << "Length = " << array->Length() << endl;
- String::Utf8Value b(array); //utf8 編碼
- //String::AsciiValue b(array); //ascii big5
- cout << *b;
- context.Dispose();
- return 0;
- }
- [puritys]V8$ ./exe/array.o
- Length = 4
- 1,string test,中文,2,2
問題與解法
建立一個 Handle
- class JSArray: public JSObject