Skip to content
This repository has been archived by the owner on Jul 24, 2024. It is now read-only.

Fix Some Leaks #2128

Merged
merged 5 commits into from
Nov 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions memory-tests/_measure.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"use strict";

module.exports = function iterateAndMeasure(fn, mod = 1000000) {
let count = 0;
while (true) {
count++;
fn();
if (count % mod === 0) {
console.log(process.memoryUsage().rss / 1000000);
}
}
}
6 changes: 6 additions & 0 deletions memory-tests/boolean.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict';

var types = require('../').types;
var iterateAndMeasure = require('./_measure');

iterateAndMeasure(function() { return types.Boolean(true).getValue(); });
15 changes: 15 additions & 0 deletions memory-tests/function-bridge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"use strict";

var sass = require("../");
var iterateAndMeasure = require('./_measure');

iterateAndMeasure(function() {
sass.renderSync({
data: '#{headings()} { color: #08c; }',
functions: {
'headings()': function() {
return new sass.types.String('hi');
}
}
});
}, 10000);
17 changes: 17 additions & 0 deletions memory-tests/map.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

var types = require('../').types;
var iterateAndMeasure = require('./_measure');

iterateAndMeasure(function() {
var key = new types.String('the-key');
var value = new types.String('the-value');

var map = new types.Map(1);

map.setKey(0, key);
map.setValue(0, value);

map.getKey(0);
}, 100000);

6 changes: 6 additions & 0 deletions memory-tests/string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
'use strict';

var types = require('../').types;
var iterateAndMeasure = require('./_measure');

iterateAndMeasure(function() { return new types.String('hi'); });
7 changes: 5 additions & 2 deletions src/binding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,9 @@ int ExtractOptions(v8::Local<v8::Object> options, void* cptr, sass_context_wrapp
CustomFunctionBridge *bridge = new CustomFunctionBridge(callback, ctx_w->is_sync);
ctx_w->function_bridges.push_back(bridge);

Sass_Function_Entry fn = sass_make_function(create_string(signature), sass_custom_function, bridge);
char* sig = create_string(signature);
Sass_Function_Entry fn = sass_make_function(sig, sass_custom_function, bridge);
free(sig);
sass_function_set_list_entry(fn_list, i, fn);
}

Expand Down Expand Up @@ -267,7 +269,7 @@ NAN_METHOD(render) {
struct Sass_Data_Context* dctx = sass_make_data_context(source_string);
sass_context_wrapper* ctx_w = sass_make_context_wrapper();

if (ExtractOptions(options, dctx, ctx_w, false, false) >= 0) {
if (ExtractOptions(options, dctx, ctx_w, false, false) >= 0) {

int status = uv_queue_work(uv_default_loop(), &ctx_w->request, compile_it, (uv_after_work_cb)MakeCallback);

Expand All @@ -290,6 +292,7 @@ NAN_METHOD(render_sync) {
}

sass_free_context_wrapper(ctx_w);

info.GetReturnValue().Set(result == 0);
}

Expand Down
10 changes: 5 additions & 5 deletions src/callback_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Nan::Persistent<v8::Function> CallbackBridge<T, L>::wrapper_constructor;

template <typename T, typename L>
CallbackBridge<T, L>::CallbackBridge(v8::Local<v8::Function> callback, bool is_sync) : callback(new Nan::Callback(callback)), is_sync(is_sync) {
/*
/*
* This is invoked from the main JavaScript thread.
* V8 context is available.
*/
Expand Down Expand Up @@ -89,7 +89,7 @@ template <typename T, typename L>
T CallbackBridge<T, L>::operator()(std::vector<void*> argv) {
// argv.push_back(wrapper);
if (this->is_sync) {
/*
/*
* This is invoked from the main JavaScript thread.
* V8 context is available.
*
Expand All @@ -110,7 +110,7 @@ T CallbackBridge<T, L>::operator()(std::vector<void*> argv) {
this->callback->Call(argv_v8.size(), &argv_v8[0])
);
} else {
/*
/*
* This is invoked from the worker thread.
* No V8 context and functions available.
* Just wait for response from asynchronously
Expand Down Expand Up @@ -141,7 +141,7 @@ template <typename T, typename L>
void CallbackBridge<T, L>::dispatched_async_uv_callback(uv_async_t *req) {
CallbackBridge* bridge = static_cast<CallbackBridge*>(req->data);

/*
/*
* Function scheduled via uv_async mechanism, therefore
* it is invoked from the main JavaScript thread.
* V8 context is available.
Expand Down Expand Up @@ -169,7 +169,7 @@ void CallbackBridge<T, L>::dispatched_async_uv_callback(uv_async_t *req) {
template <typename T, typename L>
NAN_METHOD(CallbackBridge<T COMMA L>::ReturnCallback) {

/*
/*
* Callback function invoked by the user code.
* It is invoked from the main JavaScript thread.
* V8 context is available.
Expand Down
13 changes: 8 additions & 5 deletions src/custom_function_bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
#include "sass_types/factory.h"
#include "sass_types/value.h"

Sass_Value* CustomFunctionBridge::post_process_return_value(v8::Local<v8::Value> val) const {
SassTypes::Value *v_;
if ((v_ = SassTypes::Factory::unwrap(val))) {
return v_->get_sass_value();
Sass_Value* CustomFunctionBridge::post_process_return_value(v8::Local<v8::Value> _val) const {
SassTypes::Value *value = SassTypes::Factory::unwrap(_val);
if (value) {
return value->get_sass_value();
} else {
return sass_make_error("A SassValue object was expected.");
}
Expand All @@ -17,7 +17,10 @@ std::vector<v8::Local<v8::Value>> CustomFunctionBridge::pre_process_args(std::ve
std::vector<v8::Local<v8::Value>> argv = std::vector<v8::Local<v8::Value>>();

for (void* value : in) {
argv.push_back(SassTypes::Factory::create(static_cast<Sass_Value*>(value))->get_js_object());
Sass_Value* x = static_cast<Sass_Value*>(value);
SassTypes::Value* y = SassTypes::Factory::create(x);

argv.push_back(y->get_js_object());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this only cosmetic change or is there some deeper reason behind it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cosmetic

}

return argv;
Expand Down
6 changes: 4 additions & 2 deletions src/custom_importer_bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ SassImportList CustomImporterBridge::post_process_return_value(v8::Local<v8::Val
imports[i] = sass_make_import_entry(0, 0, 0);

sass_import_set_error(imports[i], message, -1, -1);
free(message);
}
else {
imports[i] = get_importer_entry(object);
Expand All @@ -43,6 +44,7 @@ SassImportList CustomImporterBridge::post_process_return_value(v8::Local<v8::Val
imports[0] = sass_make_import_entry(0, 0, 0);

sass_import_set_error(imports[0], message, -1, -1);
free(message);
}
else if (returned_value->IsObject()) {
imports = sass_make_import_list(1);
Expand All @@ -55,12 +57,12 @@ SassImportList CustomImporterBridge::post_process_return_value(v8::Local<v8::Val
Sass_Import* CustomImporterBridge::check_returned_string(Nan::MaybeLocal<v8::Value> value, const char *msg) const
{
v8::Local<v8::Value> checked;
if (value.ToLocal(&checked)) {
if (value.ToLocal(&checked)) {
if (!checked->IsUndefined() && !checked->IsString()) {
goto err;
} else {
return nullptr;
}
}
}
err:
auto entry = sass_make_import_entry(0, 0, 0);
Expand Down
20 changes: 9 additions & 11 deletions src/sass_types/boolean.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ namespace SassTypes
Nan::Persistent<v8::Function> Boolean::constructor;
bool Boolean::constructor_locked = false;

Boolean::Boolean(bool v) : value(v) {}
Boolean::Boolean(bool _value) {
value = sass_make_boolean(_value);
}

Boolean& Boolean::get_singleton(bool v) {
static Boolean instance_false(false), instance_true(true);
Expand All @@ -15,7 +17,7 @@ namespace SassTypes

v8::Local<v8::Function> Boolean::get_constructor() {
Nan::EscapableHandleScope scope;
v8::Local<v8::Function> conslocal;
v8::Local<v8::Function> conslocal;
if (constructor.IsEmpty()) {
v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);

Expand All @@ -42,16 +44,15 @@ namespace SassTypes
return scope.Escape(conslocal);
}

Sass_Value* Boolean::get_sass_value() {
return sass_make_boolean(value);
}

v8::Local<v8::Object> Boolean::get_js_object() {
return Nan::New(this->js_object);
}

NAN_METHOD(Boolean::New) {
v8::Local<v8::Boolean> Boolean::get_js_boolean() {
return sass_boolean_get_value(this->value) ? Nan::True() : Nan::False();
}

NAN_METHOD(Boolean::New) {
if (info.IsConstructCall()) {
if (constructor_locked) {
return Nan::ThrowTypeError("Cannot instantiate SassBoolean");
Expand All @@ -67,9 +68,6 @@ namespace SassTypes
}

NAN_METHOD(Boolean::GetValue) {
Boolean *out;
if ((out = static_cast<Boolean*>(Factory::unwrap(info.This())))) {
info.GetReturnValue().Set(Nan::New(out->value));
}
info.GetReturnValue().Set(Boolean::Unwrap<Boolean>(info.This())->get_js_boolean());
}
}
3 changes: 1 addition & 2 deletions src/sass_types/boolean.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ namespace SassTypes
static Boolean& get_singleton(bool);
static v8::Local<v8::Function> get_constructor();

Sass_Value* get_sass_value();
v8::Local<v8::Object> get_js_object();

static NAN_METHOD(New);
Expand All @@ -21,11 +20,11 @@ namespace SassTypes
private:
Boolean(bool);

bool value;
Nan::Persistent<v8::Object> js_object;

static Nan::Persistent<v8::Function> constructor;
static bool constructor_locked;
v8::Local<v8::Boolean> get_js_boolean();
};
}

Expand Down
16 changes: 8 additions & 8 deletions src/sass_types/color.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,19 @@ namespace SassTypes
}

NAN_METHOD(Color::GetR) {
info.GetReturnValue().Set(sass_color_get_r(unwrap(info.This())->value));
info.GetReturnValue().Set(sass_color_get_r(Color::Unwrap<Color>(info.This())->value));
}

NAN_METHOD(Color::GetG) {
info.GetReturnValue().Set(sass_color_get_g(unwrap(info.This())->value));
info.GetReturnValue().Set(sass_color_get_g(Color::Unwrap<Color>(info.This())->value));
}

NAN_METHOD(Color::GetB) {
info.GetReturnValue().Set(sass_color_get_b(unwrap(info.This())->value));
info.GetReturnValue().Set(sass_color_get_b(Color::Unwrap<Color>(info.This())->value));
}

NAN_METHOD(Color::GetA) {
info.GetReturnValue().Set(sass_color_get_a(unwrap(info.This())->value));
info.GetReturnValue().Set(sass_color_get_a(Color::Unwrap<Color>(info.This())->value));
}

NAN_METHOD(Color::SetR) {
Expand All @@ -86,7 +86,7 @@ namespace SassTypes
return Nan::ThrowTypeError("Supplied value should be a number");
}

sass_color_set_r(unwrap(info.This())->value, Nan::To<double>(info[0]).FromJust());
sass_color_set_r(Color::Unwrap<Color>(info.This())->value, Nan::To<double>(info[0]).FromJust());
}

NAN_METHOD(Color::SetG) {
Expand All @@ -98,7 +98,7 @@ namespace SassTypes
return Nan::ThrowTypeError("Supplied value should be a number");
}

sass_color_set_g(unwrap(info.This())->value, Nan::To<double>(info[0]).FromJust());
sass_color_set_g(Color::Unwrap<Color>(info.This())->value, Nan::To<double>(info[0]).FromJust());
}

NAN_METHOD(Color::SetB) {
Expand All @@ -110,7 +110,7 @@ namespace SassTypes
return Nan::ThrowTypeError("Supplied value should be a number");
}

sass_color_set_b(unwrap(info.This())->value, Nan::To<double>(info[0]).FromJust());
sass_color_set_b(Color::Unwrap<Color>(info.This())->value, Nan::To<double>(info[0]).FromJust());
}

NAN_METHOD(Color::SetA) {
Expand All @@ -122,6 +122,6 @@ namespace SassTypes
return Nan::ThrowTypeError("Supplied value should be a number");
}

sass_color_set_a(unwrap(info.This())->value, Nan::To<double>(info[0]).FromJust());
sass_color_set_a(Color::Unwrap<Color>(info.This())->value, Nan::To<double>(info[0]).FromJust());
}
}
11 changes: 6 additions & 5 deletions src/sass_types/factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,12 @@ namespace SassTypes
}

Value* Factory::unwrap(v8::Local<v8::Value> obj) {
// Todo: non-SassValue objects could easily fall under that condition, need to be more specific.
if (!obj->IsObject() || obj.As<v8::Object>()->InternalFieldCount() != 1) {
if (obj->IsObject()) {
v8::Local<v8::Object> v8_obj = obj.As<v8::Object>();
if (v8_obj->InternalFieldCount() == 1) {
return SassTypes::Value::Unwrap<Value>(v8_obj);
}
}
return NULL;
}

return static_cast<Value*>(Nan::GetInternalFieldPointer(obj.As<v8::Object>(), 0));
}
}
10 changes: 5 additions & 5 deletions src/sass_types/list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ namespace SassTypes
return Nan::ThrowTypeError("Supplied index should be an integer");
}

Sass_Value* list = unwrap(info.This())->value;
Sass_Value* list = List::Unwrap<List>(info.This())->value;
size_t index = Nan::To<uint32_t>(info[0]).FromJust();


Expand All @@ -73,14 +73,14 @@ namespace SassTypes

Value* sass_value = Factory::unwrap(info[1]);
if (sass_value) {
sass_list_set_value(unwrap(info.This())->value, Nan::To<uint32_t>(info[0]).FromJust(), sass_value->get_sass_value());
sass_list_set_value(List::Unwrap<List>(info.This())->value, Nan::To<uint32_t>(info[0]).FromJust(), sass_value->get_sass_value());
} else {
Nan::ThrowTypeError("A SassValue is expected as the list item");
}
}

NAN_METHOD(List::GetSeparator) {
info.GetReturnValue().Set(sass_list_get_separator(unwrap(info.This())->value) == SASS_COMMA);
info.GetReturnValue().Set(sass_list_get_separator(List::Unwrap<List>(info.This())->value) == SASS_COMMA);
}

NAN_METHOD(List::SetSeparator) {
Expand All @@ -92,10 +92,10 @@ namespace SassTypes
return Nan::ThrowTypeError("Supplied value should be a boolean");
}

sass_list_set_separator(unwrap(info.This())->value, Nan::To<bool>(info[0]).FromJust() ? SASS_COMMA : SASS_SPACE);
sass_list_set_separator(List::Unwrap<List>(info.This())->value, Nan::To<bool>(info[0]).FromJust() ? SASS_COMMA : SASS_SPACE);
}

NAN_METHOD(List::GetLength) {
info.GetReturnValue().Set(Nan::New<v8::Number>(sass_list_get_length(unwrap(info.This())->value)));
info.GetReturnValue().Set(Nan::New<v8::Number>(sass_list_get_length(List::Unwrap<List>(info.This())->value)));
}
}
Loading