diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown index 5c77c7f22f2609..1f0562ede2c938 100644 --- a/doc/api/addons.markdown +++ b/doc/api/addons.markdown @@ -41,23 +41,32 @@ First we create a file `hello.cc`: // hello.cc #include - using namespace v8; + namespace demo { + + using v8::FunctionCallbackInfo; + using v8::HandleScope; + using v8::Isolate; + using v8::Local; + using v8::Object; + using v8::String; + using v8::Value; void Method(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); + Isolate* isolate = args.GetIsolate(); args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world")); } - void init(Handle exports) { + void init(Local exports) { NODE_SET_METHOD(exports, "hello", Method); } NODE_MODULE(addon, init) + } // namespace demo + Note that all io.js addons must export an initialization function: - void Initialize (Handle exports); + void Initialize(Local exports); NODE_MODULE(module_name, Initialize) There is no semi-colon after `NODE_MODULE` as it's not a function (see @@ -142,11 +151,20 @@ function calls and return a result. This is the main and only needed source // addon.cc #include - using namespace v8; + namespace demo { + + using v8::Exception; + using v8::FunctionCallbackInfo; + using v8::HandleScope; + using v8::Isolate; + using v8::Local; + using v8::Number; + using v8::Object; + using v8::String; + using v8::Value; void Add(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); + Isolate* isolate = args.GetIsolate(); if (args.Length() < 2) { isolate->ThrowException(Exception::TypeError( @@ -166,12 +184,14 @@ function calls and return a result. This is the main and only needed source args.GetReturnValue().Set(num); } - void Init(Handle exports) { + void Init(Local exports) { NODE_SET_METHOD(exports, "add", Add); } NODE_MODULE(addon, Init) + } // namespace demo + You can test it with the following JavaScript snippet: // test.js @@ -188,24 +208,34 @@ there. Here's `addon.cc`: // addon.cc #include - using namespace v8; + namespace demo { - void RunCallback(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); + using v8::Function; + using v8::FunctionCallbackInfo; + using v8::HandleScope; + using v8::Isolate; + using v8::Local; + using v8::Null; + using v8::Object; + using v8::String; + using v8::Value; + void RunCallback(const FunctionCallbackInfo& args) { + Isolate* isolate = args.GetIsolate(); Local cb = Local::Cast(args[0]); const unsigned argc = 1; Local argv[argc] = { String::NewFromUtf8(isolate, "hello world") }; - cb->Call(isolate->GetCurrentContext()->Global(), argc, argv); + cb->Call(Null(isolate), argc, argv); } - void Init(Handle exports, Handle module) { + void Init(Local exports, Local module) { NODE_SET_METHOD(module, "exports", RunCallback); } NODE_MODULE(addon, Init) + } // namespace demo + Note that this example uses a two-argument form of `Init()` that receives the full `module` object as the second argument. This allows the addon to completely overwrite `exports` with a single function instead of @@ -230,11 +260,18 @@ the string passed to `createObject()`: // addon.cc #include - using namespace v8; + namespace demo { + + using v8::FunctionCallbackInfo; + using v8::HandleScope; + using v8::Isolate; + using v8::Local; + using v8::Object; + using v8::String; + using v8::Value; void CreateObject(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); + Isolate* isolate = args.GetIsolate(); Local obj = Object::New(isolate); obj->Set(String::NewFromUtf8(isolate, "msg"), args[0]->ToString()); @@ -242,12 +279,14 @@ the string passed to `createObject()`: args.GetReturnValue().Set(obj); } - void Init(Handle exports, Handle module) { + void Init(Local exports, Local module) { NODE_SET_METHOD(module, "exports", CreateObject); } NODE_MODULE(addon, Init) + } // namespace demo + To test it in JavaScript: // test.js @@ -266,17 +305,25 @@ wraps a C++ function: // addon.cc #include - using namespace v8; + namespace demo { + + using v8::Function; + using v8::FunctionCallbackInfo; + using v8::FunctionTemplate; + using v8::HandleScope; + using v8::Isolate; + using v8::Local; + using v8::Object; + using v8::String; + using v8::Value; void MyFunction(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); + Isolate* isolate = args.GetIsolate(); args.GetReturnValue().Set(String::NewFromUtf8(isolate, "hello world")); } void CreateFunction(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); + Isolate* isolate = args.GetIsolate(); Local tpl = FunctionTemplate::New(isolate, MyFunction); Local fn = tpl->GetFunction(); @@ -287,12 +334,14 @@ wraps a C++ function: args.GetReturnValue().Set(fn); } - void Init(Handle exports, Handle module) { + void Init(Local exports, Local module) { NODE_SET_METHOD(module, "exports", CreateFunction); } NODE_MODULE(addon, Init) + } // namespace demo + To test: // test.js @@ -312,14 +361,19 @@ module `addon.cc`: #include #include "myobject.h" - using namespace v8; + namespace demo { + + using v8::Local; + using v8::Object; - void InitAll(Handle exports) { + void InitAll(Local exports) { MyObject::Init(exports); } NODE_MODULE(addon, InitAll) + } // namespace demo + Then in `myobject.h` make your wrapper inherit from `node::ObjectWrap`: // myobject.h @@ -329,9 +383,11 @@ Then in `myobject.h` make your wrapper inherit from `node::ObjectWrap`: #include #include + namespace demo { + class MyObject : public node::ObjectWrap { public: - static void Init(v8::Handle exports); + static void Init(v8::Local exports); private: explicit MyObject(double value = 0); @@ -343,6 +399,8 @@ Then in `myobject.h` make your wrapper inherit from `node::ObjectWrap`: double value_; }; + } // namespace demo + #endif And in `myobject.cc` implement the various methods that you want to expose. @@ -352,7 +410,19 @@ prototype: // myobject.cc #include "myobject.h" - using namespace v8; + namespace demo { + + using v8::Function; + using v8::FunctionCallbackInfo; + using v8::FunctionTemplate; + using v8::HandleScope; + using v8::Isolate; + using v8::Local; + using v8::Number; + using v8::Object; + using v8::Persistent; + using v8::String; + using v8::Value; Persistent MyObject::constructor; @@ -362,8 +432,8 @@ prototype: MyObject::~MyObject() { } - void MyObject::Init(Handle exports) { - Isolate* isolate = Isolate::GetCurrent(); + void MyObject::Init(Local exports) { + Isolate* isolate = exports->GetIsolate(); // Prepare constructor template Local tpl = FunctionTemplate::New(isolate, New); @@ -379,8 +449,7 @@ prototype: } void MyObject::New(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); + Isolate* isolate = args.GetIsolate(); if (args.IsConstructCall()) { // Invoked as constructor: `new MyObject(...)` @@ -398,8 +467,7 @@ prototype: } void MyObject::PlusOne(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); + Isolate* isolate = args.GetIsolate(); MyObject* obj = ObjectWrap::Unwrap(args.Holder()); obj->value_ += 1; @@ -407,6 +475,8 @@ prototype: args.GetReturnValue().Set(Number::New(isolate, obj->value_)); } + } // namespace demo + Test it with: // test.js @@ -432,22 +502,30 @@ Let's register our `createObject` method in `addon.cc`: #include #include "myobject.h" - using namespace v8; + namespace demo { + + using v8::FunctionCallbackInfo; + using v8::HandleScope; + using v8::Isolate; + using v8::Local; + using v8::Object; + using v8::String; + using v8::Value; void CreateObject(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); MyObject::NewInstance(args); } - void InitAll(Handle exports, Handle module) { - MyObject::Init(); + void InitAll(Local exports, Local module) { + MyObject::Init(exports->GetIsolate()); NODE_SET_METHOD(module, "exports", CreateObject); } NODE_MODULE(addon, InitAll) + } // namespace demo + In `myobject.h` we now introduce the static method `NewInstance` that takes care of instantiating the object (i.e. it does the job of `new` in JavaScript): @@ -458,9 +536,11 @@ care of instantiating the object (i.e. it does the job of `new` in JavaScript): #include #include + namespace demo { + class MyObject : public node::ObjectWrap { public: - static void Init(); + static void Init(v8::Isolate* isolate); static void NewInstance(const v8::FunctionCallbackInfo& args); private: @@ -473,6 +553,8 @@ care of instantiating the object (i.e. it does the job of `new` in JavaScript): double value_; }; + } // namespace demo + #endif The implementation is similar to the above in `myobject.cc`: @@ -481,7 +563,19 @@ The implementation is similar to the above in `myobject.cc`: #include #include "myobject.h" - using namespace v8; + namespace demo { + + using v8::Function; + using v8::FunctionCallbackInfo; + using v8::FunctionTemplate; + using v8::HandleScope; + using v8::Isolate; + using v8::Local; + using v8::Number; + using v8::Object; + using v8::Persistent; + using v8::String; + using v8::Value; Persistent MyObject::constructor; @@ -491,8 +585,7 @@ The implementation is similar to the above in `myobject.cc`: MyObject::~MyObject() { } - void MyObject::Init() { - Isolate* isolate = Isolate::GetCurrent(); + void MyObject::Init(Isolate* isolate) { // Prepare constructor template Local tpl = FunctionTemplate::New(isolate, New); tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject")); @@ -505,8 +598,7 @@ The implementation is similar to the above in `myobject.cc`: } void MyObject::New(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); + Isolate* isolate = args.GetIsolate(); if (args.IsConstructCall()) { // Invoked as constructor: `new MyObject(...)` @@ -524,11 +616,10 @@ The implementation is similar to the above in `myobject.cc`: } void MyObject::NewInstance(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); + Isolate* isolate = args.GetIsolate(); const unsigned argc = 1; - Handle argv[argc] = { args[0] }; + Local argv[argc] = { args[0] }; Local cons = Local::New(isolate, constructor); Local instance = cons->NewInstance(argc, argv); @@ -536,8 +627,7 @@ The implementation is similar to the above in `myobject.cc`: } void MyObject::PlusOne(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); + Isolate* isolate = args.GetIsolate(); MyObject* obj = ObjectWrap::Unwrap(args.Holder()); obj->value_ += 1; @@ -545,6 +635,8 @@ The implementation is similar to the above in `myobject.cc`: args.GetReturnValue().Set(Number::New(isolate, obj->value_)); } + } // namespace demo + Test it with: // test.js @@ -573,17 +665,23 @@ In the following `addon.cc` we introduce a function `add()` that can take on two #include #include "myobject.h" - using namespace v8; + namespace demo { + + using v8::FunctionCallbackInfo; + using v8::HandleScope; + using v8::Isolate; + using v8::Local; + using v8::Number; + using v8::Object; + using v8::String; + using v8::Value; void CreateObject(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); MyObject::NewInstance(args); } void Add(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); + Isolate* isolate = args.GetIsolate(); MyObject* obj1 = node::ObjectWrap::Unwrap( args[0]->ToObject()); @@ -594,8 +692,8 @@ In the following `addon.cc` we introduce a function `add()` that can take on two args.GetReturnValue().Set(Number::New(isolate, sum)); } - void InitAll(Handle exports) { - MyObject::Init(); + void InitAll(Local exports) { + MyObject::Init(exports->GetIsolate()); NODE_SET_METHOD(exports, "createObject", CreateObject); NODE_SET_METHOD(exports, "add", Add); @@ -603,6 +701,8 @@ In the following `addon.cc` we introduce a function `add()` that can take on two NODE_MODULE(addon, InitAll) + } // namespace demo + To make things interesting we introduce a public method in `myobject.h` so we can probe private values after unwrapping the object: @@ -613,9 +713,11 @@ can probe private values after unwrapping the object: #include #include + namespace demo { + class MyObject : public node::ObjectWrap { public: - static void Init(); + static void Init(v8::Isolate* isolate); static void NewInstance(const v8::FunctionCallbackInfo& args); inline double value() const { return value_; } @@ -628,6 +730,8 @@ can probe private values after unwrapping the object: double value_; }; + } // namespace demo + #endif The implementation of `myobject.cc` is similar as before: @@ -636,7 +740,18 @@ The implementation of `myobject.cc` is similar as before: #include #include "myobject.h" - using namespace v8; + namespace demo { + + using v8::Function; + using v8::FunctionCallbackInfo; + using v8::FunctionTemplate; + using v8::HandleScope; + using v8::Isolate; + using v8::Local; + using v8::Object; + using v8::Persistent; + using v8::String; + using v8::Value; Persistent MyObject::constructor; @@ -646,9 +761,7 @@ The implementation of `myobject.cc` is similar as before: MyObject::~MyObject() { } - void MyObject::Init() { - Isolate* isolate = Isolate::GetCurrent(); - + void MyObject::Init(Isolate* isolate) { // Prepare constructor template Local tpl = FunctionTemplate::New(isolate, New); tpl->SetClassName(String::NewFromUtf8(isolate, "MyObject")); @@ -658,8 +771,7 @@ The implementation of `myobject.cc` is similar as before: } void MyObject::New(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); + Isolate* isolate = args.GetIsolate(); if (args.IsConstructCall()) { // Invoked as constructor: `new MyObject(...)` @@ -677,17 +789,18 @@ The implementation of `myobject.cc` is similar as before: } void MyObject::NewInstance(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); + Isolate* isolate = args.GetIsolate(); const unsigned argc = 1; - Handle argv[argc] = { args[0] }; + Local argv[argc] = { args[0] }; Local cons = Local::New(isolate, constructor); Local instance = cons->NewInstance(argc, argv); args.GetReturnValue().Set(instance); } + } // namespace demo + Test it with: // test.js