sassc 2.2.1 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/CHANGELOG.md +18 -0
- data/Rakefile +1 -3
- data/ext/extconf.rb +13 -5
- data/ext/libsass/VERSION +1 -1
- data/ext/libsass/include/sass/base.h +2 -1
- data/ext/libsass/include/sass/context.h +4 -0
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +158 -168
- data/ext/libsass/src/ast.hpp +389 -230
- data/ext/libsass/src/ast_def_macros.hpp +18 -10
- data/ext/libsass/src/ast_fwd_decl.cpp +4 -3
- data/ext/libsass/src/ast_fwd_decl.hpp +98 -165
- data/ext/libsass/src/ast_helpers.hpp +292 -0
- data/ext/libsass/src/ast_sel_cmp.cpp +219 -732
- data/ext/libsass/src/ast_sel_super.cpp +539 -0
- data/ext/libsass/src/ast_sel_unify.cpp +207 -212
- data/ext/libsass/src/ast_sel_weave.cpp +616 -0
- data/ext/libsass/src/ast_selectors.cpp +594 -1026
- data/ext/libsass/src/ast_selectors.hpp +339 -385
- data/ext/libsass/src/ast_supports.cpp +36 -52
- data/ext/libsass/src/ast_supports.hpp +29 -29
- data/ext/libsass/src/ast_values.cpp +271 -84
- data/ext/libsass/src/ast_values.hpp +116 -107
- data/ext/libsass/src/backtrace.cpp +9 -9
- data/ext/libsass/src/backtrace.hpp +5 -5
- data/ext/libsass/src/base64vlq.cpp +2 -2
- data/ext/libsass/src/base64vlq.hpp +1 -1
- data/ext/libsass/src/bind.cpp +18 -18
- data/ext/libsass/src/bind.hpp +1 -1
- data/ext/libsass/src/c2ast.cpp +3 -3
- data/ext/libsass/src/c2ast.hpp +1 -1
- data/ext/libsass/src/cencode.c +4 -6
- data/ext/libsass/src/check_nesting.cpp +40 -41
- data/ext/libsass/src/check_nesting.hpp +6 -2
- data/ext/libsass/src/color_maps.cpp +14 -13
- data/ext/libsass/src/color_maps.hpp +1 -9
- data/ext/libsass/src/constants.cpp +5 -0
- data/ext/libsass/src/constants.hpp +6 -0
- data/ext/libsass/src/context.cpp +92 -119
- data/ext/libsass/src/context.hpp +41 -53
- data/ext/libsass/src/cssize.cpp +66 -149
- data/ext/libsass/src/cssize.hpp +17 -23
- data/ext/libsass/src/dart_helpers.hpp +199 -0
- data/ext/libsass/src/debugger.hpp +451 -295
- data/ext/libsass/src/emitter.cpp +15 -16
- data/ext/libsass/src/emitter.hpp +10 -12
- data/ext/libsass/src/environment.cpp +27 -27
- data/ext/libsass/src/environment.hpp +29 -24
- data/ext/libsass/src/error_handling.cpp +62 -41
- data/ext/libsass/src/error_handling.hpp +61 -51
- data/ext/libsass/src/eval.cpp +167 -281
- data/ext/libsass/src/eval.hpp +27 -29
- data/ext/libsass/src/eval_selectors.cpp +75 -0
- data/ext/libsass/src/expand.cpp +275 -222
- data/ext/libsass/src/expand.hpp +36 -16
- 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 +81 -72
- data/ext/libsass/src/file.hpp +28 -37
- data/ext/libsass/src/fn_colors.cpp +20 -18
- data/ext/libsass/src/fn_lists.cpp +30 -29
- data/ext/libsass/src/fn_maps.cpp +3 -3
- data/ext/libsass/src/fn_miscs.cpp +34 -46
- data/ext/libsass/src/fn_numbers.cpp +20 -13
- data/ext/libsass/src/fn_selectors.cpp +98 -128
- data/ext/libsass/src/fn_strings.cpp +47 -33
- data/ext/libsass/src/fn_utils.cpp +31 -29
- data/ext/libsass/src/fn_utils.hpp +17 -11
- data/ext/libsass/src/inspect.cpp +186 -148
- data/ext/libsass/src/inspect.hpp +31 -29
- data/ext/libsass/src/lexer.cpp +20 -82
- data/ext/libsass/src/lexer.hpp +5 -16
- data/ext/libsass/src/listize.cpp +23 -37
- data/ext/libsass/src/listize.hpp +8 -9
- data/ext/libsass/src/mapping.hpp +1 -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/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
- data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
- data/ext/libsass/src/memory.hpp +12 -0
- data/ext/libsass/src/operation.hpp +71 -61
- data/ext/libsass/src/operators.cpp +19 -18
- data/ext/libsass/src/operators.hpp +11 -11
- data/ext/libsass/src/ordered_map.hpp +112 -0
- data/ext/libsass/src/output.cpp +45 -64
- data/ext/libsass/src/output.hpp +6 -6
- data/ext/libsass/src/parser.cpp +512 -700
- data/ext/libsass/src/parser.hpp +89 -97
- data/ext/libsass/src/parser_selectors.cpp +189 -0
- data/ext/libsass/src/permutate.hpp +164 -0
- data/ext/libsass/src/plugins.cpp +7 -7
- data/ext/libsass/src/plugins.hpp +8 -8
- data/ext/libsass/src/position.cpp +7 -26
- data/ext/libsass/src/position.hpp +44 -21
- data/ext/libsass/src/prelexer.cpp +6 -6
- data/ext/libsass/src/remove_placeholders.cpp +55 -56
- data/ext/libsass/src/remove_placeholders.hpp +21 -18
- data/ext/libsass/src/sass.cpp +16 -15
- data/ext/libsass/src/sass.hpp +10 -5
- data/ext/libsass/src/sass2scss.cpp +4 -4
- data/ext/libsass/src/sass_context.cpp +91 -122
- data/ext/libsass/src/sass_context.hpp +2 -2
- data/ext/libsass/src/sass_functions.cpp +1 -1
- data/ext/libsass/src/sass_values.cpp +8 -11
- 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 +22 -18
- data/ext/libsass/src/source_map.hpp +12 -9
- data/ext/libsass/src/stylesheet.cpp +22 -0
- data/ext/libsass/src/stylesheet.hpp +57 -0
- data/ext/libsass/src/to_value.cpp +2 -2
- data/ext/libsass/src/to_value.hpp +1 -1
- data/ext/libsass/src/units.cpp +24 -22
- data/ext/libsass/src/units.hpp +8 -8
- data/ext/libsass/src/utf8_string.cpp +9 -10
- data/ext/libsass/src/utf8_string.hpp +7 -6
- data/ext/libsass/src/util.cpp +48 -50
- data/ext/libsass/src/util.hpp +20 -21
- data/ext/libsass/src/util_string.cpp +111 -61
- data/ext/libsass/src/util_string.hpp +62 -8
- data/ext/libsass/src/values.cpp +12 -12
- data/lib/sassc/engine.rb +5 -3
- data/lib/sassc/functions_handler.rb +8 -8
- data/lib/sassc/native.rb +4 -6
- data/lib/sassc/script.rb +4 -4
- data/lib/sassc/version.rb +1 -1
- data/test/functions_test.rb +18 -1
- data/test/native_test.rb +4 -4
- metadata +29 -15
- data/ext/libsass/src/extend.cpp +0 -2132
- data/ext/libsass/src/extend.hpp +0 -86
- data/ext/libsass/src/node.cpp +0 -322
- data/ext/libsass/src/node.hpp +0 -118
- data/ext/libsass/src/paths.hpp +0 -71
- data/ext/libsass/src/sass_util.cpp +0 -152
- data/ext/libsass/src/sass_util.hpp +0 -256
- data/ext/libsass/src/subset_map.cpp +0 -58
- data/ext/libsass/src/subset_map.hpp +0 -76
- data/lib/sassc/native/lib_c.rb +0 -21
data/ext/libsass/src/lexer.cpp
CHANGED
@@ -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
|
-
|
33
|
-
|
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(
|
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(
|
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(
|
54
|
+
bool is_character(char chr)
|
118
55
|
{
|
119
56
|
// valid alpha, numeric or unicode char (plus hyphen)
|
120
|
-
return
|
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
|
129
|
-
const char* alpha(const char* src) { return
|
130
|
-
const char*
|
131
|
-
const char*
|
132
|
-
const char*
|
133
|
-
const char*
|
134
|
-
const char*
|
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
|
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
|
data/ext/libsass/src/lexer.hpp
CHANGED
@@ -24,19 +24,11 @@ namespace Sass {
|
|
24
24
|
// BASIC CLASS MATCHERS
|
25
25
|
//####################################
|
26
26
|
|
27
|
-
//
|
28
|
-
bool
|
29
|
-
|
30
|
-
bool
|
31
|
-
bool
|
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
|
|
data/ext/libsass/src/listize.cpp
CHANGED
@@ -16,7 +16,13 @@ namespace Sass {
|
|
16
16
|
Listize::Listize()
|
17
17
|
{ }
|
18
18
|
|
19
|
-
Expression* Listize::
|
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()(
|
37
|
+
Expression* Listize::operator()(CompoundSelector* sel)
|
32
38
|
{
|
33
|
-
|
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()(
|
47
|
+
Expression* Listize::operator()(ComplexSelector* sel)
|
42
48
|
{
|
43
|
-
List_Obj l = SASS_MEMORY_NEW(List, sel->pstate()
|
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
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
l->append(SASS_MEMORY_NEW(String_Quoted,
|
61
|
-
|
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
|
}
|
data/ext/libsass/src/listize.hpp
CHANGED
@@ -5,13 +5,8 @@
|
|
5
5
|
// __EXTENSIONS__ fix on Solaris.
|
6
6
|
#include "sass.hpp"
|
7
7
|
|
8
|
-
#include
|
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()(
|
27
|
-
Expression* operator()(
|
28
|
-
Expression* operator()(
|
25
|
+
Expression* operator()(SelectorList*);
|
26
|
+
Expression* operator()(ComplexSelector*);
|
27
|
+
Expression* operator()(CompoundSelector*);
|
29
28
|
|
30
29
|
// generic fallback
|
31
30
|
template <typename U>
|
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
|