From 927615e1f072d8fff3d9b84660cdce15a239e36c Mon Sep 17 00:00:00 2001 From: dearblue Date: Mon, 22 Feb 2021 23:32:43 +0900 Subject: Added other methods for `Binding` - Added to `mruby-binding-core` - `Binding#local_variable_defined?` - `Binding#local_variable_get` - `Binding#local_variable_set` - `Binding#local_variables` - `Binding#receiver` - `Binding#source_location` - `Binding#inspect` - Added to `mruby-proc-binding` - `Proc#binding` The reason for separating `Proc#binding` is that core-mrbgems has a method that returns a closure object to minimize possible problems with being able to manipulate internal variables. By separating it as different mrbgem, each user can judge this problem and incorporate it arbitrarily. --- src/proc.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'src/proc.c') diff --git a/src/proc.c b/src/proc.c index 89fcd3d28..cfaf37af6 100644 --- a/src/proc.c +++ b/src/proc.c @@ -372,6 +372,44 @@ mrb_proc_get_caller(mrb_state *mrb, struct REnv **envp) return proc; } +#define IREP_LVAR_MERGE_DEFAULT 50 +#define IREP_LVAR_MERGE_MINIMUM 8 +#define IREP_LVAR_MERGE_MAXIMUM 240 + +#ifdef MRB_IREP_LVAR_MERGE_LIMIT +# define IREP_LVAR_MERGE_LIMIT \ + ((MRB_IREP_LVAR_MERGE_LIMIT) < IREP_LVAR_MERGE_MINIMUM ? IREP_LVAR_MERGE_MINIMUM : \ + (MRB_IREP_LVAR_MERGE_LIMIT) > IREP_LVAR_MERGE_MAXIMUM ? IREP_LVAR_MERGE_MAXIMUM : \ + (MRB_IREP_LVAR_MERGE_LIMIT)) +#else +# define IREP_LVAR_MERGE_LIMIT IREP_LVAR_MERGE_DEFAULT +#endif + +void +mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, const mrb_sym *lv, const mrb_value *stack) +{ + mrb_assert(!(irep->flags & MRB_IREP_NO_FREE)); + + if ((irep->nlocals + num) > IREP_LVAR_MERGE_LIMIT) { + mrb_raise(mrb, E_RUNTIME_ERROR, "too many local variables for binding (mruby limitation)"); + } + + if (!lv) { + mrb_raise(mrb, E_RUNTIME_ERROR, "unavailable local variable names"); + } + + irep->lv = (mrb_sym*)mrb_realloc(mrb, (mrb_sym*)irep->lv, sizeof(mrb_sym) * (irep->nlocals + num)); + env->stack = (mrb_value*)mrb_realloc(mrb, env->stack, sizeof(mrb_value) * (irep->nlocals + 1 /* self */ + num)); + + mrb_sym *destlv = (mrb_sym*)irep->lv + irep->nlocals - 1 /* self */; + mrb_value *destst = env->stack + irep->nlocals; + memmove(destlv, lv, sizeof(mrb_sym) * num); + memmove(destst, stack, sizeof(mrb_value) * num); + irep->nlocals += num; + irep->nregs = irep->nlocals; + MRB_ENV_SET_LEN(env, irep->nlocals); +} + void mrb_init_proc(mrb_state *mrb) { -- cgit v1.2.3