Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorFedor Indutny <fedor.indutny@gmail.com>2012-01-23 22:30:28 +0400
committerFedor Indutny <fedor.indutny@gmail.com>2012-01-23 22:30:28 +0400
commit667aae596cded9336f50574386683ec39ada43f2 (patch)
tree41918ad8d4801cc34215b054cb63dc83bd1ce8a5 /doc
parent2433eeb3850a91feb99bab530cb7183800166390 (diff)
parent6c0c00a2052ec613503a0322dcbabb6fcf41dab0 (diff)
Merge branch 'v0.6'
Conflicts: ChangeLog doc/template.html lib/cluster.js lib/http.js lib/tls.js src/node.h src/node_version.h test/simple/test-cluster-kill-workers.js
Diffstat (limited to 'doc')
-rw-r--r--doc/api/addons.markdown547
-rw-r--r--doc/api/appendix_1.markdown2
-rw-r--r--doc/community/index.html6
-rw-r--r--doc/index.html14
-rw-r--r--doc/logos/index.html2
5 files changed, 556 insertions, 15 deletions
diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown
index 6f99f8be48e..4527b24063b 100644
--- a/doc/api/addons.markdown
+++ b/doc/api/addons.markdown
@@ -6,7 +6,8 @@ knowledge of several libraries:
- V8 JavaScript, a C++ library. Used for interfacing with JavaScript:
creating objects, calling functions, etc. Documented mostly in the
- `v8.h` header file (`deps/v8/include/v8.h` in the Node source tree).
+ `v8.h` header file (`deps/v8/include/v8.h` in the Node source tree),
+ which is also available [online](http://izs.me/v8-docs/main.html).
- [libuv](https://github.com/joyent/libuv), C event loop library. Anytime one
needs to wait for a file descriptor to become readable, wait for a timer, or
@@ -22,12 +23,15 @@ Node statically compiles all its dependencies into the executable. When
compiling your module, you don't need to worry about linking to any of these
libraries.
+
+### Hello world
+
To get started let's make a small Addon which is the C++ equivalent of
the following Javascript code:
exports.hello = function() { return 'world'; };
-To get started we create a file `hello.cc`:
+First we create a file `hello.cc`:
#include <node.h>
#include <v8.h>
@@ -40,7 +44,8 @@ To get started we create a file `hello.cc`:
}
void init(Handle<Object> target) {
- NODE_SET_METHOD(target, "hello", Method);
+ target->Set(String::NewSymbol("hello"),
+ FunctionTemplate::New(Method)->GetFunction());
}
NODE_MODULE(hello, init)
@@ -87,5 +92,537 @@ the recently built module:
console.log(addon.hello()); // 'world'
-For the moment, that is all the documentation on addons. Please see
-<https://github.com/pietern/hiredis-node> for a real example.
+Please see patterns below for further information or
+<https://github.com/pietern/hiredis-node> for an example in production.
+
+
+## Addon patterns
+
+Below are some addon patterns to help you get started. Consult the online
+[v8 reference](http://izs.me/v8-docs/main.html) for help with the various v8
+calls, and v8's [Embedder's Guide](http://code.google.com/apis/v8/embed.html)
+for an explanation of several concepts used such as handles, scopes,
+function templates, etc.
+
+To compile these examples, create the `wscript` file below and run
+`node-waf configure build`:
+
+ srcdir = '.'
+ blddir = 'build'
+ VERSION = '0.0.1'
+
+ def set_options(opt):
+ opt.tool_options('compiler_cxx')
+
+ def configure(conf):
+ conf.check_tool('compiler_cxx')
+ conf.check_tool('node_addon')
+
+ def build(bld):
+ obj = bld.new_task_gen('cxx', 'shlib', 'node_addon')
+ obj.target = 'addon'
+ obj.source = ['addon.cc']
+
+In cases where there is more than one `.cc` file, simply add the file name to the
+`obj.source` array, e.g.:
+
+ obj.source = ['addon.cc', 'myexample.cc']
+
+
+#### Function arguments
+
+The following pattern illustrates how to read arguments from JavaScript
+function calls and return a result. This is the main and only needed source
+`addon.cc`:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+
+ using namespace v8;
+
+ Handle<Value> Add(const Arguments& args) {
+ HandleScope scope;
+
+ if (args.Length() < 2) {
+ ThrowException(Exception::TypeError(String::New("Wrong number of arguments")));
+ return scope.Close(Undefined());
+ }
+
+ if (!args[0]->IsNumber() || !args[1]->IsNumber()) {
+ ThrowException(Exception::TypeError(String::New("Wrong arguments")));
+ return scope.Close(Undefined());
+ }
+
+ Local<Number> num = Number::New(args[0]->NumberValue() +
+ args[1]->NumberValue());
+ return scope.Close(num);
+ }
+
+ void Init(Handle<Object> target) {
+ target->Set(String::NewSymbol("add"),
+ FunctionTemplate::New(Add)->GetFunction());
+ }
+
+ NODE_MODULE(addon, Init)
+
+You can test it with the following JavaScript snippet:
+
+ var addon = require('./build/Release/addon');
+
+ console.log( 'This should be eight:', addon.add(3,5) );
+
+
+#### Callbacks
+
+You can pass JavaScript functions to a C++ function and execute them from
+there. Here's `addon.cc`:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+
+ using namespace v8;
+
+ Handle<Value> RunCallback(const Arguments& args) {
+ HandleScope scope;
+
+ Local<Function> cb = Local<Function>::Cast(args[0]);
+ const unsigned argc = 1;
+ Local<Value> argv[argc] = { Local<Value>::New(String::New("hello world")) };
+ cb->Call(Context::GetCurrent()->Global(), argc, argv);
+
+ return scope.Close(Undefined());
+ }
+
+ void Init(Handle<Object> target) {
+ target->Set(String::NewSymbol("runCallback"),
+ FunctionTemplate::New(RunCallback)->GetFunction());
+ }
+
+ NODE_MODULE(addon, Init)
+
+To test it run the following JavaScript snippet:
+
+ var addon = require('./build/Release/addon');
+
+ addon.runCallback(function(msg){
+ console.log(msg); // 'hello world'
+ });
+
+
+#### Object factory
+
+You can create and return new objects from within a C++ function with this
+`addon.cc` pattern, which returns an object with property `msg` that echoes
+the string passed to `createObject()`:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+
+ using namespace v8;
+
+ Handle<Value> CreateObject(const Arguments& args) {
+ HandleScope scope;
+
+ Local<Object> obj = Object::New();
+ obj->Set(String::NewSymbol("msg"), args[0]->ToString());
+
+ return scope.Close(obj);
+ }
+
+ void Init(Handle<Object> target) {
+ target->Set(String::NewSymbol("createObject"),
+ FunctionTemplate::New(CreateObject)->GetFunction());
+ }
+
+ NODE_MODULE(addon, Init)
+
+To test it in JavaScript:
+
+ var addon = require('./build/Release/addon');
+
+ var obj1 = addon.createObject('hello');
+ var obj2 = addon.createObject('world');
+ console.log(obj1.msg+' '+obj2.msg); // 'hello world'
+
+
+#### Function factory
+
+This pattern illustrates how to create and return a JavaScript function that
+wraps a C++ function:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+
+ using namespace v8;
+
+ Handle<Value> MyFunction(const Arguments& args) {
+ HandleScope scope;
+ return scope.Close(String::New("hello world"));
+ }
+
+ Handle<Value> CreateFunction(const Arguments& args) {
+ HandleScope scope;
+
+ Local<FunctionTemplate> tpl = FunctionTemplate::New(MyFunction);
+ Local<Function> fn = tpl->GetFunction();
+ fn->SetName(String::NewSymbol("theFunction")); // omit this to make it anonymous
+
+ return scope.Close(fn);
+ }
+
+ void Init(Handle<Object> target) {
+ target->Set(String::NewSymbol("createFunction"),
+ FunctionTemplate::New(CreateFunction)->GetFunction());
+ }
+
+ NODE_MODULE(addon, Init)
+
+
+To test:
+
+ var addon = require('./build/Release/addon');
+
+ var fn = addon.createFunction();
+ console.log(fn()); // 'hello world'
+
+
+#### Wrapping C++ objects
+
+Here we will create a wrapper for a C++ object/class `MyObject` that can be
+instantiated in JavaScript through the `new` operator. First prepare the main
+module `addon.cc`:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+ #include "myobject.h"
+
+ using namespace v8;
+
+ void InitAll(Handle<Object> target) {
+ MyObject::Init(target);
+ }
+
+ NODE_MODULE(addon, InitAll)
+
+Then in `myobject.h` make your wrapper inherit from `node::ObjectWrap`:
+
+ #ifndef MYOBJECT_H
+ #define MYOBJECT_H
+
+ #include <node.h>
+
+ class MyObject : public node::ObjectWrap {
+ public:
+ static void Init(v8::Handle<v8::Object> target);
+
+ private:
+ MyObject();
+ ~MyObject();
+
+ static v8::Handle<v8::Value> New(const v8::Arguments& args);
+ static v8::Handle<v8::Value> PlusOne(const v8::Arguments& args);
+ double counter_;
+ };
+
+ #endif
+
+And in `myobject.cc` implement the various methods that you want to expose.
+Here we expose the method `plusOne` by adding it to the constructor's
+prototype:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+ #include "myobject.h"
+
+ using namespace v8;
+
+ MyObject::MyObject() {};
+ MyObject::~MyObject() {};
+
+ void MyObject::Init(Handle<Object> target) {
+ // Prepare constructor template
+ Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
+ tpl->SetClassName(String::NewSymbol("MyObject"));
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
+ // Prototype
+ tpl->PrototypeTemplate()->Set(String::NewSymbol("plusOne"),
+ FunctionTemplate::New(PlusOne)->GetFunction());
+
+ Persistent<Function> constructor = Persistent<Function>::New(tpl->GetFunction());
+ target->Set(String::NewSymbol("MyObject"), constructor);
+ }
+
+ Handle<Value> MyObject::New(const Arguments& args) {
+ HandleScope scope;
+
+ MyObject* obj = new MyObject();
+ obj->counter_ = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
+ obj->Wrap(args.This());
+
+ return args.This();
+ }
+
+ Handle<Value> MyObject::PlusOne(const Arguments& args) {
+ HandleScope scope;
+
+ MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.This());
+ obj->counter_ += 1;
+
+ return scope.Close(Number::New(obj->counter_));
+ }
+
+Test it with:
+
+ var addon = require('./build/Release/addon');
+
+ var obj = new addon.MyObject(10);
+ console.log( obj.plusOne() ); // 11
+ console.log( obj.plusOne() ); // 12
+ console.log( obj.plusOne() ); // 13
+
+
+#### Factory of wrapped objects
+
+This is useful when you want to be able to create native objects without
+explicitly instantiating them with the `new` operator in JavaScript, e.g.
+
+ var obj = addon.createObject();
+ // instead of:
+ // var obj = new addon.Object();
+
+Let's register our `createObject` method in `addon.cc`:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+ #include "myobject.h"
+
+ using namespace v8;
+
+ Handle<Value> CreateObject(const Arguments& args) {
+ HandleScope scope;
+ return scope.Close(MyObject::NewInstance(args));
+ }
+
+ void InitAll(Handle<Object> target) {
+ MyObject::Init();
+
+ target->Set(String::NewSymbol("createObject"),
+ FunctionTemplate::New(CreateObject)->GetFunction());
+ }
+
+ NODE_MODULE(addon, InitAll)
+
+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):
+
+ #define BUILDING_NODE_EXTENSION
+ #ifndef MYOBJECT_H
+ #define MYOBJECT_H
+
+ #include <node.h>
+
+ class MyObject : public node::ObjectWrap {
+ public:
+ static void Init();
+ static v8::Handle<v8::Value> NewInstance(const v8::Arguments& args);
+
+ private:
+ MyObject();
+ ~MyObject();
+
+ static v8::Persistent<v8::Function> constructor;
+ static v8::Handle<v8::Value> New(const v8::Arguments& args);
+ static v8::Handle<v8::Value> PlusOne(const v8::Arguments& args);
+ double counter_;
+ };
+
+ #endif
+
+The implementation is similar to the above in `myobject.cc`:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+ #include "myobject.h"
+
+ using namespace v8;
+
+ MyObject::MyObject() {};
+ MyObject::~MyObject() {};
+
+ Persistent<Function> MyObject::constructor;
+
+ void MyObject::Init() {
+ // Prepare constructor template
+ Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
+ tpl->SetClassName(String::NewSymbol("MyObject"));
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
+ // Prototype
+ tpl->PrototypeTemplate()->Set(String::NewSymbol("plusOne"),
+ FunctionTemplate::New(PlusOne)->GetFunction());
+
+ constructor = Persistent<Function>::New(tpl->GetFunction());
+ }
+
+ Handle<Value> MyObject::New(const Arguments& args) {
+ HandleScope scope;
+
+ MyObject* obj = new MyObject();
+ obj->counter_ = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
+ obj->Wrap(args.This());
+
+ return args.This();
+ }
+
+ Handle<Value> MyObject::NewInstance(const Arguments& args) {
+ HandleScope scope;
+
+ const unsigned argc = 1;
+ Handle<Value> argv[argc] = { args[0] };
+ Local<Object> instance = constructor->NewInstance(argc, argv);
+
+ return scope.Close(instance);
+ }
+
+ Handle<Value> MyObject::PlusOne(const Arguments& args) {
+ HandleScope scope;
+
+ MyObject* obj = ObjectWrap::Unwrap<MyObject>(args.This());
+ obj->counter_ += 1;
+
+ return scope.Close(Number::New(obj->counter_));
+ }
+
+Test it with:
+
+ var addon = require('./build/Release/addon');
+
+ var obj = addon.createObject(10);
+ console.log( obj.plusOne() ); // 11
+ console.log( obj.plusOne() ); // 12
+ console.log( obj.plusOne() ); // 13
+
+ var obj2 = addon.createObject(20);
+ console.log( obj2.plusOne() ); // 21
+ console.log( obj2.plusOne() ); // 22
+ console.log( obj2.plusOne() ); // 23
+
+
+#### Passing wrapped objects around
+
+In addition to wrapping and returning C++ objects, you can pass them around
+by unwrapping them with Node's `node::ObjectWrap::Unwrap` helper function.
+In the following `addon.cc` we introduce a function `add()` that can take on two
+`MyObject` objects:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+ #include "myobject.h"
+
+ using namespace v8;
+
+ Handle<Value> CreateObject(const Arguments& args) {
+ HandleScope scope;
+ return scope.Close(MyObject::NewInstance(args));
+ }
+
+ Handle<Value> Add(const Arguments& args) {
+ HandleScope scope;
+
+ MyObject* obj1 = node::ObjectWrap::Unwrap<MyObject>(
+ args[0]->ToObject());
+ MyObject* obj2 = node::ObjectWrap::Unwrap<MyObject>(
+ args[1]->ToObject());
+
+ double sum = obj1->Val() + obj2->Val();
+ return scope.Close(Number::New(sum));
+ }
+
+ void InitAll(Handle<Object> target) {
+ MyObject::Init();
+
+ target->Set(String::NewSymbol("createObject"),
+ FunctionTemplate::New(CreateObject)->GetFunction());
+
+ target->Set(String::NewSymbol("add"),
+ FunctionTemplate::New(Add)->GetFunction());
+ }
+
+ NODE_MODULE(addon, InitAll)
+
+To make things interesting we introduce a public method in `myobject.h` so we
+can probe private values after unwrapping the object:
+
+ #define BUILDING_NODE_EXTENSION
+ #ifndef MYOBJECT_H
+ #define MYOBJECT_H
+
+ #include <node.h>
+
+ class MyObject : public node::ObjectWrap {
+ public:
+ static void Init();
+ static v8::Handle<v8::Value> NewInstance(const v8::Arguments& args);
+ double Val() const { return val_; }
+
+ private:
+ MyObject();
+ ~MyObject();
+
+ static v8::Persistent<v8::Function> constructor;
+ static v8::Handle<v8::Value> New(const v8::Arguments& args);
+ double val_;
+ };
+
+ #endif
+
+The implementation of `myobject.cc` is similar as before:
+
+ #define BUILDING_NODE_EXTENSION
+ #include <node.h>
+ #include "myobject.h"
+
+ using namespace v8;
+
+ MyObject::MyObject() {};
+ MyObject::~MyObject() {};
+
+ Persistent<Function> MyObject::constructor;
+
+ void MyObject::Init() {
+ // Prepare constructor template
+ Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
+ tpl->SetClassName(String::NewSymbol("MyObject"));
+ tpl->InstanceTemplate()->SetInternalFieldCount(1);
+
+ constructor = Persistent<Function>::New(tpl->GetFunction());
+ }
+
+ Handle<Value> MyObject::New(const Arguments& args) {
+ HandleScope scope;
+
+ MyObject* obj = new MyObject();
+ obj->val_ = args[0]->IsUndefined() ? 0 : args[0]->NumberValue();
+ obj->Wrap(args.This());
+
+ return args.This();
+ }
+
+ Handle<Value> MyObject::NewInstance(const Arguments& args) {
+ HandleScope scope;
+
+ const unsigned argc = 1;
+ Handle<Value> argv[argc] = { args[0] };
+ Local<Object> instance = constructor->NewInstance(argc, argv);
+
+ return scope.Close(instance);
+ }
+
+Test it with:
+
+ var addon = require('./build/Release/addon');
+
+ var obj1 = addon.createObject(10);
+ var obj2 = addon.createObject(20);
+ var result = addon.add(obj1, obj2);
+
+ console.log(result); // 30
diff --git a/doc/api/appendix_1.markdown b/doc/api/appendix_1.markdown
index d25d7f9f3c3..59430c20e25 100644
--- a/doc/api/appendix_1.markdown
+++ b/doc/api/appendix_1.markdown
@@ -38,7 +38,7 @@ elsewhere.
- [ncurses](https://github.com/mscdex/node-ncurses)
- Testing/TDD/BDD: [vows](http://vowsjs.org/),
- [expresso](https://github.com/visionmedia/expresso),
+ [mocha](https://github.com/visionmedia/mocha),
[mjsunit.runner](https://github.com/tmpvar/mjsunit.runner)
Patches to this list are welcome.
diff --git a/doc/community/index.html b/doc/community/index.html
index dec8b58b900..3219f7bf847 100644
--- a/doc/community/index.html
+++ b/doc/community/index.html
@@ -28,7 +28,11 @@
</div>
<div id="content" class="clearfix">
<div id="column1" class="interior">
- <p>Node's most valuable feature is the friendly and colorful community of developers. There are many places where this group congregates on the internet. This page attempts to highlight the best forums.</p>
+ <p>Node's most valuable feature is the friendly and <a
+ href="http://blip.tv/jsconf/nodeconf-2011-marak-squires-5729610">colorful
+ community</a> of developers. There are many places where
+ this group congregates on the internet. This page attempts
+ to highlight the best forums.</p>
<h2>Periodicals</h2>
diff --git a/doc/index.html b/doc/index.html
index 61f10893d7b..3769002f911 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -77,15 +77,15 @@
<a href="#" id="download-close">X</a>
<img id="download-logo" src="download-logo.png" alt="node.js">
<ul id="installers" class="clearfix">
- <li><a href="http://nodejs.org/dist/v0.6.7/node-v0.6.7.msi">Windows Installer</a><br>node-v0.6.7.msi</li>
- <li><a href="http://nodejs.org/dist/v0.6.7/node-v0.6.7.pkg">Macintosh Installer</a><br>node-v0.6.7.pkg</li>
- <li id="source"><a href="http://nodejs.org/dist/v0.6.7/node-v0.6.7.tar.gz">Source Code</a><br>node-v0.6.7.tar.gz</li>
+ <li><a href="http://nodejs.org/dist/v0.6.8/node-v0.6.8.msi">Windows Installer</a><br>node-v0.6.8.msi</li>
+ <li><a href="http://nodejs.org/dist/v0.6.8/node-v0.6.8.pkg">Macintosh Installer</a><br>node-v0.6.8.pkg</li>
+ <li id="source"><a href="http://nodejs.org/dist/v0.6.8/node-v0.6.8.tar.gz">Source Code</a><br>node-v0.6.8.tar.gz</li>
</ul>
<ul id="documentation">
- <li><a href="https://raw.github.com/joyent/node/v0.6.7/ChangeLog">Change Log</a></li>
- <li><a href="http://nodejs.org/docs/v0.6.7/api/index.html">Documentation</a></li>
- <li><a href="http://nodejs.org/dist/v0.6.7">Other release files</a></li>
- <li><a href="https://raw.github.com/joyent/node/v0.6.7/LICENSE">License</a></li>
+ <li><a href="https://raw.github.com/joyent/node/v0.6.8/ChangeLog">Change Log</a></li>
+ <li><a href="http://nodejs.org/docs/v0.6.8/api/index.html">Documentation</a></li>
+ <li><a href="http://nodejs.org/dist/v0.6.8">Other release files</a></li>
+ <li><a href="https://raw.github.com/joyent/node/v0.6.8/LICENSE">License</a></li>
<li><a href="https://github.com/joyent/node">Git Repository</a></li>
<li><a href="https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager">Installing
with a Package Manager</a>
diff --git a/doc/logos/index.html b/doc/logos/index.html
index 403abe2da0e..35c575cb551 100644
--- a/doc/logos/index.html
+++ b/doc/logos/index.html
@@ -60,7 +60,7 @@
</div>
</div>
<div id="footer">
- <p>Copyright <a href="http://joyent.com">Joyent, Inc</a>., Node.js is a <a href="trademark-policy.pdf">trademark of Joyent, Inc</a>., <a href="https://raw.github.com/joyent/node/v0.6.7/LICENSE">View License</a></p>
+ <p>Copyright <a href="http://joyent.com">Joyent, Inc</a>., Node.js is a <a href="trademark-policy.pdf">trademark of Joyent, Inc</a>., <a href="https://raw.github.com/joyent/node/v0.6.8/LICENSE">View License</a></p>
</div>