diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e1a7e36..b08deae9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v1.9.1 + +* Skip `ti_do_expression` where possible for performance increase, pr #452. + # v1.9.0 * Include `tasks` and `restarts` for `modules_info()` on _node_ scope, issue #447. diff --git a/inc/ti/do.h b/inc/ti/do.h index 435091ca..cfed6005 100644 --- a/inc/ti/do.h +++ b/inc/ti/do.h @@ -12,6 +12,23 @@ typedef int (*ti_do_cb)(ti_query_t * query, cleri_node_t * nd, ex_t * e); int ti_do_expression(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_function(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_var(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_ano(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_false(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_true(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_float(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_int(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_nil(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_regex(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_string(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_template(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_var_assign(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_instance(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_enum_get(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_thing(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_array(ti_query_t * query, cleri_node_t * nd, ex_t * e); +int ti_do_paranthesis(ti_query_t * query, cleri_node_t * nd, ex_t * e); int ti_do_operation(ti_query_t * query, cleri_node_t * nd, ex_t * e); int ti_do_bit_sl(ti_query_t * query, cleri_node_t * nd, ex_t * e); int ti_do_bit_sr(ti_query_t * query, cleri_node_t * nd, ex_t * e); diff --git a/inc/ti/version.h b/inc/ti/version.h index 0f0f058d..1641b6e3 100644 --- a/inc/ti/version.h +++ b/inc/ti/version.h @@ -6,7 +6,7 @@ #define TI_VERSION_MAJOR 1 #define TI_VERSION_MINOR 9 -#define TI_VERSION_PATCH 0 +#define TI_VERSION_PATCH 1 /* The syntax version is used to test compatibility with functions * using the `ti_nodes_check_syntax()` function */ @@ -25,7 +25,7 @@ * "-rc0" * "" */ -#define TI_VERSION_PRE_RELEASE "" +#define TI_VERSION_PRE_RELEASE "-alpha0" #define TI_MAINTAINER \ "Jeroen van der Heijden " diff --git a/src/ti/do.c b/src/ti/do.c index 91f27c5f..7a880a78 100644 --- a/src/ti/do.c +++ b/src/ti/do.c @@ -1903,6 +1903,169 @@ static inline int do__template(ti_query_t * query, cleri_node_t * nd, ex_t * e) return ti_template_compile(nd->data, query, e); } +static inline int do__float(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + if (!nd->data) + { + nd->data = ti_vfloat_create(strx_to_double(nd->str, NULL)); + if (!nd->data) + { + ex_set_mem(e); + return e->nr; + } + assert(vec_space(query->immutable_cache)); + VEC_push(query->immutable_cache, nd->data); + } + query->rval = nd->data; + ti_incref(query->rval); + return e->nr; +} + +static inline int do__int(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + if (!nd->data) + { + int64_t i = strx_to_int64(nd->str, NULL); + if (errno == ERANGE) + { + ex_set(e, EX_OVERFLOW, "integer overflow"); + return e->nr; + } + nd->data = ti_vint_create(i); + if (!nd->data) + { + ex_set_mem(e); + return e->nr; + } + assert(vec_space(query->immutable_cache)); + VEC_push(query->immutable_cache, nd->data); + } + query->rval = nd->data; + ti_incref(query->rval); + return e->nr; +} + +static inline int do__regex(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + if (!nd->data) + { + nd->data = ti_regex_from_strn(nd->str, nd->len, e); + if (!nd->data) + return e->nr; + assert(vec_space(query->immutable_cache)); + VEC_push(query->immutable_cache, nd->data); + } + query->rval = nd->data; + ti_incref(query->rval); + return e->nr; +} + +static inline int do__string(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + if (!nd->data) + { + nd->data = ti_str_from_ti_string(nd->str, nd->len); + if (!nd->data) + { + ex_set_mem(e); + return e->nr; + } + assert(vec_space(query->immutable_cache)); + VEC_push(query->immutable_cache, nd->data); + } + query->rval = nd->data; + ti_incref(query->rval); + return e->nr; +} + +int ti_do_var(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + return do__var(query, nd->children->next->children, e); +} + +int ti_do_function(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + return do__function(query, nd->children->next, e); +} + +int ti_do_ano(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + return do__ano(query, nd->children->next, e); +} + +int ti_do_false(ti_query_t * query, cleri_node_t * UNUSED(nd), ex_t * e) +{ + query->rval = (ti_val_t *) ti_vbool_get(false); + return e->nr; +} + +int ti_do_true(ti_query_t * query, cleri_node_t * UNUSED(nd), ex_t * e) +{ + query->rval = (ti_val_t *) ti_vbool_get(true); + return e->nr; +} + +int ti_do_nil(ti_query_t * query, cleri_node_t * UNUSED(nd), ex_t * e) +{ + query->rval = (ti_val_t *) ti_nil_get(); + return e->nr; +} + +int ti_do_float(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + return do__float(query, nd->children->next, e); +} + +int ti_do_int(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + return do__int(query, nd->children->next, e); +} + +int ti_do_regex(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + return do__regex(query, nd->children->next, e); +} + +int ti_do_string(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + return do__string(query, nd->children->next, e); +} + +int ti_do_template(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + return do__template(query, nd->children->next, e); +} + +int ti_do_var_assign(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + return do__var_assign(query, nd->children->next, e); +} + +int ti_do_instance(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + return do__instance(query, nd->children->next, e); +} + +int ti_do_enum_get(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + return do__enum_get(query, nd->children->next, e); +} + +int ti_do_thing(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + return do__thing(query, nd->children->next, e, (uintptr_t) nd->data); +} + +int ti_do_array(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + return do__array(query, nd->children->next, e); +} + +int ti_do_paranthesis(ti_query_t * query, cleri_node_t * nd, ex_t * e) +{ + return ti_do_statement(query, nd->children->next->children->next, e); +} + int ti_do_expression(ti_query_t * query, cleri_node_t * nd, ex_t * e) { int preopr = (int) ((intptr_t) nd->children->data); @@ -1941,70 +2104,23 @@ int ti_do_expression(ti_query_t * query, cleri_node_t * nd, ex_t * e) query->rval = (ti_val_t *) ti_vbool_get(false); break; case CLERI_GID_T_FLOAT: - if (!nd->data) - { - nd->data = ti_vfloat_create(strx_to_double(nd->str, NULL)); - if (!nd->data) - { - ex_set_mem(e); - return e->nr; - } - assert(vec_space(query->immutable_cache)); - VEC_push(query->immutable_cache, nd->data); - } - query->rval = nd->data; - ti_incref(query->rval); + if (do__float(query, nd, e)) + return e->nr; break; case CLERI_GID_T_INT: - if (!nd->data) - { - int64_t i = strx_to_int64(nd->str, NULL); - if (errno == ERANGE) - { - ex_set(e, EX_OVERFLOW, "integer overflow"); - return e->nr; - } - nd->data = ti_vint_create(i); - if (!nd->data) - { - ex_set_mem(e); - return e->nr; - } - assert(vec_space(query->immutable_cache)); - VEC_push(query->immutable_cache, nd->data); - } - query->rval = nd->data; - ti_incref(query->rval); + if (do__int(query, nd, e)) + return e->nr; break; case CLERI_GID_T_NIL: query->rval = (ti_val_t *) ti_nil_get(); break; case CLERI_GID_T_REGEX: - if (!nd->data) - { - nd->data = ti_regex_from_strn(nd->str, nd->len, e); - if (!nd->data) - return e->nr; - assert(vec_space(query->immutable_cache)); - VEC_push(query->immutable_cache, nd->data); - } - query->rval = nd->data; - ti_incref(query->rval); + if (do__regex(query, nd, e)) + return e->nr; break; case CLERI_GID_T_STRING: - if (!nd->data) - { - nd->data = ti_str_from_ti_string(nd->str, nd->len); - if (!nd->data) - { - ex_set_mem(e); - return e->nr; - } - assert(vec_space(query->immutable_cache)); - VEC_push(query->immutable_cache, nd->data); - } - query->rval = nd->data; - ti_incref(query->rval); + if (do__string(query, nd, e)) + return e->nr; break; case CLERI_GID_T_TRUE: query->rval = (ti_val_t *) ti_vbool_get(true); diff --git a/src/ti/qbind.c b/src/ti/qbind.c index 75c4731e..38845c2d 100644 --- a/src/ti/qbind.c +++ b/src/ti/qbind.c @@ -1344,7 +1344,77 @@ static inline void qbind__expression(ti_qbind_t * qbind, cleri_node_t * nd) /* chain */ if (nd->children->next->next->next) + { qbind__chain(qbind, nd->children->next->next->next); + } + else if (!preopr && !nd->children->next->next->children) + { + /* no `preopr`, `chain` nor `index`, this means we can overwrite the + * full `ti_do_expression` and set a direct call + */ + switch (node->next->cl_obj->gid) + { + case CLERI_GID_T_ANO: + nd->data = ti_do_ano; + break; + case CLERI_GID_T_FALSE: + nd->data = ti_do_false; + break; + case CLERI_GID_T_FLOAT: + nd->data = ti_do_float; + break; + case CLERI_GID_T_INT: + nd->data = ti_do_int; + break; + case CLERI_GID_T_NIL: + nd->data = ti_do_nil; + break; + case CLERI_GID_T_REGEX: + nd->data = ti_do_regex; + break; + case CLERI_GID_T_STRING: + nd->data = ti_do_string; + break; + case CLERI_GID_T_TRUE: + nd->data = ti_do_true; + break; + case CLERI_GID_TEMPLATE: + nd->data = ti_do_template; + break; + case CLERI_GID_VAR_OPT_MORE: + if (!node->next->children->next) + { + nd->data = ti_do_var; + break; + } + + switch (node->next->children->next->cl_obj->gid) + { + case CLERI_GID_FUNCTION: + nd->data = ti_do_function; + break; + case CLERI_GID_ASSIGN: + nd->data = ti_do_var_assign; + break; + case CLERI_GID_INSTANCE: + nd->data = ti_do_instance; + break; + case CLERI_GID_ENUM_: + nd->data = ti_do_enum_get; + break; + } + break; + case CLERI_GID_THING: + nd->data = ti_do_thing; + break; + case CLERI_GID_ARRAY: + nd->data = ti_do_array; + break; + case CLERI_GID_PARENTHESIS: + nd->data = ti_do_paranthesis; + break; + } + } } static inline void qbind__if_statement(ti_qbind_t * qbind, cleri_node_t * nd)