Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport #369

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ LINT_SOURCES = \
test/cpp/bufferworkerpersistent.cpp \
test/cpp/error.cpp \
test/cpp/gc.cpp \
test/cpp/isolatedata.cpp \
test/cpp/makecallback.cpp \
test/cpp/morenews.cpp \
test/cpp/multifile1.cpp \
test/cpp/multifile2.cpp \
Expand All @@ -38,9 +40,11 @@ LINT_SOURCES = \
test/cpp/returnnull.cpp \
test/cpp/returnundefined.cpp \
test/cpp/returnvalue.cpp \
test/cpp/settemplate.cpp \
test/cpp/settergetter.cpp \
test/cpp/strings.cpp \
test/cpp/symbols.cpp \
test/cpp/threadlocal.cpp \
test/cpp/weak.cpp \
node_modules/node-gyp/gyp/data/win/large-pdb-shim.cc

Expand Down
62 changes: 42 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,17 +295,17 @@ NAN_METHOD(CalculateAsync) {
* <a href="#api_nan_set_internal_field_pointer"><b><code>NanSetInternalFieldPointer</code></b></a>
* <a href="#api_nan_object_wrap_handle"><b><code>NanObjectWrapHandle</code></b></a>
* <del><a href="#api_nan_symbol"><b><code>NanSymbol</code></b></a></del>
* <a href="#api_nan_get_pointer_safe"><b><code>NanGetPointerSafe</code></b></a>
* <a href="#api_nan_set_pointer_safe"><b><code>NanSetPointerSafe</code></b></a>
* <del><a href="#api_nan_get_pointer_safe"><b><code>NanGetPointerSafe</code></b></a></del>
* <del><a href="#api_nan_set_pointer_safe"><b><code>NanSetPointerSafe</code></b></a></del>
* <del><a href="#api_nan_raw_string"><b><code>NanRawString</code></b></a></del>
* <del><a href="#api_nan_c_string"><b><code>NanCString</code></b></a></del>
* <a href="#api_nan_ascii_string"><b><code>NanAsciiString</code></b></a>
* <a href="#api_nan_utf8_string"><b><code>NanUtf8String</code></b></a>
* <a href="#api_nan_ucs2_string"><b><code>NanUcs2String</code></b></a>
* <a href="#api_nan_boolean_option_value"><b><code>NanBooleanOptionValue</code></b></a>
* <a href="#api_nan_uint32_option_value"><b><code>NanUInt32OptionValue</code></b></a>
* <a href="#api_nan_error"><b><code>NanError</code></b>, <b><code>NanTypeError</code></b>, <b><code>NanRangeError</code></b></a>
* <a href="#api_nan_throw_error"><b><code>NanThrowError</code></b>, <b><code>NanThrowTypeError</code></b>, <b><code>NanThrowRangeError</code></b>, <b><code>NanThrowError(Handle<Value>)</code></b>, <b><code>NanThrowError(Handle<Value>, int)</code></b></a>
* <del><a href="#api_nan_boolean_option_value"><b><code>NanBooleanOptionValue</code></b></a></del>
* <del><a href="#api_nan_uint32_option_value"><b><code>NanUInt32OptionValue</code></b></a></del>
* <a href="#api_nan_error"><b><code>NanError</code></b>, <b><code>NanRangeError</code></b>, <b><code>NanReferenceError</code></b>, <b><code>NanSyntaxError</code></b>, <b><code>NanTypeError</code></b></a>
* <a href="#api_nan_throw_error"><b><code>NanThrowError</code></b>, <b><code>NanThrowRangeError</code></b>, <b><code>NanThrowReferenceError</code></b>, <b><code>NanThrowSyntaxError</code></b>, <b><code>NanThrowTypeError</code></b>, <b><code>NanThrowError(Handle<Value>)</code></b>, <b><code>NanThrowError(Handle<Value>, int)</code></b></a>
* <a href="#api_nan_new_buffer_handle"><b><code>NanNewBufferHandle(char *, size_t, FreeCallback, void *)</code></b>, <b><code>NanNewBufferHandle(char *, uint32_t)</code></b>, <b><code>NanNewBufferHandle(uint32_t)</code></b></a>
* <a href="#api_nan_buffer_use"><b><code>NanBufferUse(char *, uint32_t)</code></b></a>
* <del><a href="#api_nan_new_context_handle"><b><code>NanNewContextHandle</code></b></a></del>
Expand All @@ -318,6 +318,9 @@ NAN_METHOD(CalculateAsync) {
* <a href="#api_nan_set_prototype_template"><b><code>NanSetPrototypeTemplate</code></b></a>
* <a href="#api_nan_set_instance_template"><b><code>NanSetInstanceTemplate</code></b></a>
* <a href="#api_nan_make_callback"><b><code>NanMakeCallback</code></b></a>
* <a href="#api_nan_fatal_exception"><b><code>NanFatalException</code></b></a>
* <a href="#api_nan_get_isolate_data"><b><code>NanGetIsolateData</code></b></a>
* <a href="#api_nan_set_isolate_data"><b><code>NanSetIsolateData</code></b></a>
* <a href="#api_nan_encode"><b><code>NanEncode</code></b></a>
* <a href="#api_nan_decode_bytes"><b><code>NanDecodeBytes</code></b></a>
* <a href="#api_nan_decode_write"><b><code>NanDecodeWrite</code></b></a>
Expand Down Expand Up @@ -740,9 +743,10 @@ if (obj->Has(NanNew<String>("foo")))
```

<a name="api_nan_get_pointer_safe"></a>
### Type NanGetPointerSafe(Type *[, Type])
### ~~Type NanGetPointerSafe(Type *[, Type])~~

A helper for getting values from optional pointers. If the pointer is `NULL`, the function returns the optional default value, which defaults to `0`. Otherwise, the function returns the value the pointer points to.
Deprecated.
~~A helper for getting values from optional pointers. If the pointer is `NULL`, the function returns the optional default value, which defaults to `0`. Otherwise, the function returns the value the pointer points to.~~

```c++
char *plugh(uint32_t *optional) {
Expand All @@ -756,9 +760,10 @@ char *plugh(uint32_t *optional) {
```

<a name="api_nan_set_pointer_safe"></a>
### bool NanSetPointerSafe(Type *, Type)
### ~~bool NanSetPointerSafe(Type *, Type)~~

A helper for setting optional argument pointers. If the pointer is `NULL`, the function simply returns `false`. Otherwise, the value is assigned to the variable the pointer points to.
Deprecated.
~~A helper for setting optional argument pointers. If the pointer is `NULL`, the function simply returns `false`. Otherwise, the value is assigned to the variable the pointer points to.~~

```c++
const char *plugh(size_t *outputsize) {
Expand Down Expand Up @@ -941,11 +946,12 @@ printf(**str);
```

<a name="api_nan_boolean_option_value"></a>
### bool NanBooleanOptionValue(Handle&lt;Value&gt;, Handle&lt;String&gt;[, bool])
### ~~bool NanBooleanOptionValue(Handle&lt;Value&gt;, Handle&lt;String&gt;[, bool])~~

When you have an "options" object that you need to fetch properties from, boolean options can be fetched with this pair. They check first if the object exists (`IsEmpty`), then if the object has the given property (`Has`) then they get and convert/coerce the property to a `bool`.
Deprecated.
~~When you have an "options" object that you need to fetch properties from, boolean options can be fetched with this pair. They check first if the object exists (`IsEmpty`), then if the object has the given property (`Has`) then they get and convert/coerce the property to a `bool`.~~

The optional last parameter is the *default* value, which is `false` if left off:
~~The optional last parameter is the *default* value, which is `false` if left off:~~

```c++
// `foo` is false unless the user supplies a truthy value for it
Expand All @@ -955,29 +961,30 @@ bool bar = NanBooleanOptionValueDefTrue(optionsObj, NanNew<String>("bar"), true)
```

<a name="api_nan_uint32_option_value"></a>
### uint32_t NanUInt32OptionValue(Handle&lt;Value&gt;, Handle&lt;String&gt;, uint32_t)
### ~~uint32_t NanUInt32OptionValue(Handle&lt;Value&gt;, Handle&lt;String&gt;, uint32_t)~~

Similar to `NanBooleanOptionValue`, use `NanUInt32OptionValue` to fetch an integer option from your options object. Can be any kind of JavaScript `Number` and it will be coerced to an unsigned 32-bit integer.
Deprecated.
~~Similar to `NanBooleanOptionValue`, use `NanUInt32OptionValue` to fetch an integer option from your options object. Can be any kind of JavaScript `Number` and it will be coerced to an unsigned 32-bit integer.~~

Requires all 3 arguments as a default is not optional:
~~Requires all 3 arguments as a default is not optional:~~

```c++
uint32_t count = NanUInt32OptionValue(optionsObj, NanNew<String>("count"), 1024);
```

<a name="api_nan_error"></a>
### NanError(message), NanTypeError(message), NanRangeError(message)
### NanError(message), NanRangeError(message), NanReferenceError(message), NanSyntaxError(message), NanTypeError(message)

For making `Error`, `TypeError` and `RangeError` objects.
For making `Error`, `RangeError`, `ReferenceError`, `SyntaxError` and `TypeError` objects.

```c++
Local<Value> res = NanError("you must supply a callback argument");
```

<a name="api_nan_throw_error"></a>
### NanThrowError(message), NanThrowTypeError(message), NanThrowRangeError(message), NanThrowError(Local&lt;Value&gt;), NanThrowError(Local&lt;Value&gt;, int)
### NanThrowError(message), NanThrowRangeError(message), NanThrowReferenceError(message), NanThrowSyntaxError(message), NanThrowTypeError(message), NanThrowError(Local&lt;Value&gt;), NanThrowError(Local&lt;Value&gt;, int)

For throwing `Error`, `TypeError` and `RangeError` objects.
For throwing `Error`, `RangeError`, `ReferenceError`, `SyntaxError` and `TypeError` objects.

```c++
NanThrowError("you must supply a callback argument");
Expand Down Expand Up @@ -1103,6 +1110,21 @@ Use to add instance properties on function templates.

Use instead of `node::MakeCallback` to call javascript functions. This (or `NanCallback`) is the only proper way of calling functions. You must _*never, ever*_ directly use `Function::Call`, it will lead to run-time failures.

<a name="api_nan_fatal_exception"></a>
### NanFatalException(const v8::TryCatch &amp;)

Replaces `node::FatalException`.

<a name="api_nan_get_isolate_data"></a>
### NanGetIsolateData(v8::Isolate *)

Replaces `v8::Isolate::GetData`.

<a name="api_nan_set_isolate_data"></a>
### NanSetIsolateData(v8::Isolate *, T*)

Replaces `v8::Isolate::SetData`.

<a name="api_nan_encode"></a>
### NanEncode(const void*, size_t[, enum Nan::Encoding])

Expand Down
34 changes: 29 additions & 5 deletions nan.h
Original file line number Diff line number Diff line change
Expand Up @@ -1721,14 +1721,38 @@ class NanCallback {

NAN_INLINE void SaveToPersistent(
const char *key, const v8::Local<v8::Object> &obj) {
v8::Local<v8::Object> handle = NanNew(persistentHandle);
handle->Set(NanNew<v8::String>(key), obj);
NanScope();
NanNew(persistentHandle)->Set(NanNew(key), obj);
}

NAN_INLINE void SaveToPersistent(
const v8::Handle<v8::String> &key, const v8::Local<v8::Object> &obj) {
NanScope();
NanNew(persistentHandle)->Set(key, obj);
}

NAN_INLINE void SaveToPersistent(
uint32_t index, const v8::Local<v8::Object> &obj) {
NanScope();
NanNew(persistentHandle)->Set(index, obj);
}

NAN_INLINE v8::Local<v8::Object> GetFromPersistent(const char *key) const {
NanEscapableScope();
return NanEscapeScope(
NanNew(persistentHandle)->Get(NanNew(key)).As<v8::Object>());
}

NAN_INLINE v8::Local<v8::Object>
GetFromPersistent(const v8::Local<v8::String> &key) const {
NanEscapableScope();
return NanEscapeScope(NanNew(persistentHandle)->Get(key).As<v8::Object>());
}

v8::Local<v8::Object> GetFromPersistent(const char *key) const {
NAN_INLINE v8::Local<v8::Object> GetFromPersistent(uint32_t index) const {
NanEscapableScope();
v8::Local<v8::Object> handle = NanNew(persistentHandle);
return NanEscapeScope(handle->Get(NanNew(key)).As<v8::Object>());
return NanEscapeScope(
NanNew(persistentHandle)->Get(index).As<v8::Object>());
}

virtual void Execute() = 0;
Expand Down
14 changes: 11 additions & 3 deletions test/cpp/bufferworkerpersistent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ class BufferWorker : public NanAsyncWorker {

NanScope();

/* test them all */
SaveToPersistent("buffer", bufferHandle);
SaveToPersistent(NanNew("puffer"), bufferHandle);
SaveToPersistent(0u, bufferHandle);
}

~BufferWorker() {}
Expand All @@ -35,9 +38,14 @@ class BufferWorker : public NanAsyncWorker {
void HandleOKCallback () {
NanScope();

v8::Local<v8::Object> handle = GetFromPersistent("buffer");
v8::Local<v8::Value> argv[] = { handle };
callback->Call(1, argv);
v8::Local<v8::Value> handle = GetFromPersistent("buffer");
callback->Call(1, &handle);

handle = GetFromPersistent(NanNew("puffer"));
callback->Call(1, &handle);

handle = GetFromPersistent(0u);
callback->Call(1, &handle);
}

private:
Expand Down
67 changes: 33 additions & 34 deletions test/cpp/makecallback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@
#include <nan.h>

class MyObject : public node::ObjectWrap {
public:
static void Init(v8::Handle<v8::Object> exports);
public:
static void Init(v8::Handle<v8::Object> exports);

private:
MyObject();
~MyObject();
private:
MyObject();
~MyObject();

static NAN_METHOD(New);
static NAN_METHOD(CallEmit);
static v8::Persistent<v8::Function> constructor;
static NAN_METHOD(New);
static NAN_METHOD(CallEmit);
static v8::Persistent<v8::Function> constructor;
};

v8::Persistent<v8::Function> MyObject::constructor;
Expand All @@ -30,45 +30,44 @@ MyObject::~MyObject() {
}

void MyObject::Init(v8::Handle<v8::Object> exports) {
NanScope();
NanScope();

// Prepare constructor template
v8::Local<v8::FunctionTemplate> tpl = NanNew<v8::FunctionTemplate>(New);
tpl->SetClassName(NanNew<v8::String>("MyObject"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);
// Prepare constructor template
v8::Local<v8::FunctionTemplate> tpl = NanNew<v8::FunctionTemplate>(New);
tpl->SetClassName(NanNew<v8::String>("MyObject"));
tpl->InstanceTemplate()->SetInternalFieldCount(1);

NODE_SET_PROTOTYPE_METHOD(tpl, "call_emit", CallEmit);
NODE_SET_PROTOTYPE_METHOD(tpl, "call_emit", CallEmit);

NanAssignPersistent<v8::Function>(constructor, tpl->GetFunction());
exports->Set(NanNew<v8::String>("MyObject"), tpl->GetFunction());
NanAssignPersistent<v8::Function>(constructor, tpl->GetFunction());
exports->Set(NanNew<v8::String>("MyObject"), tpl->GetFunction());
}

NAN_METHOD(MyObject::New) {
NanScope();

if (args.IsConstructCall()) {
MyObject* obj = new MyObject();
obj->Wrap(args.This());
NanReturnValue(args.This());
}
else {
v8::Local<v8::Function> cons = NanNew<v8::Function>(constructor);
NanReturnValue(cons->NewInstance());
}
NanScope();

if (args.IsConstructCall()) {
MyObject* obj = new MyObject();
obj->Wrap(args.This());
NanReturnValue(args.This());
} else {
v8::Local<v8::Function> cons = NanNew<v8::Function>(constructor);
NanReturnValue(cons->NewInstance());
}
}

NAN_METHOD(MyObject::CallEmit) {
NanScope();
v8::Handle<v8::Value> argv[1] = {
NanNew("event"), // event name
};
NanScope();
v8::Handle<v8::Value> argv[1] = {
NanNew("event"), // event name
};

NanMakeCallback(args.This(), "emit", 1, argv);
NanReturnUndefined();
NanMakeCallback(args.This(), "emit", 1, argv);
NanReturnUndefined();
}

void Init(v8::Handle<v8::Object> exports) {
MyObject::Init(exports);
MyObject::Init(exports);
}

NODE_MODULE(makecallback, Init)
Loading