sassc 2.1.0.pre3 → 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 +24 -0
  4. data/Rakefile +2 -4
  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.hpp +12 -0
  81. data/ext/libsass/src/memory/allocator.cpp +48 -0
  82. data/ext/libsass/src/memory/allocator.hpp +138 -0
  83. data/ext/libsass/src/memory/config.hpp +20 -0
  84. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  85. data/ext/libsass/src/memory/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
  86. data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +55 -9
  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 +11 -13
  132. data/lib/sassc/native.rb +9 -7
  133. data/lib/sassc/script.rb +4 -6
  134. data/lib/sassc/version.rb +1 -1
  135. data/test/functions_test.rb +38 -1
  136. data/test/native_test.rb +4 -4
  137. metadata +31 -18
  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
@@ -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
@@ -2,7 +2,7 @@
2
2
  #include <iostream>
3
3
  #include <typeinfo>
4
4
 
5
- #include "SharedPtr.hpp"
5
+ #include "shared_ptr.hpp"
6
6
  #include "../ast_fwd_decl.hpp"
7
7
 
8
8
  #ifdef DEBUG_SHARED_PTR
@@ -26,7 +26,7 @@ namespace Sass {
26
26
  }
27
27
  }
28
28
  }
29
- std::vector<SharedObj*> SharedObj::all;
29
+ sass::vector<SharedObj*> SharedObj::all;
30
30
  #endif
31
31
 
32
32
  bool SharedObj::taint = false;
@@ -3,14 +3,21 @@
3
3
 
4
4
  #include "sass/base.h"
5
5
 
6
+ #include "../sass.hpp"
7
+ #include "allocator.hpp"
6
8
  #include <cstddef>
7
9
  #include <iostream>
8
10
  #include <string>
9
11
  #include <type_traits>
10
12
  #include <vector>
11
13
 
14
+ // https://lokiastari.com/blog/2014/12/30/c-plus-plus-by-example-smart-pointer/index.html
15
+ // https://lokiastari.com/blog/2015/01/15/c-plus-plus-by-example-smart-pointer-part-ii/index.html
16
+ // https://lokiastari.com/blog/2015/01/23/c-plus-plus-by-example-smart-pointer-part-iii/index.html
17
+
12
18
  namespace Sass {
13
19
 
20
+ // Forward declaration
14
21
  class SharedPtr;
15
22
 
16
23
  ///////////////////////////////////////////////////////////////////////////////
@@ -42,6 +49,16 @@ namespace Sass {
42
49
 
43
50
  #endif
44
51
 
52
+ // SharedObj is the base class for all objects that can be stored as a shared object
53
+ // It adds the reference counter and other values directly to the objects
54
+ // This gives a slight overhead when directly used as a stack object, but has some
55
+ // advantages for our code. It is safe to create two shared pointers from the same
56
+ // objects, as the "control block" is directly attached to it. This would lead
57
+ // to undefined behavior with std::shared_ptr. This also avoids the need to
58
+ // allocate additional control blocks and/or the need to dereference two
59
+ // pointers on each operation. This can be optimized in `std::shared_ptr`
60
+ // too by using `std::make_shared` (where the control block and the actual
61
+ // object are allocated in one continuous memory block via one single call).
45
62
  class SharedObj {
46
63
  public:
47
64
  SharedObj() : refcount(0), detached(false) {
@@ -51,18 +68,23 @@ namespace Sass {
51
68
  }
52
69
  virtual ~SharedObj() {
53
70
  #ifdef DEBUG_SHARED_PTR
54
- all.clear();
71
+ for (size_t i = 0; i < all.size(); i++) {
72
+ if (all[i] == this) {
73
+ all.erase(all.begin() + i);
74
+ break;
75
+ }
76
+ }
55
77
  #endif
56
78
  }
57
79
 
58
80
  #ifdef DEBUG_SHARED_PTR
59
81
  static void dumpMemLeaks();
60
- SharedObj* trace(std::string file, size_t line) {
82
+ SharedObj* trace(sass::string file, size_t line) {
61
83
  this->file = file;
62
84
  this->line = line;
63
85
  return this;
64
86
  }
65
- std::string getDbgFile() { return file; }
87
+ sass::string getDbgFile() { return file; }
66
88
  size_t getDbgLine() { return line; }
67
89
  void setDbg(bool dbg) { this->dbg = dbg; }
68
90
  size_t getRefCount() const { return refcount; }
@@ -70,7 +92,16 @@ namespace Sass {
70
92
 
71
93
  static void setTaint(bool val) { taint = val; }
72
94
 
73
- virtual const std::string to_string() const = 0;
95
+ #ifdef SASS_CUSTOM_ALLOCATOR
96
+ inline void* operator new(size_t nbytes) {
97
+ return allocateMem(nbytes);
98
+ }
99
+ inline void operator delete(void* ptr) {
100
+ return deallocateMem(ptr);
101
+ }
102
+ #endif
103
+
104
+ virtual sass::string to_string() const = 0;
74
105
  protected:
75
106
  friend class SharedPtr;
76
107
  friend class Memory_Manager;
@@ -78,13 +109,16 @@ namespace Sass {
78
109
  bool detached;
79
110
  static bool taint;
80
111
  #ifdef DEBUG_SHARED_PTR
81
- std::string file;
112
+ sass::string file;
82
113
  size_t line;
83
114
  bool dbg = false;
84
- static std::vector<SharedObj*> all;
115
+ static sass::vector<SharedObj*> all;
85
116
  #endif
86
117
  };
87
118
 
119
+ // SharedPtr is a intermediate (template-less) base class for SharedImpl.
120
+ // ToDo: there should be a way to include this in SharedImpl and to get
121
+ // ToDo: rid of all the static_cast that are now needed in SharedImpl.
88
122
  class SharedPtr {
89
123
  public:
90
124
  SharedPtr() : node(nullptr) {}
@@ -114,6 +148,11 @@ namespace Sass {
114
148
  // Prevents all SharedPtrs from freeing this node until it is assigned to another SharedPtr.
115
149
  SharedObj* detach() {
116
150
  if (node != nullptr) node->detached = true;
151
+ #ifdef DEBUG_SHARED_PTR
152
+ if (node->dbg) {
153
+ std::cerr << "DETACHING NODE\n";
154
+ }
155
+ #endif
117
156
  return node;
118
157
  }
119
158
 
@@ -136,6 +175,11 @@ namespace Sass {
136
175
  #endif
137
176
  delete node;
138
177
  }
178
+ else if (node->refcount == 0) {
179
+ #ifdef DEBUG_SHARED_PTR
180
+ if (node->dbg) std::cerr << "NODE EVAEDED DELETE " << node << "\n";
181
+ #endif
182
+ }
139
183
  }
140
184
  void incRefCount() {
141
185
  if (node == nullptr) return;
@@ -149,7 +193,8 @@ namespace Sass {
149
193
 
150
194
  template <class T>
151
195
  class SharedImpl : private SharedPtr {
152
- public:
196
+
197
+ public:
153
198
  SharedImpl() : SharedPtr(nullptr) {}
154
199
 
155
200
  template <class U>
@@ -172,9 +217,9 @@ namespace Sass {
172
217
  SharedPtr::operator=(static_cast<const SharedImpl<T>&>(rhs)));
173
218
  }
174
219
 
175
- operator const std::string() const {
220
+ operator sass::string() const {
176
221
  if (node) return node->to_string();
177
- return "[nullptr]";
222
+ return "null";
178
223
  }
179
224
 
180
225
  using SharedPtr::isNull;
@@ -185,6 +230,7 @@ namespace Sass {
185
230
  T* operator-> () const { return static_cast<T*>(this->obj()); };
186
231
  T* ptr () const { return static_cast<T*>(this->obj()); };
187
232
  T* detach() { return static_cast<T*>(SharedPtr::detach()); }
233
+
188
234
  };
189
235
 
190
236
  // Comparison operators, based on: