Susumu Yata
null+****@clear*****
Tue Nov 21 15:46:05 JST 2017
Susumu Yata 2017-11-21 15:46:05 +0900 (Tue, 21 Nov 2017) New Revision: d85e14a13860c0acd5f9f30c8c8b8f62af8e9279 https://github.com/groonga/groonga/commit/d85e14a13860c0acd5f9f30c8c8b8f62af8e9279 Message: ctx: resize ctx->impl->stack on demand This change enables in_values() with more than 1,024 arguments. GitHub: fix #781 Modified files: lib/ctx.c lib/expr.c lib/expr_executor.c lib/grn_ctx_impl.h Modified: lib/ctx.c (+14 -0) =================================================================== --- lib/ctx.c 2017-11-21 11:57:32 +0900 (6a9c3ee3a) +++ lib/ctx.c 2017-11-21 15:46:05 +0900 (e66aff2b5) @@ -250,7 +250,18 @@ grn_ctx_impl_init(grn_ctx *ctx) ctx->impl = NULL; return ctx->rc; } + if (!(ctx->impl->stack = GRN_MALLOCN(grn_obj *, GRN_STACK_SIZE))) { + grn_array_close(ctx, ctx->impl->values); + grn_pat_close(ctx, ctx->impl->temporary_columns); + CRITICAL_SECTION_FIN(ctx->impl->lock); + grn_io_anon_unmap(ctx, &mi, IMPL_SIZE); + grn_hash_close(ctx, ctx->impl->ios); + grn_hash_close(ctx, ctx->impl->expr_vars); + ctx->impl = NULL; + return ctx->rc; + } ctx->impl->stack_curr = 0; + ctx->impl->stack_size = GRN_STACK_SIZE; ctx->impl->curr_expr = NULL; GRN_TEXT_INIT(&ctx->impl->current_request_id, 0); ctx->impl->current_request_timer_id = NULL; @@ -505,6 +516,9 @@ grn_ctx_fin(grn_ctx *ctx) }); grn_hash_close(ctx, ctx->impl->expr_vars); } + if (ctx->impl->stack) { + GRN_FREE(ctx->impl->stack); + } if (ctx->impl->db && ctx->flags & GRN_CTX_PER_DB) { grn_obj *db = ctx->impl->db; ctx->impl->db = NULL; Modified: lib/expr.c (+43 -10) =================================================================== --- lib/expr.c 2017-11-21 11:57:32 +0900 (41e49ec3f) +++ lib/expr.c 2017-11-21 15:46:05 +0900 (62f072ad8) @@ -297,13 +297,33 @@ grn_ctx_pop(grn_ctx *ctx) } grn_rc +grn_ctx_expand_stack(grn_ctx *ctx) +{ + uint32_t stack_size = ctx->impl->stack_size * 2; + grn_obj **stack = (grn_obj **)GRN_REALLOC(ctx->impl->stack, + sizeof(grn_obj *) * stack_size); + if (!stack) { + return ctx->rc; + } + ctx->impl->stack = stack; + ctx->impl->stack_size = stack_size; + return GRN_SUCCESS; +} + +grn_rc grn_ctx_push(grn_ctx *ctx, grn_obj *obj) { - if (ctx && ctx->impl && ctx->impl->stack_curr < GRN_STACK_SIZE) { - ctx->impl->stack[ctx->impl->stack_curr++] = obj; - return GRN_SUCCESS; + if (!ctx || !ctx->impl) { + return GRN_INVALID_ARGUMENT; + } + if (ctx->impl->stack_curr >= ctx->impl->stack_size) { + grn_rc rc = grn_ctx_expand_stack(ctx); + if (rc != GRN_SUCCESS) { + return rc; + } } - return GRN_STACK_OVER_FLOW; + ctx->impl->stack[ctx->impl->stack_curr++] = obj; + return GRN_SUCCESS; } grn_obj * @@ -1427,8 +1447,9 @@ grn_expr_rewrite(grn_ctx *ctx, grn_obj *expr) block\ vp = e->values + e->values_curr;\ sp = ctx->impl->stack + ctx->impl->stack_curr;\ - s0 = sp[-1];\ - s1 = sp[-2];\ + s_ = ctx->impl->stack;\ + s0 = (sp > s_) ? sp[-1] : NULL;\ + s1 = (sp > s_ + 1) ? sp[-2] : NULL;\ } while (0) #define GEO_RESOLUTION 3600000 @@ -1508,7 +1529,13 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller) if (vp - e->values > e->values_tail) { e->values_tail = vp - e->values; }\ }\ s1 = s0;\ - if (sp >= s_ + GRN_STACK_SIZE) { ERR(GRN_INVALID_ARGUMENT, "stack overflow"); goto exit; }\ + if (sp >= s_ + ctx->impl->stack_size) {\ + if (grn_ctx_expand_stack(ctx) != GRN_SUCCESS) {\ + goto exit;\ + }\ + sp += (ctx->impl->stack - s_);\ + s_ = ctx->impl->stack;\ + }\ *sp++ = s0 = v;\ } while (0) @@ -1518,12 +1545,18 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller) s0 = s1;\ sp--;\ if (sp < s_) { ERR(GRN_INVALID_ARGUMENT, "stack underflow"); goto exit; }\ - s1 = sp[-2];\ + s1 = (sp > s_ - 1) ? sp[-2] : NULL;\ } while (0) #define ALLOC1(value) do {\ s1 = s0;\ - if (sp >= s_ + GRN_STACK_SIZE) { ERR(GRN_INVALID_ARGUMENT, "stack overflow"); goto exit; }\ + if (sp >= s_ + ctx->impl->stack_size) {\ + if (grn_ctx_expand_stack(ctx) != GRN_SUCCESS) {\ + goto exit;\ + }\ + sp += (ctx->impl->stack - s_);\ + s_ = ctx->impl->stack;\ + }\ *sp++ = s0 = value = vp++;\ if (vp - e->values > e->values_tail) { e->values_tail = vp - e->values; }\ } while (0) @@ -1547,7 +1580,7 @@ grn_proc_call(grn_ctx *ctx, grn_obj *proc, int nargs, grn_obj *caller) arg1 = s1;\ sp--;\ if (sp < s_ + 1) { ERR(GRN_INVALID_ARGUMENT, "stack underflow"); goto exit; }\ - s1 = sp[-2];\ + s1 = (sp > s_ + 1) ? sp[-2] : NULL;\ sp[-1] = s0 = value = vp++;\ if (vp - e->values > e->values_tail) { e->values_tail = vp - e->values; }\ s0->header.impl_flags |= GRN_OBJ_EXPRVALUE;\ Modified: lib/expr_executor.c (+7 -0) =================================================================== --- lib/expr_executor.c 2017-11-21 11:57:32 +0900 (4fcf93a40) +++ lib/expr_executor.c 2017-11-21 15:46:05 +0900 (c538668d1) @@ -467,6 +467,8 @@ grn_expr_executor_init_proc(grn_ctx *ctx, proc->funcs[PROC_INIT](ctx, 0, NULL, &(proc_ctx->user_data)); } +grn_rc grn_ctx_expand_stack(grn_ctx *ctx); + static grn_obj * grn_expr_executor_exec_proc(grn_ctx *ctx, grn_expr_executor *executor, @@ -496,6 +498,11 @@ grn_expr_executor_exec_proc(grn_ctx *ctx, expr->codes -= 1; args = ctx->impl->stack + ctx->impl->stack_curr; + while (ctx->impl->stack_curr + n_args > ctx->impl->stack_size) { + if (grn_ctx_expand_stack(ctx) != GRN_SUCCESS) { + return NULL; + } + } ctx->impl->stack_curr += n_args; expr->values_curr = expr->values_tail; result = proc->funcs[PROC_NEXT](ctx, Modified: lib/grn_ctx_impl.h (+2 -1) =================================================================== --- lib/grn_ctx_impl.h 2017-11-21 11:57:32 +0900 (2d72065d4) +++ lib/grn_ctx_impl.h 2017-11-21 15:46:05 +0900 (4050c37cb) @@ -161,8 +161,9 @@ struct _grn_ctx_impl { #endif /* expression portion */ - grn_obj *stack[GRN_STACK_SIZE]; + grn_obj **stack; uint32_t stack_curr; + uint32_t stack_size; grn_hash *expr_vars; grn_obj *curr_expr; grn_obj current_request_id; -------------- next part -------------- HTML����������������������������... URL: https://lists.osdn.me/mailman/archives/groonga-commit/attachments/20171121/5b24ca1c/attachment-0001.htm