sassc 2.0.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (260) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.gitmodules +1 -1
  4. data/.travis.yml +9 -3
  5. data/CHANGELOG.md +36 -0
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +43 -7
  9. data/ext/depend +4 -0
  10. data/ext/extconf.rb +92 -0
  11. data/ext/libsass/VERSION +1 -0
  12. data/ext/libsass/include/sass/base.h +9 -1
  13. data/ext/libsass/include/sass/context.h +5 -1
  14. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  15. data/ext/libsass/src/ast.cpp +755 -2028
  16. data/ext/libsass/src/ast.hpp +492 -2477
  17. data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
  18. data/ext/libsass/src/ast2c.hpp +39 -0
  19. data/ext/libsass/src/ast_def_macros.hpp +70 -10
  20. data/ext/libsass/src/ast_fwd_decl.cpp +5 -3
  21. data/ext/libsass/src/ast_fwd_decl.hpp +107 -296
  22. data/ext/libsass/src/ast_helpers.hpp +292 -0
  23. data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
  24. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  25. data/ext/libsass/src/ast_sel_unify.cpp +275 -0
  26. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  27. data/ext/libsass/src/ast_selectors.cpp +1043 -0
  28. data/ext/libsass/src/ast_selectors.hpp +522 -0
  29. data/ext/libsass/src/ast_supports.cpp +114 -0
  30. data/ext/libsass/src/ast_supports.hpp +121 -0
  31. data/ext/libsass/src/ast_values.cpp +1154 -0
  32. data/ext/libsass/src/ast_values.hpp +498 -0
  33. data/ext/libsass/src/backtrace.cpp +11 -7
  34. data/ext/libsass/src/backtrace.hpp +5 -5
  35. data/ext/libsass/src/base64vlq.cpp +5 -2
  36. data/ext/libsass/src/base64vlq.hpp +1 -1
  37. data/ext/libsass/src/bind.cpp +35 -34
  38. data/ext/libsass/src/bind.hpp +3 -1
  39. data/ext/libsass/src/c2ast.cpp +64 -0
  40. data/ext/libsass/src/c2ast.hpp +14 -0
  41. data/ext/libsass/src/cencode.c +4 -6
  42. data/ext/libsass/src/check_nesting.cpp +83 -88
  43. data/ext/libsass/src/check_nesting.hpp +39 -34
  44. data/ext/libsass/src/color_maps.cpp +168 -164
  45. data/ext/libsass/src/color_maps.hpp +152 -160
  46. data/ext/libsass/src/constants.cpp +20 -0
  47. data/ext/libsass/src/constants.hpp +19 -0
  48. data/ext/libsass/src/context.cpp +104 -121
  49. data/ext/libsass/src/context.hpp +43 -55
  50. data/ext/libsass/src/cssize.cpp +103 -188
  51. data/ext/libsass/src/cssize.hpp +45 -51
  52. data/ext/libsass/src/dart_helpers.hpp +199 -0
  53. data/ext/libsass/src/debugger.hpp +524 -361
  54. data/ext/libsass/src/emitter.cpp +26 -26
  55. data/ext/libsass/src/emitter.hpp +20 -18
  56. data/ext/libsass/src/environment.cpp +41 -27
  57. data/ext/libsass/src/environment.hpp +33 -22
  58. data/ext/libsass/src/error_handling.cpp +92 -94
  59. data/ext/libsass/src/error_handling.hpp +73 -50
  60. data/ext/libsass/src/eval.cpp +380 -515
  61. data/ext/libsass/src/eval.hpp +64 -57
  62. data/ext/libsass/src/eval_selectors.cpp +75 -0
  63. data/ext/libsass/src/expand.cpp +322 -263
  64. data/ext/libsass/src/expand.hpp +55 -39
  65. data/ext/libsass/src/extender.cpp +1188 -0
  66. data/ext/libsass/src/extender.hpp +399 -0
  67. data/ext/libsass/src/extension.cpp +43 -0
  68. data/ext/libsass/src/extension.hpp +89 -0
  69. data/ext/libsass/src/file.cpp +134 -88
  70. data/ext/libsass/src/file.hpp +28 -37
  71. data/ext/libsass/src/fn_colors.cpp +596 -0
  72. data/ext/libsass/src/fn_colors.hpp +85 -0
  73. data/ext/libsass/src/fn_lists.cpp +285 -0
  74. data/ext/libsass/src/fn_lists.hpp +34 -0
  75. data/ext/libsass/src/fn_maps.cpp +94 -0
  76. data/ext/libsass/src/fn_maps.hpp +30 -0
  77. data/ext/libsass/src/fn_miscs.cpp +244 -0
  78. data/ext/libsass/src/fn_miscs.hpp +40 -0
  79. data/ext/libsass/src/fn_numbers.cpp +227 -0
  80. data/ext/libsass/src/fn_numbers.hpp +45 -0
  81. data/ext/libsass/src/fn_selectors.cpp +205 -0
  82. data/ext/libsass/src/fn_selectors.hpp +35 -0
  83. data/ext/libsass/src/fn_strings.cpp +268 -0
  84. data/ext/libsass/src/fn_strings.hpp +34 -0
  85. data/ext/libsass/src/fn_utils.cpp +158 -0
  86. data/ext/libsass/src/fn_utils.hpp +62 -0
  87. data/ext/libsass/src/inspect.cpp +253 -266
  88. data/ext/libsass/src/inspect.hpp +72 -74
  89. data/ext/libsass/src/json.cpp +2 -2
  90. data/ext/libsass/src/lexer.cpp +25 -84
  91. data/ext/libsass/src/lexer.hpp +5 -16
  92. data/ext/libsass/src/listize.cpp +27 -43
  93. data/ext/libsass/src/listize.hpp +14 -11
  94. data/ext/libsass/src/mapping.hpp +1 -0
  95. data/ext/libsass/src/memory.hpp +12 -0
  96. data/ext/libsass/src/memory/allocator.cpp +48 -0
  97. data/ext/libsass/src/memory/allocator.hpp +138 -0
  98. data/ext/libsass/src/memory/config.hpp +20 -0
  99. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  100. data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
  101. data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
  102. data/ext/libsass/src/operation.hpp +193 -143
  103. data/ext/libsass/src/operators.cpp +56 -29
  104. data/ext/libsass/src/operators.hpp +11 -11
  105. data/ext/libsass/src/ordered_map.hpp +112 -0
  106. data/ext/libsass/src/output.cpp +59 -75
  107. data/ext/libsass/src/output.hpp +15 -22
  108. data/ext/libsass/src/parser.cpp +662 -818
  109. data/ext/libsass/src/parser.hpp +96 -100
  110. data/ext/libsass/src/parser_selectors.cpp +189 -0
  111. data/ext/libsass/src/permutate.hpp +164 -0
  112. data/ext/libsass/src/plugins.cpp +12 -8
  113. data/ext/libsass/src/plugins.hpp +8 -8
  114. data/ext/libsass/src/position.cpp +10 -26
  115. data/ext/libsass/src/position.hpp +44 -21
  116. data/ext/libsass/src/prelexer.cpp +14 -8
  117. data/ext/libsass/src/prelexer.hpp +9 -9
  118. data/ext/libsass/src/remove_placeholders.cpp +59 -57
  119. data/ext/libsass/src/remove_placeholders.hpp +20 -18
  120. data/ext/libsass/src/sass.cpp +25 -18
  121. data/ext/libsass/src/sass.hpp +22 -14
  122. data/ext/libsass/src/sass2scss.cpp +49 -18
  123. data/ext/libsass/src/sass_context.cpp +104 -132
  124. data/ext/libsass/src/sass_context.hpp +2 -2
  125. data/ext/libsass/src/sass_functions.cpp +7 -4
  126. data/ext/libsass/src/sass_functions.hpp +1 -1
  127. data/ext/libsass/src/sass_values.cpp +26 -21
  128. data/ext/libsass/src/settings.hpp +19 -0
  129. data/ext/libsass/src/source.cpp +69 -0
  130. data/ext/libsass/src/source.hpp +95 -0
  131. data/ext/libsass/src/source_data.hpp +32 -0
  132. data/ext/libsass/src/source_map.cpp +27 -20
  133. data/ext/libsass/src/source_map.hpp +14 -11
  134. data/ext/libsass/src/stylesheet.cpp +22 -0
  135. data/ext/libsass/src/stylesheet.hpp +57 -0
  136. data/ext/libsass/src/to_value.cpp +24 -22
  137. data/ext/libsass/src/to_value.hpp +18 -22
  138. data/ext/libsass/src/units.cpp +28 -22
  139. data/ext/libsass/src/units.hpp +9 -8
  140. data/ext/libsass/src/utf8/checked.h +12 -10
  141. data/ext/libsass/src/utf8/core.h +3 -0
  142. data/ext/libsass/src/utf8_string.cpp +12 -10
  143. data/ext/libsass/src/utf8_string.hpp +7 -6
  144. data/ext/libsass/src/util.cpp +97 -107
  145. data/ext/libsass/src/util.hpp +74 -30
  146. data/ext/libsass/src/util_string.cpp +125 -0
  147. data/ext/libsass/src/util_string.hpp +73 -0
  148. data/ext/libsass/src/values.cpp +33 -24
  149. data/ext/libsass/src/values.hpp +2 -2
  150. data/lib/sassc.rb +24 -0
  151. data/lib/sassc/engine.rb +7 -5
  152. data/lib/sassc/functions_handler.rb +11 -13
  153. data/lib/sassc/native.rb +10 -9
  154. data/lib/sassc/native/native_functions_api.rb +0 -5
  155. data/lib/sassc/script.rb +4 -6
  156. data/lib/sassc/version.rb +1 -1
  157. data/sassc.gemspec +32 -12
  158. data/test/engine_test.rb +32 -2
  159. data/test/functions_test.rb +38 -1
  160. data/test/native_test.rb +4 -4
  161. metadata +95 -109
  162. data/ext/Rakefile +0 -3
  163. data/ext/libsass/.editorconfig +0 -15
  164. data/ext/libsass/.gitattributes +0 -2
  165. data/ext/libsass/.github/CONTRIBUTING.md +0 -65
  166. data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
  167. data/ext/libsass/.gitignore +0 -85
  168. data/ext/libsass/.travis.yml +0 -64
  169. data/ext/libsass/COPYING +0 -25
  170. data/ext/libsass/GNUmakefile.am +0 -88
  171. data/ext/libsass/INSTALL +0 -1
  172. data/ext/libsass/LICENSE +0 -25
  173. data/ext/libsass/Makefile +0 -351
  174. data/ext/libsass/Makefile.conf +0 -55
  175. data/ext/libsass/Readme.md +0 -104
  176. data/ext/libsass/SECURITY.md +0 -10
  177. data/ext/libsass/appveyor.yml +0 -91
  178. data/ext/libsass/configure.ac +0 -138
  179. data/ext/libsass/contrib/libsass.spec +0 -66
  180. data/ext/libsass/docs/README.md +0 -20
  181. data/ext/libsass/docs/api-context-example.md +0 -45
  182. data/ext/libsass/docs/api-context-internal.md +0 -163
  183. data/ext/libsass/docs/api-context.md +0 -295
  184. data/ext/libsass/docs/api-doc.md +0 -215
  185. data/ext/libsass/docs/api-function-example.md +0 -67
  186. data/ext/libsass/docs/api-function-internal.md +0 -8
  187. data/ext/libsass/docs/api-function.md +0 -74
  188. data/ext/libsass/docs/api-importer-example.md +0 -112
  189. data/ext/libsass/docs/api-importer-internal.md +0 -20
  190. data/ext/libsass/docs/api-importer.md +0 -86
  191. data/ext/libsass/docs/api-value-example.md +0 -55
  192. data/ext/libsass/docs/api-value-internal.md +0 -76
  193. data/ext/libsass/docs/api-value.md +0 -154
  194. data/ext/libsass/docs/build-on-darwin.md +0 -27
  195. data/ext/libsass/docs/build-on-gentoo.md +0 -55
  196. data/ext/libsass/docs/build-on-windows.md +0 -139
  197. data/ext/libsass/docs/build-shared-library.md +0 -35
  198. data/ext/libsass/docs/build-with-autotools.md +0 -78
  199. data/ext/libsass/docs/build-with-makefiles.md +0 -68
  200. data/ext/libsass/docs/build-with-mingw.md +0 -107
  201. data/ext/libsass/docs/build-with-visual-studio.md +0 -90
  202. data/ext/libsass/docs/build.md +0 -97
  203. data/ext/libsass/docs/compatibility-plan.md +0 -48
  204. data/ext/libsass/docs/contributing.md +0 -17
  205. data/ext/libsass/docs/custom-functions-internal.md +0 -122
  206. data/ext/libsass/docs/dev-ast-memory.md +0 -223
  207. data/ext/libsass/docs/implementations.md +0 -56
  208. data/ext/libsass/docs/plugins.md +0 -47
  209. data/ext/libsass/docs/setup-environment.md +0 -68
  210. data/ext/libsass/docs/source-map-internals.md +0 -51
  211. data/ext/libsass/docs/trace.md +0 -26
  212. data/ext/libsass/docs/triage.md +0 -17
  213. data/ext/libsass/docs/unicode.md +0 -39
  214. data/ext/libsass/extconf.rb +0 -6
  215. data/ext/libsass/include/sass/version.h.in +0 -12
  216. data/ext/libsass/m4/.gitkeep +0 -0
  217. data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +0 -167
  218. data/ext/libsass/res/resource.rc +0 -35
  219. data/ext/libsass/script/bootstrap +0 -13
  220. data/ext/libsass/script/branding +0 -10
  221. data/ext/libsass/script/ci-build-libsass +0 -134
  222. data/ext/libsass/script/ci-build-plugin +0 -62
  223. data/ext/libsass/script/ci-install-compiler +0 -6
  224. data/ext/libsass/script/ci-install-deps +0 -20
  225. data/ext/libsass/script/ci-report-coverage +0 -42
  226. data/ext/libsass/script/spec +0 -5
  227. data/ext/libsass/script/tap-driver +0 -652
  228. data/ext/libsass/script/tap-runner +0 -1
  229. data/ext/libsass/script/test-leaks.pl +0 -103
  230. data/ext/libsass/src/GNUmakefile.am +0 -54
  231. data/ext/libsass/src/extend.cpp +0 -2130
  232. data/ext/libsass/src/extend.hpp +0 -86
  233. data/ext/libsass/src/functions.cpp +0 -2234
  234. data/ext/libsass/src/functions.hpp +0 -198
  235. data/ext/libsass/src/memory/SharedPtr.cpp +0 -114
  236. data/ext/libsass/src/memory/SharedPtr.hpp +0 -206
  237. data/ext/libsass/src/node.cpp +0 -319
  238. data/ext/libsass/src/node.hpp +0 -118
  239. data/ext/libsass/src/paths.hpp +0 -71
  240. data/ext/libsass/src/sass_util.cpp +0 -149
  241. data/ext/libsass/src/sass_util.hpp +0 -256
  242. data/ext/libsass/src/subset_map.cpp +0 -55
  243. data/ext/libsass/src/subset_map.hpp +0 -76
  244. data/ext/libsass/src/support/libsass.pc.in +0 -11
  245. data/ext/libsass/src/to_c.hpp +0 -39
  246. data/ext/libsass/test/test_node.cpp +0 -94
  247. data/ext/libsass/test/test_paths.cpp +0 -28
  248. data/ext/libsass/test/test_selector_difference.cpp +0 -25
  249. data/ext/libsass/test/test_specificity.cpp +0 -25
  250. data/ext/libsass/test/test_subset_map.cpp +0 -472
  251. data/ext/libsass/test/test_superselector.cpp +0 -69
  252. data/ext/libsass/test/test_unification.cpp +0 -31
  253. data/ext/libsass/version.sh +0 -10
  254. data/ext/libsass/win/libsass.sln +0 -39
  255. data/ext/libsass/win/libsass.sln.DotSettings +0 -9
  256. data/ext/libsass/win/libsass.targets +0 -118
  257. data/ext/libsass/win/libsass.vcxproj +0 -188
  258. data/ext/libsass/win/libsass.vcxproj.filters +0 -357
  259. data/lib/sassc/native/lib_c.rb +0 -21
  260. data/lib/tasks/libsass.rb +0 -33
@@ -1,32 +1,35 @@
1
1
  #ifndef SASS_LISTIZE_H
2
2
  #define SASS_LISTIZE_H
3
3
 
4
- #include <vector>
5
- #include <iostream>
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 "ast.hpp"
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<Expression_Ptr, Listize> {
15
+ class Listize : public Operation_CRTP<Expression*, Listize> {
17
16
 
18
- Expression_Ptr fallback_impl(AST_Node_Ptr n);
17
+ public:
18
+
19
+ static Expression* perform(AST_Node* node);
19
20
 
20
21
  public:
21
22
  Listize();
22
23
  ~Listize() { }
23
24
 
24
- Expression_Ptr operator()(Selector_List_Ptr);
25
- Expression_Ptr operator()(Complex_Selector_Ptr);
26
- Expression_Ptr operator()(Compound_Selector_Ptr);
25
+ Expression* operator()(SelectorList*);
26
+ Expression* operator()(ComplexSelector*);
27
+ Expression* operator()(CompoundSelector*);
27
28
 
29
+ // generic fallback
28
30
  template <typename U>
29
- Expression_Ptr fallback(U x) { return fallback_impl(x); }
31
+ Expression* fallback(U x)
32
+ { return Cast<Expression>(x); }
30
33
  };
31
34
 
32
35
  }
@@ -2,6 +2,7 @@
2
2
  #define SASS_MAPPING_H
3
3
 
4
4
  #include "position.hpp"
5
+ #include "backtrace.hpp"
5
6
 
6
7
  namespace Sass {
7
8
 
@@ -0,0 +1,12 @@
1
+ #ifndef SASS_MEMORY_H
2
+ #define SASS_MEMORY_H
3
+
4
+ #include "settings.hpp"
5
+
6
+ // Include memory headers
7
+ #include "memory/config.hpp"
8
+ #include "memory/allocator.hpp"
9
+ #include "memory/shared_ptr.hpp"
10
+ #include "memory/memory_pool.hpp"
11
+
12
+ #endif
@@ -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