mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-01-06 14:20:19 +01:00
[script] Add a finish method to the interpreter
When using fonts circular references are established between the holdover font caches and the interpreter which need manual intervention via cairo_script_interpreter_finish() to break.
This commit is contained in:
parent
098822d7ee
commit
867c88ae90
5 changed files with 70 additions and 25 deletions
|
|
@ -232,6 +232,7 @@ execute (cairo_perf_t *perf,
|
|||
cairo_perf_timer_stop ();
|
||||
times[i] = cairo_perf_timer_elapsed ();
|
||||
|
||||
cairo_script_interpreter_finish (csi);
|
||||
cairo_script_interpreter_destroy (csi);
|
||||
|
||||
if (perf->raw) {
|
||||
|
|
@ -426,12 +427,10 @@ cairo_perf_fini (cairo_perf_t *perf)
|
|||
{
|
||||
cairo_boilerplate_free_targets (perf->targets);
|
||||
free (perf->times);
|
||||
#if 0 /* XXX */
|
||||
cairo_debug_reset_static_data ();
|
||||
#if HAVE_FCFINI
|
||||
FcFini ();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
|
|
|
|||
|
|
@ -116,6 +116,9 @@ _csi_perm_alloc (csi_t *ctx, int size)
|
|||
void *
|
||||
_csi_slab_alloc (csi_t *ctx, int size)
|
||||
{
|
||||
#if CSI_DEBUG_MALLOC
|
||||
return malloc (size);
|
||||
#else
|
||||
int chunk_size;
|
||||
csi_chunk_t *chunk;
|
||||
void *ptr;
|
||||
|
|
@ -150,6 +153,7 @@ _csi_slab_alloc (csi_t *ctx, int size)
|
|||
chunk->rem--;
|
||||
|
||||
return ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -161,12 +165,16 @@ _csi_slab_free (csi_t *ctx, void *ptr, int size)
|
|||
if (_csi_unlikely (ptr == NULL))
|
||||
return;
|
||||
|
||||
#if CSI_DEBUG_MALLOC
|
||||
free (ptr);
|
||||
#else
|
||||
chunk_size = 2 * sizeof (void *);
|
||||
chunk_size = (size + chunk_size - 1) / chunk_size;
|
||||
|
||||
free_list = ptr;
|
||||
*free_list = ctx->slabs[chunk_size].free_list;
|
||||
ctx->slabs[chunk_size].free_list = ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -396,16 +404,6 @@ _csi_fini (csi_t *ctx)
|
|||
_csi_scanner_fini (ctx, &ctx->scanner);
|
||||
|
||||
_csi_hash_table_fini (&ctx->strings);
|
||||
|
||||
if (ctx->free_array != NULL)
|
||||
csi_array_free (ctx, ctx->free_array);
|
||||
if (ctx->free_dictionary != NULL)
|
||||
csi_dictionary_free (ctx, ctx->free_dictionary);
|
||||
if (ctx->free_string != NULL)
|
||||
csi_string_free (ctx, ctx->free_string);
|
||||
|
||||
_csi_slab_fini (ctx);
|
||||
_csi_perm_fini (ctx);
|
||||
}
|
||||
|
||||
csi_status_t
|
||||
|
|
@ -530,6 +528,8 @@ cairo_script_interpreter_run (csi_t *ctx, const char *filename)
|
|||
|
||||
if (ctx->status)
|
||||
return ctx->status;
|
||||
if (ctx->finished)
|
||||
return ctx->status = CSI_STATUS_INTERPRETER_FINISHED;
|
||||
|
||||
ctx->status = csi_file_new (ctx, &file, filename, "r");
|
||||
if (ctx->status)
|
||||
|
|
@ -550,6 +550,8 @@ cairo_script_interpreter_feed_string (csi_t *ctx, const char *line, int len)
|
|||
|
||||
if (ctx->status)
|
||||
return ctx->status;
|
||||
if (ctx->finished)
|
||||
return ctx->status = CSI_STATUS_INTERPRETER_FINISHED;
|
||||
|
||||
if (len < 0)
|
||||
len = strlen (line);
|
||||
|
|
@ -573,6 +575,22 @@ cairo_script_interpreter_reference (csi_t *ctx)
|
|||
}
|
||||
slim_hidden_def (cairo_script_interpreter_reference);
|
||||
|
||||
cairo_status_t
|
||||
cairo_script_interpreter_finish (csi_t *ctx)
|
||||
{
|
||||
csi_status_t status;
|
||||
|
||||
status = ctx->status;
|
||||
if (! ctx->finished) {
|
||||
_csi_fini (ctx);
|
||||
ctx->finished = 1;
|
||||
} else if (status == CAIRO_STATUS_SUCCESS) {
|
||||
status = ctx->status = CSI_STATUS_INTERPRETER_FINISHED;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
cairo_script_interpreter_destroy (csi_t *ctx)
|
||||
{
|
||||
|
|
@ -582,7 +600,18 @@ cairo_script_interpreter_destroy (csi_t *ctx)
|
|||
if (--ctx->ref_count)
|
||||
return status;
|
||||
|
||||
_csi_fini (ctx);
|
||||
if (! ctx->finished)
|
||||
_csi_fini (ctx);
|
||||
|
||||
if (ctx->free_array != NULL)
|
||||
csi_array_free (ctx, ctx->free_array);
|
||||
if (ctx->free_dictionary != NULL)
|
||||
csi_dictionary_free (ctx, ctx->free_dictionary);
|
||||
if (ctx->free_string != NULL)
|
||||
csi_string_free (ctx, ctx->free_string);
|
||||
|
||||
_csi_slab_fini (ctx);
|
||||
_csi_perm_fini (ctx);
|
||||
free (ctx);
|
||||
|
||||
return status;
|
||||
|
|
|
|||
|
|
@ -91,6 +91,9 @@ cairo_script_interpreter_feed_string (cairo_script_interpreter_t *ctx,
|
|||
cairo_public cairo_script_interpreter_t *
|
||||
cairo_script_interpreter_reference (cairo_script_interpreter_t *ctx);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_script_interpreter_finish (cairo_script_interpreter_t *ctx);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_script_interpreter_destroy (cairo_script_interpreter_t *ctx);
|
||||
|
||||
|
|
|
|||
|
|
@ -157,6 +157,16 @@ _csi_array_execute (csi_t *ctx, csi_array_t *array)
|
|||
void
|
||||
csi_array_free (csi_t *ctx, csi_array_t *array)
|
||||
{
|
||||
#if CSI_DEBUG_MALLOC
|
||||
_csi_stack_fini (ctx, &array->stack);
|
||||
_csi_slab_free (ctx, array, sizeof (csi_array_t));
|
||||
#else
|
||||
csi_integer_t n;
|
||||
|
||||
for (n = 0; n < array->stack.len; n++)
|
||||
csi_object_free (ctx, &array->stack.objects[n]);
|
||||
array->stack.len = 0;
|
||||
|
||||
if (ctx->free_array != NULL) {
|
||||
if (array->stack.size > ctx->free_array->stack.size) {
|
||||
csi_array_t *tmp = ctx->free_array;
|
||||
|
|
@ -166,18 +176,9 @@ csi_array_free (csi_t *ctx, csi_array_t *array)
|
|||
|
||||
_csi_stack_fini (ctx, &array->stack);
|
||||
_csi_slab_free (ctx, array, sizeof (csi_array_t));
|
||||
} else {
|
||||
csi_integer_t n;
|
||||
|
||||
for (n = 0; n < array->stack.len; n++)
|
||||
csi_object_free (ctx, &array->stack.objects[n]);
|
||||
array->stack.len = 0;
|
||||
|
||||
if (ctx->free_array == NULL)
|
||||
ctx->free_array = array;
|
||||
else
|
||||
csi_array_free (ctx, array);
|
||||
}
|
||||
} else
|
||||
ctx->free_array = array;
|
||||
#endif
|
||||
}
|
||||
|
||||
csi_status_t
|
||||
|
|
@ -262,11 +263,16 @@ csi_dictionary_free (csi_t *ctx,
|
|||
_dictionary_entry_pluck,
|
||||
&data);
|
||||
|
||||
#if CSI_DEBUG_MALLOC
|
||||
_csi_hash_table_fini (&dict->hash_table);
|
||||
_csi_slab_free (ctx, dict, sizeof (csi_dictionary_t));
|
||||
#else
|
||||
if (ctx->free_dictionary != NULL) {
|
||||
_csi_hash_table_fini (&dict->hash_table);
|
||||
_csi_slab_free (ctx, dict, sizeof (csi_dictionary_t));
|
||||
} else
|
||||
ctx->free_dictionary = dict;
|
||||
#endif
|
||||
}
|
||||
|
||||
csi_status_t
|
||||
|
|
@ -575,6 +581,10 @@ _csi_string_execute (csi_t *ctx, csi_string_t *string)
|
|||
void
|
||||
csi_string_free (csi_t *ctx, csi_string_t *string)
|
||||
{
|
||||
#if CSI_DEBUG_MALLOC
|
||||
_csi_free (ctx, string->string);
|
||||
_csi_slab_free (ctx, string, sizeof (csi_string_t));
|
||||
#else
|
||||
if (ctx->free_string != NULL) {
|
||||
if (string->len > ctx->free_string->len) {
|
||||
csi_string_t *tmp = ctx->free_string;
|
||||
|
|
@ -586,6 +596,7 @@ csi_string_free (csi_t *ctx, csi_string_t *string)
|
|||
_csi_slab_free (ctx, string, sizeof (csi_string_t));
|
||||
} else
|
||||
ctx->free_string = string;
|
||||
#endif
|
||||
}
|
||||
|
||||
csi_status_t
|
||||
|
|
|
|||
|
|
@ -219,6 +219,7 @@ typedef enum _csi_status {
|
|||
CSI_STATUS_SCRIPT_INVALID_TYPE,
|
||||
CSI_STATUS_SCRIPT_INVALID_INDEX,
|
||||
CSI_STATUS_SCRIPT_UNDEFINED_NAME,
|
||||
CSI_STATUS_INTERPRETER_FINISHED,
|
||||
|
||||
_CSI_STATUS_SCRIPT_LAST_ERROR,
|
||||
CSI_INT_STATUS_UNSUPPORTED
|
||||
|
|
@ -453,6 +454,8 @@ struct _cairo_script_interpreter {
|
|||
int ref_count;
|
||||
csi_status_t status;
|
||||
|
||||
unsigned int finished : 1;
|
||||
|
||||
csi_hooks_t hooks;
|
||||
|
||||
csi_hash_table_t strings;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue