Commit dd1f3a9d by Marcin Cieslak

Return NULL when failed to construct a Sass value

::construct() methods may return NULL and
indicate an error in the returned error value.
parent 4a6a9cc6
...@@ -5,14 +5,14 @@ namespace SassTypes ...@@ -5,14 +5,14 @@ namespace SassTypes
{ {
Color::Color(Sass_Value* v) : SassValueWrapper(v) {} Color::Color(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* Color::construct(const std::vector<v8::Local<v8::Value>> raw_val) { Sass_Value* Color::construct(const std::vector<v8::Local<v8::Value>> raw_val, Sass_Value **out) {
double a = 1.0, r = 0, g = 0, b = 0; double a = 1.0, r = 0, g = 0, b = 0;
unsigned argb; unsigned argb;
switch (raw_val.size()) { switch (raw_val.size()) {
case 1: case 1:
if (!raw_val[0]->IsNumber()) { if (!raw_val[0]->IsNumber()) {
throw std::invalid_argument("Only argument should be an integer."); return fail("Only argument should be an integer.", out);
} }
argb = Nan::To<int32_t>(raw_val[0]).FromJust(); argb = Nan::To<int32_t>(raw_val[0]).FromJust();
...@@ -24,7 +24,7 @@ namespace SassTypes ...@@ -24,7 +24,7 @@ namespace SassTypes
case 4: case 4:
if (!raw_val[3]->IsNumber()) { if (!raw_val[3]->IsNumber()) {
throw std::invalid_argument("Constructor arguments should be numbers exclusively."); return fail("Constructor arguments should be numbers exclusively.", out);
} }
a = Nan::To<double>(raw_val[3]).FromJust(); a = Nan::To<double>(raw_val[3]).FromJust();
...@@ -32,7 +32,7 @@ namespace SassTypes ...@@ -32,7 +32,7 @@ namespace SassTypes
case 3: case 3:
if (!raw_val[0]->IsNumber() || !raw_val[1]->IsNumber() || !raw_val[2]->IsNumber()) { if (!raw_val[0]->IsNumber() || !raw_val[1]->IsNumber() || !raw_val[2]->IsNumber()) {
throw std::invalid_argument("Constructor arguments should be numbers exclusively."); return fail("Constructor arguments should be numbers exclusively.", out);
} }
r = Nan::To<double>(raw_val[0]).FromJust(); r = Nan::To<double>(raw_val[0]).FromJust();
...@@ -44,10 +44,10 @@ namespace SassTypes ...@@ -44,10 +44,10 @@ namespace SassTypes
break; break;
default: default:
throw std::invalid_argument("Constructor should be invoked with either 0, 1, 3 or 4 arguments."); return fail("Constructor should be invoked with either 0, 1, 3 or 4 arguments.", out);
} }
return sass_make_color(r, g, b, a); return *out = sass_make_color(r, g, b, a);
} }
void Color::initPrototype(v8::Local<v8::FunctionTemplate> proto) { void Color::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
......
...@@ -10,7 +10,7 @@ namespace SassTypes ...@@ -10,7 +10,7 @@ namespace SassTypes
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<v8::Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>, Sass_Value **);
static void initPrototype(v8::Local<v8::FunctionTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
......
...@@ -6,18 +6,18 @@ namespace SassTypes ...@@ -6,18 +6,18 @@ namespace SassTypes
{ {
Error::Error(Sass_Value* v) : SassValueWrapper(v) {} Error::Error(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* Error::construct(const std::vector<v8::Local<v8::Value>> raw_val) { Sass_Value* Error::construct(const std::vector<v8::Local<v8::Value>> raw_val, Sass_Value **out) {
char const* value = ""; char const* value = "";
if (raw_val.size() >= 1) { if (raw_val.size() >= 1) {
if (!raw_val[0]->IsString()) { if (!raw_val[0]->IsString()) {
throw std::invalid_argument("Argument should be a string."); return fail("Argument should be a string.", out);
} }
value = create_string(raw_val[0]); value = create_string(raw_val[0]);
} }
return sass_make_error(value); return *out = sass_make_error(value);
} }
void Error::initPrototype(v8::Local<v8::FunctionTemplate>) {} void Error::initPrototype(v8::Local<v8::FunctionTemplate>) {}
......
...@@ -10,7 +10,7 @@ namespace SassTypes ...@@ -10,7 +10,7 @@ namespace SassTypes
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<v8::Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>, Sass_Value **);
static void initPrototype(v8::Local<v8::FunctionTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
}; };
......
...@@ -5,27 +5,27 @@ namespace SassTypes ...@@ -5,27 +5,27 @@ namespace SassTypes
{ {
List::List(Sass_Value* v) : SassValueWrapper(v) {} List::List(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* List::construct(const std::vector<v8::Local<v8::Value>> raw_val) { Sass_Value* List::construct(const std::vector<v8::Local<v8::Value>> raw_val, Sass_Value **out) {
size_t length = 0; size_t length = 0;
bool comma = true; bool comma = true;
if (raw_val.size() >= 1) { if (raw_val.size() >= 1) {
if (!raw_val[0]->IsNumber()) { if (!raw_val[0]->IsNumber()) {
throw std::invalid_argument("First argument should be an integer."); return fail("First argument should be an integer.", out);
} }
length = Nan::To<uint32_t>(raw_val[0]).FromJust(); length = Nan::To<uint32_t>(raw_val[0]).FromJust();
if (raw_val.size() >= 2) { if (raw_val.size() >= 2) {
if (!raw_val[1]->IsBoolean()) { if (!raw_val[1]->IsBoolean()) {
throw std::invalid_argument("Second argument should be a boolean."); return fail("Second argument should be a boolean.", out);
} }
comma = Nan::To<bool>(raw_val[1]).FromJust(); comma = Nan::To<bool>(raw_val[1]).FromJust();
} }
} }
return sass_make_list(length, comma ? SASS_COMMA : SASS_SPACE); return *out = sass_make_list(length, comma ? SASS_COMMA : SASS_SPACE);
} }
void List::initPrototype(v8::Local<v8::FunctionTemplate> proto) { void List::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
......
...@@ -10,7 +10,7 @@ namespace SassTypes ...@@ -10,7 +10,7 @@ namespace SassTypes
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<v8::Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>, Sass_Value **);
static void initPrototype(v8::Local<v8::FunctionTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
......
...@@ -5,18 +5,18 @@ namespace SassTypes ...@@ -5,18 +5,18 @@ namespace SassTypes
{ {
Map::Map(Sass_Value* v) : SassValueWrapper(v) {} Map::Map(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* Map::construct(const std::vector<v8::Local<v8::Value>> raw_val) { Sass_Value* Map::construct(const std::vector<v8::Local<v8::Value>> raw_val, Sass_Value **out) {
size_t length = 0; size_t length = 0;
if (raw_val.size() >= 1) { if (raw_val.size() >= 1) {
if (!raw_val[0]->IsNumber()) { if (!raw_val[0]->IsNumber()) {
throw std::invalid_argument("First argument should be an integer."); return fail("First argument should be an integer.", out);
} }
length = Nan::To<uint32_t>(raw_val[0]).FromJust(); length = Nan::To<uint32_t>(raw_val[0]).FromJust();
} }
return sass_make_map(length); return *out = sass_make_map(length);
} }
void Map::initPrototype(v8::Local<v8::FunctionTemplate> proto) { void Map::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
......
...@@ -10,7 +10,7 @@ namespace SassTypes ...@@ -10,7 +10,7 @@ namespace SassTypes
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<v8::Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>, Sass_Value **);
static void initPrototype(v8::Local<v8::FunctionTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
......
...@@ -6,27 +6,27 @@ namespace SassTypes ...@@ -6,27 +6,27 @@ namespace SassTypes
{ {
Number::Number(Sass_Value* v) : SassValueWrapper(v) {} Number::Number(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* Number::construct(const std::vector<v8::Local<v8::Value>> raw_val) { Sass_Value* Number::construct(const std::vector<v8::Local<v8::Value>> raw_val, Sass_Value **out) {
double value = 0; double value = 0;
char const* unit = ""; char const* unit = "";
if (raw_val.size() >= 1) { if (raw_val.size() >= 1) {
if (!raw_val[0]->IsNumber()) { if (!raw_val[0]->IsNumber()) {
throw std::invalid_argument("First argument should be a number."); return fail("First argument should be a number.", out);
} }
value = Nan::To<double>(raw_val[0]).FromJust(); value = Nan::To<double>(raw_val[0]).FromJust();
if (raw_val.size() >= 2) { if (raw_val.size() >= 2) {
if (!raw_val[1]->IsString()) { if (!raw_val[1]->IsString()) {
throw std::invalid_argument("Second argument should be a string."); return fail("Second argument should be a string.", out);
} }
unit = create_string(raw_val[1]); unit = create_string(raw_val[1]);
} }
} }
return sass_make_number(value, unit); return *out = sass_make_number(value, unit);
} }
void Number::initPrototype(v8::Local<v8::FunctionTemplate> proto) { void Number::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
......
...@@ -11,7 +11,7 @@ namespace SassTypes ...@@ -11,7 +11,7 @@ namespace SassTypes
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<v8::Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>, Sass_Value **out);
static void initPrototype(v8::Local<v8::FunctionTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
......
...@@ -95,15 +95,15 @@ namespace SassTypes ...@@ -95,15 +95,15 @@ namespace SassTypes
localArgs[i] = info[i]; localArgs[i] = info[i];
} }
if (info.IsConstructCall()) { if (info.IsConstructCall()) {
try { Sass_Value* value;
Sass_Value* value = T::construct(localArgs); if (T::construct(localArgs, &value) != NULL) {
T* obj = new T(value); T* obj = new T(value);
sass_delete_value(value); sass_delete_value(value);
Nan::SetInternalFieldPointer(info.This(), 0, obj); Nan::SetInternalFieldPointer(info.This(), 0, obj);
obj->js_object.Reset(info.This()); obj->js_object.Reset(info.This());
} catch (const std::exception& e) { } else {
return Nan::ThrowError(Nan::New<v8::String>(e.what()).ToLocalChecked()); return Nan::ThrowError(Nan::New<v8::String>(sass_error_get_message(value)).ToLocalChecked());
} }
} else { } else {
v8::Local<v8::Function> cons = T::get_constructor(); v8::Local<v8::Function> cons = T::get_constructor();
......
...@@ -6,18 +6,18 @@ namespace SassTypes ...@@ -6,18 +6,18 @@ namespace SassTypes
{ {
String::String(Sass_Value* v) : SassValueWrapper(v) {} String::String(Sass_Value* v) : SassValueWrapper(v) {}
Sass_Value* String::construct(const std::vector<v8::Local<v8::Value>> raw_val) { Sass_Value* String::construct(const std::vector<v8::Local<v8::Value>> raw_val, Sass_Value **out) {
char const* value = ""; char const* value = "";
if (raw_val.size() >= 1) { if (raw_val.size() >= 1) {
if (!raw_val[0]->IsString()) { if (!raw_val[0]->IsString()) {
throw std::invalid_argument("Argument should be a string."); return fail("Argument should be a string.", out);
} }
value = create_string(raw_val[0]); value = create_string(raw_val[0]);
} }
return sass_make_string(value); return *out = sass_make_string(value);
} }
void String::initPrototype(v8::Local<v8::FunctionTemplate> proto) { void String::initPrototype(v8::Local<v8::FunctionTemplate> proto) {
......
...@@ -10,7 +10,7 @@ namespace SassTypes ...@@ -10,7 +10,7 @@ namespace SassTypes
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<v8::Local<v8::Value>>); static Sass_Value* construct(const std::vector<v8::Local<v8::Value>>, Sass_Value **);
static void initPrototype(v8::Local<v8::FunctionTemplate>); static void initPrototype(v8::Local<v8::FunctionTemplate>);
......
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