[wasm-shape] Retry shaping if out-of-memory

This commit is contained in:
Behdad Esfahbod 2023-02-24 19:04:39 -07:00
parent cb382e489d
commit 2568890d15
2 changed files with 27 additions and 3 deletions

View File

@ -283,10 +283,20 @@ _hb_wasm_shape (hb_shape_plan_t *shape_plan,
const hb_feature_t *features, const hb_feature_t *features,
unsigned int num_features) unsigned int num_features)
{ {
if (unlikely (buffer->in_error ()))
return false;
bool ret = true; bool ret = true;
hb_face_t *face = font->face; hb_face_t *face = font->face;
const hb_wasm_face_data_t *face_data = face->data.wasm; const hb_wasm_face_data_t *face_data = face->data.wasm;
bool retried = false;
if (0)
{
retry:
DEBUG_MSG (WASM, font, "Retrying...");
}
wasm_function_inst_t func = nullptr; wasm_function_inst_t func = nullptr;
hb_wasm_shape_plan_t *plan = acquire_shape_plan (face, face_data); hb_wasm_shape_plan_t *plan = acquire_shape_plan (face, face_data);
@ -340,15 +350,25 @@ _hb_wasm_shape (hb_shape_plan_t *shape_plan,
if (unlikely (buffer->in_error ())) if (unlikely (buffer->in_error ()))
{ {
DEBUG_MSG (WASM, module_inst, "Buffer in error. Memory allocation fail?"); DEBUG_MSG (WASM, module_inst, "Buffer in error. Memory allocation fail in the wasm?");
goto fail; if (retried)
goto fail;
buffer->successful = true;
retried = true;
release_shape_plan (face_data, plan);
goto retry;
} }
if (unlikely (!ret)) if (unlikely (!ret))
{ {
DEBUG_MSG (WASM, module_inst, "Calling shape() failed: %s", DEBUG_MSG (WASM, module_inst, "Calling shape() failed: %s",
wasm_runtime_get_exception(module_inst)); wasm_runtime_get_exception(module_inst));
goto fail; if (retried)
goto fail;
buffer->successful = true;
retried = true;
release_shape_plan (face_data, plan);
goto retry;
} }
/* TODO Regularize clusters according to direction & cluster level, /* TODO Regularize clusters according to direction & cluster level,

View File

@ -83,6 +83,8 @@ shape (void *shape_plan,
unsigned length = contents.length; unsigned length = contents.length;
uint32_t *chars = (uint32_t *) malloc (length * sizeof (uint32_t)); uint32_t *chars = (uint32_t *) malloc (length * sizeof (uint32_t));
if (!chars)
return false;
for (unsigned int i = 0; i < contents.length; ++i) for (unsigned int i = 0; i < contents.length; ++i)
chars[i] = contents.info[i].codepoint; chars[i] = contents.info[i].codepoint;
@ -114,6 +116,8 @@ shape (void *shape_plan,
buffer_contents_realloc (&contents, length); buffer_contents_realloc (&contents, length);
cluster_t *clusters = (cluster_t *) malloc (length * sizeof (cluster_t)); cluster_t *clusters = (cluster_t *) malloc (length * sizeof (cluster_t));
uint32_t *gids = (uint32_t *) malloc (length * sizeof (uint32_t)); uint32_t *gids = (uint32_t *) malloc (length * sizeof (uint32_t));
if (!clusters || !gids)
return false;
memset (clusters, 0, sizeof (clusters[0]) * length); memset (clusters, 0, sizeof (clusters[0]) * length);
codepoint_t *pg = gids; codepoint_t *pg = gids;