sassc 2.0.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.gitmodules +1 -1
- data/.travis.yml +9 -3
- data/CHANGELOG.md +36 -0
- data/CODE_OF_CONDUCT.md +1 -1
- data/README.md +1 -1
- data/Rakefile +43 -7
- data/ext/depend +4 -0
- data/ext/extconf.rb +92 -0
- data/ext/libsass/VERSION +1 -0
- data/ext/libsass/include/sass/base.h +9 -1
- data/ext/libsass/include/sass/context.h +5 -1
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +755 -2028
- data/ext/libsass/src/ast.hpp +492 -2477
- data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
- data/ext/libsass/src/ast2c.hpp +39 -0
- data/ext/libsass/src/ast_def_macros.hpp +70 -10
- data/ext/libsass/src/ast_fwd_decl.cpp +5 -3
- data/ext/libsass/src/ast_fwd_decl.hpp +107 -296
- data/ext/libsass/src/ast_helpers.hpp +292 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +275 -0
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +1043 -0
- data/ext/libsass/src/ast_selectors.hpp +522 -0
- data/ext/libsass/src/ast_supports.cpp +114 -0
- data/ext/libsass/src/ast_supports.hpp +121 -0
- data/ext/libsass/src/ast_values.cpp +1154 -0
- data/ext/libsass/src/ast_values.hpp +498 -0
- data/ext/libsass/src/backtrace.cpp +11 -7
- data/ext/libsass/src/backtrace.hpp +5 -5
- data/ext/libsass/src/base64vlq.cpp +5 -2
- data/ext/libsass/src/base64vlq.hpp +1 -1
- data/ext/libsass/src/bind.cpp +35 -34
- data/ext/libsass/src/bind.hpp +3 -1
- data/ext/libsass/src/c2ast.cpp +64 -0
- data/ext/libsass/src/c2ast.hpp +14 -0
- data/ext/libsass/src/cencode.c +4 -6
- data/ext/libsass/src/check_nesting.cpp +83 -88
- data/ext/libsass/src/check_nesting.hpp +39 -34
- data/ext/libsass/src/color_maps.cpp +168 -164
- data/ext/libsass/src/color_maps.hpp +152 -160
- data/ext/libsass/src/constants.cpp +20 -0
- data/ext/libsass/src/constants.hpp +19 -0
- data/ext/libsass/src/context.cpp +104 -121
- data/ext/libsass/src/context.hpp +43 -55
- data/ext/libsass/src/cssize.cpp +103 -188
- data/ext/libsass/src/cssize.hpp +45 -51
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debugger.hpp +524 -361
- data/ext/libsass/src/emitter.cpp +26 -26
- data/ext/libsass/src/emitter.hpp +20 -18
- data/ext/libsass/src/environment.cpp +41 -27
- data/ext/libsass/src/environment.hpp +33 -22
- data/ext/libsass/src/error_handling.cpp +92 -94
- data/ext/libsass/src/error_handling.hpp +73 -50
- data/ext/libsass/src/eval.cpp +380 -515
- data/ext/libsass/src/eval.hpp +64 -57
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +322 -263
- data/ext/libsass/src/expand.hpp +55 -39
- data/ext/libsass/src/extender.cpp +1188 -0
- data/ext/libsass/src/extender.hpp +399 -0
- data/ext/libsass/src/extension.cpp +43 -0
- data/ext/libsass/src/extension.hpp +89 -0
- data/ext/libsass/src/file.cpp +134 -88
- data/ext/libsass/src/file.hpp +28 -37
- data/ext/libsass/src/fn_colors.cpp +596 -0
- data/ext/libsass/src/fn_colors.hpp +85 -0
- data/ext/libsass/src/fn_lists.cpp +285 -0
- data/ext/libsass/src/fn_lists.hpp +34 -0
- data/ext/libsass/src/fn_maps.cpp +94 -0
- data/ext/libsass/src/fn_maps.hpp +30 -0
- data/ext/libsass/src/fn_miscs.cpp +244 -0
- data/ext/libsass/src/fn_miscs.hpp +40 -0
- data/ext/libsass/src/fn_numbers.cpp +227 -0
- data/ext/libsass/src/fn_numbers.hpp +45 -0
- data/ext/libsass/src/fn_selectors.cpp +205 -0
- data/ext/libsass/src/fn_selectors.hpp +35 -0
- data/ext/libsass/src/fn_strings.cpp +268 -0
- data/ext/libsass/src/fn_strings.hpp +34 -0
- data/ext/libsass/src/fn_utils.cpp +158 -0
- data/ext/libsass/src/fn_utils.hpp +62 -0
- data/ext/libsass/src/inspect.cpp +253 -266
- data/ext/libsass/src/inspect.hpp +72 -74
- data/ext/libsass/src/json.cpp +2 -2
- data/ext/libsass/src/lexer.cpp +25 -84
- data/ext/libsass/src/lexer.hpp +5 -16
- data/ext/libsass/src/listize.cpp +27 -43
- data/ext/libsass/src/listize.hpp +14 -11
- data/ext/libsass/src/mapping.hpp +1 -0
- data/ext/libsass/src/memory.hpp +12 -0
- data/ext/libsass/src/memory/allocator.cpp +48 -0
- data/ext/libsass/src/memory/allocator.hpp +138 -0
- data/ext/libsass/src/memory/config.hpp +20 -0
- data/ext/libsass/src/memory/memory_pool.hpp +186 -0
- data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
- data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
- data/ext/libsass/src/operation.hpp +193 -143
- data/ext/libsass/src/operators.cpp +56 -29
- data/ext/libsass/src/operators.hpp +11 -11
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +59 -75
- data/ext/libsass/src/output.hpp +15 -22
- data/ext/libsass/src/parser.cpp +662 -818
- data/ext/libsass/src/parser.hpp +96 -100
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +12 -8
- data/ext/libsass/src/plugins.hpp +8 -8
- data/ext/libsass/src/position.cpp +10 -26
- data/ext/libsass/src/position.hpp +44 -21
- data/ext/libsass/src/prelexer.cpp +14 -8
- data/ext/libsass/src/prelexer.hpp +9 -9
- data/ext/libsass/src/remove_placeholders.cpp +59 -57
- data/ext/libsass/src/remove_placeholders.hpp +20 -18
- data/ext/libsass/src/sass.cpp +25 -18
- data/ext/libsass/src/sass.hpp +22 -14
- data/ext/libsass/src/sass2scss.cpp +49 -18
- data/ext/libsass/src/sass_context.cpp +104 -132
- data/ext/libsass/src/sass_context.hpp +2 -2
- data/ext/libsass/src/sass_functions.cpp +7 -4
- data/ext/libsass/src/sass_functions.hpp +1 -1
- data/ext/libsass/src/sass_values.cpp +26 -21
- data/ext/libsass/src/settings.hpp +19 -0
- data/ext/libsass/src/source.cpp +69 -0
- data/ext/libsass/src/source.hpp +95 -0
- data/ext/libsass/src/source_data.hpp +32 -0
- data/ext/libsass/src/source_map.cpp +27 -20
- data/ext/libsass/src/source_map.hpp +14 -11
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +24 -22
- data/ext/libsass/src/to_value.hpp +18 -22
- data/ext/libsass/src/units.cpp +28 -22
- data/ext/libsass/src/units.hpp +9 -8
- data/ext/libsass/src/utf8/checked.h +12 -10
- data/ext/libsass/src/utf8/core.h +3 -0
- data/ext/libsass/src/utf8_string.cpp +12 -10
- data/ext/libsass/src/utf8_string.hpp +7 -6
- data/ext/libsass/src/util.cpp +97 -107
- data/ext/libsass/src/util.hpp +74 -30
- data/ext/libsass/src/util_string.cpp +125 -0
- data/ext/libsass/src/util_string.hpp +73 -0
- data/ext/libsass/src/values.cpp +33 -24
- data/ext/libsass/src/values.hpp +2 -2
- data/lib/sassc.rb +24 -0
- data/lib/sassc/engine.rb +7 -5
- data/lib/sassc/functions_handler.rb +11 -13
- data/lib/sassc/native.rb +10 -9
- data/lib/sassc/native/native_functions_api.rb +0 -5
- data/lib/sassc/script.rb +4 -6
- data/lib/sassc/version.rb +1 -1
- data/sassc.gemspec +32 -12
- data/test/engine_test.rb +32 -2
- data/test/functions_test.rb +38 -1
- data/test/native_test.rb +4 -4
- metadata +95 -109
- data/ext/Rakefile +0 -3
- data/ext/libsass/.editorconfig +0 -15
- data/ext/libsass/.gitattributes +0 -2
- data/ext/libsass/.github/CONTRIBUTING.md +0 -65
- data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
- data/ext/libsass/.gitignore +0 -85
- data/ext/libsass/.travis.yml +0 -64
- data/ext/libsass/COPYING +0 -25
- data/ext/libsass/GNUmakefile.am +0 -88
- data/ext/libsass/INSTALL +0 -1
- data/ext/libsass/LICENSE +0 -25
- data/ext/libsass/Makefile +0 -351
- data/ext/libsass/Makefile.conf +0 -55
- data/ext/libsass/Readme.md +0 -104
- data/ext/libsass/SECURITY.md +0 -10
- data/ext/libsass/appveyor.yml +0 -91
- data/ext/libsass/configure.ac +0 -138
- data/ext/libsass/contrib/libsass.spec +0 -66
- data/ext/libsass/docs/README.md +0 -20
- data/ext/libsass/docs/api-context-example.md +0 -45
- data/ext/libsass/docs/api-context-internal.md +0 -163
- data/ext/libsass/docs/api-context.md +0 -295
- data/ext/libsass/docs/api-doc.md +0 -215
- data/ext/libsass/docs/api-function-example.md +0 -67
- data/ext/libsass/docs/api-function-internal.md +0 -8
- data/ext/libsass/docs/api-function.md +0 -74
- data/ext/libsass/docs/api-importer-example.md +0 -112
- data/ext/libsass/docs/api-importer-internal.md +0 -20
- data/ext/libsass/docs/api-importer.md +0 -86
- data/ext/libsass/docs/api-value-example.md +0 -55
- data/ext/libsass/docs/api-value-internal.md +0 -76
- data/ext/libsass/docs/api-value.md +0 -154
- data/ext/libsass/docs/build-on-darwin.md +0 -27
- data/ext/libsass/docs/build-on-gentoo.md +0 -55
- data/ext/libsass/docs/build-on-windows.md +0 -139
- data/ext/libsass/docs/build-shared-library.md +0 -35
- data/ext/libsass/docs/build-with-autotools.md +0 -78
- data/ext/libsass/docs/build-with-makefiles.md +0 -68
- data/ext/libsass/docs/build-with-mingw.md +0 -107
- data/ext/libsass/docs/build-with-visual-studio.md +0 -90
- data/ext/libsass/docs/build.md +0 -97
- data/ext/libsass/docs/compatibility-plan.md +0 -48
- data/ext/libsass/docs/contributing.md +0 -17
- data/ext/libsass/docs/custom-functions-internal.md +0 -122
- data/ext/libsass/docs/dev-ast-memory.md +0 -223
- data/ext/libsass/docs/implementations.md +0 -56
- data/ext/libsass/docs/plugins.md +0 -47
- data/ext/libsass/docs/setup-environment.md +0 -68
- data/ext/libsass/docs/source-map-internals.md +0 -51
- data/ext/libsass/docs/trace.md +0 -26
- data/ext/libsass/docs/triage.md +0 -17
- data/ext/libsass/docs/unicode.md +0 -39
- data/ext/libsass/extconf.rb +0 -6
- data/ext/libsass/include/sass/version.h.in +0 -12
- data/ext/libsass/m4/.gitkeep +0 -0
- data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +0 -167
- data/ext/libsass/res/resource.rc +0 -35
- data/ext/libsass/script/bootstrap +0 -13
- data/ext/libsass/script/branding +0 -10
- data/ext/libsass/script/ci-build-libsass +0 -134
- data/ext/libsass/script/ci-build-plugin +0 -62
- data/ext/libsass/script/ci-install-compiler +0 -6
- data/ext/libsass/script/ci-install-deps +0 -20
- data/ext/libsass/script/ci-report-coverage +0 -42
- data/ext/libsass/script/spec +0 -5
- data/ext/libsass/script/tap-driver +0 -652
- data/ext/libsass/script/tap-runner +0 -1
- data/ext/libsass/script/test-leaks.pl +0 -103
- data/ext/libsass/src/GNUmakefile.am +0 -54
- data/ext/libsass/src/extend.cpp +0 -2130
- data/ext/libsass/src/extend.hpp +0 -86
- data/ext/libsass/src/functions.cpp +0 -2234
- data/ext/libsass/src/functions.hpp +0 -198
- data/ext/libsass/src/memory/SharedPtr.cpp +0 -114
- data/ext/libsass/src/memory/SharedPtr.hpp +0 -206
- data/ext/libsass/src/node.cpp +0 -319
- data/ext/libsass/src/node.hpp +0 -118
- data/ext/libsass/src/paths.hpp +0 -71
- data/ext/libsass/src/sass_util.cpp +0 -149
- data/ext/libsass/src/sass_util.hpp +0 -256
- data/ext/libsass/src/subset_map.cpp +0 -55
- data/ext/libsass/src/subset_map.hpp +0 -76
- data/ext/libsass/src/support/libsass.pc.in +0 -11
- data/ext/libsass/src/to_c.hpp +0 -39
- data/ext/libsass/test/test_node.cpp +0 -94
- data/ext/libsass/test/test_paths.cpp +0 -28
- data/ext/libsass/test/test_selector_difference.cpp +0 -25
- data/ext/libsass/test/test_specificity.cpp +0 -25
- data/ext/libsass/test/test_subset_map.cpp +0 -472
- data/ext/libsass/test/test_superselector.cpp +0 -69
- data/ext/libsass/test/test_unification.cpp +0 -31
- data/ext/libsass/version.sh +0 -10
- data/ext/libsass/win/libsass.sln +0 -39
- data/ext/libsass/win/libsass.sln.DotSettings +0 -9
- data/ext/libsass/win/libsass.targets +0 -118
- data/ext/libsass/win/libsass.vcxproj +0 -188
- data/ext/libsass/win/libsass.vcxproj.filters +0 -357
- data/lib/sassc/native/lib_c.rb +0 -21
- data/lib/tasks/libsass.rb +0 -33
data/ext/libsass/src/listize.hpp
CHANGED
@@ -1,32 +1,35 @@
|
|
1
1
|
#ifndef SASS_LISTIZE_H
|
2
2
|
#define SASS_LISTIZE_H
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
// sass.hpp must go before all system headers to get the
|
5
|
+
// __EXTENSIONS__ fix on Solaris.
|
6
|
+
#include "sass.hpp"
|
6
7
|
|
7
|
-
#include "
|
8
|
-
#include "context.hpp"
|
8
|
+
#include "ast_fwd_decl.hpp"
|
9
9
|
#include "operation.hpp"
|
10
|
-
#include "environment.hpp"
|
11
10
|
|
12
11
|
namespace Sass {
|
13
12
|
|
14
13
|
struct Backtrace;
|
15
14
|
|
16
|
-
class Listize : public Operation_CRTP<
|
15
|
+
class Listize : public Operation_CRTP<Expression*, Listize> {
|
17
16
|
|
18
|
-
|
17
|
+
public:
|
18
|
+
|
19
|
+
static Expression* perform(AST_Node* node);
|
19
20
|
|
20
21
|
public:
|
21
22
|
Listize();
|
22
23
|
~Listize() { }
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
Expression* operator()(SelectorList*);
|
26
|
+
Expression* operator()(ComplexSelector*);
|
27
|
+
Expression* operator()(CompoundSelector*);
|
27
28
|
|
29
|
+
// generic fallback
|
28
30
|
template <typename U>
|
29
|
-
|
31
|
+
Expression* fallback(U x)
|
32
|
+
{ return Cast<Expression>(x); }
|
30
33
|
};
|
31
34
|
|
32
35
|
}
|
data/ext/libsass/src/mapping.hpp
CHANGED
@@ -0,0 +1,48 @@
|
|
1
|
+
#include "../sass.hpp"
|
2
|
+
#include "allocator.hpp"
|
3
|
+
#include "memory_pool.hpp"
|
4
|
+
|
5
|
+
#if defined (_MSC_VER) // Visual studio
|
6
|
+
#define thread_local __declspec( thread )
|
7
|
+
#elif defined (__GCC__) // GCC
|
8
|
+
#define thread_local __thread
|
9
|
+
#endif
|
10
|
+
|
11
|
+
namespace Sass {
|
12
|
+
|
13
|
+
#ifdef SASS_CUSTOM_ALLOCATOR
|
14
|
+
|
15
|
+
// Only use PODs for thread_local
|
16
|
+
// Objects get unpredictable init order
|
17
|
+
static thread_local MemoryPool* pool;
|
18
|
+
static thread_local size_t allocations;
|
19
|
+
|
20
|
+
void* allocateMem(size_t size)
|
21
|
+
{
|
22
|
+
if (pool == nullptr) {
|
23
|
+
pool = new MemoryPool();
|
24
|
+
}
|
25
|
+
allocations++;
|
26
|
+
return pool->allocate(size);
|
27
|
+
}
|
28
|
+
|
29
|
+
void deallocateMem(void* ptr, size_t size)
|
30
|
+
{
|
31
|
+
|
32
|
+
// It seems thread_local variable might be discharged!?
|
33
|
+
// But the destructors of e.g. static strings is still
|
34
|
+
// called, although their memory was discharged too.
|
35
|
+
// Fine with me as long as address sanitizer is happy.
|
36
|
+
if (pool == nullptr || allocations == 0) { return; }
|
37
|
+
|
38
|
+
pool->deallocate(ptr);
|
39
|
+
if (--allocations == 0) {
|
40
|
+
delete pool;
|
41
|
+
pool = nullptr;
|
42
|
+
}
|
43
|
+
|
44
|
+
}
|
45
|
+
|
46
|
+
#endif
|
47
|
+
|
48
|
+
}
|
@@ -0,0 +1,138 @@
|
|
1
|
+
#ifndef SASS_ALLOCATOR_H
|
2
|
+
#define SASS_ALLOCATOR_H
|
3
|
+
|
4
|
+
#include "config.hpp"
|
5
|
+
#include "../settings.hpp"
|
6
|
+
#include "../MurmurHash2.hpp"
|
7
|
+
|
8
|
+
#include <vector>
|
9
|
+
#include <limits>
|
10
|
+
#include <iostream>
|
11
|
+
#include <algorithm>
|
12
|
+
#include <functional>
|
13
|
+
|
14
|
+
namespace Sass {
|
15
|
+
|
16
|
+
#ifndef SASS_CUSTOM_ALLOCATOR
|
17
|
+
|
18
|
+
template <typename T> using Allocator = std::allocator<T>;
|
19
|
+
|
20
|
+
#else
|
21
|
+
|
22
|
+
void* allocateMem(size_t size);
|
23
|
+
|
24
|
+
void deallocateMem(void* ptr, size_t size = 1);
|
25
|
+
|
26
|
+
template<typename T>
|
27
|
+
class Allocator
|
28
|
+
{
|
29
|
+
public:
|
30
|
+
|
31
|
+
// Allocator traits
|
32
|
+
typedef T type;
|
33
|
+
typedef type value_type;
|
34
|
+
typedef value_type* pointer;
|
35
|
+
typedef value_type const* const_pointer;
|
36
|
+
typedef value_type& reference;
|
37
|
+
typedef value_type const& const_reference;
|
38
|
+
typedef std::size_t size_type;
|
39
|
+
typedef std::ptrdiff_t difference_type;
|
40
|
+
|
41
|
+
template<typename U>
|
42
|
+
struct rebind
|
43
|
+
{
|
44
|
+
typedef Allocator<U> other;
|
45
|
+
};
|
46
|
+
|
47
|
+
// Constructor
|
48
|
+
Allocator(void) {}
|
49
|
+
|
50
|
+
// Copy Constructor
|
51
|
+
template<typename U>
|
52
|
+
Allocator(Allocator<U> const&)
|
53
|
+
{}
|
54
|
+
|
55
|
+
// allocate but don't initialize count of elements of type T
|
56
|
+
pointer allocate(size_type count, const_pointer /* hint */ = 0)
|
57
|
+
{
|
58
|
+
return (pointer)(Sass::allocateMem(count * sizeof(T)));
|
59
|
+
}
|
60
|
+
|
61
|
+
// deallocate storage ptr of deleted elements
|
62
|
+
void deallocate(pointer ptr, size_type count)
|
63
|
+
{
|
64
|
+
Sass::deallocateMem(ptr, count);
|
65
|
+
}
|
66
|
+
|
67
|
+
// return maximum number of elements that can be allocated
|
68
|
+
size_type max_size() const throw()
|
69
|
+
{
|
70
|
+
return std::numeric_limits<size_type>::max() / sizeof(T);
|
71
|
+
}
|
72
|
+
|
73
|
+
// Address of object
|
74
|
+
type* address(type& obj) const { return &obj; }
|
75
|
+
type const* address(type const& obj) const { return &obj; }
|
76
|
+
|
77
|
+
// Construct object
|
78
|
+
void construct(type* ptr, type const& ref) const
|
79
|
+
{
|
80
|
+
// In-place copy construct
|
81
|
+
new(ptr) type(ref);
|
82
|
+
}
|
83
|
+
|
84
|
+
// Destroy object
|
85
|
+
void destroy(type* ptr) const
|
86
|
+
{
|
87
|
+
// Call destructor
|
88
|
+
ptr->~type();
|
89
|
+
}
|
90
|
+
|
91
|
+
};
|
92
|
+
|
93
|
+
template<typename T, typename U>
|
94
|
+
bool operator==(Allocator<T> const& left,
|
95
|
+
Allocator<U> const& right)
|
96
|
+
{
|
97
|
+
return true;
|
98
|
+
}
|
99
|
+
|
100
|
+
template<typename T, typename U>
|
101
|
+
bool operator!=(Allocator<T> const& left,
|
102
|
+
Allocator<U> const& right)
|
103
|
+
{
|
104
|
+
return !(left == right);
|
105
|
+
}
|
106
|
+
|
107
|
+
#endif
|
108
|
+
|
109
|
+
namespace sass {
|
110
|
+
template <typename T> using vector = std::vector<T, Sass::Allocator<T>>;
|
111
|
+
using string = std::basic_string<char, std::char_traits<char>, Sass::Allocator<char>>;
|
112
|
+
using sstream = std::basic_stringstream<char, std::char_traits<char>, Sass::Allocator<char>>;
|
113
|
+
using ostream = std::basic_ostringstream<char, std::char_traits<char>, Sass::Allocator<char>>;
|
114
|
+
using istream = std::basic_istringstream<char, std::char_traits<char>, Sass::Allocator<char>>;
|
115
|
+
}
|
116
|
+
|
117
|
+
}
|
118
|
+
|
119
|
+
#ifdef SASS_CUSTOM_ALLOCATOR
|
120
|
+
|
121
|
+
namespace std {
|
122
|
+
// Only GCC seems to need this specialization!?
|
123
|
+
template <> struct hash<Sass::sass::string> {
|
124
|
+
public:
|
125
|
+
inline size_t operator()(
|
126
|
+
const Sass::sass::string& name) const
|
127
|
+
{
|
128
|
+
return MurmurHash2(
|
129
|
+
(void*)name.c_str(),
|
130
|
+
(int)name.size(),
|
131
|
+
0x73617373);
|
132
|
+
}
|
133
|
+
};
|
134
|
+
}
|
135
|
+
|
136
|
+
#endif
|
137
|
+
|
138
|
+
#endif
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#ifndef SASS_MEMORY_CONFIG_H
|
2
|
+
#define SASS_MEMORY_CONFIG_H
|
3
|
+
|
4
|
+
// Define memory alignment requirements
|
5
|
+
#define SASS_MEM_ALIGN sizeof(unsigned int)
|
6
|
+
|
7
|
+
// Minimal alignment for memory fragments. Must be a multiple
|
8
|
+
// of `SASS_MEM_ALIGN` and should not be too big (maybe 1 or 2)
|
9
|
+
#define SassAllocatorHeadSize sizeof(unsigned int)
|
10
|
+
|
11
|
+
// The number of bytes we use for our book-keeping before every
|
12
|
+
// memory fragment. Needed to know to which bucket we belongs on
|
13
|
+
// deallocations, or if it should go directly to the `free` call.
|
14
|
+
#define SassAllocatorBookSize sizeof(unsigned int)
|
15
|
+
|
16
|
+
// Bytes reserve for book-keeping on the arenas
|
17
|
+
// Currently unused and for later optimization
|
18
|
+
#define SassAllocatorArenaHeadSize 0
|
19
|
+
|
20
|
+
#endif
|
@@ -0,0 +1,186 @@
|
|
1
|
+
#ifndef SASS_MEMORY_POOL_H
|
2
|
+
#define SASS_MEMORY_POOL_H
|
3
|
+
|
4
|
+
#include <stdlib.h>
|
5
|
+
#include <iostream>
|
6
|
+
#include <algorithm>
|
7
|
+
#include <climits>
|
8
|
+
#include <vector>
|
9
|
+
|
10
|
+
namespace Sass {
|
11
|
+
|
12
|
+
// SIMPLE MEMORY-POOL ALLOCATOR WITH FREE-LIST ON TOP
|
13
|
+
|
14
|
+
// This is a memory pool allocator with a free list on top.
|
15
|
+
// We only allocate memory arenas from the system in specific
|
16
|
+
// sizes (`SassAllocatorArenaSize`). Users claim memory slices
|
17
|
+
// of certain sizes from the pool. If the allocation is too big
|
18
|
+
// to fit into our buckets, we use regular malloc/free instead.
|
19
|
+
|
20
|
+
// When the systems starts, we allocate the first arena and then
|
21
|
+
// start to give out addresses to memory slices. During that
|
22
|
+
// we steadily increase `offset` until the current arena is full.
|
23
|
+
// Once that happens we allocate a new arena and continue.
|
24
|
+
// https://en.wikipedia.org/wiki/Memory_pool
|
25
|
+
|
26
|
+
// Fragments that get deallocated are not really freed, we put
|
27
|
+
// them on our free-list. For every bucket we have a pointer to
|
28
|
+
// the first item for reuse. That item itself holds a pointer to
|
29
|
+
// the previously free item (regular free-list implementation).
|
30
|
+
// https://en.wikipedia.org/wiki/Free_list
|
31
|
+
|
32
|
+
// On allocation calls we first check if there is any suitable
|
33
|
+
// item on the free-list. If there is we pop it from the stack
|
34
|
+
// and return it to the caller. Otherwise we have to take out
|
35
|
+
// a new slice from the current `arena` and increase `offset`.
|
36
|
+
|
37
|
+
// Note that this is not thread safe. This is on purpose as we
|
38
|
+
// want to use the memory pool in a thread local usage. In order
|
39
|
+
// to get this thread safe you need to only allocate one pool
|
40
|
+
// per thread. This can be achieved by using thread local PODs.
|
41
|
+
// Simply create a pool on the first allocation and dispose
|
42
|
+
// it once all allocations have been returned. E.g. by using:
|
43
|
+
// static thread_local size_t allocations;
|
44
|
+
// static thread_local MemoryPool* pool;
|
45
|
+
|
46
|
+
class MemoryPool {
|
47
|
+
|
48
|
+
// Current arena we fill up
|
49
|
+
char* arena;
|
50
|
+
|
51
|
+
// Position into the arena
|
52
|
+
size_t offset = std::string::npos;
|
53
|
+
|
54
|
+
// A list of full arenas
|
55
|
+
std::vector<void*> arenas;
|
56
|
+
|
57
|
+
// One pointer for every bucket (zero init)
|
58
|
+
#ifdef _MSC_VER
|
59
|
+
#pragma warning (suppress:4351)
|
60
|
+
#endif
|
61
|
+
void* freeList[SassAllocatorBuckets]{};
|
62
|
+
|
63
|
+
// Increase the address until it sits on a
|
64
|
+
// memory aligned address (maybe use `aligned`).
|
65
|
+
inline static size_t alignMemAddr(size_t addr) {
|
66
|
+
return (addr + SASS_MEM_ALIGN - 1) & ~(SASS_MEM_ALIGN - 1);
|
67
|
+
}
|
68
|
+
|
69
|
+
public:
|
70
|
+
|
71
|
+
// Default ctor
|
72
|
+
MemoryPool() :
|
73
|
+
// Wait for first allocation
|
74
|
+
arena(nullptr),
|
75
|
+
// Set to maximum value in order to
|
76
|
+
// make an allocation on the first run
|
77
|
+
offset(std::string::npos)
|
78
|
+
{
|
79
|
+
}
|
80
|
+
|
81
|
+
// Destructor
|
82
|
+
~MemoryPool() {
|
83
|
+
// Delete full arenas
|
84
|
+
for (auto area : arenas) {
|
85
|
+
free(area);
|
86
|
+
}
|
87
|
+
// Delete current arena
|
88
|
+
free(arena);
|
89
|
+
|
90
|
+
}
|
91
|
+
|
92
|
+
// Allocate a slice of the memory pool
|
93
|
+
void* allocate(size_t size)
|
94
|
+
{
|
95
|
+
|
96
|
+
// Increase size so its memory is aligned
|
97
|
+
size = alignMemAddr(
|
98
|
+
// Make sure we have enough space for us to
|
99
|
+
// create the pointer to the free list later
|
100
|
+
std::max(sizeof(void*), size)
|
101
|
+
// and the size needed for our book-keeping
|
102
|
+
+ SassAllocatorBookSize);
|
103
|
+
|
104
|
+
// Size must be multiple of alignment
|
105
|
+
// So we can derive bucket index from it
|
106
|
+
size_t bucket = size / SASS_MEM_ALIGN;
|
107
|
+
|
108
|
+
// Everything bigger is allocated via malloc
|
109
|
+
// Malloc is optimized for exactly this case
|
110
|
+
if (bucket >= SassAllocatorBuckets) {
|
111
|
+
char* buffer = (char*)malloc(size);
|
112
|
+
if (buffer == nullptr) {
|
113
|
+
throw std::bad_alloc();
|
114
|
+
}
|
115
|
+
// Mark it for deallocation via free
|
116
|
+
((unsigned int*)buffer)[0] = UINT_MAX;
|
117
|
+
// Return pointer after our book-keeping space
|
118
|
+
return (void*)(buffer + SassAllocatorBookSize);
|
119
|
+
}
|
120
|
+
// Use custom allocator
|
121
|
+
else {
|
122
|
+
// Get item from free list
|
123
|
+
void*& free = freeList[bucket];
|
124
|
+
// Do we have a free item?
|
125
|
+
if (free != nullptr) {
|
126
|
+
// Copy pointer to return
|
127
|
+
void* ptr = free;
|
128
|
+
// Update free list pointer
|
129
|
+
free = ((void**)ptr)[0];
|
130
|
+
// Return popped item
|
131
|
+
return ptr;
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
// Make sure we have enough space in the arena
|
136
|
+
if (!arena || offset > SassAllocatorArenaSize - size) {
|
137
|
+
if (arena) arenas.emplace_back(arena);
|
138
|
+
arena = (char*)malloc(SassAllocatorArenaSize);
|
139
|
+
if (arena == nullptr) throw std::bad_alloc();
|
140
|
+
offset = SassAllocatorArenaHeadSize;
|
141
|
+
}
|
142
|
+
|
143
|
+
// Get pointer into the arena
|
144
|
+
char* buffer = arena + offset;
|
145
|
+
// Consume object size
|
146
|
+
offset += size;
|
147
|
+
|
148
|
+
// Set the bucket index for this slice
|
149
|
+
((unsigned int*)buffer)[0] = (unsigned int)bucket;
|
150
|
+
|
151
|
+
// Return pointer after our book-keeping space
|
152
|
+
return (void*)(buffer + SassAllocatorBookSize);
|
153
|
+
|
154
|
+
}
|
155
|
+
// EO allocate
|
156
|
+
|
157
|
+
void deallocate(void* ptr)
|
158
|
+
{
|
159
|
+
|
160
|
+
// Rewind buffer from pointer
|
161
|
+
char* buffer = (char*)ptr -
|
162
|
+
SassAllocatorBookSize;
|
163
|
+
|
164
|
+
// Get the bucket index stored in the header
|
165
|
+
unsigned int bucket = ((unsigned int*)buffer)[0];
|
166
|
+
|
167
|
+
// Check allocation method
|
168
|
+
if (bucket != UINT_MAX) {
|
169
|
+
// Let memory point to previous item in free list
|
170
|
+
((void**)ptr)[0] = freeList[bucket];
|
171
|
+
// Free list now points to our memory
|
172
|
+
freeList[bucket] = (void*)ptr;
|
173
|
+
}
|
174
|
+
else {
|
175
|
+
// Release memory
|
176
|
+
free(buffer);
|
177
|
+
}
|
178
|
+
|
179
|
+
}
|
180
|
+
// EO deallocate
|
181
|
+
|
182
|
+
};
|
183
|
+
|
184
|
+
}
|
185
|
+
|
186
|
+
#endif
|