sassc 2.2.1 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/CHANGELOG.md +18 -0
  4. data/Rakefile +1 -3
  5. data/ext/extconf.rb +13 -5
  6. data/ext/libsass/VERSION +1 -1
  7. data/ext/libsass/include/sass/base.h +2 -1
  8. data/ext/libsass/include/sass/context.h +4 -0
  9. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  10. data/ext/libsass/src/ast.cpp +158 -168
  11. data/ext/libsass/src/ast.hpp +389 -230
  12. data/ext/libsass/src/ast_def_macros.hpp +18 -10
  13. data/ext/libsass/src/ast_fwd_decl.cpp +4 -3
  14. data/ext/libsass/src/ast_fwd_decl.hpp +98 -165
  15. data/ext/libsass/src/ast_helpers.hpp +292 -0
  16. data/ext/libsass/src/ast_sel_cmp.cpp +219 -732
  17. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  18. data/ext/libsass/src/ast_sel_unify.cpp +207 -212
  19. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  20. data/ext/libsass/src/ast_selectors.cpp +594 -1026
  21. data/ext/libsass/src/ast_selectors.hpp +339 -385
  22. data/ext/libsass/src/ast_supports.cpp +36 -52
  23. data/ext/libsass/src/ast_supports.hpp +29 -29
  24. data/ext/libsass/src/ast_values.cpp +271 -84
  25. data/ext/libsass/src/ast_values.hpp +116 -107
  26. data/ext/libsass/src/backtrace.cpp +9 -9
  27. data/ext/libsass/src/backtrace.hpp +5 -5
  28. data/ext/libsass/src/base64vlq.cpp +2 -2
  29. data/ext/libsass/src/base64vlq.hpp +1 -1
  30. data/ext/libsass/src/bind.cpp +18 -18
  31. data/ext/libsass/src/bind.hpp +1 -1
  32. data/ext/libsass/src/c2ast.cpp +3 -3
  33. data/ext/libsass/src/c2ast.hpp +1 -1
  34. data/ext/libsass/src/cencode.c +4 -6
  35. data/ext/libsass/src/check_nesting.cpp +40 -41
  36. data/ext/libsass/src/check_nesting.hpp +6 -2
  37. data/ext/libsass/src/color_maps.cpp +14 -13
  38. data/ext/libsass/src/color_maps.hpp +1 -9
  39. data/ext/libsass/src/constants.cpp +5 -0
  40. data/ext/libsass/src/constants.hpp +6 -0
  41. data/ext/libsass/src/context.cpp +92 -119
  42. data/ext/libsass/src/context.hpp +41 -53
  43. data/ext/libsass/src/cssize.cpp +66 -149
  44. data/ext/libsass/src/cssize.hpp +17 -23
  45. data/ext/libsass/src/dart_helpers.hpp +199 -0
  46. data/ext/libsass/src/debugger.hpp +451 -295
  47. data/ext/libsass/src/emitter.cpp +15 -16
  48. data/ext/libsass/src/emitter.hpp +10 -12
  49. data/ext/libsass/src/environment.cpp +27 -27
  50. data/ext/libsass/src/environment.hpp +29 -24
  51. data/ext/libsass/src/error_handling.cpp +62 -41
  52. data/ext/libsass/src/error_handling.hpp +61 -51
  53. data/ext/libsass/src/eval.cpp +167 -281
  54. data/ext/libsass/src/eval.hpp +27 -29
  55. data/ext/libsass/src/eval_selectors.cpp +75 -0
  56. data/ext/libsass/src/expand.cpp +275 -222
  57. data/ext/libsass/src/expand.hpp +36 -16
  58. data/ext/libsass/src/extender.cpp +1188 -0
  59. data/ext/libsass/src/extender.hpp +399 -0
  60. data/ext/libsass/src/extension.cpp +43 -0
  61. data/ext/libsass/src/extension.hpp +89 -0
  62. data/ext/libsass/src/file.cpp +81 -72
  63. data/ext/libsass/src/file.hpp +28 -37
  64. data/ext/libsass/src/fn_colors.cpp +20 -18
  65. data/ext/libsass/src/fn_lists.cpp +30 -29
  66. data/ext/libsass/src/fn_maps.cpp +3 -3
  67. data/ext/libsass/src/fn_miscs.cpp +34 -46
  68. data/ext/libsass/src/fn_numbers.cpp +20 -13
  69. data/ext/libsass/src/fn_selectors.cpp +98 -128
  70. data/ext/libsass/src/fn_strings.cpp +47 -33
  71. data/ext/libsass/src/fn_utils.cpp +31 -29
  72. data/ext/libsass/src/fn_utils.hpp +17 -11
  73. data/ext/libsass/src/inspect.cpp +186 -148
  74. data/ext/libsass/src/inspect.hpp +31 -29
  75. data/ext/libsass/src/lexer.cpp +20 -82
  76. data/ext/libsass/src/lexer.hpp +5 -16
  77. data/ext/libsass/src/listize.cpp +23 -37
  78. data/ext/libsass/src/listize.hpp +8 -9
  79. data/ext/libsass/src/mapping.hpp +1 -0
  80. data/ext/libsass/src/memory/allocator.cpp +48 -0
  81. data/ext/libsass/src/memory/allocator.hpp +138 -0
  82. data/ext/libsass/src/memory/config.hpp +20 -0
  83. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  84. data/ext/libsass/src/memory/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
  85. data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
  86. data/ext/libsass/src/memory.hpp +12 -0
  87. data/ext/libsass/src/operation.hpp +71 -61
  88. data/ext/libsass/src/operators.cpp +19 -18
  89. data/ext/libsass/src/operators.hpp +11 -11
  90. data/ext/libsass/src/ordered_map.hpp +112 -0
  91. data/ext/libsass/src/output.cpp +45 -64
  92. data/ext/libsass/src/output.hpp +6 -6
  93. data/ext/libsass/src/parser.cpp +512 -700
  94. data/ext/libsass/src/parser.hpp +89 -97
  95. data/ext/libsass/src/parser_selectors.cpp +189 -0
  96. data/ext/libsass/src/permutate.hpp +164 -0
  97. data/ext/libsass/src/plugins.cpp +7 -7
  98. data/ext/libsass/src/plugins.hpp +8 -8
  99. data/ext/libsass/src/position.cpp +7 -26
  100. data/ext/libsass/src/position.hpp +44 -21
  101. data/ext/libsass/src/prelexer.cpp +6 -6
  102. data/ext/libsass/src/remove_placeholders.cpp +55 -56
  103. data/ext/libsass/src/remove_placeholders.hpp +21 -18
  104. data/ext/libsass/src/sass.cpp +16 -15
  105. data/ext/libsass/src/sass.hpp +10 -5
  106. data/ext/libsass/src/sass2scss.cpp +4 -4
  107. data/ext/libsass/src/sass_context.cpp +91 -122
  108. data/ext/libsass/src/sass_context.hpp +2 -2
  109. data/ext/libsass/src/sass_functions.cpp +1 -1
  110. data/ext/libsass/src/sass_values.cpp +8 -11
  111. data/ext/libsass/src/settings.hpp +19 -0
  112. data/ext/libsass/src/source.cpp +69 -0
  113. data/ext/libsass/src/source.hpp +95 -0
  114. data/ext/libsass/src/source_data.hpp +32 -0
  115. data/ext/libsass/src/source_map.cpp +22 -18
  116. data/ext/libsass/src/source_map.hpp +12 -9
  117. data/ext/libsass/src/stylesheet.cpp +22 -0
  118. data/ext/libsass/src/stylesheet.hpp +57 -0
  119. data/ext/libsass/src/to_value.cpp +2 -2
  120. data/ext/libsass/src/to_value.hpp +1 -1
  121. data/ext/libsass/src/units.cpp +24 -22
  122. data/ext/libsass/src/units.hpp +8 -8
  123. data/ext/libsass/src/utf8_string.cpp +9 -10
  124. data/ext/libsass/src/utf8_string.hpp +7 -6
  125. data/ext/libsass/src/util.cpp +48 -50
  126. data/ext/libsass/src/util.hpp +20 -21
  127. data/ext/libsass/src/util_string.cpp +111 -61
  128. data/ext/libsass/src/util_string.hpp +62 -8
  129. data/ext/libsass/src/values.cpp +12 -12
  130. data/lib/sassc/engine.rb +5 -3
  131. data/lib/sassc/functions_handler.rb +8 -8
  132. data/lib/sassc/native.rb +4 -6
  133. data/lib/sassc/script.rb +4 -4
  134. data/lib/sassc/version.rb +1 -1
  135. data/test/functions_test.rb +18 -1
  136. data/test/native_test.rb +4 -4
  137. metadata +29 -15
  138. data/ext/libsass/src/extend.cpp +0 -2132
  139. data/ext/libsass/src/extend.hpp +0 -86
  140. data/ext/libsass/src/node.cpp +0 -322
  141. data/ext/libsass/src/node.hpp +0 -118
  142. data/ext/libsass/src/paths.hpp +0 -71
  143. data/ext/libsass/src/sass_util.cpp +0 -152
  144. data/ext/libsass/src/sass_util.hpp +0 -256
  145. data/ext/libsass/src/subset_map.cpp +0 -58
  146. data/ext/libsass/src/subset_map.hpp +0 -76
  147. data/lib/sassc/native/lib_c.rb +0 -21
@@ -2,11 +2,11 @@
2
2
  // __EXTENSIONS__ fix on Solaris.
3
3
  #include "sass.hpp"
4
4
 
5
- #include <cctype>
6
5
  #include <iostream>
7
6
  #include <iomanip>
8
7
  #include "lexer.hpp"
9
8
  #include "constants.hpp"
9
+ #include "util_string.hpp"
10
10
 
11
11
 
12
12
  namespace Sass {
@@ -28,77 +28,14 @@ namespace Sass {
28
28
  const char* kwd_minus(const char* src) { return exactly<'-'>(src); };
29
29
  const char* kwd_slash(const char* src) { return exactly<'/'>(src); };
30
30
 
31
- //####################################
32
- // implement some function that do exist in the standard
33
- // but those are locale aware which brought some trouble
34
- // this even seems to improve performance by quite a bit
35
- //####################################
36
-
37
- bool is_alpha(const char& chr)
38
- {
39
- return unsigned(chr - 'A') <= 'Z' - 'A' ||
40
- unsigned(chr - 'a') <= 'z' - 'a';
41
- }
42
-
43
- bool is_space(const char& chr)
44
- {
45
- // adapted the technique from is_alpha
46
- return chr == ' ' || unsigned(chr - '\t') <= '\r' - '\t';
47
- }
48
-
49
- bool is_digit(const char& chr)
50
- {
51
- // adapted the technique from is_alpha
52
- return unsigned(chr - '0') <= '9' - '0';
53
- }
54
-
55
- bool is_number(const char& chr)
56
- {
57
- // adapted the technique from is_alpha
58
- return is_digit(chr) || chr == '-' || chr == '+';
59
- }
60
-
61
- bool is_xdigit(const char& chr)
62
- {
63
- // adapted the technique from is_alpha
64
- return unsigned(chr - '0') <= '9' - '0' ||
65
- unsigned(chr - 'a') <= 'f' - 'a' ||
66
- unsigned(chr - 'A') <= 'F' - 'A';
67
- }
68
-
69
- bool is_punct(const char& chr)
70
- {
71
- // locale independent
72
- return chr == '.';
73
- }
74
-
75
- bool is_alnum(const char& chr)
76
- {
77
- return is_alpha(chr) || is_digit(chr);
78
- }
79
-
80
- // check if char is outside ascii range
81
- bool is_unicode(const char& chr)
82
- {
83
- // check for unicode range
84
- return unsigned(chr) > 127;
85
- }
86
-
87
- // check if char is outside ascii range
88
- // but with specific ranges (copied from Ruby Sass)
89
- bool is_nonascii(const char& chr)
90
- {
91
- unsigned int cmp = unsigned(chr);
92
- return (
93
- (cmp >= 128 && cmp <= 15572911) ||
94
- (cmp >= 15630464 && cmp <= 15712189) ||
95
- (cmp >= 4036001920)
96
- );
31
+ bool is_number(char chr) {
32
+ return Util::ascii_isdigit(static_cast<unsigned char>(chr)) ||
33
+ chr == '-' || chr == '+';
97
34
  }
98
35
 
99
36
  // check if char is within a reduced ascii range
100
37
  // valid in a uri (copied from Ruby Sass)
101
- bool is_uri_character(const char& chr)
38
+ bool is_uri_character(char chr)
102
39
  {
103
40
  unsigned int cmp = unsigned(chr);
104
41
  return (cmp > 41 && cmp < 127) ||
@@ -107,17 +44,19 @@ namespace Sass {
107
44
 
108
45
  // check if char is within a reduced ascii range
109
46
  // valid for escaping (copied from Ruby Sass)
110
- bool is_escapable_character(const char& chr)
47
+ bool is_escapable_character(char chr)
111
48
  {
112
49
  unsigned int cmp = unsigned(chr);
113
50
  return cmp > 31 && cmp < 127;
114
51
  }
115
52
 
116
53
  // Match word character (look ahead)
117
- bool is_character(const char& chr)
54
+ bool is_character(char chr)
118
55
  {
119
56
  // valid alpha, numeric or unicode char (plus hyphen)
120
- return is_alnum(chr) || is_unicode(chr) || chr == '-';
57
+ return Util::ascii_isalnum(static_cast<unsigned char>(chr)) ||
58
+ !Util::ascii_isascii(static_cast<unsigned char>(chr)) ||
59
+ chr == '-';
121
60
  }
122
61
 
123
62
  //####################################
@@ -125,16 +64,13 @@ namespace Sass {
125
64
  //####################################
126
65
 
127
66
  // create matchers that advance the position
128
- const char* space(const char* src) { return is_space(*src) ? src + 1 : 0; }
129
- const char* alpha(const char* src) { return is_alpha(*src) ? src + 1 : 0; }
130
- const char* unicode(const char* src) { return is_unicode(*src) ? src + 1 : 0; }
131
- const char* nonascii(const char* src) { return is_nonascii(*src) ? src + 1 : 0; }
132
- const char* digit(const char* src) { return is_digit(*src) ? src + 1 : 0; }
133
- const char* xdigit(const char* src) { return is_xdigit(*src) ? src + 1 : 0; }
134
- const char* alnum(const char* src) { return is_alnum(*src) ? src + 1 : 0; }
135
- const char* punct(const char* src) { return is_punct(*src) ? src + 1 : 0; }
136
- const char* hyphen(const char* src) { return *src && *src == '-' ? src + 1 : 0; }
137
- const char* character(const char* src) { return is_character(*src) ? src + 1 : 0; }
67
+ const char* space(const char* src) { return Util::ascii_isspace(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }
68
+ const char* alpha(const char* src) { return Util::ascii_isalpha(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }
69
+ const char* nonascii(const char* src) { return Util::ascii_isascii(static_cast<unsigned char>(*src)) ? nullptr : src + 1; }
70
+ const char* digit(const char* src) { return Util::ascii_isdigit(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }
71
+ const char* xdigit(const char* src) { return Util::ascii_isxdigit(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }
72
+ const char* alnum(const char* src) { return Util::ascii_isalnum(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }
73
+ const char* hyphen(const char* src) { return *src == '-' ? src + 1 : 0; }
138
74
  const char* uri_character(const char* src) { return is_uri_character(*src) ? src + 1 : 0; }
139
75
  const char* escapable_character(const char* src) { return is_escapable_character(*src) ? src + 1 : 0; }
140
76
 
@@ -157,7 +93,9 @@ namespace Sass {
157
93
  const char* re_linebreak(const char* src)
158
94
  {
159
95
  // end of file or unix linefeed return here
160
- if (*src == 0 || *src == '\n' || *src == '\f') return src + 1;
96
+ if (*src == 0) return src;
97
+ // end of file or unix linefeed return here
98
+ if (*src == '\n' || *src == '\f') return src + 1;
161
99
  // a carriage return may optionally be followed by a linefeed
162
100
  if (*src == '\r') return *(src + 1) == '\n' ? src + 2 : src + 1;
163
101
  // no linefeed
@@ -24,19 +24,11 @@ namespace Sass {
24
24
  // BASIC CLASS MATCHERS
25
25
  //####################################
26
26
 
27
- // These are locale independant
28
- bool is_space(const char& src);
29
- bool is_alpha(const char& src);
30
- bool is_punct(const char& src);
31
- bool is_digit(const char& src);
32
- bool is_number(const char& src);
33
- bool is_alnum(const char& src);
34
- bool is_xdigit(const char& src);
35
- bool is_unicode(const char& src);
36
- bool is_nonascii(const char& src);
37
- bool is_character(const char& src);
38
- bool is_uri_character(const char& src);
39
- bool escapable_character(const char& src);
27
+ // Matches ASCII digits, +, and -.
28
+ bool is_number(char src);
29
+
30
+ bool is_uri_character(char src);
31
+ bool escapable_character(char src);
40
32
 
41
33
  // Match a single ctype predicate.
42
34
  const char* space(const char* src);
@@ -44,11 +36,8 @@ namespace Sass {
44
36
  const char* digit(const char* src);
45
37
  const char* xdigit(const char* src);
46
38
  const char* alnum(const char* src);
47
- const char* punct(const char* src);
48
39
  const char* hyphen(const char* src);
49
- const char* unicode(const char* src);
50
40
  const char* nonascii(const char* src);
51
- const char* character(const char* src);
52
41
  const char* uri_character(const char* src);
53
42
  const char* escapable_character(const char* src);
54
43
 
@@ -16,7 +16,13 @@ namespace Sass {
16
16
  Listize::Listize()
17
17
  { }
18
18
 
19
- Expression* Listize::operator()(Selector_List* sel)
19
+ Expression* Listize::perform(AST_Node* node)
20
+ {
21
+ Listize listize;
22
+ return node->perform(&listize);
23
+ }
24
+
25
+ Expression* Listize::operator()(SelectorList* sel)
20
26
  {
21
27
  List_Obj l = SASS_MEMORY_NEW(List, sel->pstate(), sel->length(), SASS_COMMA);
22
28
  l->from_selector(true);
@@ -28,9 +34,9 @@ namespace Sass {
28
34
  return SASS_MEMORY_NEW(Null, l->pstate());
29
35
  }
30
36
 
31
- Expression* Listize::operator()(Compound_Selector* sel)
37
+ Expression* Listize::operator()(CompoundSelector* sel)
32
38
  {
33
- std::string str;
39
+ sass::string str;
34
40
  for (size_t i = 0, L = sel->length(); i < L; ++i) {
35
41
  Expression* e = (*sel)[i]->perform(this);
36
42
  if (e) str += e->to_string();
@@ -38,45 +44,25 @@ namespace Sass {
38
44
  return SASS_MEMORY_NEW(String_Quoted, sel->pstate(), str);
39
45
  }
40
46
 
41
- Expression* Listize::operator()(Complex_Selector* sel)
47
+ Expression* Listize::operator()(ComplexSelector* sel)
42
48
  {
43
- List_Obj l = SASS_MEMORY_NEW(List, sel->pstate(), 2);
49
+ List_Obj l = SASS_MEMORY_NEW(List, sel->pstate());
50
+ // ToDo: investigate what this does
51
+ // Note: seems reated to parent ref
44
52
  l->from_selector(true);
45
- Compound_Selector_Obj head = sel->head();
46
- if (head && !head->is_empty_reference())
47
- {
48
- Expression* hh = head->perform(this);
49
- if (hh) l->append(hh);
50
- }
51
53
 
52
- std::string reference = ! sel->reference() ? ""
53
- : sel->reference()->to_string();
54
- switch(sel->combinator())
55
- {
56
- case Complex_Selector::PARENT_OF:
57
- l->append(SASS_MEMORY_NEW(String_Quoted, sel->pstate(), ">"));
58
- break;
59
- case Complex_Selector::ADJACENT_TO:
60
- l->append(SASS_MEMORY_NEW(String_Quoted, sel->pstate(), "+"));
61
- break;
62
- case Complex_Selector::REFERENCE:
63
- l->append(SASS_MEMORY_NEW(String_Quoted, sel->pstate(), "/" + reference + "/"));
64
- break;
65
- case Complex_Selector::PRECEDES:
66
- l->append(SASS_MEMORY_NEW(String_Quoted, sel->pstate(), "~"));
67
- break;
68
- case Complex_Selector::ANCESTOR_OF:
69
- break;
70
- default: break;
54
+ for (auto component : sel->elements()) {
55
+ if (CompoundSelectorObj compound = Cast<CompoundSelector>(component)) {
56
+ if (!compound->empty()) {
57
+ ExpressionObj hh = compound->perform(this);
58
+ if (hh) l->append(hh);
59
+ }
60
+ }
61
+ else if (component) {
62
+ l->append(SASS_MEMORY_NEW(String_Quoted, component->pstate(), component->to_string()));
63
+ }
71
64
  }
72
65
 
73
- Complex_Selector_Obj tail = sel->tail();
74
- if (tail)
75
- {
76
- Expression_Obj tt = tail->perform(this);
77
- if (List* ls = Cast<List>(tt))
78
- { l->concat(ls); }
79
- }
80
66
  if (l->length() == 0) return 0;
81
67
  return l.detach();
82
68
  }
@@ -5,13 +5,8 @@
5
5
  // __EXTENSIONS__ fix on Solaris.
6
6
  #include "sass.hpp"
7
7
 
8
- #include <vector>
9
- #include <iostream>
10
-
11
- #include "ast.hpp"
12
- #include "context.hpp"
8
+ #include "ast_fwd_decl.hpp"
13
9
  #include "operation.hpp"
14
- #include "environment.hpp"
15
10
 
16
11
  namespace Sass {
17
12
 
@@ -19,13 +14,17 @@ namespace Sass {
19
14
 
20
15
  class Listize : public Operation_CRTP<Expression*, Listize> {
21
16
 
17
+ public:
18
+
19
+ static Expression* perform(AST_Node* node);
20
+
22
21
  public:
23
22
  Listize();
24
23
  ~Listize() { }
25
24
 
26
- Expression* operator()(Selector_List*);
27
- Expression* operator()(Complex_Selector*);
28
- Expression* operator()(Compound_Selector*);
25
+ Expression* operator()(SelectorList*);
26
+ Expression* operator()(ComplexSelector*);
27
+ Expression* operator()(CompoundSelector*);
29
28
 
30
29
  // generic fallback
31
30
  template <typename U>
@@ -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,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