Skip to content

Commit

Permalink
Merge tag 'v0.14.3' into mt
Browse files Browse the repository at this point in the history
The switch to nan 2 caused quite a number of merge conflicts and other build
errors, so this is considerably more than just a simple merge.
  • Loading branch information
gagern committed Aug 30, 2015
2 parents bf2af58 + 50e2089 commit f6c2c2f
Show file tree
Hide file tree
Showing 23 changed files with 749 additions and 616 deletions.
20 changes: 19 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
language: node_js

env:
- CXX=g++-4.8

node_js:
- "0.10"
- "0.12"
- iojs-2.0
- iojs-1
- iojs-2
- iojs-3

addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8

sudo: false

before_install:
- $CXX --version
- case ${TRAVIS_NODE_VERSION} in 0.8*|0.10*) npm update -g npm ;; esac
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
[![Build Status](https://secure.travis-ci.org/gagern/libxmljs.svg?branch=master)](http://travis-ci.org/gagern/libxmljs)

This project is a fork of [libxmljs](https://github.com/polotek/libxmljs).
The current version 0.14.3 is based on libxmljs 0.14.2 and libxml 2.9.2.
The current version 0.14.4 is based on libxmljs 0.14.3 and libxml 2.9.2.

Libxmljs was originally designed with single-threaded operations in mind.
There are no asynchroneous operations for things like parsing XML documents.
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"Martin von Gagern <[email protected]>"
],
"description": "multi-threaded libxml bindings for v8 javascript engine",
"version": "0.14.3",
"version": "0.14.4",
"scripts": {
"test": "node --expose_gc ./node_modules/.bin/nodeunit test"
},
Expand All @@ -25,7 +25,7 @@
},
"dependencies": {
"bindings": "1.2.1",
"nan": "1.8.4"
"nan": "2.0.7"
},
"devDependencies": {
"nodeunit": "0.9.0"
Expand Down
61 changes: 39 additions & 22 deletions src/libxmljs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
namespace libxmljs {

bool tlsInitialized = false;
nauv_key_t tlsKey;
Nan::nauv_key_t tlsKey;
bool isAsync = false; // Only set on V8 thread when no workers are running
int numWorkers = 0; // Only access from V8 thread

Expand All @@ -36,7 +36,7 @@ void adjustMem(ssize_t diff)
if (isAsync)
{
WorkerSentinel* worker =
static_cast<WorkerSentinel*>(nauv_key_get(&tlsKey));
static_cast<WorkerSentinel*>(Nan::nauv_key_get(&tlsKey));
if (worker)
{
worker->parent.memAdjustments += diff;
Expand All @@ -60,7 +60,7 @@ void adjustMem(ssize_t diff)
assert(diff <= 0);
return;
}
NanAdjustExternalMemory(diff);
Nan::AdjustExternalMemory(diff);
}

void* memMalloc(size_t size)
Expand Down Expand Up @@ -104,7 +104,7 @@ char* memStrdup(const char* str)
WorkerParent::WorkerParent() : memAdjustments(0) {
if (!tlsInitialized)
{
nauv_key_create(&tlsKey);
Nan::nauv_key_create(&tlsKey);
tlsInitialized = true;
}
if (numWorkers++ == 0)
Expand All @@ -115,7 +115,7 @@ WorkerParent::WorkerParent() : memAdjustments(0) {

// Tear down in V8 thread
WorkerParent::~WorkerParent() {
NanAdjustExternalMemory(memAdjustments);
Nan::AdjustExternalMemory(memAdjustments);
if (--numWorkers == 0)
{
isAsync = false;
Expand All @@ -124,13 +124,29 @@ WorkerParent::~WorkerParent() {

// Set up in worker thread
WorkerSentinel::WorkerSentinel(WorkerParent& parent) : parent(parent) {
nauv_key_set(&tlsKey, this);
Nan::nauv_key_set(&tlsKey, this);
xmlMemSetup(memFree, memMalloc, memRealloc, memStrdup);
}

// Tear down in worker thread
WorkerSentinel::~WorkerSentinel() {
nauv_key_set(&tlsKey, NULL);
Nan::nauv_key_set(&tlsKey, NULL);
}

// callback function for `xmlDeregisterNodeDefault`
void xmlDeregisterNodeCallback(xmlNode* xml_obj)
{
if (xml_obj->_private)
{
XmlNode* node = static_cast<XmlNode*>(xml_obj->_private);

// flag the XmlNode object as freed
node->freed = true;

// save a reference to the doc so we can still `unref` it
node->doc = xml_obj->doc;
}
return;
}

// ensure destruction at exit time
Expand All @@ -139,6 +155,9 @@ LibXMLJS LibXMLJS::instance;

LibXMLJS::LibXMLJS()
{
// set the callback for when a node is about to be freed
xmlDeregisterNodeDefault(xmlDeregisterNodeCallback);

// Setup our own memory handling (see xmlmemory.h/c)
xmlMemSetup(memFree, memMalloc, memRealloc, memStrdup);

Expand All @@ -152,9 +171,9 @@ LibXMLJS::~LibXMLJS()
}

v8::Local<v8::Object> listFeatures() {
v8::Local<v8::Object> target = NanNew<v8::Object>();
#define FEAT(x) target->Set(NanNew<v8::String>(# x), \
NanNew<v8::Boolean>(xmlHasFeature(XML_WITH_ ## x)))
v8::Local<v8::Object> target = Nan::New<v8::Object>();
#define FEAT(x) Nan::Set(target, Nan::New<v8::String>(# x).ToLocalChecked(), \
Nan::New<v8::Boolean>(xmlHasFeature(XML_WITH_ ## x)))
// See enum xmlFeature in parser.h
FEAT(THREAD);
FEAT(TREE);
Expand Down Expand Up @@ -192,27 +211,25 @@ v8::Local<v8::Object> listFeatures() {
return target;
}

// used by node.js to initialize libraries
extern "C" void
init(v8::Handle<v8::Object> target)
NAN_MODULE_INIT(init)
{
NanScope();
Nan::HandleScope scope;

XmlDocument::Initialize(target);
XmlSaxParser::Initialize(target);

target->Set(NanNew<v8::String>("libxml_version"),
NanNew<v8::String>(LIBXML_DOTTED_VERSION));
Nan::Set(target, Nan::New<v8::String>("libxml_version").ToLocalChecked(),
Nan::New<v8::String>(LIBXML_DOTTED_VERSION).ToLocalChecked());

target->Set(NanNew<v8::String>("libxml_parser_version"),
NanNew<v8::String>(xmlParserVersion));
Nan::Set(target, Nan::New<v8::String>("libxml_parser_version").ToLocalChecked(),
Nan::New<v8::String>(xmlParserVersion).ToLocalChecked());

target->Set(NanNew<v8::String>("libxml_debug_enabled"),
NanNew<v8::Boolean>(debugging));
Nan::Set(target, Nan::New<v8::String>("libxml_debug_enabled").ToLocalChecked(),
Nan::New<v8::Boolean>(debugging));

target->Set(NanNew<v8::String>("features"), listFeatures());
Nan::Set(target, Nan::New<v8::String>("features").ToLocalChecked(), listFeatures());

target->Set(NanNew<v8::String>("libxml"), target);
Nan::Set(target, Nan::New<v8::String>("libxml").ToLocalChecked(), target);
}

NODE_MODULE(xmljs, init)
Expand Down
2 changes: 1 addition & 1 deletion src/libxmljs.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#define LIBXMLJS_ARGUMENT_TYPE_CHECK(arg, type, err) \
if (!arg->type()) { \
return NanThrowTypeError(err); \
return Nan::ThrowTypeError(err); \
}

namespace libxmljs {
Expand Down
80 changes: 40 additions & 40 deletions src/xml_attribute.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

namespace libxmljs {

v8::Persistent<v8::FunctionTemplate> XmlAttribute::constructor_template;
Nan::Persistent<v8::FunctionTemplate> XmlAttribute::constructor_template;

NAN_METHOD(XmlAttribute::New) {
NanScope();
Nan::HandleScope scope;

NanReturnValue(args.Holder());
return info.GetReturnValue().Set(info.Holder());
}

v8::Local<v8::Object>
Expand All @@ -18,11 +18,11 @@ XmlAttribute::New(xmlNode* xml_obj, const xmlChar* name, const xmlChar* value)
assert(attr);

if (attr->_private) {
return NanObjectWrapHandle(static_cast<XmlNode*>(xml_obj->_private));
return static_cast<XmlNode*>(xml_obj->_private)->handle();
}

XmlAttribute* attribute = new XmlAttribute(attr);
v8::Local<v8::Object> obj = NanNew(constructor_template)->GetFunction()->NewInstance();
v8::Local<v8::Object> obj = Nan::New(constructor_template)->GetFunction()->NewInstance();
attribute->Wrap(obj);
return obj;
}
Expand All @@ -33,75 +33,75 @@ XmlAttribute::New(xmlAttr* attr)
assert(attr->type == XML_ATTRIBUTE_NODE);

if (attr->_private) {
return NanObjectWrapHandle(static_cast<XmlNode*>(attr->_private));
return static_cast<XmlNode*>(attr->_private)->handle();
}

XmlAttribute* attribute = new XmlAttribute(attr);
v8::Local<v8::Object> obj = NanNew(constructor_template)->GetFunction()->NewInstance();
v8::Local<v8::Object> obj = Nan::New(constructor_template)->GetFunction()->NewInstance();
attribute->Wrap(obj);
return obj;
}

NAN_METHOD(XmlAttribute::Name) {
NanScope();
XmlAttribute *attr = ObjectWrap::Unwrap<XmlAttribute>(args.Holder());
Nan::HandleScope scope;
XmlAttribute *attr = Nan::ObjectWrap::Unwrap<XmlAttribute>(info.Holder());
assert(attr);

NanReturnValue(attr->get_name());
return info.GetReturnValue().Set(attr->get_name());
}

NAN_METHOD(XmlAttribute::Value) {
NanScope();
XmlAttribute *attr = ObjectWrap::Unwrap<XmlAttribute>(args.Holder());
Nan::HandleScope scope;
XmlAttribute *attr = Nan::ObjectWrap::Unwrap<XmlAttribute>(info.Holder());
assert(attr);

// attr.value('new value');
if (args.Length() > 0) {
attr->set_value(*v8::String::Utf8Value(args[0]));
NanReturnValue(args.Holder());
if (info.Length() > 0) {
attr->set_value(*v8::String::Utf8Value(info[0]));
return info.GetReturnValue().Set(info.Holder());
}

// attr.value();
NanReturnValue(attr->get_value());
return info.GetReturnValue().Set(attr->get_value());
}

NAN_METHOD(XmlAttribute::Node) {
NanScope();
XmlAttribute *attr = ObjectWrap::Unwrap<XmlAttribute>(args.Holder());
Nan::HandleScope scope;
XmlAttribute *attr = Nan::ObjectWrap::Unwrap<XmlAttribute>(info.Holder());
assert(attr);

NanReturnValue(attr->get_element());
return info.GetReturnValue().Set(attr->get_element());
}

NAN_METHOD(XmlAttribute::Namespace) {
NanScope();
XmlAttribute *attr = ObjectWrap::Unwrap<XmlAttribute>(args.Holder());
Nan::HandleScope scope;
XmlAttribute *attr = Nan::ObjectWrap::Unwrap<XmlAttribute>(info.Holder());
assert(attr);

NanReturnValue(attr->get_namespace());
return info.GetReturnValue().Set(attr->get_namespace());
}

v8::Local<v8::Value>
XmlAttribute::get_name() {
if (xml_obj->name)
return NanNew<v8::String>((const char*)xml_obj->name,
xmlStrlen(xml_obj->name));
return Nan::New<v8::String>((const char*)xml_obj->name,
xmlStrlen(xml_obj->name)).ToLocalChecked();

return NanNull();
return Nan::Null();
}

v8::Local<v8::Value>
XmlAttribute::get_value() {
NanEscapableScope();
Nan::EscapableHandleScope scope;
xmlChar* value = xmlNodeGetContent(xml_obj);
if (value != NULL) {
v8::Local<v8::String> ret_value = NanNew<v8::String>((const char*)value,
xmlStrlen(value));
v8::Local<v8::String> ret_value = Nan::New<v8::String>((const char*)value,
xmlStrlen(value)).ToLocalChecked();
xmlFree(value);
return NanEscapeScope(ret_value);
return scope.Escape(ret_value);
}

return NanNull();
return Nan::Null();
}

void
Expand Down Expand Up @@ -142,26 +142,26 @@ XmlAttribute::get_element() {
v8::Local<v8::Value>
XmlAttribute::get_namespace() {
if (!xml_obj->ns) {
return NanNull();
return Nan::Null();
}
return XmlNamespace::New(xml_obj->ns);
}

void
XmlAttribute::Initialize(v8::Handle<v8::Object> target) {
NanScope();
Nan::HandleScope scope;
v8::Local<v8::FunctionTemplate> tmpl =
NanNew<v8::FunctionTemplate>(XmlAttribute::New);
NanAssignPersistent(constructor_template, tmpl);
tmpl->Inherit(NanNew(XmlNode::constructor_template));
Nan::New<v8::FunctionTemplate>(XmlAttribute::New);
constructor_template.Reset( tmpl);
tmpl->Inherit(Nan::New(XmlNode::constructor_template));
tmpl->InstanceTemplate()->SetInternalFieldCount(1);

NODE_SET_PROTOTYPE_METHOD(tmpl, "name", XmlAttribute::Name);
NODE_SET_PROTOTYPE_METHOD(tmpl, "value", XmlAttribute::Value);
NODE_SET_PROTOTYPE_METHOD(tmpl, "node", XmlAttribute::Node);
NODE_SET_PROTOTYPE_METHOD(tmpl, "namespace", XmlAttribute::Namespace);
Nan::SetPrototypeMethod(tmpl, "name", XmlAttribute::Name);
Nan::SetPrototypeMethod(tmpl, "value", XmlAttribute::Value);
Nan::SetPrototypeMethod(tmpl, "node", XmlAttribute::Node);
Nan::SetPrototypeMethod(tmpl, "namespace", XmlAttribute::Namespace);

target->Set(NanNew<v8::String>("Attribute"),
Nan::Set(target, Nan::New<v8::String>("Attribute").ToLocalChecked(),
tmpl->GetFunction());
}

Expand Down
2 changes: 1 addition & 1 deletion src/xml_attribute.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class XmlAttribute : public XmlNode {
XmlNode(reinterpret_cast<xmlNode*>(node)) {}

static void Initialize(v8::Handle<v8::Object> target);
static v8::Persistent<v8::FunctionTemplate> constructor_template;
static Nan::Persistent<v8::FunctionTemplate> constructor_template;

static v8::Local<v8::Object> New(xmlNode* xml_obj,
const xmlChar* name, const xmlChar* value);
Expand Down
Loading

0 comments on commit f6c2c2f

Please sign in to comment.