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