summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@netsurf-browser.org>2009-02-15 13:30:03 +0000
committerDaniel Silverstone <dsilvers@netsurf-browser.org>2009-02-15 13:30:03 +0000
commit074079fb5e1520106397d036a66d84c25d3486df (patch)
tree77d3df8ec184c32429d6398a773bb7e8330ded40
parent942fa601d79edc6e36ba0999233a94398ee172bd (diff)
downloadlibcss-074079fb5e1520106397d036a66d84c25d3486df.tar.gz
libcss-074079fb5e1520106397d036a66d84c25d3486df.tar.bz2
Most of the interned string lifetimes are at least no shorter than we think they ought to be.
svn path=/trunk/libcss/; revision=6532
-rw-r--r--src/parse/parse.c42
-rw-r--r--src/parse/properties.c53
-rw-r--r--src/stylesheet.c47
-rw-r--r--test/parse-auto.c2
4 files changed, 124 insertions, 20 deletions
diff --git a/src/parse/parse.c b/src/parse/parse.c
index 484be31..f195c50 100644
--- a/src/parse/parse.c
+++ b/src/parse/parse.c
@@ -145,6 +145,8 @@ static inline css_error parseMalformedDeclaration(css_parser *parser);
static inline css_error parseMalformedSelector(css_parser *parser);
static inline css_error parseMalformedAtRule(css_parser *parser);
+static inline void unref_interned_strings_in_tokens(css_parser *parser);
+
/**
* Dispatch table for parsing, indexed by major state number
*/
@@ -612,7 +614,8 @@ css_error getToken(css_parser *parser, const css_token **token)
t->data.len, &t->idata);
if (t->ilower == NULL)
- t->ilower = t->idata;
+ t->ilower = lwc_context_string_ref(parser->dictionary,
+ t->idata);
if (lerror != lwc_error_ok)
return css_error_from_lwc_error(lerror);
@@ -647,7 +650,7 @@ css_error pushBack(css_parser *parser, const css_token *token)
/* The pushback buffer depth is 1 token. Assert this. */
assert(parser->pushback == NULL);
-
+
perror = parserutils_vector_remove_last(parser->tokens);
if (perror != PARSERUTILS_OK)
return css_error_from_parserutils_error(perror);
@@ -731,7 +734,8 @@ css_error parseStart(css_parser *parser)
parser->event(CSS_PARSER_END_STYLESHEET, NULL,
parser->event_pw);
}
-
+
+ unref_interned_strings_in_tokens(parser);
parserutils_vector_clear(parser->tokens);
return done(parser);
@@ -763,6 +767,7 @@ css_error parseStylesheet(css_parser *parser)
if (error != CSS_OK)
return error;
+ unref_interned_strings_in_tokens(parser);
parserutils_vector_clear(parser->tokens);
return done(parser);
@@ -832,6 +837,7 @@ css_error parseRuleset(css_parser *parser)
switch (state->substate) {
case Initial:
+ unref_interned_strings_in_tokens(parser);
parserutils_vector_clear(parser->tokens);
error = getToken(parser, &token);
@@ -1004,6 +1010,7 @@ css_error parseAtRule(css_parser *parser)
switch (state->substate) {
case Initial:
+ unref_interned_strings_in_tokens(parser);
parserutils_vector_clear(parser->tokens);
error = getToken(parser, &token);
@@ -1158,14 +1165,15 @@ css_error parseBlock(css_parser *parser)
parser->event_pw);
}
- parserutils_vector_clear(parser->tokens);
-
if (token->type != CSS_TOKEN_CHAR || lwc_string_length(token->ilower) != 1 ||
lwc_string_data(token->ilower)[0] != '{') {
/* This should never happen, as FIRST(block) == '{' */
assert(0 && "Expected {");
}
+ unref_interned_strings_in_tokens(parser);
+ parserutils_vector_clear(parser->tokens);
+
state->substate = WS;
/* Fall through */
case WS:
@@ -1214,6 +1222,7 @@ css_error parseBlock(css_parser *parser)
parser->event(CSS_PARSER_END_BLOCK, NULL, parser->event_pw);
}
+ unref_interned_strings_in_tokens(parser);
parserutils_vector_clear(parser->tokens);
return done(parser);
@@ -1345,6 +1354,7 @@ css_error parseSelector(css_parser *parser)
parser_state to = { sAny1, Initial };
parser_state subsequent = { sSelector, AfterAny1 };
+ unref_interned_strings_in_tokens(parser);
parserutils_vector_clear(parser->tokens);
return transition(parser, to, subsequent);
@@ -1371,6 +1381,7 @@ css_error parseDeclaration(css_parser *parser)
parser_state to = { sProperty, Initial };
parser_state subsequent = { sDeclaration, Colon };
+ unref_interned_strings_in_tokens(parser);
parserutils_vector_clear(parser->tokens);
return transition(parser, to, subsequent);
@@ -2040,6 +2051,7 @@ css_error parseMalformedDeclaration(css_parser *parser)
return error;
/* Discard the tokens we've read */
+ unref_interned_strings_in_tokens(parser);
parserutils_vector_clear(parser->tokens);
return done(parser);
@@ -2134,6 +2146,7 @@ css_error parseMalformedSelector(css_parser *parser)
return error;
/* Discard the tokens we've read */
+ unref_interned_strings_in_tokens(parser);
parserutils_vector_clear(parser->tokens);
return done(parser);
@@ -2241,12 +2254,31 @@ css_error parseMalformedAtRule(css_parser *parser)
return error;
/* Discard the tokens we've read */
+ unref_interned_strings_in_tokens(parser);
parserutils_vector_clear(parser->tokens);
return done(parser);
}
+/**
+ * Iterate the token vector and unref any interned strings in the tokens.
+ *
+ * \param parser The parser whose tokens we are cleaning up.
+ */
+static inline void unref_interned_strings_in_tokens(css_parser *parser)
+{
+ int32_t ctx = 0;
+ const css_token *tok;
+
+ while ((tok = parserutils_vector_iterate(parser->tokens, &ctx)) != NULL) {
+ if (tok->idata != NULL)
+ lwc_context_string_unref(parser->dictionary, tok->idata);
+ if (tok->ilower != NULL)
+ lwc_context_string_unref(parser->dictionary, tok->ilower);
+ }
+}
+
#ifndef NDEBUG
#ifdef DEBUG_STACK
static void printer(void *item)
diff --git a/src/parse/properties.c b/src/parse/properties.c
index a4de6ef..f54b3f9 100644
--- a/src/parse/properties.c
+++ b/src/parse/properties.c
@@ -764,6 +764,7 @@ css_error parse_background_image(css_language *c,
/* Copy the bytecode to it */
memcpy((*result)->bytecode, &opv, sizeof(opv));
if ((flags & FLAG_INHERIT) == false && value == BACKGROUND_IMAGE_URI) {
+ lwc_context_string_ref(c->sheet->dictionary, token->idata);
memcpy((uint8_t *) (*result)->bytecode + sizeof(opv),
&token->idata,
sizeof(lwc_string *));
@@ -1760,8 +1761,11 @@ css_error parse_counter_increment(css_language *c,
memcpy(ptr, &opv, sizeof(opv));
ptr += sizeof(opv);
}
+
+ lwc_context_string_ref(c->sheet->dictionary, name);
memcpy(ptr, &name, sizeof(name));
ptr += sizeof(name);
+
memcpy(ptr, &increment, sizeof(increment));
ptr += sizeof(increment);
@@ -1925,8 +1929,11 @@ css_error parse_counter_reset(css_language *c,
memcpy(ptr, &opv, sizeof(opv));
ptr += sizeof(opv);
}
+
+ lwc_context_string_ref(c->sheet->dictionary, name);
memcpy(ptr, &name, sizeof(name));
ptr += sizeof(name);
+
memcpy(ptr, &increment, sizeof(increment));
ptr += sizeof(increment);
@@ -2001,6 +2008,7 @@ css_error parse_cue_after(css_language *c,
/* Copy the bytecode to it */
memcpy((*result)->bytecode, &opv, sizeof(opv));
if ((flags & FLAG_INHERIT) == false && value == CUE_AFTER_URI) {
+ lwc_context_string_ref(c->sheet->dictionary, token->idata);
memcpy((uint8_t *) (*result)->bytecode + sizeof(opv),
&token->idata,
sizeof(lwc_string *));
@@ -2055,6 +2063,7 @@ css_error parse_cue_before(css_language *c,
/* Copy the bytecode to it */
memcpy((*result)->bytecode, &opv, sizeof(opv));
if ((flags & FLAG_INHERIT) == false && value == CUE_BEFORE_URI) {
+ lwc_context_string_ref(c->sheet->dictionary, token->idata);
memcpy((uint8_t *) (*result)->bytecode + sizeof(opv),
&token->idata,
sizeof(lwc_string *));
@@ -2246,7 +2255,8 @@ css_error parse_cursor(css_language *c,
memcpy(ptr, &opv, sizeof(opv));
ptr += sizeof(opv);
}
-
+
+ lwc_context_string_ref(c->sheet->dictionary, uri);
memcpy(ptr, &uri, sizeof(uri));
ptr += sizeof(uri);
@@ -2793,7 +2803,8 @@ css_error parse_font_family(css_language *c,
while (token != NULL) {
if (token->type == CSS_TOKEN_IDENT) {
- lwc_string *name = token->idata;
+ lwc_string *tok_idata = token->idata;
+ lwc_string *name = tok_idata;
lwc_string *newname;
if (token->ilower == c->strings[SERIF]) {
@@ -2903,6 +2914,12 @@ css_error parse_font_family(css_language *c,
}
if (opv == FONT_FAMILY_IDENT_LIST) {
+ /* Only ref 'name' again if the token owns it,
+ * otherwise we already own the only ref to the
+ * new name generated above.
+ */
+ if (name == tok_idata)
+ lwc_context_string_ref(c->sheet->dictionary, name);
memcpy(ptr, &name, sizeof(name));
ptr += sizeof(name);
}
@@ -2913,7 +2930,8 @@ css_error parse_font_family(css_language *c,
memcpy(ptr, &opv, sizeof(opv));
ptr += sizeof(opv);
}
-
+
+ lwc_context_string_ref(c->sheet->dictionary, token->idata);
memcpy(ptr, &token->idata,
sizeof(token->idata));
ptr += sizeof(token->idata);
@@ -3554,6 +3572,7 @@ css_error parse_list_style_image(css_language *c,
/* Copy the bytecode to it */
memcpy((*result)->bytecode, &opv, sizeof(opv));
if ((flags & FLAG_INHERIT) == false && value == LIST_STYLE_IMAGE_URI) {
+ lwc_context_string_ref(c->sheet->dictionary, token->idata);
memcpy((uint8_t *) (*result)->bytecode + sizeof(opv),
&token->idata,
sizeof(lwc_string *));
@@ -4655,7 +4674,8 @@ css_error parse_play_during(css_language *c,
memcpy((*result)->bytecode, &opv, sizeof(opv));
if ((flags & FLAG_INHERIT) == false &&
(value & PLAY_DURING_TYPE_MASK) == PLAY_DURING_URI) {
- memcpy((uint8_t *) (*result)->bytecode + sizeof(opv),
+ lwc_context_string_ref(c->sheet->dictionary, uri);
+ memcpy((uint8_t *) (*result)->bytecode + sizeof(opv),
&uri, sizeof(lwc_string *));
}
@@ -4829,10 +4849,13 @@ css_error parse_quotes(css_language *c,
memcpy(ptr, &opv, sizeof(opv));
ptr += sizeof(opv);
}
-
+
+ lwc_context_string_ref(c->sheet->dictionary, open);
memcpy(ptr, &open, sizeof(open));
ptr += sizeof(open);
- memcpy(ptr, &close, sizeof(close));
+
+ lwc_context_string_ref(c->sheet->dictionary, close);
+ memcpy(ptr, &close, sizeof(close));
ptr += sizeof(close);
first = false;
@@ -5964,7 +5987,8 @@ css_error parse_voice_family(css_language *c,
while (token != NULL) {
if (token->type == CSS_TOKEN_IDENT) {
- lwc_string *name = token->idata;
+ lwc_string *tok_idata = token->idata;
+ lwc_string *name = tok_idata;
lwc_string *newname;
if (token->ilower == c->strings[MALE]) {
@@ -6064,6 +6088,12 @@ css_error parse_voice_family(css_language *c,
}
if (opv == VOICE_FAMILY_IDENT_LIST) {
+ /* Only ref 'name' again if the token owns it,
+ * otherwise we already own the only ref to the
+ * new name generated above.
+ */
+ if (name == tok_idata)
+ lwc_context_string_ref(c->sheet->dictionary, name);
memcpy(ptr, &name, sizeof(name));
ptr += sizeof(name);
}
@@ -6074,7 +6104,8 @@ css_error parse_voice_family(css_language *c,
memcpy(ptr, &opv, sizeof(opv));
ptr += sizeof(opv);
}
-
+
+ lwc_context_string_ref(c->sheet->dictionary, token->idata);
memcpy(ptr, &token->idata,
sizeof(token->idata));
ptr += sizeof(token->idata);
@@ -7296,6 +7327,7 @@ css_error parse_content_list(css_language *c,
}
if (buffer != NULL) {
+ lwc_context_string_ref(c->sheet->dictionary, token->idata);
memcpy(buffer + offset, &token->idata,
sizeof(token->idata));
}
@@ -7314,6 +7346,7 @@ css_error parse_content_list(css_language *c,
}
if (buffer != NULL) {
+ lwc_context_string_ref(c->sheet->dictionary, token->idata);
memcpy(buffer + offset, &token->idata,
sizeof(token->idata));
}
@@ -7340,6 +7373,7 @@ css_error parse_content_list(css_language *c,
return CSS_INVALID;
if (buffer != NULL) {
+ lwc_context_string_ref(c->sheet->dictionary, token->idata);
memcpy(buffer + offset, &token->idata,
sizeof(token->idata));
}
@@ -7419,6 +7453,7 @@ css_error parse_content_list(css_language *c,
}
if (buffer != NULL) {
+ lwc_context_string_ref(c->sheet->dictionary, name);
memcpy(buffer + offset, &name, sizeof(name));
}
@@ -7507,12 +7542,14 @@ css_error parse_content_list(css_language *c,
}
if (buffer != NULL) {
+ lwc_context_string_ref(c->sheet->dictionary, name);
memcpy(buffer + offset, &name, sizeof(name));
}
offset += sizeof(name);
if (buffer != NULL) {
+ lwc_context_string_ref(c->sheet->dictionary, sep);
memcpy(buffer + offset, &sep, sizeof(sep));
}
diff --git a/src/stylesheet.c b/src/stylesheet.c
index e6dd5d9..41a3341 100644
--- a/src/stylesheet.c
+++ b/src/stylesheet.c
@@ -526,6 +526,8 @@ css_error css_stylesheet_style_create(css_stylesheet *sheet, uint32_t len,
* \param sheet The stylesheet context
* \param style The style to destroy
* \return CSS_OK on success, appropriate error otherwise
+ *
+ * \todo This really ought to unref all the strings in the bytecode.
*/
css_error css_stylesheet_style_destroy(css_stylesheet *sheet, css_style *style)
{
@@ -562,7 +564,7 @@ css_error css_stylesheet_selector_create(css_stylesheet *sheet,
memset(sel, 0, sizeof(css_selector));
sel->data.type = CSS_SELECTOR_ELEMENT;
- sel->data.name = name;
+ sel->data.name = lwc_context_string_ref(sheet->dictionary, name);
sel->data.value = NULL;
/* Initial specificity -- 1 for an element, 0 for universal */
@@ -589,6 +591,7 @@ css_error css_stylesheet_selector_destroy(css_stylesheet *sheet,
css_selector *selector)
{
css_selector *c, *d;
+ css_selector_detail *detail;
if (sheet == NULL || selector == NULL)
return CSS_BADPARM;
@@ -600,9 +603,30 @@ css_error css_stylesheet_selector_destroy(css_stylesheet *sheet,
for (c = selector->combinator; c != NULL; c = d) {
d = c->combinator;
+ for (detail = &c->data; detail;) {
+ lwc_context_string_unref(sheet->dictionary, detail->name);
+ if (detail->value != NULL)
+ lwc_context_string_unref(sheet->dictionary, detail->value);
+ if (detail->next)
+ detail++;
+ else
+ detail = NULL;
+ }
+
sheet->alloc(c, 0, sheet->pw);
}
-
+
+ for (detail = &selector->data; detail;) {
+ lwc_context_string_unref(sheet->dictionary, detail->name);
+ if (detail->value != NULL)
+ lwc_context_string_unref(sheet->dictionary, detail->value);
+ if (detail->next)
+ detail++;
+ else
+ detail = NULL;
+ }
+
+
/* Destroy this selector */
sheet->alloc(selector, 0, sheet->pw);
@@ -675,7 +699,12 @@ css_error css_stylesheet_selector_append_specific(css_stylesheet *sheet,
(&temp->data)[num_details + 1] = *detail;
/* Flag that there's another block */
(&temp->data)[num_details].next = 1;
-
+
+ /* Ref the strings */
+ lwc_context_string_ref(sheet->dictionary, detail->name);
+ if (detail->value != NULL)
+ lwc_context_string_ref(sheet->dictionary, detail->value);
+
(*parent) = temp;
/* Update parent's specificity */
@@ -839,11 +868,17 @@ css_error css_stylesheet_rule_destroy(css_stylesheet *sheet, css_rule *rule)
}
break;
case CSS_RULE_CHARSET:
+ {
+ css_rule_charset *charset = (css_rule_charset *) rule;
+ lwc_context_string_unref(sheet->dictionary, charset->encoding);
+ }
break;
case CSS_RULE_IMPORT:
{
css_rule_import *import = (css_rule_import *) rule;
-
+
+ lwc_context_string_unref(sheet->dictionary, import->url);
+
if (import->sheet != NULL)
css_stylesheet_destroy(import->sheet);
}
@@ -1015,7 +1050,7 @@ css_error css_stylesheet_rule_set_charset(css_stylesheet *sheet,
assert(rule->type == CSS_RULE_CHARSET);
/* Set rule's encoding field */
- r->encoding = charset;
+ r->encoding = lwc_context_string_ref(sheet->dictionary, charset);
return CSS_OK;
}
@@ -1043,7 +1078,7 @@ css_error css_stylesheet_rule_set_nascent_import(css_stylesheet *sheet,
assert(rule->type == CSS_RULE_IMPORT);
/* Set the rule's sheet field */
- r->url = url;
+ r->url = lwc_context_string_ref(sheet->dictionary, url);
r->media = media;
return CSS_OK;
diff --git a/test/parse-auto.c b/test/parse-auto.c
index 1bb868b..dfd99ca 100644
--- a/test/parse-auto.c
+++ b/test/parse-auto.c
@@ -64,7 +64,7 @@ static void dump_string(lwc_string *string, char **ptr);
static void *myrealloc(void *data, size_t len, void *pw)
{
UNUSED(pw);
-
+
return realloc(data, len);
}