Commit ec138705 authored by Jérémy Lal's avatar Jérémy Lal

Imported Upstream version 0.10.21~dfsg1

parent 72a7901e
2013.09.30, Version 0.10.20 (Stable) 2013.10.18, Version 0.10.21 (Stable)
* uv: Upgrade to v0.10.18
* crypto: clear errors from verify failure (Timothy J Fontaine)
* dtrace: interpret two byte strings (Dave Pacheco)
* fs: fix fs.truncate() file content zeroing bug (Ben Noordhuis)
* http: provide backpressure for pipeline flood (isaacs)
* tls: fix premature connection termination (Ben Noordhuis)
2013.09.30, Version 0.10.20 (Stable), d7234c8d50a1af73f60d2d3c0cc7eed17429a481
* tls: fix sporadic hang and partial reads (Fedor Indutny) * tls: fix sporadic hang and partial reads (Fedor Indutny)
- fixes "npm ERR! cb() never called!" - fixes "npm ERR! cb() never called!"
......
...@@ -28,6 +28,19 @@ Windows: ...@@ -28,6 +28,19 @@ Windows:
vcbuild.bat vcbuild.bat
You can download pre-built binaries for various operating systems from
[http://nodejs.org/download/](http://nodejs.org/download/). The Windows
and OS X installers will prompt you for the location to install to.
The tarballs are self-contained; you can extract them to a local directory
with:
tar xzf /path/to/node-<version>-<platform>-<arch>.tar.gz
Or system-wide with:
cd /usr/local && tar --strip-components 1 -xzf \
/path/to/node-<version>-<platform>-<arch>.tar.gz
### To run the tests: ### To run the tests:
Unix/Macintosh: Unix/Macintosh:
......
2013.09.25, Version 0.10.17 (Stable) 2013.10.19, Version 0.10.18 (Stable)
Changes since version 0.10.17:
* unix: fix uv_spawn() NULL pointer deref on ENOMEM (Ben Noordhuis)
* unix: don't close inherited fds on uv_spawn() fail (Ben Noordhuis)
* unix: revert recent FSEvent changes (Ben Noordhuis)
* unix: fix non-synchronized access in signal.c (Ben Noordhuis)
2013.09.25, Version 0.10.17 (Stable), 9670e0a93540c2f0d86c84a375f2303383c11e7e
Changes since version 0.10.16: Changes since version 0.10.16:
......
...@@ -36,8 +36,8 @@ ...@@ -36,8 +36,8 @@
#define UV_PLATFORM_LOOP_FIELDS \ #define UV_PLATFORM_LOOP_FIELDS \
uv_thread_t cf_thread; \ uv_thread_t cf_thread; \
void* _cf_reserved; \ void* cf_cb; \
void* cf_state; \ void* cf_loop; \
uv_mutex_t cf_mutex; \ uv_mutex_t cf_mutex; \
uv_sem_t cf_sem; \ uv_sem_t cf_sem; \
ngx_queue_t cf_signals; \ ngx_queue_t cf_signals; \
...@@ -47,10 +47,10 @@ ...@@ -47,10 +47,10 @@
char* realpath; \ char* realpath; \
int realpath_len; \ int realpath_len; \
int cf_flags; \ int cf_flags; \
void* cf_event; \ void* cf_eventstream; \
uv_async_t* cf_cb; \ uv_async_t* cf_cb; \
ngx_queue_t cf_member; \ ngx_queue_t cf_events; \
uv_sem_t _cf_reserved; \ uv_sem_t cf_sem; \
uv_mutex_t cf_mutex; \ uv_mutex_t cf_mutex; \
#define UV_STREAM_PRIVATE_PLATFORM_FIELDS \ #define UV_STREAM_PRIVATE_PLATFORM_FIELDS \
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <ifaddrs.h> #include <ifaddrs.h>
#include <net/if.h> #include <net/if.h>
#include <CoreFoundation/CFRunLoop.h>
#include <mach/mach.h> #include <mach/mach.h>
#include <mach/mach_time.h> #include <mach/mach_time.h>
#include <mach-o/dyld.h> /* _NSGetExecutablePath */ #include <mach-o/dyld.h> /* _NSGetExecutablePath */
...@@ -35,19 +37,144 @@ ...@@ -35,19 +37,144 @@
#include <sys/sysctl.h> #include <sys/sysctl.h>
#include <unistd.h> /* sysconf */ #include <unistd.h> /* sysconf */
/* Forward declarations */
static void uv__cf_loop_runner(void* arg);
static void uv__cf_loop_cb(void* arg);
typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t;
struct uv__cf_loop_signal_s {
void* arg;
cf_loop_signal_cb cb;
ngx_queue_t member;
};
int uv__platform_loop_init(uv_loop_t* loop, int default_loop) { int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
loop->cf_state = NULL; CFRunLoopSourceContext ctx;
int r;
if (uv__kqueue_init(loop)) if (uv__kqueue_init(loop))
return -1; return -1;
loop->cf_loop = NULL;
if ((r = uv_mutex_init(&loop->cf_mutex)))
return r;
if ((r = uv_sem_init(&loop->cf_sem, 0)))
return r;
ngx_queue_init(&loop->cf_signals);
memset(&ctx, 0, sizeof(ctx));
ctx.info = loop;
ctx.perform = uv__cf_loop_cb;
loop->cf_cb = CFRunLoopSourceCreate(NULL, 0, &ctx);
if ((r = uv_thread_create(&loop->cf_thread, uv__cf_loop_runner, loop)))
return r;
/* Synchronize threads */
uv_sem_wait(&loop->cf_sem);
assert(ACCESS_ONCE(CFRunLoopRef, loop->cf_loop) != NULL);
return 0; return 0;
} }
void uv__platform_loop_delete(uv_loop_t* loop) { void uv__platform_loop_delete(uv_loop_t* loop) {
uv__fsevents_loop_delete(loop); ngx_queue_t* item;
uv__cf_loop_signal_t* s;
assert(loop->cf_loop != NULL);
uv__cf_loop_signal(loop, NULL, NULL);
uv_thread_join(&loop->cf_thread);
uv_sem_destroy(&loop->cf_sem);
uv_mutex_destroy(&loop->cf_mutex);
/* Free any remaining data */
while (!ngx_queue_empty(&loop->cf_signals)) {
item = ngx_queue_head(&loop->cf_signals);
s = ngx_queue_data(item, uv__cf_loop_signal_t, member);
ngx_queue_remove(item);
free(s);
}
}
static void uv__cf_loop_runner(void* arg) {
uv_loop_t* loop;
loop = arg;
/* Get thread's loop */
ACCESS_ONCE(CFRunLoopRef, loop->cf_loop) = CFRunLoopGetCurrent();
CFRunLoopAddSource(loop->cf_loop,
loop->cf_cb,
kCFRunLoopDefaultMode);
uv_sem_post(&loop->cf_sem);
CFRunLoopRun();
CFRunLoopRemoveSource(loop->cf_loop,
loop->cf_cb,
kCFRunLoopDefaultMode);
}
static void uv__cf_loop_cb(void* arg) {
uv_loop_t* loop;
ngx_queue_t* item;
ngx_queue_t split_head;
uv__cf_loop_signal_t* s;
loop = arg;
uv_mutex_lock(&loop->cf_mutex);
ngx_queue_init(&split_head);
if (!ngx_queue_empty(&loop->cf_signals)) {
ngx_queue_t* split_pos = ngx_queue_next(&loop->cf_signals);
ngx_queue_split(&loop->cf_signals, split_pos, &split_head);
}
uv_mutex_unlock(&loop->cf_mutex);
while (!ngx_queue_empty(&split_head)) {
item = ngx_queue_head(&split_head);
s = ngx_queue_data(item, uv__cf_loop_signal_t, member);
/* This was a termination signal */
if (s->cb == NULL)
CFRunLoopStop(loop->cf_loop);
else
s->cb(s->arg);
ngx_queue_remove(item);
free(s);
}
}
void uv__cf_loop_signal(uv_loop_t* loop, cf_loop_signal_cb cb, void* arg) {
uv__cf_loop_signal_t* item;
item = malloc(sizeof(*item));
/* XXX: Fail */
if (item == NULL)
abort();
item->arg = arg;
item->cb = cb;
uv_mutex_lock(&loop->cf_mutex);
ngx_queue_insert_tail(&loop->cf_signals, &item->member);
uv_mutex_unlock(&loop->cf_mutex);
assert(loop->cf_loop != NULL);
CFRunLoopSourceSignal(loop->cf_cb);
CFRunLoopWakeUp(loop->cf_loop);
} }
......
This diff is collapsed.
...@@ -216,10 +216,12 @@ int uv__make_socketpair(int fds[2], int flags); ...@@ -216,10 +216,12 @@ int uv__make_socketpair(int fds[2], int flags);
int uv__make_pipe(int fds[2], int flags); int uv__make_pipe(int fds[2], int flags);
#if defined(__APPLE__) #if defined(__APPLE__)
typedef void (*cf_loop_signal_cb)(void*);
void uv__cf_loop_signal(uv_loop_t* loop, cf_loop_signal_cb cb, void* arg);
int uv__fsevents_init(uv_fs_event_t* handle); int uv__fsevents_init(uv_fs_event_t* handle);
int uv__fsevents_close(uv_fs_event_t* handle); int uv__fsevents_close(uv_fs_event_t* handle);
void uv__fsevents_loop_delete(uv_loop_t* loop);
/* OSX < 10.7 has no file events, polyfill them */ /* OSX < 10.7 has no file events, polyfill them */
#ifndef MAC_OS_X_VERSION_10_7 #ifndef MAC_OS_X_VERSION_10_7
......
...@@ -307,7 +307,7 @@ int uv_fs_event_init(uv_loop_t* loop, ...@@ -307,7 +307,7 @@ int uv_fs_event_init(uv_loop_t* loop,
#if defined(__APPLE__) #if defined(__APPLE__)
/* Nullify field to perform checks later */ /* Nullify field to perform checks later */
handle->cf_cb = NULL; handle->cf_eventstream = NULL;
handle->realpath = NULL; handle->realpath = NULL;
handle->realpath_len = 0; handle->realpath_len = 0;
handle->cf_flags = flags; handle->cf_flags = flags;
......
...@@ -186,7 +186,7 @@ skip: ...@@ -186,7 +186,7 @@ skip:
/* /*
* Used for initializing stdio streams like options.stdin_stream. Returns * Used for initializing stdio streams like options.stdin_stream. Returns
* zero on success. * zero on success. See also the cleanup section in uv_spawn().
*/ */
static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) { static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
int mask; int mask;
...@@ -463,11 +463,18 @@ int uv_spawn(uv_loop_t* loop, ...@@ -463,11 +463,18 @@ int uv_spawn(uv_loop_t* loop,
error: error:
uv__set_sys_error(process->loop, errno); uv__set_sys_error(process->loop, errno);
for (i = 0; i < stdio_count; i++) { if (pipes != NULL) {
close(pipes[i][0]); for (i = 0; i < stdio_count; i++) {
close(pipes[i][1]); if (i < options.stdio_count)
if (options.stdio[i].flags & (UV_INHERIT_FD | UV_INHERIT_STREAM))
continue;
if (pipes[i][0] != -1)
close(pipes[i][0]);
if (pipes[i][1] != -1)
close(pipes[i][1]);
}
free(pipes);
} }
free(pipes);
return -1; return -1;
} }
......
...@@ -141,7 +141,10 @@ static void uv__signal_handler(int signum) { ...@@ -141,7 +141,10 @@ static void uv__signal_handler(int signum) {
saved_errno = errno; saved_errno = errno;
memset(&msg, 0, sizeof msg); memset(&msg, 0, sizeof msg);
uv__signal_lock(); if (uv__signal_lock()) {
errno = saved_errno;
return;
}
for (handle = uv__signal_first_handle(signum); for (handle = uv__signal_first_handle(signum);
handle != NULL && handle->signum == signum; handle != NULL && handle->signum == signum;
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#define UV_VERSION_MAJOR 0 #define UV_VERSION_MAJOR 0
#define UV_VERSION_MINOR 10 #define UV_VERSION_MINOR 10
#define UV_VERSION_PATCH 17 #define UV_VERSION_PATCH 18
#define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_IS_RELEASE 1
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title> Node.js v0.10.20 Manual &amp; Documentation</title> <title> Node.js v0.10.21 Manual &amp; Documentation</title>
<link rel="stylesheet" href="assets/style.css"> <link rel="stylesheet" href="assets/style.css">
<link rel="stylesheet" href="assets/sh.css"> <link rel="stylesheet" href="assets/sh.css">
<link rel="canonical" href="http://nodejs.org/api/_toc.html"> <link rel="canonical" href="http://nodejs.org/api/_toc.html">
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
<div id="column1" class="interior"> <div id="column1" class="interior">
<header> <header>
<h1>Node.js v0.10.20 Manual &amp; Documentation</h1> <h1>Node.js v0.10.21 Manual &amp; Documentation</h1>
<div id="gtoc"> <div id="gtoc">
<p> <p>
<a href="index.html" name="toc">Index</a> | <a href="index.html" name="toc">Index</a> |
...@@ -105,7 +105,7 @@ ...@@ -105,7 +105,7 @@
<li><a href="http://twitter.com/nodejs" class="twitter">@nodejs</a></li> <li><a href="http://twitter.com/nodejs" class="twitter">@nodejs</a></li>
</ul> </ul>
<p>Copyright <a href="http://joyent.com/">Joyent, Inc</a>, Node.js is a <a href="/trademark-policy.pdf">trademark</a> of Joyent, Inc. View <a href="https://raw.github.com/joyent/node/v0.10.20/LICENSE">license</a>.</p> <p>Copyright <a href="http://joyent.com/">Joyent, Inc</a>, Node.js is a <a href="/trademark-policy.pdf">trademark</a> of Joyent, Inc. View <a href="https://raw.github.com/joyent/node/v0.10.21/LICENSE">license</a>.</p>
</div> </div>
<script src="../sh_main.js"></script> <script src="../sh_main.js"></script>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Addons Node.js v0.10.20 Manual &amp; Documentation</title> <title>Addons Node.js v0.10.21 Manual &amp; Documentation</title>
<link rel="stylesheet" href="assets/style.css"> <link rel="stylesheet" href="assets/style.css">
<link rel="stylesheet" href="assets/sh.css"> <link rel="stylesheet" href="assets/sh.css">
<link rel="canonical" href="http://nodejs.org/api/addons.html"> <link rel="canonical" href="http://nodejs.org/api/addons.html">
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
<div id="column1" class="interior"> <div id="column1" class="interior">
<header> <header>
<h1>Node.js v0.10.20 Manual &amp; Documentation</h1> <h1>Node.js v0.10.21 Manual &amp; Documentation</h1>
<div id="gtoc"> <div id="gtoc">
<p> <p>
<a href="index.html" name="toc">Index</a> | <a href="index.html" name="toc">Index</a> |
...@@ -390,12 +390,13 @@ class MyObject : public node::ObjectWrap { ...@@ -390,12 +390,13 @@ class MyObject : public node::ObjectWrap {
static void Init(v8::Handle&lt;v8::Object&gt; exports); static void Init(v8::Handle&lt;v8::Object&gt; exports);
private: private:
MyObject(); explicit MyObject(double value = 0);
~MyObject(); ~MyObject();
static v8::Handle&lt;v8::Value&gt; New(const v8::Arguments&amp; args); static v8::Handle&lt;v8::Value&gt; New(const v8::Arguments&amp; args);
static v8::Handle&lt;v8::Value&gt; PlusOne(const v8::Arguments&amp; args); static v8::Handle&lt;v8::Value&gt; PlusOne(const v8::Arguments&amp; args);
double counter_; static v8::Persistent&lt;v8::Function&gt; constructor;
double value_;
}; };
#endif</code></pre> #endif</code></pre>
...@@ -410,8 +411,13 @@ prototype: ...@@ -410,8 +411,13 @@ prototype:
using namespace v8; using namespace v8;
MyObject::MyObject() {}; Persistent&lt;Function&gt; MyObject::constructor;
MyObject::~MyObject() {};
MyObject::MyObject(double value) : value_(value) {
}
MyObject::~MyObject() {
}
void MyObject::Init(Handle&lt;Object&gt; exports) { void MyObject::Init(Handle&lt;Object&gt; exports) {
// Prepare constructor template // Prepare constructor template
...@@ -421,28 +427,34 @@ void MyObject::Init(Handle&lt;Object&gt; exports) { ...@@ -421,28 +427,34 @@ void MyObject::Init(Handle&lt;Object&gt; exports) {
// Prototype // Prototype
tpl-&gt;PrototypeTemplate()-&gt;Set(String::NewSymbol(&quot;plusOne&quot;), tpl-&gt;PrototypeTemplate()-&gt;Set(String::NewSymbol(&quot;plusOne&quot;),
FunctionTemplate::New(PlusOne)-&gt;GetFunction()); FunctionTemplate::New(PlusOne)-&gt;GetFunction());
constructor = Persistent&lt;Function&gt;::New(tpl-&gt;GetFunction());
Persistent&lt;Function&gt; constructor = Persistent&lt;Function&gt;::New(tpl-&gt;GetFunction());
exports-&gt;Set(String::NewSymbol(&quot;MyObject&quot;), constructor); exports-&gt;Set(String::NewSymbol(&quot;MyObject&quot;), constructor);
} }
Handle&lt;Value&gt; MyObject::New(const Arguments&amp; args) { Handle&lt;Value&gt; MyObject::New(const Arguments&amp; args) {
HandleScope scope; HandleScope scope;
MyObject* obj = new MyObject(); if (args.IsConstructCall()) {
obj-&gt;counter_ = args[0]-&gt;IsUndefined() ? 0 : args[0]-&gt;NumberValue(); // Invoked as constructor: `new MyObject(...)`
obj-&gt;Wrap(args.This()); double value = args[0]-&gt;IsUndefined() ? 0 : args[0]-&gt;NumberValue();
MyObject* obj = new MyObject(value);
return args.This(); obj-&gt;Wrap(args.This());
return args.This();
} else {
// Invoked as plain function `MyObject(...)`, turn into construct call.
const int argc = 1;
Local&lt;Value&gt; argv[argc] = { args[0] };
return scope.Close(constructor-&gt;NewInstance(argc, argv));
}
} }
Handle&lt;Value&gt; MyObject::PlusOne(const Arguments&amp; args) { Handle&lt;Value&gt; MyObject::PlusOne(const Arguments&amp; args) {
HandleScope scope; HandleScope scope;
MyObject* obj = ObjectWrap::Unwrap&lt;MyObject&gt;(args.This()); MyObject* obj = ObjectWrap::Unwrap&lt;MyObject&gt;(args.This());
obj-&gt;counter_ += 1; obj-&gt;value_ += 1;
return scope.Close(Number::New(obj-&gt;counter_)); return scope.Close(Number::New(obj-&gt;value_));
}</code></pre> }</code></pre>
<p>Test it with: <p>Test it with:
...@@ -499,13 +511,13 @@ class MyObject : public node::ObjectWrap { ...@@ -499,13 +511,13 @@ class MyObject : public node::ObjectWrap {
static v8::Handle&lt;v8::Value&gt; NewInstance(const v8::Arguments&amp; args); static v8::Handle&lt;v8::Value&gt; NewInstance(const v8::Arguments&amp; args);
private: private:
MyObject(); explicit MyObject(double value = 0);
~MyObject(); ~MyObject();
static v8::Persistent&lt;v8::Function&gt; constructor;
static v8::Handle&lt;v8::Value&gt; New(const v8::Arguments&amp; args); static v8::Handle&lt;v8::Value&gt; New(const v8::Arguments&amp; args);
static v8::Handle&lt;v8::Value&gt; PlusOne(const v8::Arguments&amp; args); static v8::Handle&lt;v8::Value&gt; PlusOne(const v8::Arguments&amp; args);
double counter_; static v8::Persistent&lt;v8::Function&gt; constructor;
double value_;
}; };
#endif</code></pre> #endif</code></pre>
...@@ -518,11 +530,14 @@ class MyObject : public node::ObjectWrap { ...@@ -518,11 +530,14 @@ class MyObject : public node::ObjectWrap {
using namespace v8; using namespace v8;
MyObject::MyObject() {};
MyObject::~MyObject() {};
Persistent&lt;Function&gt; MyObject::constructor; Persistent&lt;Function&gt; MyObject::constructor;
MyObject::MyObject(double value) : value_(value) {
}
MyObject::~MyObject() {
}
void MyObject::Init() { void MyObject::Init() {
// Prepare constructor template // Prepare constructor template
Local&lt;FunctionTemplate&gt; tpl = FunctionTemplate::New(New); Local&lt;FunctionTemplate&gt; tpl = FunctionTemplate::New(New);
...@@ -531,18 +546,24 @@ void MyObject::Init() { ...@@ -531,18 +546,24 @@ void MyObject::Init() {
// Prototype // Prototype
tpl-&gt;PrototypeTemplate()-&gt;Set(String::NewSymbol(&quot;plusOne&quot;), tpl-&gt;PrototypeTemplate()-&gt;Set(String::NewSymbol(&quot;plusOne&quot;),
FunctionTemplate::New(PlusOne)-&gt;GetFunction()); FunctionTemplate::New(PlusOne)-&gt;GetFunction());
constructor = Persistent&lt;Function&gt;::New(tpl-&gt;GetFunction()); constructor = Persistent&lt;Function&gt;::New(tpl-&gt;GetFunction());
} }
Handle&lt;Value&gt; MyObject::New(const Arguments&amp; args) { Handle&lt;Value&gt; MyObject::New(const Arguments&amp; args) {
HandleScope scope; HandleScope scope;
MyObject* obj = new MyObject(); if (args.IsConstructCall()) {
obj-&gt;counter_ = args[0]-&gt;IsUndefined() ? 0 : args[0]-&gt;NumberValue(); // Invoked as constructor: `new MyObject(...)`
obj-&gt;Wrap(args.This()); double value = args[0]-&gt;IsUndefined() ? 0 : args[0]-&gt;NumberValue();
MyObject* obj = new MyObject(value);
return args.This(); obj-&gt;Wrap(args.This());
return args.This();
} else {
// Invoked as plain function `MyObject(...)`, turn into construct call.
const int argc = 1;
Local&lt;Value&gt; argv[argc] = { args[0] };
return scope.Close(constructor-&gt;NewInstance(argc, argv));
}
} }
Handle&lt;Value&gt; MyObject::NewInstance(const Arguments&amp; args) { Handle&lt;Value&gt; MyObject::NewInstance(const Arguments&amp; args) {
...@@ -559,9 +580,9 @@ Handle&lt;Value&gt; MyObject::PlusOne(const Arguments&amp; args) { ...@@ -559,9 +580,9 @@ Handle&lt;Value&gt; MyObject::PlusOne(const Arguments&amp; args) {
HandleScope scope; HandleScope scope;
MyObject* obj = ObjectWrap::Unwrap&lt;MyObject&gt;(args.This()); MyObject* obj = ObjectWrap::Unwrap&lt;MyObject&gt;(args.This());
obj-&gt;counter_ += 1; obj-&gt;value_ += 1;
return scope.Close(Number::New(obj-&gt;counter_)); return scope.Close(Number::New(obj-&gt;value_));
}</code></pre> }</code></pre>
<p>Test it with: <p>Test it with:
...@@ -603,7 +624,7 @@ Handle&lt;Value&gt; Add(const Arguments&amp; args) { ...@@ -603,7 +624,7 @@ Handle&lt;Value&gt; Add(const Arguments&amp; args) {
MyObject* obj2 = node::ObjectWrap::Unwrap&lt;MyObject&gt;( MyObject* obj2 = node::ObjectWrap::Unwrap&lt;MyObject&gt;(
args[1]-&gt;ToObject()); args[1]-&gt;ToObject());
double sum = obj1-&gt;Val() + obj2-&gt;Val(); double sum = obj1-&gt;Value() + obj2-&gt;Value();
return scope.Close(Number::New(sum)); return scope.Close(Number::New(sum));
} }
...@@ -632,15 +653,15 @@ class MyObject : public node::ObjectWrap { ...@@ -632,15 +653,15 @@ class MyObject : public node::ObjectWrap {
public: public:
static void Init(); static void Init();
static v8::Handle&lt;v8::Value&gt; NewInstance(const v8::Arguments&amp; args); static v8::Handle&lt;v8::Value&gt; NewInstance(const v8::Arguments&amp; args);
double Val() const { return val_; } double Value() const { return value_; }
private: private:
MyObject(); explicit MyObject(double value = 0);
~MyObject(); ~MyObject();
static v8::Persistent&lt;v8::Function&gt; constructor;
static v8::Handle&lt;v8::Value&gt; New(const v8::Arguments&amp; args); static v8::Handle&lt;v8::Value&gt; New(const v8::Arguments&amp; args);
double val_; static v8::Persistent&lt;v8::Function&gt; constructor;
double value_;
}; };
#endif</code></pre> #endif</code></pre>
...@@ -653,28 +674,37 @@ class MyObject : public node::ObjectWrap { ...@@ -653,28 +674,37 @@ class MyObject : public node::ObjectWrap {
using namespace v8; using namespace v8;
MyObject::MyObject() {};
MyObject::~MyObject() {};
Persistent&lt;Function&gt; MyObject::constructor; Persistent&lt;Function&gt; MyObject::constructor;
MyObject::MyObject(double value) : value_(value) {
}
MyObject::~MyObject() {
}
void MyObject::Init() { void MyObject::Init() {
// Prepare constructor template // Prepare constructor template
Local&lt;FunctionTemplate&gt; tpl = FunctionTemplate::New(New); Local&lt;FunctionTemplate&gt; tpl = FunctionTemplate::New(New);
tpl-&gt;SetClassName(String::NewSymbol(&quot;MyObject&quot;)); tpl-&gt;SetClassName(String::NewSymbol(&quot;MyObject&quot;));
tpl-&gt;InstanceTemplate()-&gt;SetInternalFieldCount(1); tpl-&gt;InstanceTemplate()-&gt;SetInternalFieldCount(1);
constructor = Persistent&lt;Function&gt;::New(tpl-&gt;GetFunction()); constructor = Persistent&lt;Function&gt;::New(tpl-&gt;GetFunction());
} }
Handle&lt;Value&gt; MyObject::New(const Arguments&amp; args) { Handle&lt;Value&gt; MyObject::New(const Arguments&amp; args) {
HandleScope scope; HandleScope scope;