Commit d96ad377 by Marcin Cieslak

Update to io.js 3.0.0, use nan 2.0

The code has been updated to meet
the requirements of the updated V8 engine
as provided by io.js.

In some cases additional EscapableHandleScope
has been provided.

SassValueWrapper<T>::New has been changed:
in case of instance construction via
the function call "sass.types.Color(0,0,0)"
instead of "new sass.types.Color(0,0,0)"
the "new" part is no longer executed by
falling through. This should not be necessary
because the constructor is called by
the NewInstance call anyway.

This fixes the following error:

FATAL ERROR: v8::Object::SetAlignedPointerInInternalField() Internal field out of bounds
parent 34db8709
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
"glob": "^5.0.13", "glob": "^5.0.13",
"meow": "^3.3.0", "meow": "^3.3.0",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"nan": "^1.8.4", "nan": "^2.0.0",
"npmconf": "^2.1.2", "npmconf": "^2.1.2",
"pangyp": "^2.2.1", "pangyp": "^2.2.1",
"request": "^2.58.0", "request": "^2.58.0",
......
...@@ -37,12 +37,12 @@ union Sass_Value* sass_custom_function(const union Sass_Value* s_args, Sass_Func ...@@ -37,12 +37,12 @@ union Sass_Value* sass_custom_function(const union Sass_Value* s_args, Sass_Func
} }
} }
void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx_w, bool is_file, bool is_sync) { void ExtractOptions(v8::Local<v8::Object> options, void* cptr, sass_context_wrapper* ctx_w, bool is_file, bool is_sync) {
NanScope(); Nan::HandleScope scope;
struct Sass_Context* ctx; struct Sass_Context* ctx;
NanAssignPersistent(ctx_w->result, options->Get(NanNew("result"))->ToObject()); ctx_w->result.Reset(Nan::Get(options, Nan::New("result").ToLocalChecked()).ToLocalChecked()->ToObject());
if (is_file) { if (is_file) {
ctx_w->fctx = (struct Sass_File_Context*) cptr; ctx_w->fctx = (struct Sass_File_Context*) cptr;
...@@ -61,52 +61,52 @@ void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx ...@@ -61,52 +61,52 @@ void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx
ctx_w->request.data = ctx_w; ctx_w->request.data = ctx_w;
// async (callback) style // async (callback) style
Local<Function> success_callback = Local<Function>::Cast(options->Get(NanNew("success"))); v8::Local<v8::Function> success_callback = v8::Local<v8::Function>::Cast(Nan::Get(options, Nan::New("success").ToLocalChecked()).ToLocalChecked());
Local<Function> error_callback = Local<Function>::Cast(options->Get(NanNew("error"))); v8::Local<v8::Function> error_callback = v8::Local<v8::Function>::Cast(Nan::Get(options, Nan::New("error").ToLocalChecked()).ToLocalChecked());
ctx_w->success_callback = new NanCallback(success_callback); ctx_w->success_callback = new Nan::Callback(success_callback);
ctx_w->error_callback = new NanCallback(error_callback); ctx_w->error_callback = new Nan::Callback(error_callback);
} }
if (!is_file) { if (!is_file) {
ctx_w->file = create_string(options->Get(NanNew("file"))); ctx_w->file = create_string(Nan::Get(options, Nan::New("file").ToLocalChecked()));
sass_option_set_input_path(sass_options, ctx_w->file); sass_option_set_input_path(sass_options, ctx_w->file);
} }
int indent_len = options->Get(NanNew("indentWidth"))->Int32Value(); int indent_len = Nan::Get(options, Nan::New("indentWidth").ToLocalChecked()).ToLocalChecked()->Int32Value();
ctx_w->indent = (char*)malloc(indent_len + 1); ctx_w->indent = (char*)malloc(indent_len + 1);
strcpy(ctx_w->indent, std::string( strcpy(ctx_w->indent, std::string(
indent_len, indent_len,
options->Get(NanNew("indentType"))->Int32Value() == 1 ? '\t' : ' ' Nan::Get(options, Nan::New("indentType").ToLocalChecked()).ToLocalChecked()->Int32Value() == 1 ? '\t' : ' '
).c_str()); ).c_str());
ctx_w->linefeed = create_string(options->Get(NanNew("linefeed"))); ctx_w->linefeed = create_string(Nan::Get(options, Nan::New("linefeed").ToLocalChecked()));
ctx_w->include_path = create_string(options->Get(NanNew("includePaths"))); ctx_w->include_path = create_string(Nan::Get(options, Nan::New("includePaths").ToLocalChecked()));
ctx_w->out_file = create_string(options->Get(NanNew("outFile"))); ctx_w->out_file = create_string(Nan::Get(options, Nan::New("outFile").ToLocalChecked()));
ctx_w->source_map = create_string(options->Get(NanNew("sourceMap"))); ctx_w->source_map = create_string(Nan::Get(options, Nan::New("sourceMap").ToLocalChecked()));
ctx_w->source_map_root = create_string(options->Get(NanNew("sourceMapRoot"))); ctx_w->source_map_root = create_string(Nan::Get(options, Nan::New("sourceMapRoot").ToLocalChecked()));
sass_option_set_output_path(sass_options, ctx_w->out_file); sass_option_set_output_path(sass_options, ctx_w->out_file);
sass_option_set_output_style(sass_options, (Sass_Output_Style)options->Get(NanNew("style"))->Int32Value()); sass_option_set_output_style(sass_options, (Sass_Output_Style)Nan::Get(options, Nan::New("style").ToLocalChecked()).ToLocalChecked()->Int32Value());
sass_option_set_is_indented_syntax_src(sass_options, options->Get(NanNew("indentedSyntax"))->BooleanValue()); sass_option_set_is_indented_syntax_src(sass_options, Nan::Get(options, Nan::New("indentedSyntax").ToLocalChecked()).ToLocalChecked()->BooleanValue());
sass_option_set_source_comments(sass_options, options->Get(NanNew("sourceComments"))->BooleanValue()); sass_option_set_source_comments(sass_options, Nan::Get(options, Nan::New("sourceComments").ToLocalChecked()).ToLocalChecked()->BooleanValue());
sass_option_set_omit_source_map_url(sass_options, options->Get(NanNew("omitSourceMapUrl"))->BooleanValue()); sass_option_set_omit_source_map_url(sass_options, Nan::Get(options, Nan::New("omitSourceMapUrl").ToLocalChecked()).ToLocalChecked()->BooleanValue());
sass_option_set_source_map_embed(sass_options, options->Get(NanNew("sourceMapEmbed"))->BooleanValue()); sass_option_set_source_map_embed(sass_options, Nan::Get(options, Nan::New("sourceMapEmbed").ToLocalChecked()).ToLocalChecked()->BooleanValue());
sass_option_set_source_map_contents(sass_options, options->Get(NanNew("sourceMapContents"))->BooleanValue()); sass_option_set_source_map_contents(sass_options, Nan::Get(options, Nan::New("sourceMapContents").ToLocalChecked()).ToLocalChecked()->BooleanValue());
sass_option_set_source_map_file(sass_options, ctx_w->source_map); sass_option_set_source_map_file(sass_options, ctx_w->source_map);
sass_option_set_source_map_root(sass_options, ctx_w->source_map_root); sass_option_set_source_map_root(sass_options, ctx_w->source_map_root);
sass_option_set_include_path(sass_options, ctx_w->include_path); sass_option_set_include_path(sass_options, ctx_w->include_path);
sass_option_set_precision(sass_options, options->Get(NanNew("precision"))->Int32Value()); sass_option_set_precision(sass_options, Nan::Get(options, Nan::New("precision").ToLocalChecked()).ToLocalChecked()->Int32Value());
sass_option_set_indent(sass_options, ctx_w->indent); sass_option_set_indent(sass_options, ctx_w->indent);
sass_option_set_linefeed(sass_options, ctx_w->linefeed); sass_option_set_linefeed(sass_options, ctx_w->linefeed);
Local<Value> importer_callback = options->Get(NanNew("importer")); v8::Local<v8::Value> importer_callback = Nan::Get(options, Nan::New("importer").ToLocalChecked()).ToLocalChecked();
if (importer_callback->IsFunction()) { if (importer_callback->IsFunction()) {
Local<Function> importer = Local<Function>::Cast(importer_callback); v8::Local<v8::Function> importer = v8::Local<v8::Function>::Cast(importer_callback);
auto bridge = std::make_shared<CustomImporterBridge>(new NanCallback(importer), ctx_w->is_sync); auto bridge = std::make_shared<CustomImporterBridge>(new Nan::Callback(importer), ctx_w->is_sync);
ctx_w->importer_bridges.push_back(bridge); ctx_w->importer_bridges.push_back(bridge);
Sass_Importer_List c_importers = sass_make_importer_list(1); Sass_Importer_List c_importers = sass_make_importer_list(1);
...@@ -115,13 +115,13 @@ void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx ...@@ -115,13 +115,13 @@ void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx
sass_option_set_c_importers(sass_options, c_importers); sass_option_set_c_importers(sass_options, c_importers);
} }
else if (importer_callback->IsArray()) { else if (importer_callback->IsArray()) {
Handle<Array> importers = Handle<Array>::Cast(importer_callback); v8::Local<v8::Array> importers = v8::Local<v8::Array>::Cast(importer_callback);
Sass_Importer_List c_importers = sass_make_importer_list(importers->Length()); Sass_Importer_List c_importers = sass_make_importer_list(importers->Length());
for (size_t i = 0; i < importers->Length(); ++i) { for (size_t i = 0; i < importers->Length(); ++i) {
Local<Function> callback = Local<Function>::Cast(importers->Get(static_cast<uint32_t>(i))); v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(Nan::Get(importers, static_cast<uint32_t>(i)).ToLocalChecked());
auto bridge = std::make_shared<CustomImporterBridge>(new NanCallback(callback), ctx_w->is_sync); auto bridge = std::make_shared<CustomImporterBridge>(new Nan::Callback(callback), ctx_w->is_sync);
ctx_w->importer_bridges.push_back(bridge); ctx_w->importer_bridges.push_back(bridge);
c_importers[i] = sass_make_importer(sass_importer, importers->Length() - i - 1, bridge.get()); c_importers[i] = sass_make_importer(sass_importer, importers->Length() - i - 1, bridge.get());
...@@ -130,19 +130,19 @@ void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx ...@@ -130,19 +130,19 @@ void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx
sass_option_set_c_importers(sass_options, c_importers); sass_option_set_c_importers(sass_options, c_importers);
} }
Local<Value> custom_functions = options->Get(NanNew("functions")); v8::Local<v8::Value> custom_functions = Nan::Get(options, Nan::New("functions").ToLocalChecked()).ToLocalChecked();
if (custom_functions->IsObject()) { if (custom_functions->IsObject()) {
Local<Object> functions = Local<Object>::Cast(custom_functions); v8::Local<v8::Object> functions = v8::Local<v8::Object>::Cast(custom_functions);
Local<Array> signatures = functions->GetOwnPropertyNames(); v8::Local<v8::Array> signatures = Nan::GetOwnPropertyNames(functions).ToLocalChecked();
unsigned num_signatures = signatures->Length(); unsigned num_signatures = signatures->Length();
Sass_Function_List fn_list = sass_make_function_list(num_signatures); Sass_Function_List fn_list = sass_make_function_list(num_signatures);
for (unsigned i = 0; i < num_signatures; i++) { for (unsigned i = 0; i < num_signatures; i++) {
Local<String> signature = Local<String>::Cast(signatures->Get(NanNew(i))); v8::Local<v8::String> signature = v8::Local<v8::String>::Cast(Nan::Get(signatures, Nan::New(i)).ToLocalChecked());
Local<Function> callback = Local<Function>::Cast(functions->Get(signature)); v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(Nan::Get(functions, signature).ToLocalChecked());
auto bridge = std::make_shared<CustomFunctionBridge>(new NanCallback(callback), ctx_w->is_sync); auto bridge = std::make_shared<CustomFunctionBridge>(new Nan::Callback(callback), ctx_w->is_sync);
ctx_w->function_bridges.push_back(bridge); ctx_w->function_bridges.push_back(bridge);
Sass_Function_Entry fn = sass_make_function(create_string(signature), sass_custom_function, bridge.get()); Sass_Function_Entry fn = sass_make_function(create_string(signature), sass_custom_function, bridge.get());
...@@ -154,48 +154,51 @@ void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx ...@@ -154,48 +154,51 @@ void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx
} }
void GetStats(sass_context_wrapper* ctx_w, Sass_Context* ctx) { void GetStats(sass_context_wrapper* ctx_w, Sass_Context* ctx) {
NanScope(); Nan::HandleScope scope;
char** included_files = sass_context_get_included_files(ctx); char** included_files = sass_context_get_included_files(ctx);
Handle<Array> arr = NanNew<Array>(); v8::Local<v8::Array> arr = Nan::New<v8::Array>();
if (included_files) { if (included_files) {
for (int i = 0; included_files[i] != nullptr; ++i) { for (int i = 0; included_files[i] != nullptr; ++i) {
arr->Set(i, NanNew<String>(included_files[i])); Nan::Set(arr, i, Nan::New<v8::String>(included_files[i]).ToLocalChecked());
} }
} }
NanNew(ctx_w->result)->Get(NanNew("stats"))->ToObject()->Set(NanNew("includedFiles"), arr); Nan::Set(Nan::Get(Nan::New(ctx_w->result), Nan::New("stats").ToLocalChecked()).ToLocalChecked()->ToObject(), Nan::New("includedFiles").ToLocalChecked(), arr);
} }
int GetResult(sass_context_wrapper* ctx_w, Sass_Context* ctx, bool is_sync = false) { int GetResult(sass_context_wrapper* ctx_w, Sass_Context* ctx, bool is_sync = false) {
NanScope(); Nan::HandleScope scope;
v8::Local<v8::Object> result;
int status = sass_context_get_error_status(ctx); int status = sass_context_get_error_status(ctx);
result = Nan::New(ctx_w->result);
if (status == 0) { if (status == 0) {
const char* css = sass_context_get_output_string(ctx); const char* css = sass_context_get_output_string(ctx);
const char* map = sass_context_get_source_map_string(ctx); const char* map = sass_context_get_source_map_string(ctx);
NanNew(ctx_w->result)->Set(NanNew("css"), NanNewBufferHandle(css, static_cast<uint32_t>(strlen(css)))); Nan::Set(result, Nan::New("css").ToLocalChecked(), Nan::CopyBuffer(css, static_cast<uint32_t>(strlen(css))).ToLocalChecked());
GetStats(ctx_w, ctx); GetStats(ctx_w, ctx);
if (map) { if (map) {
NanNew(ctx_w->result)->Set(NanNew("map"), NanNewBufferHandle(map, static_cast<uint32_t>(strlen(map)))); Nan::Set(result, Nan::New("map").ToLocalChecked(), Nan::CopyBuffer(map, static_cast<uint32_t>(strlen(map))).ToLocalChecked());
} }
} }
else if (is_sync) { else if (is_sync) {
NanNew(ctx_w->result)->Set(NanNew("error"), NanNew<String>(sass_context_get_error_json(ctx))); Nan::Set(result, Nan::New("error").ToLocalChecked(), Nan::New<v8::String>(sass_context_get_error_json(ctx)).ToLocalChecked());
} }
return status; return status;
} }
void MakeCallback(uv_work_t* req) { void MakeCallback(uv_work_t* req) {
NanScope(); Nan::HandleScope scope;
TryCatch try_catch; Nan::TryCatch try_catch;
sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data); sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data);
struct Sass_Context* ctx; struct Sass_Context* ctx;
...@@ -215,23 +218,22 @@ void MakeCallback(uv_work_t* req) { ...@@ -215,23 +218,22 @@ void MakeCallback(uv_work_t* req) {
else if (ctx_w->error_callback) { else if (ctx_w->error_callback) {
// if error, do callback(error) // if error, do callback(error)
const char* err = sass_context_get_error_json(ctx); const char* err = sass_context_get_error_json(ctx);
Local<Value> argv[] = { v8::Local<v8::Value> argv[] = {
NanNew<String>(err) Nan::New<v8::String>(err).ToLocalChecked()
}; };
ctx_w->error_callback->Call(1, argv); ctx_w->error_callback->Call(1, argv);
} }
if (try_catch.HasCaught()) { if (try_catch.HasCaught()) {
node::FatalException(try_catch); Nan::FatalException(try_catch);
} }
sass_free_context_wrapper(ctx_w); sass_free_context_wrapper(ctx_w);
} }
NAN_METHOD(render) { NAN_METHOD(render) {
NanScope();
Local<Object> options = args[0]->ToObject(); v8::Local<v8::Object> options = info[0]->ToObject();
char* source_string = create_string(options->Get(NanNew("data"))); char* source_string = create_string(Nan::Get(options, Nan::New("data").ToLocalChecked()));
struct Sass_Data_Context* dctx = sass_make_data_context(source_string); struct Sass_Data_Context* dctx = sass_make_data_context(source_string);
sass_context_wrapper* ctx_w = sass_make_context_wrapper(); sass_context_wrapper* ctx_w = sass_make_context_wrapper();
...@@ -241,14 +243,13 @@ NAN_METHOD(render) { ...@@ -241,14 +243,13 @@ NAN_METHOD(render) {
assert(status == 0); assert(status == 0);
NanReturnUndefined(); return;
} }
NAN_METHOD(render_sync) { NAN_METHOD(render_sync) {
NanScope();
Local<Object> options = args[0]->ToObject(); v8::Local<v8::Object> options = info[0]->ToObject();
char* source_string = create_string(options->Get(NanNew("data"))); char* source_string = create_string(Nan::Get(options, Nan::New("data").ToLocalChecked()));
struct Sass_Data_Context* dctx = sass_make_data_context(source_string); struct Sass_Data_Context* dctx = sass_make_data_context(source_string);
struct Sass_Context* ctx = sass_data_context_get_context(dctx); struct Sass_Context* ctx = sass_data_context_get_context(dctx);
sass_context_wrapper* ctx_w = sass_make_context_wrapper(); sass_context_wrapper* ctx_w = sass_make_context_wrapper();
...@@ -261,14 +262,13 @@ NAN_METHOD(render_sync) { ...@@ -261,14 +262,13 @@ NAN_METHOD(render_sync) {
sass_free_context_wrapper(ctx_w); sass_free_context_wrapper(ctx_w);
NanReturnValue(NanNew<Boolean>(result == 0)); info.GetReturnValue().Set(Nan::New<v8::Boolean>(result == 0));
} }
NAN_METHOD(render_file) { NAN_METHOD(render_file) {
NanScope();
Local<Object> options = args[0]->ToObject(); v8::Local<v8::Object> options = info[0]->ToObject();
char* input_path = create_string(options->Get(NanNew("file"))); char* input_path = create_string(Nan::Get(options, Nan::New("file").ToLocalChecked()));
struct Sass_File_Context* fctx = sass_make_file_context(input_path); struct Sass_File_Context* fctx = sass_make_file_context(input_path);
sass_context_wrapper* ctx_w = sass_make_context_wrapper(); sass_context_wrapper* ctx_w = sass_make_context_wrapper();
...@@ -278,14 +278,13 @@ NAN_METHOD(render_file) { ...@@ -278,14 +278,13 @@ NAN_METHOD(render_file) {
assert(status == 0); assert(status == 0);
NanReturnUndefined(); return;
} }
NAN_METHOD(render_file_sync) { NAN_METHOD(render_file_sync) {
NanScope();
Local<Object> options = args[0]->ToObject(); v8::Local<v8::Object> options = info[0]->ToObject();
char* input_path = create_string(options->Get(NanNew("file"))); char* input_path = create_string(Nan::Get(options, Nan::New("file").ToLocalChecked()));
struct Sass_File_Context* fctx = sass_make_file_context(input_path); struct Sass_File_Context* fctx = sass_make_file_context(input_path);
struct Sass_Context* ctx = sass_file_context_get_context(fctx); struct Sass_Context* ctx = sass_file_context_get_context(fctx);
sass_context_wrapper* ctx_w = sass_make_context_wrapper(); sass_context_wrapper* ctx_w = sass_make_context_wrapper();
...@@ -298,20 +297,19 @@ NAN_METHOD(render_file_sync) { ...@@ -298,20 +297,19 @@ NAN_METHOD(render_file_sync) {
free(input_path); free(input_path);
sass_free_context_wrapper(ctx_w); sass_free_context_wrapper(ctx_w);
NanReturnValue(NanNew<Boolean>(result == 0)); info.GetReturnValue().Set(Nan::New<v8::Boolean>(result == 0));
} }
NAN_METHOD(libsass_version) { NAN_METHOD(libsass_version) {
NanScope(); info.GetReturnValue().Set(Nan::New<v8::String>(libsass_version()).ToLocalChecked());
NanReturnValue(NanNew<String>(libsass_version()));
} }
void RegisterModule(v8::Handle<v8::Object> target) { void RegisterModule(v8::Local<v8::Object> target) {
NODE_SET_METHOD(target, "render", render); Nan::SetMethod(target, "render", render);
NODE_SET_METHOD(target, "renderSync", render_sync); Nan::SetMethod(target, "renderSync", render_sync);
NODE_SET_METHOD(target, "renderFile", render_file); Nan::SetMethod(target, "renderFile", render_file);
NODE_SET_METHOD(target, "renderFileSync", render_file_sync); Nan::SetMethod(target, "renderFileSync", render_file_sync);
NODE_SET_METHOD(target, "libsassVersion", libsass_version); Nan::SetMethod(target, "libsassVersion", libsass_version);
SassTypes::Factory::initExports(target); SassTypes::Factory::initExports(target);
} }
......
...@@ -8,12 +8,10 @@ ...@@ -8,12 +8,10 @@
#define COMMA , #define COMMA ,
using namespace v8;
template <typename T, typename L = void*> template <typename T, typename L = void*>
class CallbackBridge { class CallbackBridge {
public: public:
CallbackBridge(NanCallback*, bool); CallbackBridge(Nan::Callback*, bool);
virtual ~CallbackBridge(); virtual ~CallbackBridge();
// Executes the callback // Executes the callback
...@@ -22,12 +20,12 @@ class CallbackBridge { ...@@ -22,12 +20,12 @@ class CallbackBridge {
protected: protected:
// We will expose a bridge object to the JS callback that wraps this instance so we don't loose context. // We will expose a bridge object to the JS callback that wraps this instance so we don't loose context.
// This is the V8 constructor for such objects. // This is the V8 constructor for such objects.
static Handle<Function> get_wrapper_constructor(); static Nan::MaybeLocal<v8::Function> get_wrapper_constructor();
static void async_gone(uv_handle_t *handle); static void async_gone(uv_handle_t *handle);
static NAN_METHOD(New); static NAN_METHOD(New);
static NAN_METHOD(ReturnCallback); static NAN_METHOD(ReturnCallback);
static Persistent<Function> wrapper_constructor; static Nan::Persistent<v8::Function> wrapper_constructor;
Persistent<Object> wrapper; Nan::Persistent<v8::Object> wrapper;
// The callback that will get called in the main thread after the worker thread used for the sass // The callback that will get called in the main thread after the worker thread used for the sass
// compilation step makes a call to uv_async_send() // compilation step makes a call to uv_async_send()
...@@ -36,12 +34,12 @@ class CallbackBridge { ...@@ -36,12 +34,12 @@ class CallbackBridge {
// The V8 values sent to our ReturnCallback must be read on the main thread not the sass worker thread. // The V8 values sent to our ReturnCallback must be read on the main thread not the sass worker thread.
// This gives a chance to specialized subclasses to transform those values into whatever makes sense to // This gives a chance to specialized subclasses to transform those values into whatever makes sense to
// sass before we resume the worker thread. // sass before we resume the worker thread.
virtual T post_process_return_value(Handle<Value>) const =0; virtual T post_process_return_value(v8::Local<v8::Value>) const =0;
virtual std::vector<Handle<Value>> pre_process_args(std::vector<L>) const =0; virtual std::vector<v8::Local<v8::Value>> pre_process_args(std::vector<L>) const =0;
NanCallback* callback; Nan::Callback* callback;
bool is_sync; bool is_sync;
std::mutex cv_mutex; std::mutex cv_mutex;
...@@ -53,10 +51,10 @@ class CallbackBridge { ...@@ -53,10 +51,10 @@ class CallbackBridge {
}; };
template <typename T, typename L> template <typename T, typename L>
Persistent<Function> CallbackBridge<T, L>::wrapper_constructor; Nan::Persistent<v8::Function> CallbackBridge<T, L>::wrapper_constructor;
template <typename T, typename L> template <typename T, typename L>
CallbackBridge<T, L>::CallbackBridge(NanCallback* callback, bool is_sync) : callback(callback), is_sync(is_sync) { CallbackBridge<T, L>::CallbackBridge(Nan::Callback* callback, bool is_sync) : callback(callback), is_sync(is_sync) {
// This assumes the main thread will be the one instantiating the bridge // This assumes the main thread will be the one instantiating the bridge
if (!is_sync) { if (!is_sync) {
this->async = new uv_async_t; this->async = new uv_async_t;
...@@ -64,14 +62,15 @@ CallbackBridge<T, L>::CallbackBridge(NanCallback* callback, bool is_sync) : call ...@@ -64,14 +62,15 @@ CallbackBridge<T, L>::CallbackBridge(NanCallback* callback, bool is_sync) : call
uv_async_init(uv_default_loop(), this->async, (uv_async_cb) dispatched_async_uv_callback); uv_async_init(uv_default_loop(), this->async, (uv_async_cb) dispatched_async_uv_callback);
} }
NanAssignPersistent(wrapper, NanNew(CallbackBridge<T, L>::get_wrapper_constructor())->NewInstance()); v8::Local<v8::Function> func = CallbackBridge<T, L>::get_wrapper_constructor().ToLocalChecked();
NanSetInternalFieldPointer(NanNew(wrapper), 0, this); wrapper.Reset(Nan::NewInstance(func).ToLocalChecked());
Nan::SetInternalFieldPointer(Nan::New(wrapper), 0, this);
} }
template <typename T, typename L> template <typename T, typename L>
CallbackBridge<T, L>::~CallbackBridge() { CallbackBridge<T, L>::~CallbackBridge() {
delete this->callback; delete this->callback;
NanDisposePersistent(this->wrapper); this->wrapper.Reset();
if (!is_sync) { if (!is_sync) {
uv_close((uv_handle_t*)this->async, &async_gone); uv_close((uv_handle_t*)this->async, &async_gone);
...@@ -81,13 +80,13 @@ CallbackBridge<T, L>::~CallbackBridge() { ...@@ -81,13 +80,13 @@ CallbackBridge<T, L>::~CallbackBridge() {
template <typename T, typename L> template <typename T, typename L>
T CallbackBridge<T, L>::operator()(std::vector<void*> argv) { T CallbackBridge<T, L>::operator()(std::vector<void*> argv) {
// argv.push_back(wrapper); // argv.push_back(wrapper);
if (this->is_sync) { if (this->is_sync) {
std::vector<Handle<Value>> argv_v8 = pre_process_args(argv); Nan::EscapableHandleScope scope;
argv_v8.push_back(NanNew(wrapper)); std::vector<v8::Local<v8::Value>> argv_v8 = pre_process_args(argv);
argv_v8.push_back(Nan::New(wrapper));
return this->post_process_return_value( return this->post_process_return_value(
NanNew<Value>(this->callback->Call(argv_v8.size(), &argv_v8[0])) scope.Escape(this->callback->Call(argv_v8.size(), &argv_v8[0]))
); );
} }
...@@ -105,27 +104,26 @@ template <typename T, typename L> ...@@ -105,27 +104,26 @@ template <typename T, typename L>
void CallbackBridge<T, L>::dispatched_async_uv_callback(uv_async_t *req) { void CallbackBridge<T, L>::dispatched_async_uv_callback(uv_async_t *req) {
CallbackBridge* bridge = static_cast<CallbackBridge*>(req->data); CallbackBridge* bridge = static_cast<CallbackBridge*>(req->data);
NanScope(); Nan::HandleScope scope;
TryCatch try_catch; Nan::TryCatch try_catch;
std::vector<Handle<Value>> argv_v8 = bridge->pre_process_args(bridge->argv); std::vector<v8::Local<v8::Value>> argv_v8 = bridge->pre_process_args(bridge->argv);
argv_v8.push_back(NanNew(bridge->wrapper)); argv_v8.push_back(Nan::New(bridge->wrapper));
NanNew<Value>(bridge->callback->Call(argv_v8.size(), &argv_v8[0])); bridge->callback->Call(argv_v8.size(), &argv_v8[0]);
if (try_catch.HasCaught()) { if (try_catch.HasCaught()) {
node::FatalException(try_catch); Nan::FatalException(try_catch);
} }
} }
template <typename T, typename L> template <typename T, typename L>
NAN_METHOD(CallbackBridge<T COMMA L>::ReturnCallback) { NAN_METHOD(CallbackBridge<T COMMA L>::ReturnCallback) {
NanScope();
CallbackBridge<T, L>* bridge = static_cast<CallbackBridge<T, L>*>(NanGetInternalFieldPointer(args.This(), 0)); CallbackBridge<T, L>* bridge = static_cast<CallbackBridge<T, L>*>(Nan::GetInternalFieldPointer(info.This(), 0));
TryCatch try_catch; Nan::TryCatch try_catch;
bridge->return_value = bridge->post_process_return_value(args[0]); bridge->return_value = bridge->post_process_return_value(info[0]);
{ {
std::lock_guard<std::mutex> lock(bridge->cv_mutex); std::lock_guard<std::mutex> lock(bridge->cv_mutex);
...@@ -135,33 +133,32 @@ NAN_METHOD(CallbackBridge<T COMMA L>::ReturnCallback) { ...@@ -135,33 +133,32 @@ NAN_METHOD(CallbackBridge<T COMMA L>::ReturnCallback) {
bridge->condition_variable.notify_all(); bridge->condition_variable.notify_all();
if (try_catch.HasCaught()) { if (try_catch.HasCaught()) {
node::FatalException(try_catch); Nan::FatalException(try_catch);
} }
NanReturnUndefined(); return;
} }
template <typename T, typename L> template <typename T, typename L>
Handle<Function> CallbackBridge<T, L>::get_wrapper_constructor() { Nan::MaybeLocal<v8::Function> CallbackBridge<T, L>::get_wrapper_constructor() {
if (wrapper_constructor.IsEmpty()) { if (wrapper_constructor.IsEmpty()) {
Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(New); v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
tpl->SetClassName(NanNew("CallbackBridge")); tpl->SetClassName(Nan::New("CallbackBridge").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1); tpl->InstanceTemplate()->SetInternalFieldCount(1);
tpl->PrototypeTemplate()->Set(
NanNew("success"), Nan::SetPrototypeTemplate(tpl, "success",
NanNew<FunctionTemplate>(ReturnCallback)->GetFunction() Nan::GetFunction(Nan::New<v8::FunctionTemplate>(ReturnCallback)).ToLocalChecked()
); );
NanAssignPersistent(wrapper_constructor, tpl->GetFunction()); wrapper_constructor.Reset(Nan::GetFunction(tpl).ToLocalChecked());
} }
return NanNew(wrapper_constructor); return Nan::New(wrapper_constructor);
} }
template <typename T, typename L> template <typename T, typename L>
NAN_METHOD(CallbackBridge<T COMMA L>::New) { NAN_METHOD(CallbackBridge<T COMMA L>::New) {
NanScope(); info.GetReturnValue().Set(info.This());
NanReturnValue(args.This());
} }
template <typename T, typename L> template <typename T, typename L>
......
...@@ -3,12 +3,18 @@ ...@@ -3,12 +3,18 @@
#include <string.h> #include <string.h>
#include "create_string.h" #include "create_string.h"
char* create_string(Local<Value> value) { char* create_string(Nan::MaybeLocal<v8::Value> maybevalue) {
v8::Local<v8::Value> value;
if (maybevalue.ToLocal(&value)) {
if (value->IsNull() || !value->IsString()) { if (value->IsNull() || !value->IsString()) {
return 0; return 0;
} }
} else {
return 0;
}
String::Utf8Value string(value); v8::String::Utf8Value string(value);
char *str = (char *)malloc(string.length() + 1); char *str = (char *)malloc(string.length() + 1);
strcpy(str, *string); strcpy(str, *string);
return str; return str;
......
...@@ -3,8 +3,6 @@ ...@@ -3,8 +3,6 @@
#include <nan.h> #include <nan.h>
using namespace v8; char* create_string(Nan::MaybeLocal<v8::Value>);
char* create_string(Local<Value>);
#endif #endif
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include "custom_function_bridge.h" #include "custom_function_bridge.h"
#include "sass_types/factory.h" #include "sass_types/factory.h"
Sass_Value* CustomFunctionBridge::post_process_return_value(Handle<Value> val) const { Sass_Value* CustomFunctionBridge::post_process_return_value(v8::Local<v8::Value> val) const {
try { try {
return SassTypes::Factory::unwrap(val)->get_sass_value(); return SassTypes::Factory::unwrap(val)->get_sass_value();
} }
...@@ -11,8 +11,8 @@ Sass_Value* CustomFunctionBridge::post_process_return_value(Handle<Value> val) c ...@@ -11,8 +11,8 @@ Sass_Value* CustomFunctionBridge::post_process_return_value(Handle<Value> val) c
} }
} }
std::vector<Handle<Value>> CustomFunctionBridge::pre_process_args(std::vector<void*> in) const { std::vector<v8::Local<v8::Value>> CustomFunctionBridge::pre_process_args(std::vector<void*> in) const {
std::vector<Handle<Value>> argv = std::vector<Handle<Value>>(); std::vector<v8::Local<v8::Value>> argv = std::vector<v8::Local<v8::Value>>();
for (void* value : in) { for (void* value : in) {
argv.push_back(SassTypes::Factory::create(static_cast<Sass_Value*>(value))->get_js_object()); argv.push_back(SassTypes::Factory::create(static_cast<Sass_Value*>(value))->get_js_object());
......
...@@ -5,15 +5,13 @@ ...@@ -5,15 +5,13 @@
#include <sass_context.h> #include <sass_context.h>
#include "callback_bridge.h" #include "callback_bridge.h"
using namespace v8;
class CustomFunctionBridge : public CallbackBridge<Sass_Value*> { class CustomFunctionBridge : public CallbackBridge<Sass_Value*> {
public: public:
CustomFunctionBridge(NanCallback* cb, bool is_sync) : CallbackBridge<Sass_Value*>(cb, is_sync) {} CustomFunctionBridge(Nan::Callback* cb, bool is_sync) : CallbackBridge<Sass_Value*>(cb, is_sync) {}
private: private:
Sass_Value* post_process_return_value(Handle<Value>) const; Sass_Value* post_process_return_value(v8::Local<v8::Value>) const;
std::vector<Handle<Value>> pre_process_args(std::vector<void*>) const; std::vector<v8::Local<v8::Value>> pre_process_args(std::vector<void*>) const;
}; };
#endif #endif
...@@ -2,19 +2,17 @@ ...@@ -2,19 +2,17 @@
#include "custom_importer_bridge.h" #include "custom_importer_bridge.h"
#include "create_string.h" #include "create_string.h"
SassImportList CustomImporterBridge::post_process_return_value(Handle<Value> val) const { SassImportList CustomImporterBridge::post_process_return_value(v8::Local<v8::Value> returned_value) const {
SassImportList imports = 0; SassImportList imports = 0;
NanScope(); Nan::HandleScope scope;
Local<Value> returned_value = NanNew(val);
if (returned_value->IsArray()) { if (returned_value->IsArray()) {
Handle<Array> array = Handle<Array>::Cast(returned_value); v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(returned_value);
imports = sass_make_import_list(array->Length()); imports = sass_make_import_list(array->Length());
for (size_t i = 0; i < array->Length(); ++i) { for (size_t i = 0; i < array->Length(); ++i) {
Local<Value> value = array->Get(static_cast<uint32_t>(i)); v8::Local<v8::Value> value = Nan::Get(array, static_cast<uint32_t>(i)).ToLocalChecked();
if (!value->IsObject()) { if (!value->IsObject()) {
auto entry = sass_make_import_entry(0, 0, 0); auto entry = sass_make_import_entry(0, 0, 0);
...@@ -22,10 +20,10 @@ SassImportList CustomImporterBridge::post_process_return_value(Handle<Value> val ...@@ -22,10 +20,10 @@ SassImportList CustomImporterBridge::post_process_return_value(Handle<Value> val
continue; continue;
} }
Local<Object> object = Local<Object>::Cast(value); v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value);
if (value->IsNativeError()) { if (value->IsNativeError()) {
char* message = create_string(object->Get(NanNew<String>("message"))); char* message = create_string(Nan::Get(object, Nan::New<v8::String>("message").ToLocalChecked()));
imports[i] = sass_make_import_entry(0, 0, 0); imports[i] = sass_make_import_entry(0, 0, 0);
...@@ -38,8 +36,8 @@ SassImportList CustomImporterBridge::post_process_return_value(Handle<Value> val ...@@ -38,8 +36,8 @@ SassImportList CustomImporterBridge::post_process_return_value(Handle<Value> val
} }
else if (returned_value->IsNativeError()) { else if (returned_value->IsNativeError()) {
imports = sass_make_import_list(1); imports = sass_make_import_list(1);
Local<Object> object = Local<Object>::Cast(returned_value); v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(returned_value);
char* message = create_string(object->Get(NanNew<String>("message"))); char* message = create_string(Nan::Get(object, Nan::New<v8::String>("message").ToLocalChecked()));
imports[0] = sass_make_import_entry(0, 0, 0); imports[0] = sass_make_import_entry(0, 0, 0);
...@@ -47,36 +45,42 @@ SassImportList CustomImporterBridge::post_process_return_value(Handle<Value> val ...@@ -47,36 +45,42 @@ SassImportList CustomImporterBridge::post_process_return_value(Handle<Value> val
} }
else if (returned_value->IsObject()) { else if (returned_value->IsObject()) {
imports = sass_make_import_list(1); imports = sass_make_import_list(1);
imports[0] = get_importer_entry(Local<Object>::Cast(returned_value)); imports[0] = get_importer_entry(v8::Local<v8::Object>::Cast(returned_value));
} }
return imports; return imports;
} }
Sass_Import* CustomImporterBridge::get_importer_entry(const Local<Object>& object) const { Sass_Import* CustomImporterBridge::check_returned_string(Nan::MaybeLocal<v8::Value> value, const char *msg) const
auto returned_file = object->Get(NanNew<String>("file")); {
v8::Local<v8::Value> checked;
if (!returned_file->IsUndefined() && !returned_file->IsString()) { if (value.ToLocal(&checked)) {
if (!checked->IsUndefined() && !checked->IsString()) {
goto err;
} else {
return nullptr;
}
}
err:
auto entry = sass_make_import_entry(0, 0, 0); auto entry = sass_make_import_entry(0, 0, 0);
sass_import_set_error(entry, "returned value of `file` must be a string", -1, -1); sass_import_set_error(entry, msg, -1, -1);
return entry; return entry;
} }
auto returned_contents = object->Get(NanNew<String>("contents")); Sass_Import* CustomImporterBridge::get_importer_entry(const v8::Local<v8::Object>& object) const {
auto returned_file = Nan::Get(object, Nan::New<v8::String>("file").ToLocalChecked());
auto returned_contents = Nan::Get(object, Nan::New<v8::String>("contents").ToLocalChecked()).ToLocalChecked();
auto returned_map = Nan::Get(object, Nan::New<v8::String>("map").ToLocalChecked());
Sass_Import *err;
if (!returned_contents->IsUndefined() && !returned_contents->IsString()) { if ((err = check_returned_string(returned_file, "returned value of `file` must be a string")))
auto entry = sass_make_import_entry(0, 0, 0); return err;
sass_import_set_error(entry, "returned value of `contents` must be a string", -1, -1);
return entry;
}
auto returned_map = object->Get(NanNew<String>("map")); if ((err = check_returned_string(returned_contents, "returned value of `contents` must be a string")))
return err;
if (!returned_map->IsUndefined() && !returned_map->IsString()) { if ((err = check_returned_string(returned_map, "returned value of `returned_map` must be a string")))
auto entry = sass_make_import_entry(0, 0, 0); return err;
sass_import_set_error(entry, "returned value of `map` must be a string", -1, -1);
return entry;
}
char* path = create_string(returned_file); char* path = create_string(returned_file);
char* contents = create_string(returned_contents); char* contents = create_string(returned_contents);
...@@ -85,11 +89,11 @@ Sass_Import* CustomImporterBridge::get_importer_entry(const Local<Object>& objec ...@@ -85,11 +89,11 @@ Sass_Import* CustomImporterBridge::get_importer_entry(const Local<Object>& objec
return sass_make_import_entry(path, contents, srcmap); return sass_make_import_entry(path, contents, srcmap);
} }
std::vector<Handle<Value>> CustomImporterBridge::pre_process_args(std::vector<void*> in) const { std::vector<v8::Local<v8::Value>> CustomImporterBridge::pre_process_args(std::vector<void*> in) const {
std::vector<Handle<Value>> out; std::vector<v8::Local<v8::Value>> out;
for (void* ptr : in) { for (void* ptr : in) {
out.push_back(NanNew<String>((char const*)ptr)); out.push_back(Nan::New<v8::String>((char const*)ptr).ToLocalChecked());
} }
return out; return out;
......
...@@ -5,18 +5,17 @@ ...@@ -5,18 +5,17 @@
#include <sass_context.h> #include <sass_context.h>
#include "callback_bridge.h" #include "callback_bridge.h"
using namespace v8;
typedef Sass_Import_List SassImportList; typedef Sass_Import_List SassImportList;
class CustomImporterBridge : public CallbackBridge<SassImportList> { class CustomImporterBridge : public CallbackBridge<SassImportList> {
public: public:
CustomImporterBridge(NanCallback* cb, bool is_sync) : CallbackBridge<SassImportList>(cb, is_sync) {} CustomImporterBridge(Nan::Callback* cb, bool is_sync) : CallbackBridge<SassImportList>(cb, is_sync) {}
private: private:
SassImportList post_process_return_value(Handle<Value>) const; SassImportList post_process_return_value(v8::Local<v8::Value>) const;
Sass_Import* get_importer_entry(const Local<Object>&) const; Sass_Import* check_returned_string(Nan::MaybeLocal<v8::Value> value, const char *msg) const;
std::vector<Handle<Value>> pre_process_args(std::vector<void*>) const; Sass_Import* get_importer_entry(const v8::Local<v8::Object>&) const;
std::vector<v8::Local<v8::Value>> pre_process_args(std::vector<void*>) const;
}; };
#endif #endif
...@@ -37,7 +37,7 @@ extern "C" { ...@@ -37,7 +37,7 @@ extern "C" {
delete ctx_w->error_callback; delete ctx_w->error_callback;
delete ctx_w->success_callback; delete ctx_w->success_callback;
NanDisposePersistent(ctx_w->result); ctx_w->result.Reset();
free(ctx_w->include_path); free(ctx_w->include_path);
free(ctx_w->linefeed); free(ctx_w->linefeed);
......
...@@ -14,8 +14,6 @@ ...@@ -14,8 +14,6 @@
extern "C" { extern "C" {
#endif #endif
using namespace v8;
void compile_data(struct Sass_Data_Context* dctx); void compile_data(struct Sass_Data_Context* dctx);
void compile_file(struct Sass_File_Context* fctx); void compile_file(struct Sass_File_Context* fctx);
void compile_it(uv_work_t* req); void compile_it(uv_work_t* req);
...@@ -41,9 +39,9 @@ extern "C" { ...@@ -41,9 +39,9 @@ extern "C" {
uv_work_t request; uv_work_t request;
// v8 and nan related // v8 and nan related
Persistent<Object> result; Nan::Persistent<v8::Object> result;
NanCallback* error_callback; Nan::Callback* error_callback;
NanCallback* success_callback; Nan::Callback* success_callback;
std::vector<std::shared_ptr<CustomFunctionBridge>> function_bridges; std::vector<std::shared_ptr<CustomFunctionBridge>> function_bridges;
std::vector<std::shared_ptr<CustomImporterBridge>> importer_bridges; std::vector<std::shared_ptr<CustomImporterBridge>> importer_bridges;
......
#include <nan.h> #include <nan.h>
#include "boolean.h" #include "boolean.h"
using namespace v8;
namespace SassTypes namespace SassTypes
{ {
Persistent<Function> Boolean::constructor; Nan::Persistent<v8::Function> Boolean::constructor;
bool Boolean::constructor_locked = false; bool Boolean::constructor_locked = false;
Boolean::Boolean(bool v) : value(v) {} Boolean::Boolean(bool v) : value(v) {}
...@@ -15,59 +13,63 @@ namespace SassTypes ...@@ -15,59 +13,63 @@ namespace SassTypes
return v ? instance_true : instance_false; return v ? instance_true : instance_false;
} }
Handle<Function> Boolean::get_constructor() { v8::Local<v8::Function> Boolean::get_constructor() {
Nan::EscapableHandleScope scope;
v8::Local<v8::Function> conslocal;
if (constructor.IsEmpty()) { if (constructor.IsEmpty()) {
Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(New); v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
tpl->SetClassName(NanNew("SassBoolean")); tpl->SetClassName(Nan::New("SassBoolean").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1); tpl->InstanceTemplate()->SetInternalFieldCount(1);
tpl->PrototypeTemplate()->Set(NanNew("getValue"), NanNew<FunctionTemplate>(GetValue)->GetFunction()); Nan::SetPrototypeTemplate(tpl, "getValue", Nan::GetFunction(Nan::New<v8::FunctionTemplate>(GetValue)).ToLocalChecked());
NanAssignPersistent(constructor, tpl->GetFunction()); constructor.Reset(Nan::GetFunction(tpl).ToLocalChecked());
conslocal = Nan::New(constructor);
NanAssignPersistent(get_singleton(false).js_object, NanNew(constructor)->NewInstance()); get_singleton(false).js_object.Reset(conslocal->NewInstance());
NanSetInternalFieldPointer(NanNew(get_singleton(false).js_object), 0, &get_singleton(false)); Nan::SetInternalFieldPointer(Nan::New(get_singleton(false).js_object), 0, &get_singleton(false));
NanNew(constructor)->Set(NanNew("FALSE"), NanNew(get_singleton(false).js_object)); Nan::Set(conslocal, Nan::New("FALSE").ToLocalChecked(), Nan::New(get_singleton(false).js_object));
NanAssignPersistent(get_singleton(true).js_object, NanNew(constructor)->NewInstance()); get_singleton(true).js_object.Reset(conslocal->NewInstance());
NanSetInternalFieldPointer(NanNew(get_singleton(true).js_object), 0, &get_singleton(true)); Nan::SetInternalFieldPointer(Nan::New(get_singleton(true).js_object), 0, &get_singleton(true));
NanNew(constructor)->Set(NanNew("TRUE"), NanNew(get_singleton(true).js_object)); Nan::Set(conslocal, Nan::New("TRUE").ToLocalChecked(), Nan::New(get_singleton(true).js_object));
constructor_locked = true; constructor_locked = true;
} else {
conslocal = Nan::New(constructor);
} }
return NanNew(constructor); return scope.Escape(conslocal);
} }
Sass_Value* Boolean::get_sass_value() { Sass_Value* Boolean::get_sass_value() {
return sass_make_boolean(value); return sass_make_boolean(value);
} }
Local<Object> Boolean::get_js_object() { v8::Local<v8::Object> Boolean::get_js_object() {
return NanNew(this->js_object); Nan::EscapableHandleScope scope;
return scope.Escape(Nan::New(this->js_object));
} }
NAN_METHOD(Boolean::New) { NAN_METHOD(Boolean::New) {
NanScope();
if (args.IsConstructCall()) { if (info.IsConstructCall()) {
if (constructor_locked) { if (constructor_locked) {
return NanThrowError(NanNew("Cannot instantiate SassBoolean")); return Nan::ThrowError(Nan::New("Cannot instantiate SassBoolean").ToLocalChecked());
} }
} }
else { else {
if (args.Length() != 1 || !args[0]->IsBoolean()) { if (info.Length() != 1 || !info[0]->IsBoolean()) {
return NanThrowError(NanNew("Expected one boolean argument")); return Nan::ThrowError(Nan::New("Expected one boolean argument").ToLocalChecked());
} }
NanReturnValue(NanNew(get_singleton(args[0]->ToBoolean()->Value()).get_js_object())); info.GetReturnValue().Set((get_singleton(info[0]->ToBoolean()->Value()).get_js_object()));
} }
NanReturnUndefined(); return;
} }
NAN_METHOD(Boolean::GetValue) { NAN_METHOD(Boolean::GetValue) {
NanScope(); info.GetReturnValue().Set(Nan::New(static_cast<Boolean*>(Factory::unwrap(info.This()))->value));
NanReturnValue(NanNew(static_cast<Boolean*>(Factory::unwrap(args.This()))->value));
} }
} }
...@@ -7,15 +7,13 @@ ...@@ -7,15 +7,13 @@
namespace SassTypes namespace SassTypes
{ {
using namespace v8; class Boolean : public SassTypes::Value {
class Boolean : public Value {
public: public:
static Boolean& get_singleton(bool); static Boolean& get_singleton(bool);
static Handle<Function> get_constructor(); static v8::Local<v8::Function> get_constructor();
Sass_Value* get_sass_value(); Sass_Value* get_sass_value();
Local<Object> get_js_object(); v8::Local<v8::Object> get_js_object();
static NAN_METHOD(New); static NAN_METHOD(New);
static NAN_METHOD(GetValue); static NAN_METHOD(GetValue);
...@@ -24,9 +22,9 @@ namespace SassTypes ...@@ -24,9 +22,9 @@ namespace SassTypes
Boolean(bool); Boolean(bool);
bool value; bool value;
Persistent<Object> js_object; Nan::Persistent<v8::Object> js_object;
static Persistent<Function> constructor; static Nan::Persistent<v8::Function> constructor;
static bool constructor_locked; static bool constructor_locked;
}; };
} }
......
#include <nan.h> #include <nan.h>
#include "color.h" #include "color.h"
using namespace v8;
namespace SassTypes namespace SassTypes
{ {
Color::Color(Sass_Value* v) : SassValueWrapper(v) {} Color::Color(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* Color::construct(const std::vector<Local<v8::Value>> raw_val) { Sass_Value* Color::construct(const std::vector<v8::Local<v8::Value>> raw_val) {
double a = 1.0, r = 0, g = 0, b = 0; double a = 1.0, r = 0, g = 0, b = 0;
unsigned argb; unsigned argb;
...@@ -52,86 +50,82 @@ namespace SassTypes ...@@ -52,86 +50,82 @@ namespace SassTypes
return sass_make_color(r, g, b, a); return sass_make_color(r, g, b, a);
} }
void Color::initPrototype(Handle<ObjectTemplate> proto) { void Color::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
proto->Set(NanNew("getR"), NanNew<FunctionTemplate>(GetR)->GetFunction()); Nan::SetPrototypeMethod(proto, "getR", GetR);
proto->Set(NanNew("getG"), NanNew<FunctionTemplate>(GetG)->GetFunction()); Nan::SetPrototypeMethod(proto, "getG", GetG);
proto->Set(NanNew("getB"), NanNew<FunctionTemplate>(GetB)->GetFunction()); Nan::SetPrototypeMethod(proto, "getB", GetB);
proto->Set(NanNew("getA"), NanNew<FunctionTemplate>(GetA)->GetFunction()); Nan::SetPrototypeMethod(proto, "getA", GetA);
proto->Set(NanNew("setR"), NanNew<FunctionTemplate>(SetR)->GetFunction()); Nan::SetPrototypeMethod(proto, "setR", SetR);
proto->Set(NanNew("setG"), NanNew<FunctionTemplate>(SetG)->GetFunction()); Nan::SetPrototypeMethod(proto, "setG", SetG);
proto->Set(NanNew("setB"), NanNew<FunctionTemplate>(SetB)->GetFunction()); Nan::SetPrototypeMethod(proto, "setB", SetB);
proto->Set(NanNew("setA"), NanNew<FunctionTemplate>(SetA)->GetFunction()); Nan::SetPrototypeMethod(proto, "setA", SetA);
} }
NAN_METHOD(Color::GetR) { NAN_METHOD(Color::GetR) {
NanScope(); info.GetReturnValue().Set(Nan::New(sass_color_get_r(unwrap(info.This())->value)));
NanReturnValue(NanNew(sass_color_get_r(unwrap(args.This())->value)));
} }
NAN_METHOD(Color::GetG) { NAN_METHOD(Color::GetG) {
NanScope(); info.GetReturnValue().Set(Nan::New(sass_color_get_g(unwrap(info.This())->value)));
NanReturnValue(NanNew(sass_color_get_g(unwrap(args.This())->value)));
} }
NAN_METHOD(Color::GetB) { NAN_METHOD(Color::GetB) {
NanScope(); info.GetReturnValue().Set(Nan::New(sass_color_get_b(unwrap(info.This())->value)));
NanReturnValue(NanNew(sass_color_get_b(unwrap(args.This())->value)));
} }
NAN_METHOD(Color::GetA) { NAN_METHOD(Color::GetA) {
NanScope(); info.GetReturnValue().Set(Nan::New(sass_color_get_a(unwrap(info.This())->value)));
NanReturnValue(NanNew(sass_color_get_a(unwrap(args.This())->value)));
} }
NAN_METHOD(Color::SetR) { NAN_METHOD(Color::SetR) {
if (args.Length() != 1) { if (info.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument")); return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
} }
if (!args[0]->IsNumber()) { if (!info[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied value should be a number")); return Nan::ThrowError(Nan::New("Supplied value should be a number").ToLocalChecked());
} }
sass_color_set_r(unwrap(args.This())->value, args[0]->ToNumber()->Value()); sass_color_set_r(unwrap(info.This())->value, info[0]->ToNumber()->Value());
NanReturnUndefined(); return;
} }
NAN_METHOD(Color::SetG) { NAN_METHOD(Color::SetG) {
if (args.Length() != 1) { if (info.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument")); return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
} }
if (!args[0]->IsNumber()) { if (!info[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied value should be a number")); return Nan::ThrowError(Nan::New("Supplied value should be a number").ToLocalChecked());
} }
sass_color_set_g(unwrap(args.This())->value, args[0]->ToNumber()->Value()); sass_color_set_g(unwrap(info.This())->value, info[0]->ToNumber()->Value());
NanReturnUndefined(); return;
} }
NAN_METHOD(Color::SetB) { NAN_METHOD(Color::SetB) {
if (args.Length() != 1) { if (info.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument")); return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
} }
if (!args[0]->IsNumber()) { if (!info[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied value should be a number")); return Nan::ThrowError(Nan::New("Supplied value should be a number").ToLocalChecked());
} }
sass_color_set_b(unwrap(args.This())->value, args[0]->ToNumber()->Value()); sass_color_set_b(unwrap(info.This())->value, info[0]->ToNumber()->Value());
NanReturnUndefined(); return;
} }
NAN_METHOD(Color::SetA) { NAN_METHOD(Color::SetA) {
if (args.Length() != 1) { if (info.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument")); return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
} }
if (!args[0]->IsNumber()) { if (!info[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied value should be a number")); return Nan::ThrowError(Nan::New("Supplied value should be a number").ToLocalChecked());
} }
sass_color_set_a(unwrap(args.This())->value, args[0]->ToNumber()->Value()); sass_color_set_a(unwrap(info.This())->value, info[0]->ToNumber()->Value());
NanReturnUndefined(); return;
} }
} }
...@@ -6,15 +6,13 @@ ...@@ -6,15 +6,13 @@
namespace SassTypes namespace SassTypes
{ {
using namespace v8;
class Color : public SassValueWrapper<Color> { class Color : public SassValueWrapper<Color> {
public: public:
Color(Sass_Value*); Color(Sass_Value*);
static char const* get_constructor_name() { return "SassColor"; } static char const* get_constructor_name() { return "SassColor"; }
static Sass_Value* construct(const std::vector<Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>);
static void initPrototype(Handle<ObjectTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
static NAN_METHOD(GetR); static NAN_METHOD(GetR);
static NAN_METHOD(GetG); static NAN_METHOD(GetG);
......
...@@ -2,13 +2,11 @@ ...@@ -2,13 +2,11 @@
#include "error.h" #include "error.h"
#include "../create_string.h" #include "../create_string.h"
using namespace v8;
namespace SassTypes namespace SassTypes
{ {
Error::Error(Sass_Value* v) : SassValueWrapper(v) {} Error::Error(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* Error::construct(const std::vector<Local<v8::Value>> raw_val) { Sass_Value* Error::construct(const std::vector<v8::Local<v8::Value>> raw_val) {
char const* value = ""; char const* value = "";
if (raw_val.size() >= 1) { if (raw_val.size() >= 1) {
...@@ -22,5 +20,5 @@ namespace SassTypes ...@@ -22,5 +20,5 @@ namespace SassTypes
return sass_make_error(value); return sass_make_error(value);
} }
void Error::initPrototype(Handle<ObjectTemplate>) {} void Error::initPrototype(v8::Local<v8::FunctionTemplate>) {}
} }
...@@ -6,15 +6,13 @@ ...@@ -6,15 +6,13 @@
namespace SassTypes namespace SassTypes
{ {
using namespace v8;
class Error : public SassValueWrapper<Error> { class Error : public SassValueWrapper<Error> {
public: public:
Error(Sass_Value*); Error(Sass_Value*);
static char const* get_constructor_name() { return "SassError"; } static char const* get_constructor_name() { return "SassError"; }
static Sass_Value* construct(const std::vector<Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>);
static void initPrototype(Handle<ObjectTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
}; };
} }
......
...@@ -10,11 +10,9 @@ ...@@ -10,11 +10,9 @@
#include "null.h" #include "null.h"
#include "error.h" #include "error.h"
using namespace v8;
namespace SassTypes namespace SassTypes
{ {
Value* Factory::create(Sass_Value* v) { SassTypes::Value* Factory::create(Sass_Value* v) {
switch (sass_value_get_tag(v)) { switch (sass_value_get_tag(v)) {
case SASS_NUMBER: case SASS_NUMBER:
return new Number(v); return new Number(v);
...@@ -45,26 +43,27 @@ namespace SassTypes ...@@ -45,26 +43,27 @@ namespace SassTypes
} }
} }
void Factory::initExports(Handle<Object> exports) { void Factory::initExports(v8::Local<v8::Object> exports) {
Local<Object> types = NanNew<Object>(); Nan::EscapableHandleScope scope;
exports->Set(NanNew("types"), types); v8::Local<v8::Object> types = Nan::New<v8::Object>();
types->Set(NanNew("Number"), Number::get_constructor()); Nan::Set(types, Nan::New("Number").ToLocalChecked(), Number::get_constructor());
types->Set(NanNew("String"), String::get_constructor()); Nan::Set(types, Nan::New("String").ToLocalChecked(), String::get_constructor());
types->Set(NanNew("Color"), Color::get_constructor()); Nan::Set(types, Nan::New("Color").ToLocalChecked(), Color::get_constructor());
types->Set(NanNew("Boolean"), Boolean::get_constructor()); Nan::Set(types, Nan::New("Boolean").ToLocalChecked(), Boolean::get_constructor());
types->Set(NanNew("List"), List::get_constructor()); Nan::Set(types, Nan::New("List").ToLocalChecked(), List::get_constructor());
types->Set(NanNew("Map"), Map::get_constructor()); Nan::Set(types, Nan::New("Map").ToLocalChecked(), Map::get_constructor());
types->Set(NanNew("Null"), Null::get_constructor()); Nan::Set(types, Nan::New("Null").ToLocalChecked(), Null::get_constructor());
types->Set(NanNew("Error"), Error::get_constructor()); Nan::Set(types, Nan::New("Error").ToLocalChecked(), Error::get_constructor());
Nan::Set(exports, Nan::New<v8::String>("types").ToLocalChecked(), scope.Escape(types));
} }
Value* Factory::unwrap(Handle<v8::Value> obj) { Value* Factory::unwrap(v8::Local<v8::Value> obj) {
// Todo: non-SassValue objects could easily fall under that condition, need to be more specific. // Todo: non-SassValue objects could easily fall under that condition, need to be more specific.
if (!obj->IsObject() || obj->ToObject()->InternalFieldCount() != 1) { if (!obj->IsObject() || obj->ToObject()->InternalFieldCount() != 1) {
throw std::invalid_argument("A SassValue object was expected."); throw std::invalid_argument("A SassValue object was expected.");
} }
return static_cast<Value*>(NanGetInternalFieldPointer(obj->ToObject(), 0)); return static_cast<Value*>(Nan::GetInternalFieldPointer(obj->ToObject(), 0));
} }
} }
...@@ -7,15 +7,13 @@ ...@@ -7,15 +7,13 @@
namespace SassTypes namespace SassTypes
{ {
using namespace v8;
// This is the guru that knows everything about instantiating the right subclass of SassTypes::Value // This is the guru that knows everything about instantiating the right subclass of SassTypes::Value
// to wrap a given Sass_Value object. // to wrap a given Sass_Value object.
class Factory { class Factory {
public: public:
static void initExports(Handle<Object>); static void initExports(v8::Local<v8::Object>);
static Value* create(Sass_Value*); static Value* create(Sass_Value*);
static Value* unwrap(Handle<v8::Value>); static Value* unwrap(v8::Local<v8::Value>);
}; };
} }
......
#include <nan.h> #include <nan.h>
#include "list.h" #include "list.h"
using namespace v8;
namespace SassTypes namespace SassTypes
{ {
List::List(Sass_Value* v) : SassValueWrapper(v) {} List::List(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* List::construct(const std::vector<Local<v8::Value>> raw_val) { Sass_Value* List::construct(const std::vector<v8::Local<v8::Value>> raw_val) {
size_t length = 0; size_t length = 0;
bool comma = true; bool comma = true;
...@@ -30,74 +28,71 @@ namespace SassTypes ...@@ -30,74 +28,71 @@ namespace SassTypes
return sass_make_list(length, comma ? SASS_COMMA : SASS_SPACE); return sass_make_list(length, comma ? SASS_COMMA : SASS_SPACE);
} }
void List::initPrototype(Handle<ObjectTemplate> proto) { void List::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
proto->Set(NanNew("getLength"), NanNew<FunctionTemplate>(GetLength)->GetFunction()); Nan::SetPrototypeMethod(proto, "getLength", GetLength);
proto->Set(NanNew("getSeparator"), NanNew<FunctionTemplate>(GetSeparator)->GetFunction()); Nan::SetPrototypeMethod(proto, "getSeparator", GetSeparator);
proto->Set(NanNew("setSeparator"), NanNew<FunctionTemplate>(SetSeparator)->GetFunction()); Nan::SetPrototypeMethod(proto, "setSeparator", SetSeparator);
proto->Set(NanNew("getValue"), NanNew<FunctionTemplate>(GetValue)->GetFunction()); Nan::SetPrototypeMethod(proto, "getValue", GetValue);
proto->Set(NanNew("setValue"), NanNew<FunctionTemplate>(SetValue)->GetFunction()); Nan::SetPrototypeMethod(proto, "setValue", SetValue);
} }
NAN_METHOD(List::GetValue) { NAN_METHOD(List::GetValue) {
NanScope();
if (args.Length() != 1) { if (info.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument")); return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
} }
if (!args[0]->IsNumber()) { if (!info[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied index should be an integer")); return Nan::ThrowError(Nan::New("Supplied index should be an integer").ToLocalChecked());
} }
Sass_Value* list = unwrap(args.This())->value; Sass_Value* list = unwrap(info.This())->value;
size_t index = args[0]->ToInt32()->Value(); size_t index = info[0]->ToInt32()->Value();
if (index >= sass_list_get_length(list)) { if (index >= sass_list_get_length(list)) {
return NanThrowError(NanNew("Out of bound index")); return Nan::ThrowError(Nan::New("Out of bound index").ToLocalChecked());
} }
NanReturnValue(Factory::create(sass_list_get_value(list, args[0]->ToInt32()->Value()))->get_js_object()); info.GetReturnValue().Set(Factory::create(sass_list_get_value(list, info[0]->ToInt32()->Value()))->get_js_object());
} }
NAN_METHOD(List::SetValue) { NAN_METHOD(List::SetValue) {
if (args.Length() != 2) { if (info.Length() != 2) {
return NanThrowError(NanNew("Expected two arguments")); return Nan::ThrowError(Nan::New("Expected two arguments").ToLocalChecked());
} }
if (!args[0]->IsNumber()) { if (!info[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied index should be an integer")); return Nan::ThrowError(Nan::New("Supplied index should be an integer").ToLocalChecked());
} }
if (!args[1]->IsObject()) { if (!info[1]->IsObject()) {
return NanThrowError(NanNew("Supplied value should be a SassValue object")); return Nan::ThrowError(Nan::New("Supplied value should be a SassValue object").ToLocalChecked());
} }
Value* sass_value = Factory::unwrap(args[1]); Value* sass_value = Factory::unwrap(info[1]);
sass_list_set_value(unwrap(args.This())->value, args[0]->ToInt32()->Value(), sass_value->get_sass_value()); sass_list_set_value(unwrap(info.This())->value, info[0]->ToInt32()->Value(), sass_value->get_sass_value());
NanReturnUndefined(); return;
} }
NAN_METHOD(List::GetSeparator) { NAN_METHOD(List::GetSeparator) {
NanScope(); info.GetReturnValue().Set(Nan::New(sass_list_get_separator(unwrap(info.This())->value) == SASS_COMMA));
NanReturnValue(NanNew(sass_list_get_separator(unwrap(args.This())->value) == SASS_COMMA));
} }
NAN_METHOD(List::SetSeparator) { NAN_METHOD(List::SetSeparator) {
if (args.Length() != 1) { if (info.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument")); return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
} }
if (!args[0]->IsBoolean()) { if (!info[0]->IsBoolean()) {
return NanThrowError(NanNew("Supplied value should be a boolean")); return Nan::ThrowError(Nan::New("Supplied value should be a boolean").ToLocalChecked());
} }
sass_list_set_separator(unwrap(args.This())->value, args[0]->ToBoolean()->Value() ? SASS_COMMA : SASS_SPACE); sass_list_set_separator(unwrap(info.This())->value, info[0]->ToBoolean()->Value() ? SASS_COMMA : SASS_SPACE);
NanReturnUndefined(); return;
} }
NAN_METHOD(List::GetLength) { NAN_METHOD(List::GetLength) {
NanScope(); info.GetReturnValue().Set(Nan::New<v8::Number>(sass_list_get_length(unwrap(info.This())->value)));
NanReturnValue(NanNew<v8::Number>(sass_list_get_length(unwrap(args.This())->value)));
} }
} }
...@@ -6,15 +6,13 @@ ...@@ -6,15 +6,13 @@
namespace SassTypes namespace SassTypes
{ {
using namespace v8;
class List : public SassValueWrapper<List> { class List : public SassValueWrapper<List> {
public: public:
List(Sass_Value*); List(Sass_Value*);
static char const* get_constructor_name() { return "SassList"; } static char const* get_constructor_name() { return "SassList"; }
static Sass_Value* construct(const std::vector<Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>);
static void initPrototype(Handle<ObjectTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
static NAN_METHOD(GetValue); static NAN_METHOD(GetValue);
static NAN_METHOD(SetValue); static NAN_METHOD(SetValue);
......
#include <nan.h> #include <nan.h>
#include "map.h" #include "map.h"
using namespace v8;
namespace SassTypes namespace SassTypes
{ {
Map::Map(Sass_Value* v) : SassValueWrapper(v) {} Map::Map(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* Map::construct(const std::vector<Local<v8::Value>> raw_val) { Sass_Value* Map::construct(const std::vector<v8::Local<v8::Value>> raw_val) {
size_t length = 0; size_t length = 0;
if (raw_val.size() >= 1) { if (raw_val.size() >= 1) {
...@@ -21,96 +19,93 @@ namespace SassTypes ...@@ -21,96 +19,93 @@ namespace SassTypes
return sass_make_map(length); return sass_make_map(length);
} }
void Map::initPrototype(Handle<ObjectTemplate> proto) { void Map::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
proto->Set(NanNew("getLength"), NanNew<FunctionTemplate>(GetLength)->GetFunction()); Nan::SetPrototypeMethod(proto, "getLength", GetLength);
proto->Set(NanNew("getKey"), NanNew<FunctionTemplate>(GetKey)->GetFunction()); Nan::SetPrototypeMethod(proto, "getKey", GetKey);
proto->Set(NanNew("setKey"), NanNew<FunctionTemplate>(SetKey)->GetFunction()); Nan::SetPrototypeMethod(proto, "setKey", SetKey);
proto->Set(NanNew("getValue"), NanNew<FunctionTemplate>(GetValue)->GetFunction()); Nan::SetPrototypeMethod(proto, "getValue", GetValue);
proto->Set(NanNew("setValue"), NanNew<FunctionTemplate>(SetValue)->GetFunction()); Nan::SetPrototypeMethod(proto, "setValue", SetValue);
} }
NAN_METHOD(Map::GetValue) { NAN_METHOD(Map::GetValue) {
NanScope();
if (args.Length() != 1) { if (info.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument")); return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
} }
if (!args[0]->IsNumber()) { if (!info[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied index should be an integer")); return Nan::ThrowError(Nan::New("Supplied index should be an integer").ToLocalChecked());
} }
Sass_Value* map = unwrap(args.This())->value; Sass_Value* map = unwrap(info.This())->value;
size_t index = args[0]->ToInt32()->Value(); size_t index = info[0]->ToInt32()->Value();
if (index >= sass_map_get_length(map)) { if (index >= sass_map_get_length(map)) {
return NanThrowError(NanNew("Out of bound index")); return Nan::ThrowError(Nan::New("Out of bound index").ToLocalChecked());
} }
NanReturnValue(NanNew(Factory::create(sass_map_get_value(map, args[0]->ToInt32()->Value()))->get_js_object())); info.GetReturnValue().Set(Factory::create(sass_map_get_value(map, info[0]->ToInt32()->Value()))->get_js_object());
} }
NAN_METHOD(Map::SetValue) { NAN_METHOD(Map::SetValue) {
if (args.Length() != 2) { if (info.Length() != 2) {
return NanThrowError(NanNew("Expected two arguments")); return Nan::ThrowError(Nan::New("Expected two arguments").ToLocalChecked());
} }
if (!args[0]->IsNumber()) { if (!info[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied index should be an integer")); return Nan::ThrowError(Nan::New("Supplied index should be an integer").ToLocalChecked());
} }
if (!args[1]->IsObject()) { if (!info[1]->IsObject()) {
return NanThrowError(NanNew("Supplied value should be a SassValue object")); return Nan::ThrowError(Nan::New("Supplied value should be a SassValue object").ToLocalChecked());
} }
Value* sass_value = Factory::unwrap(args[1]); Value* sass_value = Factory::unwrap(info[1]);
sass_map_set_value(unwrap(args.This())->value, args[0]->ToInt32()->Value(), sass_value->get_sass_value()); sass_map_set_value(unwrap(info.This())->value, info[0]->ToInt32()->Value(), sass_value->get_sass_value());
NanReturnUndefined(); return;
} }
NAN_METHOD(Map::GetKey) { NAN_METHOD(Map::GetKey) {
NanScope();
if (args.Length() != 1) { if (info.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument")); return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
} }
if (!args[0]->IsNumber()) { if (!info[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied index should be an integer")); return Nan::ThrowError(Nan::New("Supplied index should be an integer").ToLocalChecked());
} }
Sass_Value* map = unwrap(args.This())->value; Sass_Value* map = unwrap(info.This())->value;
size_t index = args[0]->ToInt32()->Value(); size_t index = info[0]->ToInt32()->Value();
if (index >= sass_map_get_length(map)) { if (index >= sass_map_get_length(map)) {
return NanThrowError(NanNew("Out of bound index")); return Nan::ThrowError(Nan::New("Out of bound index").ToLocalChecked());
} }
NanReturnValue(Factory::create(sass_map_get_key(map, args[0]->ToInt32()->Value()))->get_js_object()); info.GetReturnValue().Set(Factory::create(sass_map_get_key(map, info[0]->ToInt32()->Value()))->get_js_object());
} }
NAN_METHOD(Map::SetKey) { NAN_METHOD(Map::SetKey) {
if (args.Length() != 2) { if (info.Length() != 2) {
return NanThrowError(NanNew("Expected two arguments")); return Nan::ThrowError(Nan::New("Expected two arguments").ToLocalChecked());
} }
if (!args[0]->IsNumber()) { if (!info[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied index should be an integer")); return Nan::ThrowError(Nan::New("Supplied index should be an integer").ToLocalChecked());
} }
if (!args[1]->IsObject()) { if (!info[1]->IsObject()) {
return NanThrowError(NanNew("Supplied value should be a SassValue object")); return Nan::ThrowError(Nan::New("Supplied value should be a SassValue object").ToLocalChecked());
} }
Value* sass_value = Factory::unwrap(args[1]); Value* sass_value = Factory::unwrap(info[1]);
sass_map_set_key(unwrap(args.This())->value, args[0]->ToInt32()->Value(), sass_value->get_sass_value()); sass_map_set_key(unwrap(info.This())->value, info[0]->ToInt32()->Value(), sass_value->get_sass_value());
NanReturnUndefined(); return;
} }
NAN_METHOD(Map::GetLength) { NAN_METHOD(Map::GetLength) {
NanScope(); info.GetReturnValue().Set(Nan::New<v8::Number>(sass_map_get_length(unwrap(info.This())->value)));
NanReturnValue(NanNew<v8::Number>(sass_map_get_length(unwrap(args.This())->value)));
} }
} }
...@@ -6,15 +6,13 @@ ...@@ -6,15 +6,13 @@
namespace SassTypes namespace SassTypes
{ {
using namespace v8;
class Map : public SassValueWrapper<Map> { class Map : public SassValueWrapper<Map> {
public: public:
Map(Sass_Value*); Map(Sass_Value*);
static char const* get_constructor_name() { return "SassMap"; } static char const* get_constructor_name() { return "SassMap"; }
static Sass_Value* construct(const std::vector<Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>);
static void initPrototype(Handle<ObjectTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
static NAN_METHOD(GetValue); static NAN_METHOD(GetValue);
static NAN_METHOD(SetValue); static NAN_METHOD(SetValue);
......
#include <nan.h> #include <nan.h>
#include "null.h" #include "null.h"
using namespace v8;
namespace SassTypes namespace SassTypes
{ {
Persistent<Function> Null::constructor; Nan::Persistent<v8::Function> Null::constructor;
bool Null::constructor_locked = false; bool Null::constructor_locked = false;
Null::Null() {} Null::Null() {}
...@@ -15,45 +13,49 @@ namespace SassTypes ...@@ -15,45 +13,49 @@ namespace SassTypes
return singleton_instance; return singleton_instance;
} }
Handle<Function> Null::get_constructor() { v8::Local<v8::Function> Null::get_constructor() {
Nan::EscapableHandleScope scope;
v8::Local<v8::Function> conslocal;
if (constructor.IsEmpty()) { if (constructor.IsEmpty()) {
Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(New); v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
tpl->SetClassName(NanNew("SassNull")); tpl->SetClassName(Nan::New("SassNull").ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1); tpl->InstanceTemplate()->SetInternalFieldCount(1);
NanAssignPersistent(constructor, tpl->GetFunction()); constructor.Reset(Nan::GetFunction(tpl).ToLocalChecked());
conslocal = Nan::New(constructor);
NanAssignPersistent(get_singleton().js_object, NanNew(constructor)->NewInstance()); get_singleton().js_object.Reset(conslocal->NewInstance());
NanSetInternalFieldPointer(NanNew(get_singleton().js_object), 0, &get_singleton()); Nan::SetInternalFieldPointer(Nan::New(get_singleton().js_object), 0, &get_singleton());
NanNew(constructor)->Set(NanNew("NULL"), NanNew(get_singleton().js_object)); Nan::Set(conslocal, Nan::New("NULL").ToLocalChecked(), Nan::New(get_singleton().js_object));
constructor_locked = true; constructor_locked = true;
} else {
conslocal = Nan::New(constructor);
} }
return NanNew(constructor); return scope.Escape(conslocal);
} }
Sass_Value* Null::get_sass_value() { Sass_Value* Null::get_sass_value() {
return sass_make_null(); return sass_make_null();
} }
Local<Object> Null::get_js_object() { v8::Local<v8::Object> Null::get_js_object() {
return NanNew(this->js_object); return Nan::New(this->js_object);
} }
NAN_METHOD(Null::New) { NAN_METHOD(Null::New) {
NanScope();
if (args.IsConstructCall()) { if (info.IsConstructCall()) {
if (constructor_locked) { if (constructor_locked) {
return NanThrowError(NanNew("Cannot instantiate SassNull")); return Nan::ThrowError(Nan::New("Cannot instantiate SassNull").ToLocalChecked());
} }
} }
else { else {
NanReturnValue(NanNew(get_singleton().get_js_object())); info.GetReturnValue().Set(get_singleton().get_js_object());
} }
NanReturnUndefined(); return;
} }
} }
...@@ -6,24 +6,22 @@ ...@@ -6,24 +6,22 @@
namespace SassTypes namespace SassTypes
{ {
using namespace v8; class Null : public SassTypes::Value {
class Null : public Value {
public: public:
static Null& get_singleton(); static Null& get_singleton();
static Handle<Function> get_constructor(); static v8::Local<v8::Function> get_constructor();
Sass_Value* get_sass_value(); Sass_Value* get_sass_value();
Local<Object> get_js_object(); v8::Local<v8::Object> get_js_object();
static NAN_METHOD(New); static NAN_METHOD(New);
private: private:
Null(); Null();
Persistent<Object> js_object; Nan::Persistent<v8::Object> js_object;
static Persistent<Function> constructor; static Nan::Persistent<v8::Function> constructor;
static bool constructor_locked; static bool constructor_locked;
}; };
} }
......
...@@ -2,13 +2,11 @@ ...@@ -2,13 +2,11 @@
#include "number.h" #include "number.h"
#include "../create_string.h" #include "../create_string.h"
using namespace v8;
namespace SassTypes namespace SassTypes
{ {
Number::Number(Sass_Value* v) : SassValueWrapper(v) {} Number::Number(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* Number::construct(const std::vector<Local<v8::Value>> raw_val) { Sass_Value* Number::construct(const std::vector<v8::Local<v8::Value>> raw_val) {
double value = 0; double value = 0;
char const* unit = ""; char const* unit = "";
...@@ -31,48 +29,45 @@ namespace SassTypes ...@@ -31,48 +29,45 @@ namespace SassTypes
return sass_make_number(value, unit); return sass_make_number(value, unit);
} }
void Number::initPrototype(Handle<ObjectTemplate> proto) { void Number::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
proto->Set(NanNew("getValue"), NanNew<FunctionTemplate>(GetValue)->GetFunction()); Nan::SetPrototypeMethod(proto, "getValue", GetValue);
proto->Set(NanNew("getUnit"), NanNew<FunctionTemplate>(GetUnit)->GetFunction()); Nan::SetPrototypeMethod(proto, "getUnit", GetUnit);
proto->Set(NanNew("setValue"), NanNew<FunctionTemplate>(SetValue)->GetFunction()); Nan::SetPrototypeMethod(proto, "setValue", SetValue);
proto->Set(NanNew("setUnit"), NanNew<FunctionTemplate>(SetUnit)->GetFunction()); Nan::SetPrototypeMethod(proto, "setUnit", SetUnit);
} }
NAN_METHOD(Number::GetValue) { NAN_METHOD(Number::GetValue) {
NanScope(); info.GetReturnValue().Set(Nan::New<v8::Number>(sass_number_get_value(unwrap(info.This())->value)));
NanReturnValue(NanNew(sass_number_get_value(unwrap(args.This())->value)));
} }
NAN_METHOD(Number::GetUnit) { NAN_METHOD(Number::GetUnit) {
NanScope(); info.GetReturnValue().Set(Nan::New<v8::String>(sass_number_get_unit(unwrap(info.This())->value)).ToLocalChecked());
NanReturnValue(NanNew(sass_number_get_unit(unwrap(args.This())->value)));
} }
NAN_METHOD(Number::SetValue) { NAN_METHOD(Number::SetValue) {
NanScope();
if (args.Length() != 1) { if (info.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument")); return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
} }
if (!args[0]->IsNumber()) { if (!info[0]->IsNumber()) {
return NanThrowError(NanNew("Supplied value should be a number")); return Nan::ThrowError(Nan::New("Supplied value should be a number").ToLocalChecked());
} }
sass_number_set_value(unwrap(args.This())->value, args[0]->ToNumber()->Value()); sass_number_set_value(unwrap(info.This())->value, info[0]->ToNumber()->Value());
NanReturnUndefined(); return;
} }
NAN_METHOD(Number::SetUnit) { NAN_METHOD(Number::SetUnit) {
if (args.Length() != 1) { if (info.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument")); return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
} }
if (!args[0]->IsString()) { if (!info[0]->IsString()) {
return NanThrowError(NanNew("Supplied value should be a string")); return Nan::ThrowError(Nan::New("Supplied value should be a string").ToLocalChecked());
} }
sass_number_set_unit(unwrap(args.This())->value, create_string(args[0])); sass_number_set_unit(unwrap(info.This())->value, create_string(info[0]));
NanReturnUndefined(); return;
} }
} }
...@@ -6,15 +6,14 @@ ...@@ -6,15 +6,14 @@
namespace SassTypes namespace SassTypes
{ {
using namespace v8;
class Number : public SassValueWrapper<Number> { class Number : public SassValueWrapper<Number> {
public: public:
Number(Sass_Value*); Number(Sass_Value*);
static char const* get_constructor_name() { return "SassNumber"; } static char const* get_constructor_name() { return "SassNumber"; }
static Sass_Value* construct(const std::vector<Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>);
static void initPrototype(Handle<ObjectTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
static NAN_METHOD(GetValue); static NAN_METHOD(GetValue);
static NAN_METHOD(GetUnit); static NAN_METHOD(GetUnit);
......
...@@ -9,12 +9,10 @@ ...@@ -9,12 +9,10 @@
namespace SassTypes namespace SassTypes
{ {
using namespace v8;
// Include this in any SassTypes::Value subclasses to handle all the heavy lifting of constructing JS // Include this in any SassTypes::Value subclasses to handle all the heavy lifting of constructing JS
// objects and wrapping sass values inside them // objects and wrapping sass values inside them
template <class T> template <class T>
class SassValueWrapper : public Value { class SassValueWrapper : public SassTypes::Value {
public: public:
static char const* get_constructor_name() { return "SassValue"; } static char const* get_constructor_name() { return "SassValue"; }
...@@ -22,23 +20,23 @@ namespace SassTypes ...@@ -22,23 +20,23 @@ namespace SassTypes
virtual ~SassValueWrapper(); virtual ~SassValueWrapper();
Sass_Value* get_sass_value(); Sass_Value* get_sass_value();
Local<Object> get_js_object(); v8::Local<v8::Object> get_js_object();
static Handle<Function> get_constructor(); static v8::Local<v8::Function> get_constructor();
static Local<FunctionTemplate> get_constructor_template(); static v8::Local<v8::FunctionTemplate> get_constructor_template();
static NAN_METHOD(New); static NAN_METHOD(New);
protected: protected:
Sass_Value* value; Sass_Value* value;
static T* unwrap(Local<Object>); static T* unwrap(v8::Local<v8::Object>);
private: private:
static Persistent<Function> constructor; static Nan::Persistent<v8::Function> constructor;
Persistent<Object> js_object; Nan::Persistent<v8::Object> js_object;
}; };
template <class T> template <class T>
Persistent<Function> SassValueWrapper<T>::constructor; Nan::Persistent<v8::Function> SassValueWrapper<T>::constructor;
template <class T> template <class T>
SassValueWrapper<T>::SassValueWrapper(Sass_Value* v) { SassValueWrapper<T>::SassValueWrapper(Sass_Value* v) {
...@@ -47,7 +45,7 @@ namespace SassTypes ...@@ -47,7 +45,7 @@ namespace SassTypes
template <class T> template <class T>
SassValueWrapper<T>::~SassValueWrapper() { SassValueWrapper<T>::~SassValueWrapper() {
NanDisposePersistent(this->js_object); this->js_object.Reset();
sass_delete_value(this->value); sass_delete_value(this->value);
} }
...@@ -57,74 +55,64 @@ namespace SassTypes ...@@ -57,74 +55,64 @@ namespace SassTypes
} }
template <class T> template <class T>
Local<Object> SassValueWrapper<T>::get_js_object() { v8::Local<v8::Object> SassValueWrapper<T>::get_js_object() {
if (this->js_object.IsEmpty()) { if (this->js_object.IsEmpty()) {
Local<Object> wrapper = NanNew(T::get_constructor())->NewInstance(); v8::Local<v8::Object> wrapper = Nan::NewInstance(T::get_constructor()).ToLocalChecked();
delete static_cast<T*>(NanGetInternalFieldPointer(wrapper, 0)); delete static_cast<T*>(Nan::GetInternalFieldPointer(wrapper, 0));
NanSetInternalFieldPointer(wrapper, 0, this); Nan::SetInternalFieldPointer(wrapper, 0, this);
NanAssignPersistent(this->js_object, wrapper); this->js_object.Reset(wrapper);
} }
return NanNew(this->js_object); return Nan::New(this->js_object);
} }
template <class T> template <class T>
Local<FunctionTemplate> SassValueWrapper<T>::get_constructor_template() { v8::Local<v8::FunctionTemplate> SassValueWrapper<T>::get_constructor_template() {
Local<FunctionTemplate> tpl = NanNew<FunctionTemplate>(New); Nan::EscapableHandleScope scope;
tpl->SetClassName(NanNew(NanNew(T::get_constructor_name()))); v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
tpl->SetClassName(Nan::New<v8::String>(T::get_constructor_name()).ToLocalChecked());
tpl->InstanceTemplate()->SetInternalFieldCount(1); tpl->InstanceTemplate()->SetInternalFieldCount(1);
T::initPrototype(tpl->PrototypeTemplate()); T::initPrototype(tpl);
return tpl; return scope.Escape(tpl);
} }
template <class T> template <class T>
Handle<Function> SassValueWrapper<T>::get_constructor() { v8::Local<v8::Function> SassValueWrapper<T>::get_constructor() {
if (constructor.IsEmpty()) { if (constructor.IsEmpty()) {
NanAssignPersistent(constructor, T::get_constructor_template()->GetFunction()); constructor.Reset(Nan::GetFunction(T::get_constructor_template()).ToLocalChecked());
} }
return NanNew(constructor); return Nan::New(constructor);
} }
template <class T> template <class T>
NAN_METHOD(SassValueWrapper<T>::New) { NAN_METHOD(SassValueWrapper<T>::New) {
NanScope(); std::vector<v8::Local<v8::Value>> localArgs(info.Length());
if (!args.IsConstructCall()) {
unsigned argc = args.Length();
std::vector<Handle<v8::Value>> argv;
argv.reserve(argc);
for (unsigned i = 0; i < argc; i++) {
argv.push_back(args[i]);
}
NanReturnValue(NanNew(T::get_constructor())->NewInstance(argc, &argv[0]));
}
std::vector<Local<v8::Value>> localArgs(args.Length());
for (auto i = 0; i < args.Length(); ++i) { for (auto i = 0; i < info.Length(); ++i) {
localArgs[i] = args[i]; localArgs[i] = info[i];
} }
if (info.IsConstructCall()) {
try { try {
Sass_Value* value = T::construct(localArgs); Sass_Value* value = T::construct(localArgs);
T* obj = new T(value); T* obj = new T(value);
sass_delete_value(value); sass_delete_value(value);
NanSetInternalFieldPointer(args.This(), 0, obj); Nan::SetInternalFieldPointer(info.This(), 0, obj);
NanAssignPersistent(obj->js_object, args.This()); obj->js_object.Reset(info.This());
} catch (const std::exception& e) { } catch (const std::exception& e) {
return NanThrowError(NanNew(e.what())); return Nan::ThrowError(Nan::New<v8::String>(e.what()).ToLocalChecked());
}
} else {
v8::Local<v8::Function> cons = T::get_constructor();
v8::Local<v8::Object> inst = cons->NewInstance(info.Length(), &localArgs[0]);
info.GetReturnValue().Set(inst);
} }
NanReturnUndefined();
} }
template <class T> template <class T>
T* SassValueWrapper<T>::unwrap(Local<Object> obj) { T* SassValueWrapper<T>::unwrap(v8::Local<v8::Object> obj) {
return static_cast<T*>(Factory::unwrap(obj)); return static_cast<T*>(Factory::unwrap(obj));
} }
} }
......
...@@ -2,13 +2,11 @@ ...@@ -2,13 +2,11 @@
#include "string.h" #include "string.h"
#include "../create_string.h" #include "../create_string.h"
using namespace v8;
namespace SassTypes namespace SassTypes
{ {
String::String(Sass_Value* v) : SassValueWrapper(v) {} String::String(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* String::construct(const std::vector<Local<v8::Value>> raw_val) { Sass_Value* String::construct(const std::vector<v8::Local<v8::Value>> raw_val) {
char const* value = ""; char const* value = "";
if (raw_val.size() >= 1) { if (raw_val.size() >= 1) {
...@@ -22,26 +20,25 @@ namespace SassTypes ...@@ -22,26 +20,25 @@ namespace SassTypes
return sass_make_string(value); return sass_make_string(value);
} }
void String::initPrototype(Handle<ObjectTemplate> proto) { void String::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
proto->Set(NanNew("getValue"), NanNew<FunctionTemplate>(GetValue)->GetFunction()); Nan::SetPrototypeMethod(proto, "getValue", GetValue);
proto->Set(NanNew("setValue"), NanNew<FunctionTemplate>(SetValue)->GetFunction()); Nan::SetPrototypeMethod(proto, "setValue", SetValue);
} }
NAN_METHOD(String::GetValue) { NAN_METHOD(String::GetValue) {
NanScope(); info.GetReturnValue().Set(Nan::New<v8::String>(sass_string_get_value(unwrap(info.This())->value)).ToLocalChecked());
NanReturnValue(NanNew(sass_string_get_value(unwrap(args.This())->value)));
} }
NAN_METHOD(String::SetValue) { NAN_METHOD(String::SetValue) {
if (args.Length() != 1) { if (info.Length() != 1) {
return NanThrowError(NanNew("Expected just one argument")); return Nan::ThrowError(Nan::New("Expected just one argument").ToLocalChecked());
} }
if (!args[0]->IsString()) { if (!info[0]->IsString()) {
return NanThrowError(NanNew("Supplied value should be a string")); return Nan::ThrowError(Nan::New("Supplied value should be a string").ToLocalChecked());
} }
sass_string_set_value(unwrap(args.This())->value, create_string(args[0])); sass_string_set_value(unwrap(info.This())->value, create_string(info[0]));
NanReturnUndefined(); return;
} }
} }
...@@ -6,15 +6,13 @@ ...@@ -6,15 +6,13 @@
namespace SassTypes namespace SassTypes
{ {
using namespace v8;
class String : public SassValueWrapper<String> { class String : public SassValueWrapper<String> {
public: public:
String(Sass_Value*); String(Sass_Value*);
static char const* get_constructor_name() { return "SassString"; } static char const* get_constructor_name() { return "SassString"; }
static Sass_Value* construct(const std::vector<Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>);
static void initPrototype(Handle<ObjectTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
static NAN_METHOD(GetValue); static NAN_METHOD(GetValue);
static NAN_METHOD(SetValue); static NAN_METHOD(SetValue);
......
...@@ -6,13 +6,11 @@ ...@@ -6,13 +6,11 @@
namespace SassTypes namespace SassTypes
{ {
using namespace v8;
// This is the interface that all sass values must comply with // This is the interface that all sass values must comply with
class Value { class Value {
public: public:
virtual Sass_Value* get_sass_value() =0; virtual Sass_Value* get_sass_value() =0;
virtual Local<Object> get_js_object() =0; virtual v8::Local<v8::Object> get_js_object() =0;
}; };
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment