Skip to content

Commit 89acfeb

Browse files
committed
Handle loaded source code as shared objects
Makes them survive our context more easily. This enables use to safe and cheaply pass them to error handlers.
1 parent 2af9e00 commit 89acfeb

25 files changed

+367
-182
lines changed

Makefile.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ SOURCES = \
3535
units.cpp \
3636
values.cpp \
3737
plugins.cpp \
38+
source.cpp \
3839
position.cpp \
3940
lexer.cpp \
4041
parser.cpp \

src/ast.hpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,20 +81,18 @@ namespace Sass {
8181
virtual sass::string to_string() const;
8282
virtual void cloneChildren() {};
8383
// generic find function (not fully implemented yet)
84-
// ToDo: add specific implementions to all children
84+
// ToDo: add specific implementations to all children
8585
virtual bool find ( bool (*f)(AST_Node_Obj) ) { return f(this); };
8686
void update_pstate(const SourceSpan& pstate);
87-
Offset off() { return pstate().off(); }
88-
Position pos() { return pstate().pos(); }
8987

90-
// Some obects are not meant to be compared
91-
// ToDo: maybe fallback to pointer comparison?
88+
// Some objects are not meant to be compared
89+
// ToDo: maybe fall-back to pointer comparison?
9290
virtual bool operator== (const AST_Node& rhs) const {
9391
throw std::runtime_error("operator== not implemented");
9492
}
9593

9694
// We can give some reasonable implementations by using
97-
// inverst operators on the specialized implementations
95+
// invert operators on the specialized implementations
9896
virtual bool operator!= (const AST_Node& rhs) const {
9997
// Unequal if not equal
10098
return !(*this == rhs);

src/ast_fwd_decl.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
/////////////////////////////////////////////
1313
namespace Sass {
1414

15+
class SourceData;
16+
class SourceFile;
17+
class SynthFile;
18+
class ItplFile;
19+
1520
class AST_Node;
1621

1722
class ParentStatement;
@@ -127,6 +132,11 @@ namespace Sass {
127132
typedef SharedImpl<type> type##Obj; \
128133
typedef SharedImpl<type> type##_Obj; \
129134

135+
IMPL_MEM_OBJ(SourceData);
136+
IMPL_MEM_OBJ(SourceFile);
137+
IMPL_MEM_OBJ(SynthFile);
138+
IMPL_MEM_OBJ(ItplFile);
139+
130140
IMPL_MEM_OBJ(AST_Node);
131141
IMPL_MEM_OBJ(Statement);
132142
IMPL_MEM_OBJ(Block);

src/context.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "expand.hpp"
1818
#include "parser.hpp"
1919
#include "cssize.hpp"
20+
#include "source.hpp"
2021

2122
namespace Sass {
2223
using namespace Constants;
@@ -273,11 +274,11 @@ namespace Sass {
273274

274275
// get pointer to the loaded content
275276
const char* contents = resources[idx].contents;
276-
// keep a copy of the path around (for parserstates)
277-
// ToDo: we clean it, but still not very elegant!?
278-
strings.push_back(sass_copy_c_string(inc.abs_path.c_str()));
277+
SourceFileObj source = SASS_MEMORY_NEW(SourceFile,
278+
inc.abs_path.c_str(), contents, idx);
279+
279280
// create the initial parser state from resource
280-
SourceSpan pstate(strings.back(), contents, idx);
281+
SourceSpan pstate(source);
281282

282283
// check existing import stack for possible recursion
283284
for (size_t i = 0; i < import_stack.size() - 2; ++i) {
@@ -298,7 +299,7 @@ namespace Sass {
298299
}
299300

300301
// create a parser instance from the given c_str buffer
301-
Parser p(Parser::from_c_str(contents, *this, traces, pstate));
302+
Parser p(source, *this, traces);
302303
// do not yet dispose these buffers
303304
sass_import_take_source(import);
304305
sass_import_take_srcmap(import);
@@ -441,7 +442,7 @@ namespace Sass {
441442
if (const char* err_message = sass_import_get_error_message(include_ent)) {
442443
if (source || srcmap) register_resource({ importer, uniq_path }, { source, srcmap }, pstate);
443444
if (line == sass::string::npos && column == sass::string::npos) error(err_message, pstate, traces);
444-
else error(err_message, SourceSpan(ctx_path, source, Position(line, column)), traces);
445+
else { error(err_message, { pstate.source, { line, column } }, traces); }
445446
}
446447
// content for import was set
447448
else if (source) {

src/debugger.hpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,10 @@ inline sass::string longToHex(long long t) {
310310
inline sass::string pstate_source_position(AST_Node* node)
311311
{
312312
sass::sstream str;
313-
Position start(node->pstate());
314-
Position end(start + node->pstate().offset);
315-
str << (start.file == sass::string::npos ? 99999999 : start.file)
313+
Offset start(node->pstate().position);
314+
Offset end(start + node->pstate().offset);
315+
size_t file = node->pstate().getSrcId();
316+
str << (file == sass::string::npos ? 99999999 : file)
316317
<< "@[" << start.line << ":" << start.column << "]"
317318
<< "-[" << end.line << ":" << end.column << "]";
318319
#ifdef DEBUG_SHARED_PTR
@@ -419,7 +420,7 @@ inline void debug_ast(AST_Node* node, sass::string ind, Env* env)
419420
std::cerr << ind << "Parent_Reference " << selector;
420421
std::cerr << " (" << pstate_source_position(node) << ")";
421422
std::cerr << " <" << selector->hash() << ">";
422-
std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">" << std::endl;
423+
std::cerr << std::endl;
423424

424425
} else if (Cast<PseudoSelector>(node)) {
425426
PseudoSelector* selector = Cast<PseudoSelector>(node);
@@ -460,7 +461,6 @@ inline void debug_ast(AST_Node* node, sass::string ind, Env* env)
460461
std::cerr << " (" << pstate_source_position(node) << ")";
461462
std::cerr << " <" << selector->hash() << ">";
462463
std::cerr << " <<" << selector->ns_name() << ">>";
463-
std::cerr << " <" << prettyprint(selector->pstate().token.ws_before()) << ">";
464464
std::cerr << std::endl;
465465
} else if (Cast<PlaceholderSelector>(node)) {
466466

@@ -600,8 +600,7 @@ inline void debug_ast(AST_Node* node, sass::string ind, Env* env)
600600
Comment* block = Cast<Comment>(node);
601601
std::cerr << ind << "Comment " << block;
602602
std::cerr << " (" << pstate_source_position(node) << ")";
603-
std::cerr << " " << block->tabs() <<
604-
" <" << prettyprint(block->pstate().token.ws_before()) << ">" << std::endl;
603+
std::cerr << " " << block->tabs() << std::endl;
605604
debug_ast(block->text(), ind + "// ", env);
606605
} else if (Cast<If>(node)) {
607606
If* block = Cast<If>(node);
@@ -881,7 +880,7 @@ inline void debug_ast(AST_Node* node, sass::string ind, Env* env)
881880
if (expression->is_delayed()) std::cerr << " [delayed]";
882881
if (expression->is_interpolant()) std::cerr << " [interpolant]";
883882
if (expression->quote_mark()) std::cerr << " [quote_mark: " << expression->quote_mark() << "]";
884-
std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl;
883+
std::cerr << std::endl;
885884
} else if (Cast<String_Constant>(node)) {
886885
String_Constant* expression = Cast<String_Constant>(node);
887886
std::cerr << ind << "String_Constant " << expression;
@@ -892,7 +891,7 @@ inline void debug_ast(AST_Node* node, sass::string ind, Env* env)
892891
std::cerr << " [" << prettyprint(expression->value()) << "]";
893892
if (expression->is_delayed()) std::cerr << " [delayed]";
894893
if (expression->is_interpolant()) std::cerr << " [interpolant]";
895-
std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl;
894+
std::cerr << std::endl;
896895
} else if (Cast<String_Schema>(node)) {
897896
String_Schema* expression = Cast<String_Schema>(node);
898897
std::cerr << ind << "String_Schema " << expression;
@@ -905,15 +904,15 @@ inline void debug_ast(AST_Node* node, sass::string ind, Env* env)
905904
if (expression->has_interpolant()) std::cerr << " [has interpolant]";
906905
if (expression->is_left_interpolant()) std::cerr << " [left interpolant] ";
907906
if (expression->is_right_interpolant()) std::cerr << " [right interpolant] ";
908-
std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl;
907+
std::cerr << std::endl;
909908
for(const auto& i : expression->elements()) { debug_ast(i, ind + " ", env); }
910909
} else if (Cast<String>(node)) {
911910
String* expression = Cast<String>(node);
912911
std::cerr << ind << "String " << expression;
913912
std::cerr << " " << expression->concrete_type();
914913
std::cerr << " (" << pstate_source_position(node) << ")";
915914
if (expression->is_interpolant()) std::cerr << " [interpolant]";
916-
std::cerr << " <" << prettyprint(expression->pstate().token.ws_before()) << ">" << std::endl;
915+
std::cerr << std::endl;
917916
} else if (Cast<Expression>(node)) {
918917
Expression* expression = Cast<Expression>(node);
919918
std::cerr << ind << "Expression " << expression;

src/error_handling.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ namespace Sass {
1818
prefix("Error"), pstate(pstate), traces(traces)
1919
{ }
2020

21-
InvalidSass::InvalidSass(SourceSpan pstate, Backtraces traces, sass::string msg, char* owned_src)
22-
: Base(pstate, msg, traces), owned_src(owned_src)
21+
InvalidSass::InvalidSass(SourceSpan pstate, Backtraces traces, sass::string msg)
22+
: Base(pstate, msg, traces)
2323
{ }
2424

2525

src/error_handling.hpp

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,8 @@ namespace Sass {
4141

4242
class InvalidSass : public Base {
4343
public:
44-
InvalidSass(InvalidSass& other) : Base(other), owned_src(other.owned_src) {
45-
// Assumes that `this` will outlive `other`.
46-
other.owned_src = nullptr;
47-
}
48-
49-
// Required because the copy constructor's argument is not const.
50-
// Can't use `std::move` here because we build on Visual Studio 2013.
51-
InvalidSass(InvalidSass &&other) : Base(other), owned_src(other.owned_src) {
52-
other.owned_src = nullptr;
53-
}
54-
55-
InvalidSass(SourceSpan pstate, Backtraces traces, sass::string msg, char* owned_src = nullptr);
56-
virtual ~InvalidSass() throw() { sass_free_memory(owned_src); };
57-
char *owned_src;
44+
InvalidSass(SourceSpan pstate, Backtraces traces, sass::string msg);
45+
virtual ~InvalidSass() throw() {};
5846
};
5947

6048
class InvalidParent : public Base {

src/eval.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,9 +1503,9 @@ namespace Sass {
15031503
ExpressionObj sel = s->contents()->perform(this);
15041504
sass::string result_str(sel->to_string(options()));
15051505
result_str = unquote(Util::rtrim(result_str));
1506-
char* temp_cstr = sass_copy_c_string(result_str.c_str());
1507-
ctx.strings.push_back(temp_cstr); // attach to context
1508-
Parser p = Parser::from_c_str(temp_cstr, ctx, traces, s->pstate());
1506+
ItplFile* source = SASS_MEMORY_NEW(ItplFile,
1507+
result_str.c_str(), s->pstate());
1508+
Parser p(source, ctx, traces);
15091509

15101510
// If a schema contains a reference to parent it is already
15111511
// connected to it, so don't connect implicitly anymore

src/expand.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,9 @@ namespace Sass {
258258
{
259259
ExpressionObj mq = eval(m->schema());
260260
sass::string str_mq(mq->to_css(ctx.c_options));
261-
char* str = sass_copy_c_string(str_mq.c_str());
262-
ctx.strings.push_back(str);
263-
Parser parser(Parser::from_c_str(str, ctx, traces, mq->pstate()));
261+
ItplFile* source = SASS_MEMORY_NEW(ItplFile,
262+
str_mq.c_str(), m->pstate());
263+
Parser parser(source, ctx, traces);
264264
// Create a new CSS only representation of the media rule
265265
CssMediaRuleObj css = SASS_MEMORY_NEW(CssMediaRule, m->pstate(), m->block());
266266
sass::vector<CssMediaQuery_Obj> parsed = parser.parseCssMediaQueries();

src/extender.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ namespace Sass {
388388
CssMediaRuleObj mediaContext;
389389
if (mediaContexts.hasKey(rule)) mediaContext = mediaContexts.get(rule);
390390
SelectorListObj ext = extendList(rule, newExtensions, mediaContext);
391-
// If no extends actually happenedit (for example becaues unification
391+
// If no extends actually happened (for example because unification
392392
// failed), we don't need to re-register the selector.
393393
if (ObjEqualityFn(oldValue, ext)) continue;
394394
rule->elements(ext->elements());
@@ -1063,7 +1063,7 @@ namespace Sass {
10631063
// TODO(nweiz): I think there may be a way to get perfect trimming
10641064
// without going quadratic by building some sort of trie-like
10651065
// data structure that can be used to look up superselectors.
1066-
// TODO(mgreter): Check how this perfoms in C++ (up the limit)
1066+
// TODO(mgreter): Check how this performs in C++ (up the limit)
10671067
if (selectors.size() > 100) return selectors;
10681068

10691069
// This is n² on the sequences, but only comparing between separate sequences

0 commit comments

Comments
 (0)